From 0e7d4a5703f21f5db02a2299499d16a6b9bf6d4c Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 18 Mar 2013 19:52:46 +0400 Subject: [PATCH 001/205] First version of 'viz' module --- cmake/OpenCVModule.cmake | 4 +- modules/core/include/opencv2/core/affine.hpp | 6 +- modules/viz/CMakeLists.txt | 99 ++ modules/viz/include/opencv2/viz.hpp | 3 + modules/viz/include/opencv2/viz/events.hpp | 110 ++ modules/viz/include/opencv2/viz/mesh_load.hpp | 10 + modules/viz/include/opencv2/viz/types.hpp | 84 + modules/viz/include/opencv2/viz/viz3d.hpp | 71 + modules/viz/src/common.cpp | 321 ++++ modules/viz/src/interactor_style.cpp | 678 ++++++++ modules/viz/src/mesh_load.cpp | 81 + modules/viz/src/precomp.cpp | 1 + modules/viz/src/precomp.hpp | 157 ++ modules/viz/src/q/common.h | 123 ++ modules/viz/src/q/interactor_style.h | 150 ++ modules/viz/src/q/shapes.h | 124 ++ modules/viz/src/q/viz3d_impl.hpp | 469 ++++++ modules/viz/src/q/viz_types.h | 22 + modules/viz/src/shapes.cpp | 196 +++ modules/viz/src/types.cpp | 24 + modules/viz/src/viz.cpp | 1 + modules/viz/src/viz3d.cpp | 94 ++ modules/viz/src/viz3d_impl.cpp | 963 ++++++++++++ modules/viz/src/viz_main.cpp | 1398 +++++++++++++++++ modules/viz/test/test_main.cpp | 3 + modules/viz/test/test_precomp.cpp | 1 + modules/viz/test/test_precomp.hpp | 16 + modules/viz/test/test_viz3d.cpp | 133 ++ 28 files changed, 5340 insertions(+), 2 deletions(-) create mode 100644 modules/viz/CMakeLists.txt create mode 100644 modules/viz/include/opencv2/viz.hpp create mode 100644 modules/viz/include/opencv2/viz/events.hpp create mode 100644 modules/viz/include/opencv2/viz/mesh_load.hpp create mode 100644 modules/viz/include/opencv2/viz/types.hpp create mode 100644 modules/viz/include/opencv2/viz/viz3d.hpp create mode 100644 modules/viz/src/common.cpp create mode 100644 modules/viz/src/interactor_style.cpp create mode 100644 modules/viz/src/mesh_load.cpp create mode 100644 modules/viz/src/precomp.cpp create mode 100644 modules/viz/src/precomp.hpp create mode 100644 modules/viz/src/q/common.h create mode 100644 modules/viz/src/q/interactor_style.h create mode 100644 modules/viz/src/q/shapes.h create mode 100644 modules/viz/src/q/viz3d_impl.hpp create mode 100644 modules/viz/src/q/viz_types.h create mode 100644 modules/viz/src/shapes.cpp create mode 100644 modules/viz/src/types.cpp create mode 100644 modules/viz/src/viz.cpp create mode 100644 modules/viz/src/viz3d.cpp create mode 100644 modules/viz/src/viz3d_impl.cpp create mode 100644 modules/viz/src/viz_main.cpp create mode 100644 modules/viz/test/test_main.cpp create mode 100644 modules/viz/test/test_precomp.cpp create mode 100644 modules/viz/test/test_precomp.hpp create mode 100644 modules/viz/test/test_viz3d.cpp diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 48aa7139a..bd5720b30 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -432,6 +432,8 @@ macro(ocv_glob_module_sources) file(GLOB lib_hdrs "include/opencv2/*.hpp" "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h") + file(GLOB_RECURSE qq "src/q/*.h*") + file(GLOB lib_device_srcs "src/cuda/*.cu") set(device_objs "") set(lib_device_hdrs "") @@ -445,7 +447,7 @@ macro(ocv_glob_module_sources) endif() ocv_set_module_sources(${ARGN} HEADERS ${lib_hdrs} ${lib_hdrs_detail} - SOURCES ${lib_srcs} ${lib_int_hdrs} ${device_objs} ${lib_device_srcs} ${lib_device_hdrs}) + SOURCES ${lib_srcs} ${lib_int_hdrs} ${device_objs} ${lib_device_srcs} ${lib_device_hdrs} ${qq}) source_group("Src" FILES ${lib_srcs} ${lib_int_hdrs}) source_group("Include" FILES ${lib_hdrs}) diff --git a/modules/core/include/opencv2/core/affine.hpp b/modules/core/include/opencv2/core/affine.hpp index ccbc5c81b..c9329c9b6 100644 --- a/modules/core/include/opencv2/core/affine.hpp +++ b/modules/core/include/opencv2/core/affine.hpp @@ -109,6 +109,8 @@ namespace cv template operator Affine3() const; + operator cv::Mat(); + Mat4 matrix; #if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H @@ -314,6 +316,8 @@ template template inline cv::Affine3::operator Affin return Affine3(matrix); } +template inline cv::Affine3::operator cv::Mat() { return cv::Mat(matrix, false); } + template inline cv::Affine3 cv::operator*(const cv::Affine3& affine1, const cv::Affine3& affine2) { return affine2.concatenate(affine1); @@ -350,7 +354,7 @@ inline cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v) return r; } -#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H +#if (defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H) || defined CV_AFFINE_FORCE_EIGEN_PLUGIN template inline cv::Affine3::Affine3(const Eigen::Transform& affine) { diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt new file mode 100644 index 000000000..0509478fd --- /dev/null +++ b/modules/viz/CMakeLists.txt @@ -0,0 +1,99 @@ +############################################################################### +# Find qvtk +# This sets the following variables: +# QVTK_FOUND - True if QVTK was found. +# QVTK_INCLUDE_DIR - Directory containing the QVTK include files. +# QVTK_LIBRARY - QVTK library. +# if QVTK_FOUND then QVTK_INCLUDE_DIR is appended to VTK_INCLUDE_DIRS and QVTK_LIBRARY is appended to QVTK_LIBRARY_DIR +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(NOT QVTK_FOUND) + set (VTK_USE_QVTK OFF) + else(NOT QVTK_FOUND) + get_filename_component (QVTK_LIBRARY_DIR ${QVTK_LIBRARY} PATH) + set (VTK_LIBRARY_DIRS ${VTK_LIBRARY_DIRS} ${QVTK_LIBRARY_DIR}) + set (VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${QVTK_INCLUDE_DIR}) + set (VTK_USE_QVTK ON) + endif() +endmacro() + +macro(find_vtk) + find_package(VTK 5.8.0 REQUIRED) + 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 ("Warning: VTK disabled. You are to build OpenCV in STATIC but VTK is SHARED!") + endif () + endif() +endmacro() + +macro(find_boost) + # Disable the config mode of find_package(Boost) + set(Boost_NO_BOOST_CMAKE ON) + set(Boost_USE_STATIC_LIBS ON) + + find_package(Boost 1.49.0 REQUIRED COMPONENTS system thread) + + if(Boost_FOUND) + set(HAVE_BOOST ON) + + # Obtain diagnostic information about Boost's automatic linking outputted during compilation time. + add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) + include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) + link_directories(${Boost_LIBRARY_DIRS}) + message(STATUS "Boost found (include: ${Boost_INCLUDE_DIRS})") + endif() +endmacro() + +find_vtk() +find_boost() + + +find_package(OpenGL) +if (OPENGL_FOUND) + if(OPENGL_INCLUDE_DIR) + include_directories("${OPENGL_INCLUDE_DIR}") + endif() + if(OPENGL_DEFINITIONS) + add_definitions("${OPENGL_DEFINITIONS}") + endif() +endif() + + +if(NOT HAVE_VTK) + set(DEFAULT FALSE) + set(REASON "VTK was not found.") +else() + set(DEFAULT TRUE) + set(REASON) + set(VTK_USE_FILE ${VTK_USE_FILE} CACHE INTERNAL "VTK_USE_FILE") + include (${VTK_USE_FILE}) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +endif() + + +add_definitions(-DHAVE_VTK) + + +set(BUILD_opencv_viz_INIT OFF) + +include_directories(src) +set(the_description "Viz") +ocv_define_module(viz opencv_core opencv_calib3d) +#${PCL_LIBRARIES} + +target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkHybrid vtkCharts vtkFiltering vtkRendering ${OPENGL_LIBRARIES}) + +if(APPLE) + target_link_libraries(opencv_viz "-framework Cocoa") +endif() + diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp new file mode 100644 index 000000000..3e1663df5 --- /dev/null +++ b/modules/viz/include/opencv2/viz.hpp @@ -0,0 +1,3 @@ +#pragma once + +#include diff --git a/modules/viz/include/opencv2/viz/events.hpp b/modules/viz/include/opencv2/viz/events.hpp new file mode 100644 index 000000000..c39580af1 --- /dev/null +++ b/modules/viz/include/opencv2/viz/events.hpp @@ -0,0 +1,110 @@ +#pragma once + +#include +#include + +namespace cv +{ + class KeyboardEvent + { + public: + static const unsigned int Alt = 1; + static const unsigned int Ctrl = 2; + static const unsigned int Shift = 4; + + /** \brief Constructor + * \param[in] action true for key was pressed, false for released + * \param[in] key_sym the key-name that caused the action + * \param[in] key the key code that caused the action + * \param[in] alt whether the alt key was pressed at the time where this event was triggered + * \param[in] ctrl whether the ctrl was pressed at the time where this event was triggered + * \param[in] shift whether the shift was pressed at the time where this event was triggered + */ + KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); + + bool isAltPressed () const; + bool isCtrlPressed () const; + bool isShiftPressed () const; + + unsigned char getKeyCode () const; + + const std::string& getKeySym () const; + bool keyDown () const; + bool keyUp () const; + + protected: + + bool action_; + unsigned int modifiers_; + unsigned char key_code_; + std::string key_sym_; + }; + + class MouseEvent + { + public: + enum Type + { + MouseMove = 1, + MouseButtonPress, + MouseButtonRelease, + MouseScrollDown, + MouseScrollUp, + MouseDblClick + } ; + + enum MouseButton + { + NoButton = 0, + LeftButton, + MiddleButton, + RightButton, + VScroll /*other buttons, scroll wheels etc. may follow*/ + } ; + + MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); + + + Type type; + MouseButton button; + Point pointer; + unsigned int key_state; + }; +} + +//////////////////////////////////////////////////////////////////// +/// Implementation + +inline cv::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) + : action_ (_action), modifiers_ (0), key_code_(key), key_sym_ (_key_sym) +{ + if (alt) + modifiers_ = Alt; + + if (ctrl) + modifiers_ |= Ctrl; + + if (shift) + modifiers_ |= Shift; +} + +inline bool cv::KeyboardEvent::isAltPressed () const { return (modifiers_ & Alt) != 0; } +inline bool cv::KeyboardEvent::isCtrlPressed () const { return (modifiers_ & Ctrl) != 0; } +inline bool cv::KeyboardEvent::isShiftPressed () const { return (modifiers_ & Shift) != 0; } +inline unsigned char cv::KeyboardEvent::getKeyCode () const { return key_code_; } +inline const std::string& cv::KeyboardEvent::getKeySym () const { return (key_sym_); } +inline bool cv::KeyboardEvent::keyDown () const { return action_; } +inline bool cv::KeyboardEvent::keyUp () const { return !action_; } + +inline cv::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) + : type(_type), button(_button), pointer(_p), key_state(0) +{ + if (alt) + key_state = KeyboardEvent::Alt; + + if (ctrl) + key_state |= KeyboardEvent::Ctrl; + + if (shift) + key_state |= KeyboardEvent::Shift; +} diff --git a/modules/viz/include/opencv2/viz/mesh_load.hpp b/modules/viz/include/opencv2/viz/mesh_load.hpp new file mode 100644 index 000000000..737679c14 --- /dev/null +++ b/modules/viz/include/opencv2/viz/mesh_load.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include +#include +#include + +namespace temp_viz +{ + CV_EXPORTS Mesh3d::Ptr mesh_load(const String& file); +} diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp new file mode 100644 index 000000000..6085da2f2 --- /dev/null +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include +#include + +namespace temp_viz +{ + //qt creator hack + typedef cv::Scalar Scalar; + typedef cv::Mat Mat; + typedef std::string String; + + typedef cv::Vec3d Vec3d; + typedef cv::Vec4d Vec4d; + typedef cv::Vec2d Vec2d; + typedef cv::Vec2i Vec2i; + typedef cv::Matx33d Matx33d; + typedef cv::Affine3f Affine3f; + typedef cv::Affine3d Affine3d; + typedef cv::Point3f Point3f; + typedef cv::Matx44d Matx44d; + typedef cv::Matx44f Matx44f; + typedef cv::Size Size; + typedef cv::Point Point; + + + + struct CV_EXPORTS ModelCoefficients + { + std::vector values; + }; + + + class CV_EXPORTS Color : public Scalar + { + public: + Color(); + Color(double gray); + Color(double blue, double green, double red); + + Color(const Scalar& color); + + static Color black(); + static Color blue(); + static Color green(); + static Color cyan(); + + static Color red(); + static Color magenta(); + static Color yellow(); + static Color white(); + + static Color gray(); + }; + + + struct CV_EXPORTS Vertices + { + std::vector vertices; + }; + + class CV_EXPORTS Mesh3d + { + public: + typedef cv::Ptr Ptr; + + Mat cloud, colors; + std::vector polygons; + }; + + + inline Color vtkcolor(const Color& color) + { + Color scaled_color = color * (1.0/255.0); + std::swap(scaled_color[0], scaled_color[2]); + return scaled_color; + } + + inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } + + template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } +} diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp new file mode 100644 index 000000000..e48f5202f --- /dev/null +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -0,0 +1,71 @@ +#pragma once + +#if !defined YES_I_AGREE_THAT_VIZ_API_IS_NOT_STABLE_NOW_AND_BINARY_COMPARTIBILITY_WONT_BE_SUPPORTED + //#error "Viz is in beta state now. Please define macro above to use it" +#endif + +#include +#include + + +#include +#include + +namespace temp_viz +{ + class CV_EXPORTS Viz3d + { + public: + + typedef cv::Ptr Ptr; + + Viz3d(const String& window_name = String()); + ~Viz3d(); + + void setBackgroundColor(const Color& color = Color::black()); + + void addCoordinateSystem(double scale, const Affine3f& t, const String &id = "coordinate"); + + void addPointCloud(const Mat& cloud, const Mat& colors, const String& id = "cloud", const Mat& mask = Mat()); + + bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); + + + + + bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); + bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); + bool removeCoordinateSystem (const String &id = "coordinate"); + + + bool updatePointCloud (const Mat& cloud, const Mat& colors, const String& id = "cloud", const Mat& mask = Mat()); + + + bool addPolygonMesh (const Mesh3d& mesh, const String &id = "polygon"); + bool updatePolygonMesh (const Mesh3d& mesh, const String &id = "polygon"); + + bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String &id = "polyline"); + + + bool addText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String &id = ""); + + + bool addPolygon(const Mat& cloud, const Color& color, const String &id = "polygon"); + + bool addSphere (const Point3f ¢er, double radius, const Color& color, const String &id = "sphere"); + + + void spin (); + void spinOnce (int time = 1, bool force_redraw = false); + + private: + Viz3d(const Viz3d&); + Viz3d& operator=(const Viz3d&); + + struct VizImpl; + VizImpl* impl_; + }; +} + + + diff --git a/modules/viz/src/common.cpp b/modules/viz/src/common.cpp new file mode 100644 index 000000000..78678a069 --- /dev/null +++ b/modules/viz/src/common.cpp @@ -0,0 +1,321 @@ +#include +#include +#include + + +///////////////////////////////////////////////////////////////////////////////////////////// + +//Eigen::Matrix4d temp_viz::vtkToEigen (vtkMatrix4x4* vtk_matrix) +//{ +// Eigen::Matrix4d eigen_matrix = Eigen::Matrix4d::Identity (); +// for (int i=0; i < 4; i++) +// for (int j=0; j < 4; j++) +// eigen_matrix (i, j) = vtk_matrix->GetElement (i, j); + +// return eigen_matrix; +//} + +/////////////////////////////////////////////////////////////////////////////////////////////// +//Eigen::Vector2i temp_viz::worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height) +//{ +// // Transform world to clipping coordinates +// Eigen::Vector4d world (view_projection_matrix * world_pt); +// // Normalize w-component +// world /= world.w (); + +// // X/Y screen space coordinate +// int screen_x = int (floor (double (((world.x () + 1) / 2.0) * width) + 0.5)); +// int screen_y = int (floor (double (((world.y () + 1) / 2.0) * height) + 0.5)); + +// // Calculate -world_pt.y () because the screen Y axis is oriented top->down, ie 0 is top-left +// //int winY = (int) floor ( (double) (((1 - world_pt.y ()) / 2.0) * height) + 0.5); // top left + +// return (Eigen::Vector2i (screen_x, screen_y)); +//} + +///////////////////////////////////////////////////////////////////////////////////////////// +//void temp_viz::getViewFrustum (const Eigen::Matrix4d &view_projection_matrix, double planes[24]) +//{ +// // Set up the normals +// Eigen::Vector4d normals[6]; +// for (int i=0; i < 6; i++) +// { +// normals[i] = Eigen::Vector4d (0.0, 0.0, 0.0, 1.0); + +// // if i is even set to -1, if odd set to +1 +// normals[i] (i/2) = 1 - (i%2)*2; +// } + +// // Transpose the matrix for use with normals +// Eigen::Matrix4d view_matrix = view_projection_matrix.transpose (); + +// // Transform the normals to world coordinates +// for (int i=0; i < 6; i++) +// { +// normals[i] = view_matrix * normals[i]; + +// double f = 1.0/sqrt (normals[i].x () * normals[i].x () + +// normals[i].y () * normals[i].y () + +// normals[i].z () * normals[i].z ()); + +// planes[4*i + 0] = normals[i].x ()*f; +// planes[4*i + 1] = normals[i].y ()*f; +// planes[4*i + 2] = normals[i].z ()*f; +// planes[4*i + 3] = normals[i].w ()*f; +// } +//} + +//int temp_viz::cullFrustum (double frustum[24], const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb) +//{ +// int result = PCL_INSIDE_FRUSTUM; + +// for(int i =0; i < 6; i++){ +// double a = frustum[(i*4)]; +// double b = frustum[(i*4)+1]; +// double c = frustum[(i*4)+2]; +// double d = frustum[(i*4)+3]; + +// //cout << i << ": " << a << "x + " << b << "y + " << c << "z + " << d << endl; + +// // Basic VFC algorithm +// Eigen::Vector3d center ((max_bb.x () - min_bb.x ()) / 2 + min_bb.x (), +// (max_bb.y () - min_bb.y ()) / 2 + min_bb.y (), +// (max_bb.z () - min_bb.z ()) / 2 + min_bb.z ()); + +// Eigen::Vector3d radius (fabs (static_cast (max_bb.x () - center.x ())), +// fabs (static_cast (max_bb.y () - center.y ())), +// fabs (static_cast (max_bb.z () - center.z ()))); + +// double m = (center.x () * a) + (center.y () * b) + (center.z () * c) + d; +// double n = (radius.x () * fabs(a)) + (radius.y () * fabs(b)) + (radius.z () * fabs(c)); + +// if (m + n < 0){ +// result = PCL_OUTSIDE_FRUSTUM; +// break; +// } + +// if (m - n < 0) +// { +// result = PCL_INTERSECT_FRUSTUM; +// } +// } + +// return result; +//} + +//void +//temp_viz::getModelViewPosition (Eigen::Matrix4d model_view_matrix, Eigen::Vector3d &position) +//{ +// //Compute eye or position from model view matrix +// Eigen::Matrix4d inverse_model_view_matrix = model_view_matrix.inverse(); +// for (int i=0; i < 3; i++) +// { +// position(i) = inverse_model_view_matrix(i, 3); +// } +//} + +// Lookup table of max 6 bounding box vertices, followed by number of vertices, ie {v0, v1, v2, v3, v4, v5, nv} +// +// 3--------2 +// /| /| Y 0 = xmin, ymin, zmin +// / | / | | 6 = xmax, ymax. zmax +// 7--------6 | | +// | | | | | +// | 0-----|--1 +------X +// | / | / / +// |/ |/ / +// 4--------5 Z + +int hull_vertex_table[43][7] = { + { 0, 0, 0, 0, 0, 0, 0 }, // inside + { 0, 4, 7, 3, 0, 0, 4 }, // left + { 1, 2, 6, 5, 0, 0, 4 }, // right + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 5, 4, 0, 0, 4 }, // bottom + { 0, 1, 5, 4, 7, 3, 6 }, // bottom, left + { 0, 1, 2, 6, 5, 4, 6 }, // bottom, right + { 0, 0, 0, 0, 0, 0, 0 }, + { 2, 3, 7, 6, 0, 0, 4 }, // top + { 4, 7, 6, 2, 3, 0, 6 }, // top, left + { 2, 3, 7, 6, 5, 1, 6 }, // top, right + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 3, 2, 1, 0, 0, 4 }, // front + { 0, 4, 7, 3, 2, 1, 6 }, // front, left + { 0, 3, 2, 6, 5, 1, 6 }, // front, right + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 3, 2, 1, 5, 4, 6 }, // front, bottom + { 2, 1, 5, 4, 7, 3, 6 }, // front, bottom, left + { 0, 3, 2, 6, 5, 4, 6 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 3, 7, 6, 2, 1, 6 }, // front, top + { 0, 4, 7, 6, 2, 1, 6 }, // front, top, left + { 0, 3, 7, 6, 5, 1, 6 }, // front, top, right + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 4, 5, 6, 7, 0, 0, 4 }, // back + { 4, 5, 6, 7, 3, 0, 6 }, // back, left + { 1, 2, 6, 7, 4, 5, 6 }, // back, right + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 5, 6, 7, 4, 6 }, // back, bottom + { 0, 1, 5, 6, 7, 3, 6 }, // back, bottom, left + { 0, 1, 2, 6, 7, 4, 6 }, // back, bottom, right + { 0, 0, 0, 0, 0, 0, 0 }, + { 2, 3, 7, 4, 5, 6, 6 }, // back, top + { 0, 4, 5, 6, 2, 3, 6 }, // back, top, left + { 1, 2, 3, 7, 4, 5, 6 } // back, top, right +}; + +///////////////////////////////////////////////////////////////////////////////////////////// +//float +//temp_viz::viewScreenArea ( +// const Eigen::Vector3d &eye, +// const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, +// const Eigen::Matrix4d &view_projection_matrix, int width, int height) +//{ +// Eigen::Vector4d bounding_box[8]; +// bounding_box[0] = Eigen::Vector4d(min_bb.x (), min_bb.y (), min_bb.z (), 1.0); +// bounding_box[1] = Eigen::Vector4d(max_bb.x (), min_bb.y (), min_bb.z (), 1.0); +// bounding_box[2] = Eigen::Vector4d(max_bb.x (), max_bb.y (), min_bb.z (), 1.0); +// bounding_box[3] = Eigen::Vector4d(min_bb.x (), max_bb.y (), min_bb.z (), 1.0); +// bounding_box[4] = Eigen::Vector4d(min_bb.x (), min_bb.y (), max_bb.z (), 1.0); +// bounding_box[5] = Eigen::Vector4d(max_bb.x (), min_bb.y (), max_bb.z (), 1.0); +// bounding_box[6] = Eigen::Vector4d(max_bb.x (), max_bb.y (), max_bb.z (), 1.0); +// bounding_box[7] = Eigen::Vector4d(min_bb.x (), max_bb.y (), max_bb.z (), 1.0); + +// // Compute 6-bit code to classify eye with respect to the 6 defining planes +// int pos = ((eye.x () < bounding_box[0].x ()) ) // 1 = left +// + ((eye.x () > bounding_box[6].x ()) << 1) // 2 = right +// + ((eye.y () < bounding_box[0].y ()) << 2) // 4 = bottom +// + ((eye.y () > bounding_box[6].y ()) << 3) // 8 = top +// + ((eye.z () < bounding_box[0].z ()) << 4) // 16 = front +// + ((eye.z () > bounding_box[6].z ()) << 5); // 32 = back + +// // Look up number of vertices +// int num = hull_vertex_table[pos][6]; +// if (num == 0) +// { +// return (float (width * height)); +// } +// //return 0.0; + + +// // cout << "eye: " << eye.x() << " " << eye.y() << " " << eye.z() << endl; +// // cout << "min: " << bounding_box[0].x() << " " << bounding_box[0].y() << " " << bounding_box[0].z() << endl; +// // +// // cout << "pos: " << pos << " "; +// // switch(pos){ +// // case 0: cout << "inside" << endl; break; +// // case 1: cout << "left" << endl; break; +// // case 2: cout << "right" << endl; break; +// // case 3: +// // case 4: cout << "bottom" << endl; break; +// // case 5: cout << "bottom, left" << endl; break; +// // case 6: cout << "bottom, right" << endl; break; +// // case 7: +// // case 8: cout << "top" << endl; break; +// // case 9: cout << "top, left" << endl; break; +// // case 10: cout << "top, right" << endl; break; +// // case 11: +// // case 12: +// // case 13: +// // case 14: +// // case 15: +// // case 16: cout << "front" << endl; break; +// // case 17: cout << "front, left" << endl; break; +// // case 18: cout << "front, right" << endl; break; +// // case 19: +// // case 20: cout << "front, bottom" << endl; break; +// // case 21: cout << "front, bottom, left" << endl; break; +// // case 22: +// // case 23: +// // case 24: cout << "front, top" << endl; break; +// // case 25: cout << "front, top, left" << endl; break; +// // case 26: cout << "front, top, right" << endl; break; +// // case 27: +// // case 28: +// // case 29: +// // case 30: +// // case 31: +// // case 32: cout << "back" << endl; break; +// // case 33: cout << "back, left" << endl; break; +// // case 34: cout << "back, right" << endl; break; +// // case 35: +// // case 36: cout << "back, bottom" << endl; break; +// // case 37: cout << "back, bottom, left" << endl; break; +// // case 38: cout << "back, bottom, right" << endl; break; +// // case 39: +// // case 40: cout << "back, top" << endl; break; +// // case 41: cout << "back, top, left" << endl; break; +// // case 42: cout << "back, top, right" << endl; break; +// // } + +// //return -1 if inside +// Eigen::Vector2d dst[8]; +// for (int i = 0; i < num; i++) +// { +// Eigen::Vector4d world_pt = bounding_box[hull_vertex_table[pos][i]]; +// Eigen::Vector2i screen_pt = temp_viz::worldToView(world_pt, view_projection_matrix, width, height); +// // cout << "point[" << i << "]: " << screen_pt.x() << " " << screen_pt.y() << endl; +// dst[i] = Eigen::Vector2d(screen_pt.x (), screen_pt.y ()); +// } + +// double sum = 0.0; +// for (int i = 0; i < num; ++i) +// { +// sum += (dst[i].x () - dst[(i+1) % num].x ()) * (dst[i].y () + dst[(i+1) % num].y ()); +// } + +// return (fabsf (float (sum * 0.5f))); +//} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Camera::computeViewMatrix (Affine3d& view_mat) const +{ + //constructs view matrix from camera pos, view up, and the point it is looking at + //this code is based off of gluLookAt http://www.opengl.org/wiki/GluLookAt_code + + Vec3d zAxis = normalized(focal - pos); + Vec3d xAxis = normalized(zAxis.cross(view_up)); + Vec3d yAxis = xAxis.cross (zAxis); + + Matx33d R; + + R(0, 0) = xAxis[0]; R(0, 1) = xAxis[1]; R(0, 2) = xAxis[2]; + R(1, 0) = yAxis[0]; R(1, 1) = yAxis[1]; R(1, 2) = yAxis[2]; + R(1, 0) = -zAxis[0]; R(2, 1) = -zAxis[1]; R(2, 2) = -zAxis[2]; + + Vec3d t = R * (-pos); + + view_mat = Affine3d(R, t); +} + +/////////////////////////////////////////////////////////////////////// +void temp_viz::Camera::computeProjectionMatrix (Matx44d& proj) const +{ + double top = clip[0] * tan (0.5 * fovy); + double left = -(top * window_size[0]) / window_size[1]; + double right = -left; + double bottom = -top; + + double temp1 = 2.0 * clip[0]; + double temp2 = 1.0 / (right - left); + double temp3 = 1.0 / (top - bottom); + double temp4 = 1.0 / clip[1] - clip[0]; + + proj = Matx44d::zeros(); + + proj(0,0) = temp1 * temp2; + proj(1,1) = temp1 * temp3; + proj(0,2) = (right + left) * temp2; + proj(1,2) = (top + bottom) * temp3; + proj(2,2) = (-clip[1] - clip[0]) * temp4; + proj(3,2) = -1.0; + proj(2,3) = (-temp1 * clip[1]) * temp4; +} diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp new file mode 100644 index 000000000..d13ad3c35 --- /dev/null +++ b/modules/viz/src/interactor_style.cpp @@ -0,0 +1,678 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include + +using namespace cv; + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::Initialize () +{ + modifier_ = temp_viz::InteractorStyle::KB_MOD_ALT; + // Set windows size (width, height) to unknown (-1) + win_size_ = Vec2i(-1, -1); + win_pos_ = Vec2i(0, 0); + max_win_size_ = Vec2i(-1, -1); + + // Create the image filter and PNG writer objects + wif_ = vtkSmartPointer::New (); + snapshot_writer_ = vtkSmartPointer::New (); + snapshot_writer_->SetInputConnection (wif_->GetOutputPort ()); + + init_ = true; + stereo_anaglyph_mask_default_ = true; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::saveScreenshot (const std::string &file) +{ + FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); + wif_->SetInput (Interactor->GetRenderWindow ()); + wif_->Modified (); // Update the WindowToImageFilter + snapshot_writer_->Modified (); + snapshot_writer_->SetFileName (file.c_str ()); + snapshot_writer_->Write (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::zoomIn () +{ + FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); + // Zoom in + StartDolly (); + double factor = 10.0 * 0.2 * .5; + Dolly (pow (1.1, factor)); + EndDolly (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::zoomOut () +{ + FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); + // Zoom out + StartDolly (); + double factor = 10.0 * -0.2 * .5; + Dolly (pow (1.1, factor)); + EndDolly (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_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; + std::string key (Interactor->GetKeySym ()); + if (key.find ("XF86ZoomIn") != std::string::npos) + zoomIn (); + else if (key.find ("XF86ZoomOut") != std::string::npos) + zoomOut (); + + bool keymod = false; + switch (modifier_) + { + case KB_MOD_ALT: + { + keymod = Interactor->GetAltKey (); + break; + } + case KB_MOD_CTRL: + { + keymod = Interactor->GetControlKey (); + break; + } + case KB_MOD_SHIFT: + { + keymod = Interactor->GetShiftKey (); + break; + } + } + + 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; + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +boost::signals2::connection temp_viz::InteractorStyle::registerMouseCallback (boost::function callback) +{ + return (mouse_signal_.connect (callback)); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +boost::signals2::connection temp_viz::InteractorStyle::registerKeyboardCallback (boost::function callback) +{ + return (keyboard_signal_.connect (callback)); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void +temp_viz::InteractorStyle::OnKeyDown () +{ + if (!init_) + { + std::cout << "[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing" << std::endl; + return; + } + + if (!renderer_) + { + std::cout << "[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing." << std::endl; + return; + } + + FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); + + if (wif_->GetInput () == NULL) + { + wif_->SetInput (Interactor->GetRenderWindow ()); + wif_->Modified (); + snapshot_writer_->Modified (); + } + + // Save the initial windows width/height + if (win_size_[0] == -1 || win_size_[1] == -1) + win_size_ = Vec2i(Interactor->GetRenderWindow ()->GetSize ()); + + + // Get the status of special keys (Cltr+Alt+Shift) + bool shift = Interactor->GetShiftKey (); + bool ctrl = Interactor->GetControlKey (); + bool alt = Interactor->GetAltKey (); + + bool keymod = false; + switch (modifier_) + { + case KB_MOD_ALT: + { + keymod = alt; + break; + } + case KB_MOD_CTRL: + { + keymod = ctrl; + break; + } + case KB_MOD_SHIFT: + { + keymod = shift; + break; + } + } + + 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" + " c, C : display current camera/window parameters\n" + " f, F : fly to point mode\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" + " SHIFT + left click : select a point\n" + << std::endl; + break; + } + + // Switch representation to points + case 'p': case 'P': + { + vtkSmartPointer ac = CurrentRenderer->GetActors (); + vtkCollectionSimpleIterator ait; + for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) + { + for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) + { + vtkSmartPointer apart = reinterpret_cast (path->GetLastNode ()->GetViewProp ()); + apart->GetProperty ()->SetRepresentationToPoints (); + } + } + break; + } + // Save a PNG snapshot with the current screen + case 'j': case 'J': + { + char cam_fn[80], snapshot_fn[80]; + unsigned t = static_cast (time (0)); + sprintf (snapshot_fn, "screenshot-%d.png" , t); + saveScreenshot (snapshot_fn); + + sprintf (cam_fn, "screenshot-%d.cam", t); + ofstream ofs_cam; + ofs_cam.open (cam_fn); + vtkSmartPointer cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); + double clip[2], focal[3], pos[3], view[3]; + cam->GetClippingRange (clip); + cam->GetFocalPoint (focal); + cam->GetPosition (pos); + cam->GetViewUp (view); +#ifndef M_PI + # define M_PI 3.14159265358979323846 // pi +#endif + + int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); + int *win_size = Interactor->GetRenderWindow ()->GetSize (); + ofs_cam << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << + pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << + cam->GetViewAngle () / 180.0 * M_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] + << endl; + ofs_cam.close (); + + std::cout << "Screenshot (" << snapshot_fn << ") and camera information (" << cam_fn << ") successfully captured." << std::endl; + break; + } + // display current camera settings/parameters + case 'c': case 'C': + { + vtkSmartPointer cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); + double clip[2], focal[3], pos[3], view[3]; + cam->GetClippingRange (clip); + cam->GetFocalPoint (focal); + cam->GetPosition (pos); + cam->GetViewUp (view); + int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); + int *win_size = Interactor->GetRenderWindow ()->GetSize (); + std::cerr << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << + pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << + cam->GetViewAngle () / 180.0 * M_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] + << endl; + break; + } + case '=': + { + zoomIn(); + break; + } + case 43: // KEY_PLUS + { + if(alt) + zoomIn (); + else + { + vtkSmartPointer ac = CurrentRenderer->GetActors (); + vtkCollectionSimpleIterator ait; + for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) + { + for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) + { + vtkSmartPointer apart = reinterpret_cast (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 ac = CurrentRenderer->GetActors (); + vtkCollectionSimpleIterator ait; + for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) + { + for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) + { + vtkSmartPointer apart = static_cast (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 (keymod) + { + 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; + vtkAssemblyPath *path = NULL; + Interactor->GetPicker ()->Pick (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1], 0.0, CurrentRenderer); + vtkAbstractPropPicker *picker; + if ((picker = vtkAbstractPropPicker::SafeDownCast (Interactor->GetPicker ()))) + path = picker->GetPath (); + if (path != NULL) + Interactor->FlyTo (CurrentRenderer, picker->GetPickPosition ()); + AnimState = VTKIS_ANIM_OFF; + } + break; + } + // 's'/'S' w/out ALT + case 's': case 'S': + { + if (keymod) + { + int stereo_render = Interactor->GetRenderWindow ()->GetStereoRender (); + if (!stereo_render) + { + if (stereo_anaglyph_mask_default_) + { + Interactor->GetRenderWindow ()->SetAnaglyphColorMask (4, 3); + stereo_anaglyph_mask_default_ = false; + } + else + { + Interactor->GetRenderWindow ()->SetAnaglyphColorMask (2, 5); + stereo_anaglyph_mask_default_ = true; + } + } + Interactor->GetRenderWindow ()->SetStereoRender (!stereo_render); + Interactor->GetRenderWindow ()->Render (); + Interactor->Render (); + } + else + Superclass::OnKeyDown (); + break; + } + + case 'o': case 'O': + { + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); + int flag = cam->GetParallelProjection (); + cam->SetParallelProjection (!flag); + + CurrentRenderer->SetActiveCamera (cam); + CurrentRenderer->Render (); + break; + } + + // Overwrite the camera reset + case 'r': case 'R': + { + if (!keymod) + { + Superclass::OnKeyDown (); + break; + } + + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); + + static CloudActorMap::iterator it = actors_->begin (); + // it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault. + bool found_transformation = false; + + for (size_t idx = 0; idx < actors_->size (); ++idx, ++it) + { + if (it == actors_->end ()) + it = actors_->begin (); + + const CloudActor& actor = it->second; + if (actor.viewpoint_transformation_.GetPointer ()) + { + found_transformation = true; + break; + } + } + + // if a valid transformation was found, use it otherwise fall back to default view point. + if (found_transformation) + { + const CloudActor& actor = it->second; + cam->SetPosition (actor.viewpoint_transformation_->GetElement (0, 3), + actor.viewpoint_transformation_->GetElement (1, 3), + actor.viewpoint_transformation_->GetElement (2, 3)); + + cam->SetFocalPoint (actor.viewpoint_transformation_->GetElement (0, 3) - actor.viewpoint_transformation_->GetElement (0, 2), + actor.viewpoint_transformation_->GetElement (1, 3) - actor.viewpoint_transformation_->GetElement (1, 2), + actor.viewpoint_transformation_->GetElement (2, 3) - actor.viewpoint_transformation_->GetElement (2, 2)); + + cam->SetViewUp (actor.viewpoint_transformation_->GetElement (0, 1), + actor.viewpoint_transformation_->GetElement (1, 1), + actor.viewpoint_transformation_->GetElement (2, 1)); + } + 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 != actors_->end ()) + ++it; + else + it = actors_->begin (); + + CurrentRenderer->SetActiveCamera (cam); + CurrentRenderer->ResetCameraClippingRange (); + CurrentRenderer->Render (); + break; + } + + case 'q': case 'Q': + { + Interactor->ExitCallback (); + return; + } + default: + { + Superclass::OnKeyDown (); + break; + } + } + + KeyboardEvent event (true, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + keyboard_signal_ (event); + + renderer_->Render (); + Interactor->Render (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnKeyUp () +{ + KeyboardEvent event (false, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + keyboard_signal_ (event); + Superclass::OnKeyUp (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnMouseMove () +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event (MouseEvent::MouseMove, MouseEvent::NoButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + Superclass::OnMouseMove (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnLeftButtonDown () +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event (type, MouseEvent::LeftButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + Superclass::OnLeftButtonDown (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnLeftButtonUp () +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + Superclass::OnLeftButtonUp (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnMiddleButtonDown () +{ + Vec2i p(Interactor->GetEventPosition()); + + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event (type, MouseEvent::MiddleButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + Superclass::OnMiddleButtonDown (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnMiddleButtonUp () +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + Superclass::OnMiddleButtonUp (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnRightButtonDown () +{ + Vec2i p(Interactor->GetEventPosition()); + + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event (type, MouseEvent::RightButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + Superclass::OnRightButtonDown (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnRightButtonUp () +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + Superclass::OnRightButtonUp (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnMouseWheelForward () +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event (MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + if (Interactor->GetRepeatCount ()) + mouse_signal_ (event); + + if (Interactor->GetAltKey ()) + { + // zoom + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); + double opening_angle = cam->GetViewAngle (); + if (opening_angle > 15.0) + opening_angle -= 1.0; + + cam->SetViewAngle (opening_angle); + cam->Modified (); + CurrentRenderer->SetActiveCamera (cam); + CurrentRenderer->ResetCameraClippingRange (); + CurrentRenderer->Modified (); + CurrentRenderer->Render (); + renderer_->Render (); + Interactor->Render (); + } + else + Superclass::OnMouseWheelForward (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnMouseWheelBackward () +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event (MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + mouse_signal_ (event); + if (Interactor->GetRepeatCount ()) + mouse_signal_ (event); + + if (Interactor->GetAltKey ()) + { + // zoom + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); + double opening_angle = cam->GetViewAngle (); + if (opening_angle < 170.0) + opening_angle += 1.0; + + cam->SetViewAngle (opening_angle); + cam->Modified (); + CurrentRenderer->SetActiveCamera (cam); + CurrentRenderer->ResetCameraClippingRange (); + CurrentRenderer->Modified (); + CurrentRenderer->Render (); + renderer_->Render (); + Interactor->Render (); + } + else + Superclass::OnMouseWheelBackward (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::OnTimer () +{ + if (!init_) + { + std::cout << "[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n" << std::endl; + return; + } + + if (!renderer_) + { + std::cout << "[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing." << std::endl; + return; + } + renderer_->Render (); + Interactor->Render (); +} + + +namespace temp_viz +{ + // Standard VTK macro for *New () + vtkStandardNewMacro (InteractorStyle); + +} + diff --git a/modules/viz/src/mesh_load.cpp b/modules/viz/src/mesh_load.cpp new file mode 100644 index 000000000..8b0a678b7 --- /dev/null +++ b/modules/viz/src/mesh_load.cpp @@ -0,0 +1,81 @@ +#include + +#include "precomp.hpp" + +#include +#include +#include +#include +#include + +temp_viz::Mesh3d::Ptr temp_viz::mesh_load(const String& file) +{ + Mesh3d::Ptr mesh = new Mesh3d(); + + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(file.c_str()); + reader->Update(); + vtkSmartPointer poly_data = reader->GetOutput (); + + typedef unsigned int uint32_t; + mesh->polygons.clear(); + + vtkSmartPointer mesh_points = poly_data->GetPoints (); + vtkIdType nr_points = mesh_points->GetNumberOfPoints (); + vtkIdType nr_polygons = poly_data->GetNumberOfPolys (); + + mesh->cloud.create(1, nr_points, CV_32FC3); + + double point_xyz[3]; + for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) + { + mesh_points->GetPoint (i, &point_xyz[0]); + mesh->cloud.ptr()[i] = cv::Point3d(point_xyz[0], point_xyz[1], point_xyz[2]);; + } + + // Then the color information, if any + vtkUnsignedCharArray* poly_colors = NULL; + if (poly_data->GetPointData() != NULL) + poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("Colors")); + + // some applications do not save the name of scalars (including PCL's native vtk_io) + if (!poly_colors && poly_data->GetPointData () != NULL) + poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("scalars")); + + if (!poly_colors && poly_data->GetPointData () != NULL) + poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("RGB")); + + // TODO: currently only handles rgb values with 3 components + if (poly_colors && (poly_colors->GetNumberOfComponents () == 3)) + { + mesh->colors.create(1, nr_points, CV_8UC3); + unsigned char point_color[3]; + + for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) + { + poly_colors->GetTupleValue (i, &point_color[0]); + + //RGB or BGR????? + mesh->colors.ptr()[i] = cv::Vec3b(point_color[0], point_color[1], point_color[2]); + } + } + else + mesh->colors.release(); + + // Now handle the polygons + mesh->polygons.resize (nr_polygons); + vtkIdType* cell_points; + vtkIdType nr_cell_points; + vtkCellArray * mesh_polygons = poly_data->GetPolys (); + mesh_polygons->InitTraversal (); + int id_poly = 0; + while (mesh_polygons->GetNextCell (nr_cell_points, cell_points)) + { + mesh->polygons[id_poly].vertices.resize (nr_cell_points); + for (int i = 0; i < nr_cell_points; ++i) + mesh->polygons[id_poly].vertices[i] = static_cast (cell_points[i]); + ++id_poly; + } + + return mesh; +} diff --git a/modules/viz/src/precomp.cpp b/modules/viz/src/precomp.cpp new file mode 100644 index 000000000..89d145003 --- /dev/null +++ b/modules/viz/src/precomp.cpp @@ -0,0 +1 @@ +#include "precomp.hpp" \ No newline at end of file diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp new file mode 100644 index 000000000..ec60d5021 --- /dev/null +++ b/modules/viz/src/precomp.hpp @@ -0,0 +1,157 @@ +#pragma once + +#include +#include +#include + + +#include +#include +#include +#include + +#include + +#if defined __GNUC__ +#pragma GCC system_header +#ifdef __DEPRECATED +#undef __DEPRECATED +#define __DEPRECATED_DISABLED__ +#endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include +#include +#include + + + +#include +#include +#include +#include +#include + + + +#if defined __GNUC__ && defined __DEPRECATED_DISABLED__ +#define __DEPRECATED +#undef __DEPRECATED_DISABLED__ +#endif diff --git a/modules/viz/src/q/common.h b/modules/viz/src/q/common.h new file mode 100644 index 000000000..5562bf4f6 --- /dev/null +++ b/modules/viz/src/q/common.h @@ -0,0 +1,123 @@ +#pragma once + +#include +#include +#include +//#include + +namespace temp_viz +{ + //CV_EXPORTS Eigen::Matrix4d vtkToEigen (vtkMatrix4x4* vtk_matrix); + //CV_EXPORTS Eigen::Vector2i worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height); + //CV_EXPORTS void getViewFrustum (const Eigen::Matrix4d &view_projection_matrix, double planes[24]); + +// enum FrustumCull +// { +// PCL_INSIDE_FRUSTUM, +// PCL_INTERSECT_FRUSTUM, +// PCL_OUTSIDE_FRUSTUM +// }; + + //CV_EXPORTS int cullFrustum (double planes[24], const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb); + //CV_EXPORTS float viewScreenArea (const Eigen::Vector3d &eye, const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const Eigen::Matrix4d &view_projection_matrix, int width, int height); + + enum RenderingProperties + { + VIZ_POINT_SIZE, + VIZ_OPACITY, + VIZ_LINE_WIDTH, + VIZ_FONT_SIZE, + VIZ_COLOR, + VIZ_REPRESENTATION, + VIZ_IMMEDIATE_RENDERING, + VIZ_SHADING + }; + + enum RenderingRepresentationProperties + { + REPRESENTATION_POINTS, + REPRESENTATION_WIREFRAME, + REPRESENTATION_SURFACE + }; + + enum ShadingRepresentationProperties + { + SHADING_FLAT, + SHADING_GOURAUD, + SHADING_PHONG + }; + + class CV_EXPORTS Camera + { + public: + /** Focal point or lookAt. The view direction can be obtained by (focal-pos).normalized () */ + Vec3d focal; + + /** \brief Position of the camera. */ + Vec3d pos; + + /** \brief Up vector of the camera. */ + Vec3d view_up; + + /** \brief Near/far clipping planes depths */ + Vec2d clip; + + /** \brief Field of view angle in y direction (radians). */ + double fovy; + + // the following variables are the actual position and size of the window on the screen and NOT the viewport! + // except for the size, which is the same the viewport is assumed to be centered and same size as the window. + Vec2i window_size; + Vec2i window_pos; + + /** \brief Computes View matrix for Camera (Based on gluLookAt) + * \param[out] view_mat the resultant matrix + */ + void computeViewMatrix(Affine3d& view_mat) const; + + /** \brief Computes Projection Matrix for Camera + * \param[out] proj the resultant matrix + */ + void computeProjectionMatrix(Matx44d& proj) const; + + /** \brief converts point to window coordiantes + * \param[in] pt xyz point to be converted + * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 + * + * This function computes the projection and view matrix every time. + * It is very inefficient to use this for every point in the point cloud! + */ + void cvtWindowCoordinates (const cv::Point3f& pt, Vec4d& window_cord) const + { + Affine3d view; + computeViewMatrix (view); + + Matx44d proj; + computeProjectionMatrix (proj); + cvtWindowCoordinates (pt, proj * view.matrix, window_cord); + return; + } + + /** \brief converts point to window coordiantes + * \param[in] pt xyz point to be converted + * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 + * \param[in] composite_mat composite transformation matrix (proj*view) + * + * Use this function to compute window coordinates with a precomputed + * transformation function. The typical composite matrix will be + * the projection matrix * the view matrix. However, additional + * matrices like a camera disortion matrix can also be added. + */ + void cvtWindowCoordinates (const Point3f& pt, Matx44d& composite_mat, Vec4d& window_cord) const + { + Vec4d pte (pt.x, pt.y, pt.z, 1); + window_cord = composite_mat * pte; + window_cord = window_cord/window_cord[3]; + + window_cord[0] = (window_cord[0]+1.0) / 2.0*window_size[0]; + window_cord[1] = (window_cord[1]+1.0) / 2.0*window_size[1]; + window_cord[2] = (window_cord[2]+1.0) / 2.0; + } + }; + +} diff --git a/modules/viz/src/q/interactor_style.h b/modules/viz/src/q/interactor_style.h new file mode 100644 index 000000000..91493eda6 --- /dev/null +++ b/modules/viz/src/q/interactor_style.h @@ -0,0 +1,150 @@ +#pragma once + +#include +#include + +namespace temp_viz +{ + /** \brief PCLVisualizerInteractorStyle defines an unique, custom VTK + * based interactory style for PCL Visualizer applications. Besides + * defining the rendering style, we also create a list of custom actions + * that are triggered on different keys being pressed: + * + * - p, P : switch to a point-based representation + * - w, W : switch to a wireframe-based representation (where available) + * - s, S : switch to a surface-based representation (where available) + * - j, J : take a .PNG snapshot of the current window view + * - c, C : display current camera/window parameters + * - f, F : fly to point mode + * - e, E : exit the interactor\ + * - q, Q : stop and call VTK's TerminateApp + * - + / - : increment/decrement overall point size + * - r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}] + * - ALT + s, S : turn stereo mode on/off + * - ALT + f, F : switch between maximized window mode and original size + * - + * - SHIFT + left click : select a point + * + * \author Radu B. Rusu + * \ingroup visualization + */ + class CV_EXPORTS InteractorStyle : public vtkInteractorStyleTrackballCamera + { + public: + + enum KeyboardModifier + { + KB_MOD_ALT, + KB_MOD_CTRL, + KB_MOD_SHIFT + }; + + static InteractorStyle *New (); + + + InteractorStyle () {} + virtual ~InteractorStyle () {} + + // this macro defines Superclass, the isA functionality and the safe downcast method + vtkTypeMacro (InteractorStyle, vtkInteractorStyleTrackballCamera); + + /** \brief Initialization routine. Must be called before anything else. */ + virtual void Initialize (); + + /** \brief Pass a pointer to the actor map + * \param[in] actors the actor map that will be used with this style + */ + inline void setCloudActorMap (const cv::Ptr& actors) { actors_ = actors; } + + + /** \brief Pass a set of renderers to the interactor style. + * \param[in] rens the vtkRendererCollection to use + */ + void setRenderer (vtkSmartPointer& ren) { renderer_ = ren; } + + /** \brief Register a callback function for mouse events + * \param[in] cb a boost function that will be registered as a callback for a mouse event + * \return a connection object that allows to disconnect the callback function. + */ + boost::signals2::connection registerMouseCallback (boost::function cb); + + /** \brief Register a callback boost::function for keyboard events + * \param[in] cb a boost function that will be registered as a callback for a keyboard event + * \return a connection object that allows to disconnect the callback function. + */ + boost::signals2::connection registerKeyboardCallback (boost::function cb); + + + /** \brief Save the current rendered image to disk, as a PNG screenshot. + * \param[in] file the name of the PNG file + */ + void saveScreenshot (const std::string &file); + + /** \brief Change the default keyboard modified from ALT to a different special key. + * Allowed values are: + * - KB_MOD_ALT + * - KB_MOD_CTRL + * - KB_MOD_SHIFT + * \param[in] modifier the new keyboard modifier + */ + inline void setKeyboardModifier (const KeyboardModifier &modifier) { modifier_ = modifier; } + protected: + /** \brief Set to true after initialization is complete. */ + bool init_; + + /** \brief Collection of vtkRenderers stored internally. */ + //vtkSmartPointer rens_; + vtkSmartPointer renderer_; + + /** \brief Actor map stored internally. */ + cv::Ptr actors_; + + /** \brief The current window width/height. */ + Vec2i win_size_; + + /** \brief The current window position x/y. */ + Vec2i win_pos_; + + /** \brief The maximum resizeable window width/height. */ + Vec2i max_win_size_; + + /** \brief A PNG writer for screenshot captures. */ + vtkSmartPointer snapshot_writer_; + /** \brief Internal window to image filter. Needed by \a snapshot_writer_. */ + vtkSmartPointer wif_; + + boost::signals2::signal mouse_signal_; + boost::signals2::signal keyboard_signal_; + + /** \brief Interactor style internal method. Gets called whenever a key is pressed. */ + virtual void OnChar (); + + // Keyboard events + virtual void OnKeyDown (); + virtual void OnKeyUp (); + + // mouse button events + virtual void OnMouseMove (); + virtual void OnLeftButtonDown (); + virtual void OnLeftButtonUp (); + virtual void OnMiddleButtonDown (); + virtual void OnMiddleButtonUp (); + virtual void OnRightButtonDown (); + virtual void OnRightButtonUp (); + virtual void OnMouseWheelForward (); + virtual void OnMouseWheelBackward (); + + /** \brief Interactor style internal method. Gets called periodically if a timer is set. */ + virtual void OnTimer (); + + + void zoomIn (); + void zoomOut (); + + /** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */ + bool stereo_anaglyph_mask_default_; + + /** \brief The keyboard modifier to use. Default: Alt. */ + KeyboardModifier modifier_; + }; +} diff --git a/modules/viz/src/q/shapes.h b/modules/viz/src/q/shapes.h new file mode 100644 index 000000000..3ff63750d --- /dev/null +++ b/modules/viz/src/q/shapes.h @@ -0,0 +1,124 @@ +#pragma once + +#include +#include +#include "precomp.hpp" + +namespace temp_viz +{ + CV_EXPORTS vtkSmartPointer createLine (const cv::Point3f& pt1, const cv::Point3f& pt2); + CV_EXPORTS vtkSmartPointer createSphere (const cv::Point3f ¢er, float radius, int sphere_resolution = 10); + + /** \brief Create a cylinder shape from a set of model coefficients. + * \param[in] coefficients the model coefficients (point_on_axis, axis_direction, radius) + * \param[in] numsides (optional) the number of sides used for rendering the cylinder + * + * \code + * // The following are given (or computed using sample consensus techniques -- see SampleConsensusModelCylinder) + * // Eigen::Vector3f pt_on_axis, axis_direction; + * // float radius; + * + * temp_viz::ModelCoefficients cylinder_coeff; + * cylinder_coeff.values.resize (7); // We need 7 values + * cylinder_coeff.values[0] = pt_on_axis.x (); + * cylinder_coeff.values[1] = pt_on_axis.y (); + * cylinder_coeff.values[2] = pt_on_axis.z (); + * + * cylinder_coeff.values[3] = axis_direction.x (); + * cylinder_coeff.values[4] = axis_direction.y (); + * cylinder_coeff.values[5] = axis_direction.z (); + * + * cylinder_coeff.values[6] = radius; + * + * vtkSmartPointer data = temp_viz::createCylinder (cylinder_coeff, numsides); + * \endcode + * + * \ingroup visualization + */ + CV_EXPORTS vtkSmartPointer createCylinder (const temp_viz::ModelCoefficients &coefficients, int numsides = 30); + + + /** \brief Create a planar shape from a set of model coefficients. + * \param[in] coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0) + * + * \code + * // The following are given (or computed using sample consensus techniques -- see SampleConsensusModelPlane) + * // Eigen::Vector4f plane_parameters; + * + * temp_viz::ModelCoefficients plane_coeff; + * plane_coeff.values.resize (4); // We need 4 values + * plane_coeff.values[0] = plane_parameters.x (); + * plane_coeff.values[1] = plane_parameters.y (); + * plane_coeff.values[2] = plane_parameters.z (); + * plane_coeff.values[3] = plane_parameters.w (); + * + * vtkSmartPointer data = temp_viz::createPlane (plane_coeff); + * \endcode + * + * \ingroup visualization + */ + CV_EXPORTS vtkSmartPointer createPlane (const temp_viz::ModelCoefficients &coefficients); + + /** \brief Create a planar shape from a set of model coefficients. + * \param[in] coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0) + * \param[in] x,y,z projection of this point on the plane is used to get the center of the plane. + * \ingroup visualization + */ + CV_EXPORTS vtkSmartPointer createPlane (const temp_viz::ModelCoefficients &coefficients, double x, double y, double z); + + /** \brief Create a 2d circle shape from a set of model coefficients. + * \param[in] coefficients the model coefficients (x, y, radius) + * \param[in] z (optional) specify a z value (default: 0) + * + * \code + * // The following are given (or computed using sample consensus techniques -- see SampleConsensusModelCircle2D) + * // float x, y, radius; + * + * temp_viz::ModelCoefficients circle_coeff; + * circle_coeff.values.resize (3); // We need 3 values + * circle_coeff.values[0] = x; + * circle_coeff.values[1] = y; + * circle_coeff.values[2] = radius; + * + * vtkSmartPointer data = temp_viz::create2DCircle (circle_coeff, z); + * \endcode + * + * \ingroup visualization + */ + CV_EXPORTS vtkSmartPointer create2DCircle (const temp_viz::ModelCoefficients &coefficients, double z = 0.0); + + + /** \brief Creaet a cube shape from a set of model coefficients. + * \param[in] coefficients the cube coefficients (Tx, Ty, Tz, Qx, Qy, Qz, Qw, width, height, depth) + * \ingroup visualization + */ + CV_EXPORTS vtkSmartPointer createCube (const temp_viz::ModelCoefficients &coefficients); + + /** \brief Creaet a cube shape from a set of model coefficients. + * + * \param[in] translation a translation to apply to the cube from 0,0,0 + * \param[in] rotation a quaternion-based rotation to apply to the cube + * \param[in] width the cube's width + * \param[in] height the cube's height + * \param[in] depth the cube's depth + * \ingroup visualization + */ + CV_EXPORTS vtkSmartPointer createCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation, double width, double height, double depth); + + /** \brief Create a cube from a set of bounding points + * \param[in] x_min is the minimum x value of the box + * \param[in] x_max is the maximum x value of the box + * \param[in] y_min is the minimum y value of the box + * \param[in] y_max is the maximum y value of the box + * \param[in] z_min is the minimum z value of the box + * \param[in] z_max is the maximum z value of the box + * \param[in] id the cube id/name (default: "cube") + * \param[in] viewport (optional) the id of the new viewport (default: 0) + */ + CV_EXPORTS vtkSmartPointer createCube (double x_min, double x_max, double y_min, double y_max, double z_min, double z_max); + + /** \brief Allocate a new unstructured grid smartpointer. For internal use only. + * \param[out] polydata the resultant unstructured grid. + */ + CV_EXPORTS void allocVtkUnstructuredGrid (vtkSmartPointer &polydata); +} diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp new file mode 100644 index 000000000..1d946f1e1 --- /dev/null +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -0,0 +1,469 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace temp_viz +{ + +class CV_EXPORTS Viz3d::VizImpl +{ +public: + typedef cv::Ptr Ptr; + + VizImpl (const std::string &name = std::string()); + + virtual ~VizImpl (); + void setFullScreen (bool mode); + void setWindowName (const std::string &name); + + /** \brief Register a callback boost::function for keyboard events + * \param[in] cb a boost function that will be registered as a callback for a keyboard event + * \return a connection object that allows to disconnect the callback function. + */ + boost::signals2::connection registerKeyboardCallback (boost::function cb); + inline boost::signals2::connection registerKeyboardCallback (void (*callback) (const cv::KeyboardEvent&, void*), void* cookie = NULL) + { return (registerKeyboardCallback (boost::bind (callback, _1, cookie))); } + + /** \brief Register a callback function for keyboard events + * \param[in] callback the member function that will be registered as a callback for a keyboard event + * \param[in] instance instance to the class that implements the callback function + * \param[in] cookie user data that is passed to the callback + * \return a connection object that allows to disconnect the callback function. + */ + template inline boost::signals2::connection registerKeyboardCallback (void (T::*callback) (const cv::KeyboardEvent&, void*), T& instance, void* cookie = NULL) + { return (registerKeyboardCallback (boost::bind (callback, boost::ref (instance), _1, cookie))); } + + /** \brief Register a callback function for mouse events + * \param[in] cb a boost function that will be registered as a callback for a mouse event + * \return a connection object that allows to disconnect the callback function. + */ + boost::signals2::connection registerMouseCallback (boost::function cb); + inline boost::signals2::connection registerMouseCallback (void (*callback) (const cv::MouseEvent&, void*), void* cookie = NULL) + { return (registerMouseCallback (boost::bind (callback, _1, cookie))); } + + /** \brief Register a callback function for mouse events + * \param[in] callback the member function that will be registered as a callback for a mouse event + * \param[in] instance instance to the class that implements the callback function + * \param[in] cookie user data that is passed to the callback + * \return a connection object that allows to disconnect the callback function. + */ + template inline boost::signals2::connection registerMouseCallback (void (T::*callback) (const cv::MouseEvent&, void*), T& instance, void* cookie = NULL) + { return (registerMouseCallback (boost::bind (callback, boost::ref (instance), _1, cookie))); } + + void spin (); + void spinOnce (int time = 1, bool force_redraw = false); + + /** \brief Adds 3D axes describing a coordinate system to screen at x, y, z, Roll,Pitch,Yaw + * + * \param[in] scale the scale of the axes (default: 1) + * \param[in] t transformation matrix + * + * RPY Angles + * Rotate the reference frame by the angle roll about axis x + * Rotate the reference frame by the angle pitch about axis y + * Rotate the reference frame by the angle yaw about axis z + * + * Description: + * Sets the orientation of the Prop3D. Orientation is specified as + * X,Y and Z rotations in that order, but they are performed as + * RotateZ, RotateX, and finally RotateY. + * + * All axies use right hand rule. x=red axis, y=green axis, z=blue axis + * z direction is point into the screen. + * z + * \ + * \ + * \ + * -----------> x + * | + * | + * | + * | + * | + * | + * y + */ + void addCoordinateSystem (double scale, const cv::Affine3f& t, const std::string &id = "coordinate"); + + /** \brief Removes a previously added 3D axes (coordinate system) + */ + bool removeCoordinateSystem (const std::string &id = "coordinate"); + bool removePointCloud (const std::string &id = "cloud"); + inline bool removePolygonMesh (const std::string &id = "polygon") + { + // Polygon Meshes are represented internally as point clouds with special cell array structures since 1.4 + return removePointCloud (id); + } + bool removeShape (const std::string &id = "cloud"); + + bool removeText3D (const std::string &id = "cloud"); + bool removeAllPointClouds (); + bool removeAllShapes (); + + void setBackgroundColor (const Color& color); + + bool addText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize = 10, const std::string &id = ""); + bool updateText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize = 10, const std::string &id = ""); + + /** \brief Set the pose of an existing shape. Returns false if the shape doesn't exist, true if the pose was succesfully updated. */ + bool updateShapePose (const std::string &id, const cv::Affine3f& pose); + + bool addText3D (const std::string &text, const cv::Point3f &position, const Color& color, double textScale = 1.0, const std::string &id = ""); + + bool addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level = 100, float scale = 0.02f, const std::string &id = "cloud"); + void addPointCloud(const cv::Mat& cloud, const cv::Mat& colors, const std::string& id = "cloud", const cv::Mat& mask = cv::Mat()); + bool updatePointCloud (const cv::Mat& cloud, const cv::Mat& colors, const std::string& id = "cloud", const cv::Mat& mask = cv::Mat()); + + bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); + bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); + + bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const std::string &id = "polyline"); + + void setPointCloudColor (const Color& color, const std::string &id = "cloud"); + bool setPointCloudRenderingProperties (int property, double value, const std::string &id = "cloud"); + bool getPointCloudRenderingProperties (int property, double &value, const std::string &id = "cloud"); + + bool setShapeRenderingProperties (int property, double value, const std::string &id); + void setShapeColor (const Color& color, const std::string &id); + + /** \brief Set whether the point cloud is selected or not + * \param[in] selected whether the cloud is selected or not (true = selected) + * \param[in] id the point cloud object id (default: cloud) + */ + bool setPointCloudSelected (const bool selected, const std::string &id = "cloud" ); + + /** \brief Returns true when the user tried to close the window */ + bool wasStopped () const { if (interactor_ != NULL) return (stopped_); else return true; } + + /** \brief Set the stopped flag back to false */ + void resetStoppedFlag () { if (interactor_ != NULL) stopped_ = false; } + + /** \brief Stop the interaction and close the visualizaton window. */ + void close () + { + stopped_ = true; + // This tends to close the window... + interactor_->TerminateApp (); + } + + bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); + bool addLine (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, const std::string &id = "line"); + bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); + bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color_line, const Color& color_text, const std::string &id = "arrow"); + bool addSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id = "sphere"); + bool updateSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id = "sphere"); + + // Add a vtkPolydata as a mesh + bool addModelFromPolyData (vtkSmartPointer polydata, const std::string & id = "PolyData"); + bool addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const std::string &id = "PolyData"); + bool addModelFromPLYFile (const std::string &filename, const std::string &id = "PLYModel"); + bool addModelFromPLYFile (const std::string &filename, vtkSmartPointer transform, const std::string &id = "PLYModel"); + + /** \brief Add a cylinder from a set of given model coefficients + * \param[in] coefficients the model coefficients (point_on_axis, axis_direction, radius) + * \param[in] id the cylinder id/name (default: "cylinder") + * + * \code + * // The following are given (or computed using sample consensus techniques) + * // See SampleConsensusModelCylinder for more information. + * // float radius; + * + * temp_viz::ModelCoefficients cylinder_coeff; + * cylinder_coeff.values.resize (7); // We need 7 values + * cylinder_coeff.values[0] = pt_on_axis.x (); + * cylinder_coeff.values[1] = pt_on_axis.y (); + * cylinder_coeff.values[2] = pt_on_axis.z (); + * + * cylinder_coeff.values[3] = axis_direction.x (); + * cylinder_coeff.values[4] = axis_direction.y (); + * cylinder_coeff.values[5] = axis_direction.z (); + * + * cylinder_coeff.values[6] = radius; + * + * addCylinder (cylinder_coeff); + * \endcode + */ + bool addCylinder (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "cylinder"); + + /** \brief Add a plane from a set of given model coefficients + * \param[in] coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0) + * \param[in] id the plane id/name (default: "plane") + * + * \code + * // The following are given (or computed using sample consensus techniques) + * // See SampleConsensusModelPlane for more information + + * + * temp_viz::ModelCoefficients plane_coeff; + * plane_coeff.values.resize (4); // We need 4 values + * plane_coeff.values[0] = plane_parameters.x (); + * plane_coeff.values[1] = plane_parameters.y (); + * plane_coeff.values[2] = plane_parameters.z (); + * plane_coeff.values[3] = plane_parameters.w (); + * + * addPlane (plane_coeff); + * \endcode + */ + bool addPlane (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "plane"); + bool addPlane (const temp_viz::ModelCoefficients &coefficients, double x, double y, double z, const std::string &id = "plane"); + + /** \brief Add a circle from a set of given model coefficients + * \param[in] coefficients the model coefficients (x, y, radius) + * \param[in] id the circle id/name (default: "circle") + * + * \code + * // The following are given (or computed using sample consensus techniques) + * // See SampleConsensusModelCircle2D for more information + * // float x, y, radius; + * + * temp_viz::ModelCoefficients circle_coeff; + * circle_coeff.values.resize (3); // We need 3 values + * circle_coeff.values[0] = x; + * circle_coeff.values[1] = y; + * circle_coeff.values[2] = radius; + * + * vtkSmartPointer data = temp_viz::create2DCircle (circle_coeff, z); + * \endcode + */ + bool addCircle (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "circle"); + + /** \brief Add a cube from a set of given model coefficients + * \param[in] coefficients the model coefficients (Tx, Ty, Tz, Qx, Qy, Qz, Qw, width, height, depth) + * \param[in] id the cube id/name (default: "cube") + */ + bool addCube (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "cube"); + + /** \brief Add a cube from a set of given model coefficients + * \param[in] translation a translation to apply to the cube from 0,0,0 + * \param[in] rotation a quaternion-based rotation to apply to the cube + * \param[in] width the cube's width + * \param[in] height the cube's height + * \param[in] depth the cube's depth + * \param[in] id the cube id/name (default: "cube") + */ + bool addCube (const cv::Vec3f& translation, const cv::Vec3f quaternion, double width, double height, double depth, const std::string &id = "cube"); + + /** \brief Add a cube + * \param[in] x_min the min X coordinate + * \param[in] x_max the max X coordinate + * \param[in] y_min the min Y coordinate + * \param[in] y_max the max Y coordinate + * \param[in] z_min the min Z coordinate + * \param[in] z_max the max Z coordinate + * \param[in] r how much red (0.0 -> 1.0) + * \param[in] g how much green (0.0 -> 1.0) + * \param[in] b how much blue (0.0 -> 1.0) + * \param[in] id the cube id/name (default: "cube") + */ + bool addCube (float x_min, float x_max, float y_min, float y_max, float z_min, float z_max, const Color& color, const std::string &id = "cube"); + + /** \brief Changes the visual representation for all actors to surface representation. */ + void setRepresentationToSurfaceForAllActors (); + + /** \brief Changes the visual representation for all actors to points representation. */ + void setRepresentationToPointsForAllActors (); + + /** \brief Changes the visual representation for all actors to wireframe representation. */ + void setRepresentationToWireframeForAllActors (); + + /** \brief Initialize camera parameters with some default values. */ + void initCameraParameters (); + + /** \brief Search for camera parameters at the command line and set them internally. + bool getCameraParameters (int argc, char **argv); + + /** \brief Checks whether the camera parameters were manually loaded from file.*/ + bool cameraParamsSet () const; + + /** \brief Update camera parameters and render. */ + void updateCamera (); + + /** \brief Reset camera parameters and render. */ + void resetCamera (); + + /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset. + * \param[in] id the point cloud object id (default: cloud) + */ + void resetCameraViewpoint (const std::string &id = "cloud"); + + /** \brief Set the camera pose given by position, viewpoint and up vector + * \param[in] pos_x the x coordinate of the camera location + * \param[in] pos_y the y coordinate of the camera location + * \param[in] pos_z the z coordinate of the camera location + * \param[in] view_x the x component of the view point of the camera + * \param[in] view_y the y component of the view point of the camera + * \param[in] view_z the z component of the view point of the camera + * \param[in] up_x the x component of the view up direction of the camera + * \param[in] up_y the y component of the view up direction of the camera + * \param[in] up_z the y component of the view up direction of the camera + */ + void setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up); + + /** \brief Set the camera location and viewup according to the given arguments + * \param[in] pos_x the x coordinate of the camera location + * \param[in] pos_y the y coordinate of the camera location + * \param[in] pos_z the z coordinate of the camera location + * \param[in] up_x the x component of the view up direction of the camera + * \param[in] up_y the y component of the view up direction of the camera + * \param[in] up_z the z component of the view up direction of the camera + */ + void setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z); + + /** \brief Set the camera parameters via an intrinsics and and extrinsics matrix + * \note This assumes that the pixels are square and that the center of the image is at the center of the sensor. + * \param[in] intrinsics the intrinsics that will be used to compute the VTK camera parameters + * \param[in] extrinsics the extrinsics that will be used to compute the VTK camera parameters + */ + void setCameraParameters (const cv::Matx33f& intrinsics, const cv::Affine3f& extrinsics); + + /** \brief Set the camera parameters by given a full camera data structure. + * \param[in] camera camera structure containing all the camera parameters. + */ + void setCameraParameters (const Camera &camera); + + /** \brief Set the camera clipping distances. + * \param[in] near the near clipping distance (no objects closer than this to the camera will be drawn) + * \param[in] far the far clipping distance (no objects further away than this to the camera will be drawn) + */ + void setCameraClipDistances (double near, double far); + + /** \brief Set the camera vertical field of view in radians */ + void setCameraFieldOfView (double fovy); + + /** \brief Get the current camera parameters. */ + void getCameras (Camera& camera); + + /** \brief Get the current viewing pose. */ + cv::Affine3f getViewerPose (); + void saveScreenshot (const std::string &file); + + /** \brief Return a pointer to the underlying VTK Render Window used. */ + //vtkSmartPointer getRenderWindow () { return (window_); } + + void setPosition (int x, int y); + void setSize (int xw, int yw); + +private: + vtkSmartPointer interactor_; + + struct ExitMainLoopTimerCallback : public vtkCommand + { + static ExitMainLoopTimerCallback* New() + { + return new ExitMainLoopTimerCallback; + } + virtual void Execute(vtkObject* vtkNotUsed(caller), unsigned long event_id, void* call_data) + { + if (event_id != vtkCommand::TimerEvent) + return; + + int timer_id = *reinterpret_cast (call_data); + if (timer_id != right_timer_id) + return; + + // Stop vtk loop and send notification to app to wake it up + viz_->interactor_->TerminateApp (); + } + int right_timer_id; + VizImpl* viz_; + }; + + struct ExitCallback : public vtkCommand + { + static ExitCallback* New () + { + return new ExitCallback; + } + virtual void Execute (vtkObject*, unsigned long event_id, void*) + { + if (event_id == vtkCommand::ExitEvent) + { + viz_->stopped_ = true; + viz_->interactor_->TerminateApp (); + } + } + VizImpl* viz_; + }; + + /** \brief Set to false if the interaction loop is running. */ + bool stopped_; + + double s_lastDone_; + + /** \brief Global timer ID. Used in destructor only. */ + int timer_id_; + + /** \brief Callback object enabling us to leave the main loop, when a timer fires. */ + vtkSmartPointer exit_main_loop_timer_callback_; + vtkSmartPointer exit_callback_; + + vtkSmartPointer renderer_; + vtkSmartPointer window_; + + /** \brief The render window interactor style. */ + vtkSmartPointer style_; + + /** \brief Internal list with actor pointers and name IDs for point clouds. */ + cv::Ptr cloud_actor_map_; + + /** \brief Internal list with actor pointers and name IDs for shapes. */ + cv::Ptr shape_actor_map_; + + /** \brief Boolean that holds whether or not the camera parameters were manually initialized*/ + bool camera_set_; + + bool removeActorFromRenderer (const vtkSmartPointer &actor); + bool removeActorFromRenderer (const vtkSmartPointer &actor); + bool removeActorFromRenderer (const vtkSmartPointer &actor); + + //void addActorToRenderer (const vtkSmartPointer &actor); + + + /** \brief Internal method. Creates a vtk actor from a vtk polydata object. + * \param[in] data the vtk polydata object to create an actor for + * \param[out] actor the resultant vtk actor object + * \param[in] use_scalars set scalar properties to the mapper if it exists in the data. Default: true. + */ + void createActorFromVTKDataSet (const vtkSmartPointer &data, vtkSmartPointer &actor, bool use_scalars = true); + + /** \brief Updates a set of cells (vtkIdTypeArray) if the number of points in a cloud changes + * \param[out] cells the vtkIdTypeArray object (set of cells) to update + * \param[out] initcells a previously saved set of cells. If the number of points in the current cloud is + * higher than the number of cells in \a cells, and initcells contains enough data, then a copy from it + * will be made instead of regenerating the entire array. + * \param[in] nr_points the number of points in the new cloud. This dictates how many cells we need to + * generate + */ + void updateCells (vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points); + + void allocVtkPolyData (vtkSmartPointer &polydata); + void allocVtkPolyData (vtkSmartPointer &polydata); + void allocVtkUnstructuredGrid (vtkSmartPointer &polydata); + +}; + +//void getTransformationMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternionf& orientation, Eigen::Matrix4f &transformation); + +//void convertToVtkMatrix (const Eigen::Matrix4f &m, vtkSmartPointer &vtk_matrix); + +void convertToVtkMatrix (const cv::Matx44f& m, vtkSmartPointer &vtk_matrix); + +/** \brief Convert origin and orientation to vtkMatrix4x4 + * \param[in] origin the point cloud origin + * \param[in] orientation the point cloud orientation + * \param[out] vtk_matrix the resultant VTK 4x4 matrix + */ +void convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix); +void convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m); + +} + + + diff --git a/modules/viz/src/q/viz_types.h b/modules/viz/src/q/viz_types.h new file mode 100644 index 000000000..1acfa4b1a --- /dev/null +++ b/modules/viz/src/q/viz_types.h @@ -0,0 +1,22 @@ +#pragma once + +#include "precomp.hpp" + +namespace temp_viz +{ + struct CV_EXPORTS CloudActor + { + /** \brief The actor holding the data to render. */ + vtkSmartPointer actor; + + /** \brief The viewpoint transformation matrix. */ + vtkSmartPointer viewpoint_transformation_; + + /** \brief Internal cell array. Used for optimizing updatePointCloud. */ + vtkSmartPointer cells; + }; + + typedef std::map CloudActorMap; + typedef std::map > ShapeActorMap; +} + diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp new file mode 100644 index 000000000..955cf3883 --- /dev/null +++ b/modules/viz/src/shapes.cpp @@ -0,0 +1,196 @@ +#include + +inline float rad2deg (float alpha) +{ return (alpha * 57.29578f); } + +inline double rad2deg (double alpha){return (alpha * 57.29578);} + + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::createCylinder (const temp_viz::ModelCoefficients &coefficients, int numsides) +{ + vtkSmartPointer line = vtkSmartPointer::New (); + line->SetPoint1 (coefficients.values[0], coefficients.values[1], coefficients.values[2]); + line->SetPoint2 (coefficients.values[3]+coefficients.values[0], coefficients.values[4]+coefficients.values[1], coefficients.values[5]+coefficients.values[2]); + + vtkSmartPointer tuber = vtkSmartPointer::New (); + tuber->SetInputConnection (line->GetOutputPort ()); + tuber->SetRadius (coefficients.values[6]); + tuber->SetNumberOfSides (numsides); + + return (tuber->GetOutput ()); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::createCube (const temp_viz::ModelCoefficients &coefficients) +{ + // coefficients = [Tx, Ty, Tz, Qx, Qy, Qz, Qw, width, height, depth] + vtkSmartPointer t = vtkSmartPointer::New (); + t->Identity (); + t->Translate (coefficients.values[0], coefficients.values[1], coefficients.values[2]); + + Eigen::AngleAxisf a (Eigen::Quaternionf (coefficients.values[6], coefficients.values[3], + coefficients.values[4], coefficients.values[5])); + t->RotateWXYZ (rad2deg (a.angle ()), a.axis ()[0], a.axis ()[1], a.axis ()[2]); + + vtkSmartPointer cube = vtkSmartPointer::New (); + cube->SetXLength (coefficients.values[7]); + cube->SetYLength (coefficients.values[8]); + cube->SetZLength (coefficients.values[9]); + + vtkSmartPointer tf = vtkSmartPointer::New (); + tf->SetTransform (t); + tf->SetInputConnection (cube->GetOutputPort ()); + + return (tf->GetOutput ()); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::createCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation, double width, double height, double depth) +{ + // coefficients = [Tx, Ty, Tz, Qx, Qy, Qz, Qw, width, height, depth] + vtkSmartPointer t = vtkSmartPointer::New (); + t->Identity (); + t->Translate (translation.x (), translation.y (), translation.z ()); + + Eigen::AngleAxisf a (rotation); + t->RotateWXYZ (rad2deg (a.angle ()), a.axis ()[0], a.axis ()[1], a.axis ()[2]); + + vtkSmartPointer cube = vtkSmartPointer::New (); + cube->SetXLength (width); + cube->SetYLength (height); + cube->SetZLength (depth); + + vtkSmartPointer tf = vtkSmartPointer::New (); + tf->SetTransform (t); + tf->SetInputConnection (cube->GetOutputPort ()); + + return (tf->GetOutput ()); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::createCube (double x_min, double x_max, double y_min, double y_max, double z_min, double z_max) +{ + vtkSmartPointer t = vtkSmartPointer::New (); + vtkSmartPointer cube = vtkSmartPointer::New (); + cube->SetBounds (x_min, x_max, y_min, y_max, z_min, z_max); + return (cube->GetOutput ()); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::createPlane (const temp_viz::ModelCoefficients &coefficients) +{ + vtkSmartPointer plane = vtkSmartPointer::New (); + plane->SetNormal (coefficients.values[0], coefficients.values[1], coefficients.values[2]); + + double norm_sqr = coefficients.values[0] * coefficients.values[0] + + coefficients.values[1] * coefficients.values[1] + + coefficients.values[2] * coefficients.values[2]; + + plane->Push (-coefficients.values[3] / sqrt(norm_sqr)); + return (plane->GetOutput ()); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::createPlane (const temp_viz::ModelCoefficients &coefficients, double x, double y, double z) +{ + vtkSmartPointer plane = vtkSmartPointer::New (); + + + double norm_sqr = 1.0 / (coefficients.values[0] * coefficients.values[0] + + coefficients.values[1] * coefficients.values[1] + + coefficients.values[2] * coefficients.values[2] ); + +// double nx = coefficients.values [0] * norm; +// double ny = coefficients.values [1] * norm; +// double nz = coefficients.values [2] * norm; +// double d = coefficients.values [3] * norm; + +// plane->SetNormal (nx, ny, nz); + plane->SetNormal (coefficients.values[0], coefficients.values[1], coefficients.values[2]); + + double t = x * coefficients.values[0] + y * coefficients.values[1] + z * coefficients.values[2] + coefficients.values[3]; + x -= coefficients.values[0] * t * norm_sqr; + y -= coefficients.values[1] * t * norm_sqr; + z -= coefficients.values[2] * t * norm_sqr; + plane->SetCenter (x, y, z); + + return (plane->GetOutput ()); +} + + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::create2DCircle (const temp_viz::ModelCoefficients &coefficients, double z) +{ + vtkSmartPointer disk = vtkSmartPointer::New (); + // Maybe the resolution should be lower e.g. 50 or 25 + disk->SetCircumferentialResolution (100); + disk->SetInnerRadius (coefficients.values[2] - 0.001); + disk->SetOuterRadius (coefficients.values[2] + 0.001); + disk->SetCircumferentialResolution (20); + + // An alternative to could be with + /* + vtkSmartPointer circle = vtkSmartPointer::New(); + circle->SetRadius (coefficients.values[2]); + circle->SetNumberOfSides (100); + + vtkSmartPointer tube = vtkSmartPointer::New(); + tube->SetInput (circle->GetOutput()); + tube->SetNumberOfSides (25); + tube->SetRadius (0.001); + */ + + // Set the circle origin + vtkSmartPointer t = vtkSmartPointer::New (); + t->Identity (); + t->Translate (coefficients.values[0], coefficients.values[1], z); + + vtkSmartPointer tf = vtkSmartPointer::New (); + tf->SetTransform (t); + tf->SetInputConnection (disk->GetOutputPort ()); + /* + tf->SetInputConnection (tube->GetOutputPort ()); + */ + + return (tf->GetOutput ()); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::createSphere (const cv::Point3f& center, float radius, int sphere_resolution) +{ + // Set the sphere origin + vtkSmartPointer t = vtkSmartPointer::New (); + t->Identity (); + t->Translate (center.x, center.y, center.z); + + vtkSmartPointer s_sphere = vtkSmartPointer::New (); + s_sphere->SetRadius (radius); + s_sphere->SetPhiResolution (sphere_resolution); + s_sphere->SetThetaResolution (sphere_resolution); + s_sphere->LatLongTessellationOff (); + + vtkSmartPointer tf = vtkSmartPointer::New (); + tf->SetTransform (t); + tf->SetInputConnection (s_sphere->GetOutputPort ()); + tf->Update (); + + return (tf->GetOutput ()); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +vtkSmartPointer temp_viz::createLine (const cv::Point3f& pt1, const cv::Point3f& pt2) +{ + vtkSmartPointer line = vtkSmartPointer::New (); + line->SetPoint1 (pt1.x, pt1.y, pt1.z); + line->SetPoint2 (pt2.x, pt2.y, pt2.z); + line->Update (); + return line->GetOutput (); +} +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) +{ + polydata = vtkSmartPointer::New (); +} + + diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp new file mode 100644 index 000000000..0baed3a72 --- /dev/null +++ b/modules/viz/src/types.cpp @@ -0,0 +1,24 @@ +#include + + + +////////////////////////////////////////////////////////////////////////////////////////////////////// +/// cv::Color + +temp_viz::Color::Color() : Scalar(0, 0, 0) {} +temp_viz::Color::Color(double gray) : Scalar(gray, gray, gray) {} +temp_viz::Color::Color(double blue, double green, double red) : Scalar(blue, green, red) {} +temp_viz::Color::Color(const Scalar& color) : Scalar(color) {} + +temp_viz::Color temp_viz::Color::black() { return Color( 0, 0, 0); } +temp_viz::Color temp_viz::Color::green() { return Color( 0, 255, 0); } +temp_viz::Color temp_viz::Color::blue() { return Color(255, 0, 0); } +temp_viz::Color temp_viz::Color::cyan() { return Color(255, 255, 0); } + +temp_viz::Color temp_viz::Color::red() { return Color( 0, 0, 255); } +temp_viz::Color temp_viz::Color::magenta() { return Color( 0, 255, 255); } +temp_viz::Color temp_viz::Color::yellow() { return Color(255, 0, 255); } +temp_viz::Color temp_viz::Color::white() { return Color(255, 255, 255); } + +temp_viz::Color temp_viz::Color::gray() { return Color(128, 128, 128); } + diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp new file mode 100644 index 000000000..89d145003 --- /dev/null +++ b/modules/viz/src/viz.cpp @@ -0,0 +1 @@ +#include "precomp.hpp" \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp new file mode 100644 index 000000000..9e35e42e9 --- /dev/null +++ b/modules/viz/src/viz3d.cpp @@ -0,0 +1,94 @@ +#include +#include + + +temp_viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_name)) +{ + +} + +temp_viz::Viz3d::~Viz3d() +{ + +} + + +void temp_viz::Viz3d::setBackgroundColor(const Color& color) +{ + impl_->setBackgroundColor(color); +} + +void temp_viz::Viz3d::addCoordinateSystem(double scale, const Affine3f& t, const String &id) +{ + impl_->addCoordinateSystem(scale, t, id); +} + +void temp_viz::Viz3d::addPointCloud(const Mat& cloud, const Mat& colors, const String& id, const Mat& mask) +{ + impl_->addPointCloud(cloud, colors, id, mask); +} + +bool temp_viz::Viz3d::addPointCloudNormals (const Mat &cloud, const Mat& normals, int level, float scale, const String& id) +{ + return impl_->addPointCloudNormals(cloud, normals, level, scale, id); +} + +bool temp_viz::Viz3d::updatePointCloud(const Mat& cloud, const Mat& colors, const String& id, const Mat& mask) +{ + return impl_->updatePointCloud(cloud, colors, id, mask); +} + +bool temp_viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String &id) +{ + return impl_->addPolygonMesh(mesh, Mat(), id); +} + +bool temp_viz::Viz3d::updatePolygonMesh (const Mesh3d& mesh, const String &id) +{ + return impl_->updatePolygonMesh(mesh, Mat(), id); +} + +bool temp_viz::Viz3d::addPolylineFromPolygonMesh (const Mesh3d& mesh, const String &id) +{ + return impl_->addPolylineFromPolygonMesh(mesh, id); +} + +bool temp_viz::Viz3d::addText (const String &text, int xpos, int ypos, const Color& color, int fontsize, const String &id) +{ + return impl_->addText(text, xpos, ypos, color, fontsize, id); +} + +bool temp_viz::Viz3d::addPolygon(const Mat& cloud, const Color& color, const String& id) +{ + return impl_->addPolygon(cloud, color, id); +} + +bool temp_viz::Viz3d::addSphere (const cv::Point3f ¢er, double radius, const Color& color, const std::string &id) +{ + return impl_->addSphere(center, radius, color, id); +} + +void temp_viz::Viz3d::spin() +{ + impl_->spin(); +} + +void temp_viz::Viz3d::spinOnce (int time, bool force_redraw) +{ + impl_->spinOnce(time, force_redraw); +} + +bool temp_viz::Viz3d::addPlane (const ModelCoefficients &coefficients, const String &id) +{ + return impl_->addPlane(coefficients, id); +} + +bool temp_viz::Viz3d::addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String& id) +{ + return impl_->addPlane(coefficients, x, y, z, id); +} + +bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) +{ + return impl_->removeCoordinateSystem(id); +} diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp new file mode 100644 index 000000000..20d8a06f0 --- /dev/null +++ b/modules/viz/src/viz3d_impl.cpp @@ -0,0 +1,963 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +void temp_viz::Viz3d::VizImpl::setFullScreen (bool mode) +{ + if (window_) + window_->SetFullScreen (mode); +} + +void temp_viz::Viz3d::VizImpl::setWindowName (const std::string &name) +{ + if (window_) + window_->SetWindowName (name.c_str ()); +} + +void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } +void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } + +void temp_viz::Viz3d::VizImpl::addPointCloud(const cv::Mat& cloud, const cv::Mat& colors, const std::string& id, const cv::Mat& mask) +{ + CV_Assert(cloud.type() == CV_32FC3 && colors.type() == CV_8UC3 && colors.size() == cloud.size()); + CV_Assert(mask.empty() || (mask.type() == CV_8U && mask.size() == cloud.size())); + + vtkSmartPointer polydata; + + allocVtkPolyData(polydata); + //polydata = vtkSmartPointer::New (); + vtkSmartPointer vertices = vtkSmartPointer::New (); + polydata->SetVerts (vertices); + + vtkSmartPointer initcells; + vtkIdType nr_points = cloud.size().area(); + vtkSmartPointer points = polydata->GetPoints (); + + if (!points) + { + points = vtkSmartPointer::New (); + points->SetDataTypeToFloat (); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); + + // Get a pointer to the beginning of the data array + float *data = (static_cast (points->GetData ()))->GetPointer (0); + + if (mask.empty()) + { + int j = 0; + for(int y = 0; y < cloud.rows; ++y) + { + const cv::Point3f* crow = cloud.ptr(y); + for(int x = 0; x < cloud.cols; ++x) + memcpy (&data[j++ * 3], &crow[x], sizeof(cv::Point3f)); + } + } + else + { + int j = 0; + for(int y = 0; y < cloud.rows; ++y) + { + const cv::Point3f* crow = cloud.ptr(y); + const unsigned char* mrow = mask.ptr(y); + for(int x = 0; x < cloud.cols; ++x) + if (mrow[x]) + memcpy (&data[j++ * 3], &crow[x], sizeof(cv::Point3f)); + } + nr_points = j; + points->SetNumberOfPoints (nr_points); + } + + vtkSmartPointer cells = vertices->GetData (); + updateCells (cells, initcells, nr_points); + + // Set the cells and the vertices + vertices->SetCells (nr_points, cells); + + ///////////////////////////////////////////////////////////////////////////////// + + // use the given geometry handler + polydata->Update (); + + // Get the colors from the handler + bool has_colors = false; + double minmax[2]; + vtkSmartPointer scalars = vtkSmartPointer::New (); + scalars->SetNumberOfComponents (3); + reinterpret_cast(&(*scalars))->SetNumberOfTuples (nr_points); + + // Get a random color + unsigned char* colors_data = new unsigned char[nr_points * 3]; + + if (mask.empty()) + { + int j = 0; + for(int y = 0; y < colors.rows; ++y) + { + const cv::Vec3b* crow = colors.ptr(y); + for(int x = 0; x < colors.cols; ++x) + memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); + } + } + else + { + int j = 0; + for(int y = 0; y < colors.rows; ++y) + { + const cv::Vec3b* crow = colors.ptr(y); + const unsigned char* mrow = mask.ptr(y); + for(int x = 0; x < colors.cols; ++x) + if (mrow[x]) + memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); + } + } + + reinterpret_cast(&(*scalars))->SetArray (colors_data, 3 * nr_points, 0); + + ///////////////////////////////////////// + has_colors = true; + + if (has_colors) + { + polydata->GetPointData ()->SetScalars (scalars); + scalars->GetRange (minmax); + } + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (polydata, actor); + if (has_colors) + actor->GetMapper ()->SetScalarRange (minmax); + + // Add it to all renderers + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*cloud_actor_map_)[id].actor = actor; + (*cloud_actor_map_)[id].cells = initcells; + + const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); + const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); + + // Save the viewpoint transformation matrix to the global actor map + vtkSmartPointer transformation = vtkSmartPointer::New(); + convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); + (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; +} + + +bool temp_viz::Viz3d::VizImpl::updatePointCloud (const cv::Mat& cloud, const cv::Mat& colors, const std::string& id, const cv::Mat& mask) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + if (am_it == cloud_actor_map_->end ()) + return (false); + + // Get the current poly data + vtkSmartPointer polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); + if (!polydata) + return (false); + vtkSmartPointer vertices = polydata->GetVerts (); + vtkSmartPointer points = polydata->GetPoints (); + // Copy the new point array in + vtkIdType nr_points = cloud.size().area(); + points->SetNumberOfPoints (nr_points); + + // Get a pointer to the beginning of the data array + float *data = (static_cast (points->GetData ()))->GetPointer (0); + + if (mask.empty()) + { + int j = 0; + for(int y = 0; y < cloud.rows; ++y) + { + const cv::Point3f* crow = cloud.ptr(y); + for(int x = 0; x < cloud.cols; ++x) + memcpy (&data[j++ * 3], &crow[x], sizeof(cv::Point3f)); + } + } + else + { + int j = 0; + for(int y = 0; y < cloud.rows; ++y) + { + const cv::Point3f* crow = cloud.ptr(y); + const unsigned char* mrow = mask.ptr(y); + for(int x = 0; x < cloud.cols; ++x) + if (mrow[x]) + memcpy (&data[j++ * 3], &crow[x], sizeof(cv::Point3f)); + } + nr_points = j; + points->SetNumberOfPoints (nr_points); + } + + vtkSmartPointer cells = vertices->GetData (); + updateCells (cells, am_it->second.cells, nr_points); + + + // Set the cells and the vertices + vertices->SetCells (nr_points, cells); + +#if 1 + // Get the colors from the handler + // vtkSmartPointer scalars; + // color_handler.getColor (scalars); + // double minmax[2]; + // scalars->GetRange (minmax); + + // // Update the data + // polydata->GetPointData ()->SetScalars (scalars); + // polydata->Update (); + + // am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff (); + // am_it->second.actor->GetMapper ()->SetScalarRange (minmax); + + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + + // Get the colors from the handler + bool has_colors = false; + double minmax[2]; + vtkSmartPointer scalars = vtkSmartPointer::New (); + scalars->SetNumberOfComponents (3); + reinterpret_cast(&(*scalars))->SetNumberOfTuples (nr_points); + + // Get a random color + unsigned char* colors_data = new unsigned char[nr_points * 3]; + + if (mask.empty()) + { + int j = 0; + for(int y = 0; y < colors.rows; ++y) + { + const cv::Vec3b* crow = colors.ptr(y); + for(int x = 0; x < colors.cols; ++x) + memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); + } + } + else + { + int j = 0; + for(int y = 0; y < colors.rows; ++y) + { + const cv::Vec3b* crow = colors.ptr(y); + const unsigned char* mrow = mask.ptr(y); + for(int x = 0; x < colors.cols; ++x) + if (mrow[x]) + memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); + } + } + + reinterpret_cast(&(*scalars))->SetArray (colors_data, 3 * nr_points, 0); + + ///////////////////////////////////////// + has_colors = true; + + if (has_colors) + { + polydata->GetPointData ()->SetScalars (scalars); + scalars->GetRange (minmax); + } + +#else + vtkSmartPointer scalars; + polydata->GetPointData ()->SetScalars (scalars); + polydata->Update (); + double minmax[2]; + minmax[0] = std::numeric_limits::min (); + minmax[1] = std::numeric_limits::max (); + am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff (); + am_it->second.actor->GetMapper ()->SetScalarRange (minmax); +#endif + + + // Update the mapper + reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); + return (true); +} + + + +bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level, float scale, const std::string &id) +{ + CV_Assert(cloud.size() == normals.size() && cloud.type() == CV_32FC3 && normals.type() == CV_32FC3); + + if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) + return (false); + + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer lines = vtkSmartPointer::New(); + + points->SetDataTypeToFloat (); + vtkSmartPointer data = vtkSmartPointer::New (); + data->SetNumberOfComponents (3); + + vtkIdType nr_normals = 0; + float* pts = 0; + + // If the cloud is organized, then distribute the normal step in both directions + if (cloud.cols > 1 && cloud.rows > 1) + { + vtkIdType point_step = static_cast (sqrt (double (level))); + nr_normals = (static_cast ((cloud.cols - 1)/ point_step) + 1) * + (static_cast ((cloud.rows - 1) / point_step) + 1); + pts = new float[2 * nr_normals * 3]; + + vtkIdType cell_count = 0; + for (vtkIdType y = 0; y < cloud.rows; y += point_step) + for (vtkIdType x = 0; x < cloud.cols; x += point_step) + { + cv::Point3f p = cloud.at(y, x); + cv::Point3f n = normals.at(y, x) * scale; + + pts[2 * cell_count * 3 + 0] = p.x; + pts[2 * cell_count * 3 + 1] = p.y; + pts[2 * cell_count * 3 + 2] = p.z; + pts[2 * cell_count * 3 + 3] = p.x + n.x; + pts[2 * cell_count * 3 + 4] = p.y + n.y; + pts[2 * cell_count * 3 + 5] = p.z + n.z; + + lines->InsertNextCell (2); + lines->InsertCellPoint (2 * cell_count); + lines->InsertCellPoint (2 * cell_count + 1); + cell_count++; + } + } + else + { + nr_normals = (cloud.size().area() - 1) / level + 1 ; + pts = new float[2 * nr_normals * 3]; + + for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level) + { + cv::Point3f p = cloud.ptr()[i]; + cv::Point3f n = normals.ptr()[i] * scale; + + pts[2 * j * 3 + 0] = p.x; + pts[2 * j * 3 + 1] = p.y; + pts[2 * j * 3 + 2] = p.z; + pts[2 * j * 3 + 3] = p.x + n.x; + pts[2 * j * 3 + 4] = p.y + n.y; + pts[2 * j * 3 + 5] = p.z + n.z; + + lines->InsertNextCell (2); + lines->InsertCellPoint (2 * j); + lines->InsertCellPoint (2 * j + 1); + } + } + + data->SetArray (&pts[0], 2 * nr_normals * 3, 0); + points->SetData (data); + + vtkSmartPointer polyData = vtkSmartPointer::New(); + polyData->SetPoints (points); + polyData->SetLines (lines); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (polyData); + mapper->SetColorModeToMapScalars(); + mapper->SetScalarModeToUsePointData(); + + // create actor + vtkSmartPointer actor = vtkSmartPointer::New (); + actor->SetMapper (mapper); + + // Add it to all renderers + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*cloud_actor_map_)[id].actor = actor; + return (true); +} + + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addLine (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addLine] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; + + vtkSmartPointer data = createLine (pt1, pt2); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + + Color c = vtkcolor(color); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + + + +inline bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) +{ + CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); + CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); + CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); + + if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) + return std::cout << "[addPolygonMesh] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; + + // int rgb_idx = -1; + // std::vector fields; + + + // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgb", fields); + // if (rgb_idx == -1) + // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgba", fields); + + vtkSmartPointer colors_array; +#if 1 + if (!mesh.colors.empty()) + { + colors_array = vtkSmartPointer::New (); + colors_array->SetNumberOfComponents (3); + colors_array->SetName ("Colors"); + + const unsigned char* data = mesh.colors.ptr(); + + //TODO check mask + CV_Assert(mask.empty()); //because not implemented; + + for(int i = 0; i < mesh.colors.cols; ++i) + colors_array->InsertNextTupleValue(&data[i*3]); + + // temp_viz::RGB rgb_data; + // for (size_t i = 0; i < cloud->size (); ++i) + // { + // if (!isFinite (cloud->points[i])) + // continue; + // memcpy (&rgb_data, reinterpret_cast (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (temp_viz::RGB)); + // unsigned char color[3]; + // color[0] = rgb_data.r; + // color[1] = rgb_data.g; + // color[2] = rgb_data.b; + // colors->InsertNextTupleValue (color); + // } + } +#endif + + // Create points from polyMesh.cloud + vtkSmartPointer points = vtkSmartPointer::New (); + vtkIdType nr_points = mesh.cloud.size().area(); + + points->SetNumberOfPoints (nr_points); + + + // Get a pointer to the beginning of the data array + float *data = static_cast (points->GetData ())->GetPointer (0); + + + std::vector lookup; + // If the dataset is dense (no NaNs) + if (mask.empty()) + { + cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); + mesh.cloud.copyTo(hdr); + } + else + { + lookup.resize (nr_points); + + const unsigned char *mdata = mask.ptr(); + const cv::Point3f *cdata = mesh.cloud.ptr(); + cv::Point3f* out = reinterpret_cast(data); + + int j = 0; // true point index + for (int i = 0; i < nr_points; ++i) + if(mdata[i]) + { + lookup[i] = j; + out[j++] = cdata[i]; + } + nr_points = j; + points->SetNumberOfPoints (nr_points); + } + + // Get the maximum size of a polygon + int max_size_of_polygon = -1; + for (size_t i = 0; i < mesh.polygons.size (); ++i) + if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) + max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); + + vtkSmartPointer actor; + + if (mesh.polygons.size () > 1) + { + // Create polys from polyMesh.polygons + vtkSmartPointer cell_array = vtkSmartPointer::New (); + vtkIdType *cell = cell_array->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); + int idx = 0; + if (lookup.size () > 0) + { + for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) + { + size_t n_points = mesh.polygons[i].vertices.size (); + *cell++ = n_points; + //cell_array->InsertNextCell (n_points); + for (size_t j = 0; j < n_points; j++, ++idx) + *cell++ = lookup[mesh.polygons[i].vertices[j]]; + //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]); + } + } + else + { + for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) + { + size_t n_points = mesh.polygons[i].vertices.size (); + *cell++ = n_points; + //cell_array->InsertNextCell (n_points); + for (size_t j = 0; j < n_points; j++, ++idx) + *cell++ = mesh.polygons[i].vertices[j]; + //cell_array->InsertCellPoint (vertices[i].vertices[j]); + } + } + vtkSmartPointer polydata; + allocVtkPolyData (polydata); + cell_array->GetData ()->SetNumberOfValues (idx); + cell_array->Squeeze (); + polydata->SetStrips (cell_array); + polydata->SetPoints (points); + + if (colors_array) + polydata->GetPointData ()->SetScalars (colors_array); + + createActorFromVTKDataSet (polydata, actor, false); + } + else + { + vtkSmartPointer polygon = vtkSmartPointer::New (); + size_t n_points = mesh.polygons[0].vertices.size (); + polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); + + if (lookup.size () > 0) + { + for (size_t j = 0; j < n_points - 1; ++j) + polygon->GetPointIds ()->SetId (j, lookup[mesh.polygons[0].vertices[j]]); + } + else + { + for (size_t j = 0; j < n_points - 1; ++j) + polygon->GetPointIds ()->SetId (j, mesh.polygons[0].vertices[j]); + } + vtkSmartPointer poly_grid; + allocVtkUnstructuredGrid (poly_grid); + poly_grid->Allocate (1, 1); + poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); + poly_grid->SetPoints (points); + poly_grid->Update (); + if (colors_array) + poly_grid->GetPointData ()->SetScalars (colors_array); + + createActorFromVTKDataSet (poly_grid, actor, false); + } + renderer_->AddActor (actor); + actor->GetProperty ()->SetRepresentationToSurface (); + // Backface culling renders the visualization slower, but guarantees that we see all triangles + actor->GetProperty ()->BackfaceCullingOff (); + actor->GetProperty ()->SetInterpolationToFlat (); + actor->GetProperty ()->EdgeVisibilityOff (); + actor->GetProperty ()->ShadingOff (); + + // Save the pointer/ID pair to the global actor map + (*cloud_actor_map_)[id].actor = actor; + //if (vertices.size () > 1) + // (*cloud_actor_map_)[id].cells = static_cast(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData (); + + const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); + const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); + + // Save the viewpoint transformation matrix to the global actor map + vtkSmartPointer transformation = vtkSmartPointer::New(); + convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); + (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; + + return (true); +} + + +inline bool temp_viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) +{ + CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); + CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); + CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); + + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + if (am_it == cloud_actor_map_->end ()) + return (false); + + // Get the current poly data + vtkSmartPointer polydata = static_cast(am_it->second.actor->GetMapper ())->GetInput (); + if (!polydata) + return (false); + vtkSmartPointer cells = polydata->GetStrips (); + if (!cells) + return (false); + vtkSmartPointer points = polydata->GetPoints (); + // Copy the new point array in + vtkIdType nr_points = mesh.cloud.size().area(); + points->SetNumberOfPoints (nr_points); + + // Get a pointer to the beginning of the data array + float *data = (static_cast (points->GetData ()))->GetPointer (0); + + int ptr = 0; + std::vector lookup; + // If the dataset is dense (no NaNs) + if (mask.empty()) + { + cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); + mesh.cloud.copyTo(hdr); + + } + else + { + lookup.resize (nr_points); + + const unsigned char *mdata = mask.ptr(); + const cv::Point3f *cdata = mesh.cloud.ptr(); + cv::Point3f* out = reinterpret_cast(data); + + int j = 0; // true point index + for (int i = 0; i < nr_points; ++i) + if(mdata[i]) + { + lookup[i] = j; + out[j++] = cdata[i]; + } + nr_points = j; + points->SetNumberOfPoints (nr_points);; + } + + // Update colors + vtkUnsignedCharArray* colors_array = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ()); + + if (!mesh.colors.empty() && colors_array) + { + if (mask.empty()) + { + const unsigned char* data = mesh.colors.ptr(); + for(int i = 0; i < mesh.colors.cols; ++i) + colors_array->InsertNextTupleValue(&data[i*3]); + } + else + { + const unsigned char* color = mesh.colors.ptr(); + const unsigned char* mdata = mask.ptr(); + + int j = 0; + for(int i = 0; i < mesh.colors.cols; ++i) + if (mdata[i]) + colors_array->SetTupleValue (j++, &color[i*3]); + + } + } + + // Get the maximum size of a polygon + int max_size_of_polygon = -1; + for (size_t i = 0; i < mesh.polygons.size (); ++i) + if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) + max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); + + // Update the cells + cells = vtkSmartPointer::New (); + vtkIdType *cell = cells->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); + int idx = 0; + if (lookup.size () > 0) + { + for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) + { + size_t n_points = mesh.polygons[i].vertices.size (); + *cell++ = n_points; + for (size_t j = 0; j < n_points; j++, cell++, ++idx) + *cell = lookup[mesh.polygons[i].vertices[j]]; + } + } + else + { + for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) + { + size_t n_points = mesh.polygons[i].vertices.size (); + *cell++ = n_points; + for (size_t j = 0; j < n_points; j++, cell++, ++idx) + *cell = mesh.polygons[i].vertices[j]; + } + } + cells->GetData ()->SetNumberOfValues (idx); + cells->Squeeze (); + // Set the the vertices + polydata->SetStrips (cells); + polydata->Update (); + return (true); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color, bool display_length, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addArrow] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; + + // Create an Actor + vtkSmartPointer leader = vtkSmartPointer::New (); + leader->GetPositionCoordinate()->SetCoordinateSystemToWorld (); + leader->GetPositionCoordinate()->SetValue (p1.x, p1.y, p1.z); + leader->GetPosition2Coordinate()->SetCoordinateSystemToWorld (); + leader->GetPosition2Coordinate()->SetValue (p2.x, p2.y, p2.z); + leader->SetArrowStyleToFilled(); + leader->SetArrowPlacementToPoint2 (); + + if (display_length) + leader->AutoLabelOn (); + else + leader->AutoLabelOff (); + + Color c = vtkcolor(color); + leader->GetProperty ()->SetColor (c.val); + renderer_->AddActor (leader); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = leader; + return (true); +} +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color_line, const Color& color_text, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addArrow] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; + return (false); + } + + // Create an Actor + vtkSmartPointer leader = vtkSmartPointer::New (); + leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld (); + leader->GetPositionCoordinate ()->SetValue (p1.x, p1.y, p1.z); + leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld (); + leader->GetPosition2Coordinate ()->SetValue (p2.x, p2.y, p2.z); + leader->SetArrowStyleToFilled (); + leader->AutoLabelOn (); + + Color ct = vtkcolor(color_text); + leader->GetLabelTextProperty()->SetColor(ct.val); + + Color cl = vtkcolor(color_line); + leader->GetProperty ()->SetColor (cl.val); + renderer_->AddActor (leader); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = leader; + return (true); +} + +#include +//////////////////////////////////////////////////////////////////////////////////////////// +inline bool temp_viz::Viz3d::VizImpl::addSphere (const cv::Point3f& center, float radius, const Color& color, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addSphere] A shape with id <"< already exists! Please choose a different id and retry." << std::endl, false; + + //vtkSmartPointer data = createSphere (center.getVector4fMap (), radius); + vtkSmartPointer data = vtkSmartPointer::New (); + data->SetRadius (radius); + data->SetCenter (center.x, center.y, center.z); + data->SetPhiResolution (10); + data->SetThetaResolution (10); + data->LatLongTessellationOff (); + data->Update (); + + // Setup actor and mapper + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInputConnection (data->GetOutputPort ()); + + // Create an Actor + vtkSmartPointer actor = vtkSmartPointer::New (); + actor->SetMapper (mapper); + //createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetInterpolationToFlat (); + + Color c = vtkcolor(color); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ImmediateModeRenderingOn (); + actor->GetMapper ()->StaticOn (); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetMapper ()->Update (); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +inline bool temp_viz::Viz3d::VizImpl::updateSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it == shape_actor_map_->end ()) + return (false); + + ////////////////////////////////////////////////////////////////////////// + // Get the actor pointer + vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second); + vtkAlgorithm *algo = actor->GetMapper ()->GetInput ()->GetProducerPort ()->GetProducer (); + vtkSphereSource *src = vtkSphereSource::SafeDownCast (algo); + + src->SetCenter(center.x, center.y, center.z); + src->SetRadius(radius); + src->Update (); + Color c = vtkcolor(color); + actor->GetProperty ()->SetColor (c.val); + actor->Modified (); + + return (true); +} + +////////////////////////////////////////////////// +inline bool temp_viz::Viz3d::VizImpl::addText3D (const std::string &text, const cv::Point3f& position, const Color& color, double textScale, const std::string &id) +{ + std::string tid; + if (id.empty ()) + tid = text; + else + tid = id; + + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (tid); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addText3d] A text with id <" << tid << "> already exists! Please choose a different id and retry." << std::endl, false; + + vtkSmartPointer textSource = vtkSmartPointer::New (); + textSource->SetText (text.c_str()); + textSource->Update (); + + vtkSmartPointer textMapper = vtkSmartPointer::New (); + textMapper->SetInputConnection (textSource->GetOutputPort ()); + + // Since each follower may follow a different camera, we need different followers + vtkRenderer* renderer = renderer_; + + vtkSmartPointer textActor = vtkSmartPointer::New (); + textActor->SetMapper (textMapper); + textActor->SetPosition (position.x, position.y, position.z); + textActor->SetScale (textScale); + + Color c = vtkcolor(color); + textActor->GetProperty ()->SetColor (c.val); + textActor->SetCamera (renderer->GetActiveCamera ()); + + renderer->AddActor (textActor); + renderer->Render (); + + // Save the pointer/ID pair to the global actor map. If we are saving multiple vtkFollowers + // for multiple viewport + (*shape_actor_map_)[tid] = textActor; + + + return (true); +} + +inline bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) +{ + CV_Assert(cloud.type() == CV_32FC3 && cloud.rows == 1); + + vtkSmartPointer points = vtkSmartPointer::New (); + vtkSmartPointer polygon = vtkSmartPointer::New (); + + int total = cloud.size().area(); + points->SetNumberOfPoints (total); + polygon->GetPointIds ()->SetNumberOfIds (total); + + for (int i = 0; i < total; ++i) + { + cv::Point3f p = cloud.ptr()[i]; + points->SetPoint (i, p.x, p.y, p.z); + polygon->GetPointIds ()->SetId (i, i); + } + + vtkSmartPointer poly_grid; + allocVtkUnstructuredGrid (poly_grid); + poly_grid->Allocate (1, 1); + poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); + poly_grid->SetPoints (points); + poly_grid->Update (); + + + ////////////////////////////////////////////////////// + vtkSmartPointer data = poly_grid; + + Color c = vtkcolor(color); + + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + vtkSmartPointer all_data = vtkSmartPointer::New (); + + // Add old data + all_data->AddInput (reinterpret_cast ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ()); + + // Add new data + vtkSmartPointer surface_filter = vtkSmartPointer::New (); + surface_filter->SetInput (vtkUnstructuredGrid::SafeDownCast (data)); + vtkSmartPointer poly_data = surface_filter->GetOutput (); + all_data->AddInput (poly_data); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (all_data->GetOutput (), actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetProperty ()->BackfaceCullingOff (); + + removeActorFromRenderer (am_it->second); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } + else + { + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetProperty ()->BackfaceCullingOff (); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } + + return (true); +} diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp new file mode 100644 index 000000000..2c2fe5245 --- /dev/null +++ b/modules/viz/src/viz_main.cpp @@ -0,0 +1,1398 @@ +#include "precomp.hpp" + +#include +#include +#include + +#include +#ifndef __APPLE__ +vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew () +{ + return (vtkRenderWindowInteractor::New ()); +} +#endif + +///////////////////////////////////////////////////////////////////////////////////////////// +temp_viz::Viz3d::VizImpl::VizImpl (const std::string &name) + : style_ (vtkSmartPointer::New ()) + , cloud_actor_map_ (new CloudActorMap) + , shape_actor_map_ (new ShapeActorMap) + , s_lastDone_(0.0) +{ + renderer_ = vtkSmartPointer::New (); + + // Create a RendererWindow + window_ = vtkSmartPointer::New (); + + // Set the window size as 1/2 of the screen size + cv::Vec2i window_size = cv::Vec2i(window_->GetScreenSize()) / 2; + window_->SetSize (window_size.val); + + window_->AddRenderer (renderer_); + + // Create the interactor style + style_->Initialize (); + style_->setRenderer (renderer_); + style_->setCloudActorMap (cloud_actor_map_); + style_->UseTimersOn (); + + ///////////////////////////////////////////////// + interactor_ = vtkSmartPointer ::Take (vtkRenderWindowInteractorFixNew ()); + + //win_->PointSmoothingOn (); + //win_->LineSmoothingOn (); + //win_->PolygonSmoothingOn (); + window_->AlphaBitPlanesOff (); + window_->PointSmoothingOff (); + window_->LineSmoothingOff (); + window_->PolygonSmoothingOff (); + window_->SwapBuffersOn (); + window_->SetStereoTypeToAnaglyph (); + + interactor_->SetRenderWindow (window_); + interactor_->SetInteractorStyle (style_); + //interactor_->SetStillUpdateRate (30.0); + interactor_->SetDesiredUpdateRate (30.0); + + // Initialize and create timer, also create window + interactor_->Initialize (); + timer_id_ = interactor_->CreateRepeatingTimer (5000L); + + // Set a simple PointPicker + vtkSmartPointer pp = vtkSmartPointer::New (); + pp->SetTolerance (pp->GetTolerance () * 2); + interactor_->SetPicker (pp); + + exit_main_loop_timer_callback_ = vtkSmartPointer::New (); + exit_main_loop_timer_callback_->viz_ = this; + exit_main_loop_timer_callback_->right_timer_id = -1; + interactor_->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_); + + exit_callback_ = vtkSmartPointer::New (); + exit_callback_->viz_ = this; + interactor_->AddObserver (vtkCommand::ExitEvent, exit_callback_); + + resetStoppedFlag (); + + + ////////////////////////////// + + String window_name("Viz"); + window_name = name.empty() ? window_name : window_name + " - " + name; + window_->SetWindowName (window_name.c_str ()); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +temp_viz::Viz3d::VizImpl::~VizImpl () +{ + if (interactor_ != NULL) + interactor_->DestroyTimer (timer_id_); + + renderer_->Clear(); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } + +///////////////////////////////////////////////////////////////////////////////////////////// +boost::signals2::connection temp_viz::Viz3d::VizImpl::registerKeyboardCallback (boost::function callback) +{ + return (style_->registerKeyboardCallback (callback)); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +boost::signals2::connection temp_viz::Viz3d::VizImpl::registerMouseCallback (boost::function callback) +{ + return (style_->registerMouseCallback (callback)); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::spin () +{ + resetStoppedFlag (); + window_->Render (); + interactor_->Start (); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::spinOnce (int time, bool force_redraw) +{ + resetStoppedFlag (); + + if (time <= 0) + time = 1; + + if (force_redraw) + interactor_->Render (); + + double s_now_ = cv::getTickCount() / cv::getTickFrequency(); + if (s_lastDone_ > s_now_) + s_lastDone_ = s_now_; + + if ((s_now_ - s_lastDone_) > (1.0 / interactor_->GetDesiredUpdateRate ())) + { + exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer (time); + interactor_->Start (); + interactor_->DestroyTimer (exit_main_loop_timer_callback_->right_timer_id); + s_lastDone_ = s_now_; + } +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::addCoordinateSystem (double scale, const cv::Affine3f& affine, const std::string &id) +{ + vtkSmartPointer axes = vtkSmartPointer::New (); + axes->SetOrigin (0, 0, 0); + axes->SetScaleFactor (scale); + + vtkSmartPointer axes_colors = vtkSmartPointer::New (); + axes_colors->Allocate (6); + axes_colors->InsertNextValue (0.0); + axes_colors->InsertNextValue (0.0); + axes_colors->InsertNextValue (0.5); + axes_colors->InsertNextValue (0.5); + axes_colors->InsertNextValue (1.0); + axes_colors->InsertNextValue (1.0); + + vtkSmartPointer axes_data = axes->GetOutput (); + axes_data->Update (); + axes_data->GetPointData ()->SetScalars (axes_colors); + + vtkSmartPointer axes_tubes = vtkSmartPointer::New (); + axes_tubes->SetInput (axes_data); + axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); + axes_tubes->SetNumberOfSides (6); + + vtkSmartPointer axes_mapper = vtkSmartPointer::New (); + axes_mapper->SetScalarModeToUsePointData (); + axes_mapper->SetInput (axes_tubes->GetOutput ()); + + vtkSmartPointer axes_actor = vtkSmartPointer::New (); + axes_actor->SetMapper (axes_mapper); + + cv::Vec3d t = affine.translation(); + axes_actor->SetPosition (t[0], t[1], t[2]); + + cv::Matx33f m = affine.rotation(); + + cv::Vec3f rvec; + cv::Rodrigues(m, rvec); + + float r_angle = cv::norm(rvec); + rvec *= 1.f/r_angle; + + axes_actor->SetOrientation(0,0,0); + axes_actor->RotateWXYZ(r_angle*180/CV_PI,rvec[0], rvec[1], rvec[2]); + renderer_->AddActor (axes_actor); + + (*shape_actor_map_)[id] = axes_actor; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removeCoordinateSystem (const std::string &id) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it == shape_actor_map_->end ()) + return false; + + // Remove it from all renderers + if (!removeActorFromRenderer(am_it->second)) + return false; + + shape_actor_map_->erase(am_it); + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removePointCloud (const std::string &id) +{ + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + if (am_it == cloud_actor_map_->end ()) + return false; + + if (removeActorFromRenderer (am_it->second.actor)) + return cloud_actor_map_->erase (am_it), true; + + return false; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removeShape (const std::string &id) +{ + // Check to see if the given ID entry exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + // Extra step: check if there is a cloud with the same ID + CloudActorMap::iterator ca_it = cloud_actor_map_->find (id); + + bool shape = true; + // Try to find a shape first + if (am_it == shape_actor_map_->end ()) + { + // There is no cloud or shape with this ID, so just exit + if (ca_it == cloud_actor_map_->end ()) + return false; + // Cloud found, set shape to false + shape = false; + } + + // Remove the pointer/ID pair to the global actor map + if (shape) + { + if (removeActorFromRenderer (am_it->second)) + { + shape_actor_map_->erase (am_it); + return (true); + } + } + else + { + if (removeActorFromRenderer (ca_it->second.actor)) + { + cloud_actor_map_->erase (ca_it); + return true; + } + } + return false; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removeText3D (const std::string &id) +{ + // Check to see if the given ID entry exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it == shape_actor_map_->end ()) + return false; + + // Remove it from all renderers + if (removeActorFromRenderer (am_it->second)) + return shape_actor_map_->erase (am_it), true; + + return false; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removeAllPointClouds () +{ + // Check to see if the given ID entry exists + CloudActorMap::iterator am_it = cloud_actor_map_->begin (); + while (am_it != cloud_actor_map_->end () ) + { + if (removePointCloud (am_it->first)) + am_it = cloud_actor_map_->begin (); + else + ++am_it; + } + return (true); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removeAllShapes () +{ + // Check to see if the given ID entry exists + ShapeActorMap::iterator am_it = shape_actor_map_->begin (); + while (am_it != shape_actor_map_->end ()) + { + if (removeShape (am_it->first)) + am_it = shape_actor_map_->begin (); + else + ++am_it; + } + return (true); +} + + +////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) +{ + vtkLODActor* actor_to_remove = vtkLODActor::SafeDownCast (actor); + + + + // Iterate over all actors in this renderer + vtkPropCollection* actors = renderer_->GetViewProps (); + actors->InitTraversal (); + + vtkProp* current_actor = NULL; + while ((current_actor = actors->GetNextProp ()) != NULL) + { + if (current_actor != actor_to_remove) + continue; + renderer_->RemoveActor (actor); + // renderer->Render (); + // Found the correct viewport and removed the actor + return (true); + } + + return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) +{ + vtkActor* actor_to_remove = vtkActor::SafeDownCast (actor); + + // Add it to all renderers + //rens_->InitTraversal (); + + + // Iterate over all actors in this renderer + vtkPropCollection* actors = renderer_->GetViewProps (); + actors->InitTraversal (); + vtkProp* current_actor = NULL; + while ((current_actor = actors->GetNextProp ()) != NULL) + { + if (current_actor != actor_to_remove) + continue; + renderer_->RemoveActor (actor); + // renderer->Render (); + // Found the correct viewport and removed the actor + return (true); + } + return false; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) +{ + vtkProp* actor_to_remove = vtkProp::SafeDownCast(actor); + + vtkPropCollection* actors = renderer_->GetViewProps (); + actors->InitTraversal (); + vtkProp* current_actor = NULL; + while ((current_actor = actors->GetNextProp ()) != NULL) + { + if (current_actor != actor_to_remove) + continue; + renderer_->RemoveActor (actor); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::createActorFromVTKDataSet (const vtkSmartPointer &data, vtkSmartPointer &actor, bool use_scalars) +{ + if (!actor) + actor = vtkSmartPointer::New (); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (data); + + if (use_scalars) + { + vtkSmartPointer 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 (1, data->GetNumberOfPoints () / 10))); + actor->GetProperty ()->SetInterpolationToFlat (); + + /// FIXME disabling backface culling due to known VTK bug: vtkTextActors are not + /// shown when there is a vtkActor with backface culling on present in the scene + /// Please see VTK bug tracker for more details: http://www.vtk.org/Bug/view.php?id=12588 + // actor->GetProperty ()->BackfaceCullingOn (); + + actor->SetMapper (mapper); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setBackgroundColor (const Color& color) +{ + Color c = vtkcolor(color); + renderer_->SetBackground (c.val); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setPointCloudColor (const Color& color, const std::string &id) +{ + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + if (am_it != cloud_actor_map_->end ()) + { + vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); + + Color c = vtkcolor(color); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->Modified (); + } +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::getPointCloudRenderingProperties (int property, double &value, const std::string &id) +{ + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + if (am_it == cloud_actor_map_->end ()) + return false; + + vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); + + switch (property) + { + case VIZ_POINT_SIZE: + { + value = actor->GetProperty ()->GetPointSize (); + actor->Modified (); + break; + } + case VIZ_OPACITY: + { + value = actor->GetProperty ()->GetOpacity (); + actor->Modified (); + break; + } + case VIZ_LINE_WIDTH: + { + value = actor->GetProperty ()->GetLineWidth (); + actor->Modified (); + break; + } + default: + CV_Assert("getPointCloudRenderingProperties: Unknown property"); + } + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::setPointCloudRenderingProperties (int property, double value, const std::string &id) +{ + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + if (am_it == cloud_actor_map_->end ()) + return std::cout << "[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <" << id << ">!" << std::endl, false; + + vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); + + switch (property) + { + case VIZ_POINT_SIZE: + { + actor->GetProperty ()->SetPointSize (float (value)); + actor->Modified (); + break; + } + case VIZ_OPACITY: + { + actor->GetProperty ()->SetOpacity (value); + actor->Modified (); + break; + } + // Turn on/off flag to control whether data is rendered using immediate + // mode or note. Immediate mode rendering tends to be slower but it can + // handle larger datasets. The default value is immediate mode off. If you + // are having problems rendering a large dataset you might want to consider + // using immediate more rendering. + case VIZ_IMMEDIATE_RENDERING: + { + actor->GetMapper ()->SetImmediateModeRendering (int (value)); + actor->Modified (); + break; + } + case VIZ_LINE_WIDTH: + { + actor->GetProperty ()->SetLineWidth (float (value)); + actor->Modified (); + break; + } + default: + CV_Assert("setPointCloudRenderingProperties: Unknown property"); + } + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::setPointCloudSelected (const bool selected, const std::string &id) +{ + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + if (am_it == cloud_actor_map_->end ()) + return std::cout << "[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <" << id << ">!" << std::endl, false; + + vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); + if (selected) + { + actor->GetProperty ()->EdgeVisibilityOn (); + actor->GetProperty ()->SetEdgeColor (1.0, 0.0, 0.0); + actor->Modified (); + } + else + { + actor->GetProperty ()->EdgeVisibilityOff (); + actor->Modified (); + } + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setShapeColor (const Color& color, const std::string &id) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + vtkActor* actor = vtkActor::SafeDownCast (am_it->second); + + Color c = vtkcolor(color); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetProperty ()->SetColor (c.val); + actor->GetProperty ()->SetEdgeColor (c.val); + actor->GetProperty ()->SetAmbient (0.8); + actor->GetProperty ()->SetDiffuse (0.8); + actor->GetProperty ()->SetSpecular (0.8); + actor->GetProperty ()->SetLighting (0); + actor->Modified (); + } +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double value, const std::string &id) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it == shape_actor_map_->end ()) + return std::cout << "[setShapeRenderingProperties] Could not find any shape with id <" << id << ">!\n" << std::endl, false; + + vtkActor* actor = vtkActor::SafeDownCast (am_it->second); + + switch (property) + { + case VIZ_POINT_SIZE: + { + actor->GetProperty ()->SetPointSize (float (value)); + actor->Modified (); + break; + } + case VIZ_OPACITY: + { + actor->GetProperty ()->SetOpacity (value); + actor->Modified (); + break; + } + case VIZ_LINE_WIDTH: + { + actor->GetProperty ()->SetLineWidth (float (value)); + actor->Modified (); + break; + } + case VIZ_FONT_SIZE: + { + vtkTextActor* text_actor = vtkTextActor::SafeDownCast (am_it->second); + vtkSmartPointer tprop = text_actor->GetTextProperty (); + tprop->SetFontSize (int (value)); + text_actor->Modified (); + break; + } + case VIZ_REPRESENTATION: + { + switch (int (value)) + { + case REPRESENTATION_POINTS: actor->GetProperty ()->SetRepresentationToPoints (); break; + case REPRESENTATION_WIREFRAME: actor->GetProperty ()->SetRepresentationToWireframe (); break; + case REPRESENTATION_SURFACE: actor->GetProperty ()->SetRepresentationToSurface (); break; + } + actor->Modified (); + break; + } + case VIZ_SHADING: + { + switch (int (value)) + { + case SHADING_FLAT: actor->GetProperty ()->SetInterpolationToFlat (); break; + case SHADING_GOURAUD: + { + if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) + { + std::cout << "[temp_viz::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Gouraud shading was requested. Estimating normals...\n" << std::endl; + + vtkSmartPointer normals = vtkSmartPointer::New (); + normals->SetInput (actor->GetMapper ()->GetInput ()); + normals->Update (); + vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ()); + } + actor->GetProperty ()->SetInterpolationToGouraud (); + break; + } + case SHADING_PHONG: + { + if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) + { + std::cout << "[temp_viz::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Phong shading was requested. Estimating normals...\n" << std::endl; + vtkSmartPointer normals = vtkSmartPointer::New (); + normals->SetInput (actor->GetMapper ()->GetInput ()); + normals->Update (); + vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ()); + } + actor->GetProperty ()->SetInterpolationToPhong (); + break; + } + } + actor->Modified (); + break; + } + default: + CV_Assert("setShapeRenderingProperties: Unknown property"); + + } + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::initCameraParameters () +{ + Camera camera_temp; + // Set default camera parameters to something meaningful + camera_temp.clip = Vec2d(0.01, 1000.01); + + // Look straight along the z-axis + camera_temp.focal = Vec3d(0.0, 0.0, 1.0); + + // Position the camera at the origin + camera_temp.pos = Vec3d(0.0, 0.0, 0.0); + + // Set the up-vector of the camera to be the y-axis + camera_temp.view_up = Vec3d(0.0, 1.0, 0.0); + + // Set the camera field of view to about + camera_temp.fovy = 0.8575; + camera_temp.window_size = Vec2i(window_->GetScreenSize()) / 2; + camera_temp.window_pos = Vec2i(0, 0); + + setCameraParameters (camera_temp); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::cameraParamsSet () const { return (camera_set_); } + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::updateCamera () +{ + std::cout << "[temp_viz::PCLVisualizer::updateCamera()] This method was deprecated, just re-rendering all scenes now." << std::endl; + //rens_->InitTraversal (); + // Update the camera parameters + + renderer_->Render (); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::updateShapePose (const std::string &id, const cv::Affine3f& pose) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + + vtkLODActor* actor; + + if (am_it == shape_actor_map_->end ()) + return (false); + else + actor = vtkLODActor::SafeDownCast (am_it->second); + + vtkSmartPointer matrix = vtkSmartPointer::New (); + + convertToVtkMatrix (pose.matrix, matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); + + return (true); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::getCameras (temp_viz::Camera& camera) +{ + vtkCamera* active_camera = renderer_->GetActiveCamera (); + + camera.pos = cv::Vec3d(active_camera->GetPosition()); + camera.focal = cv::Vec3d(active_camera->GetFocalPoint()); + camera.clip = cv::Vec2d(active_camera->GetClippingRange()); + camera.view_up = cv::Vec3d(active_camera->GetViewUp()); + + camera.fovy = active_camera->GetViewAngle()/ 180.0 * CV_PI; + camera.window_size = cv::Vec2i(renderer_->GetRenderWindow()->GetSize()); + camera.window_pos = cv::Vec2d::all(0); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +cv::Affine3f temp_viz::Viz3d::VizImpl::getViewerPose () +{ + vtkCamera& camera = *renderer_->GetActiveCamera (); + + Vec3d pos(camera.GetPosition()); + Vec3d view_up(camera.GetViewUp()); + Vec3d focal(camera.GetFocalPoint()); + + Vec3d y_axis = normalized(view_up); + Vec3d z_axis = normalized(focal - pos); + Vec3d x_axis = normalized(y_axis.cross(z_axis)); + + cv::Matx33d R; + R(0, 0) = x_axis[0]; + R(0, 1) = y_axis[0]; + R(0, 2) = z_axis[0]; + + R(1, 0) = x_axis[1]; + R(1, 1) = y_axis[1]; + R(1, 2) = z_axis[1]; + + R(2, 0) = x_axis[2]; + R(2, 1) = y_axis[2]; + R(2, 2) = z_axis[2]; + + return cv::Affine3f(R, pos); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::resetCamera () +{ + renderer_->ResetCamera (); +} + + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up) +{ + + vtkSmartPointer cam = renderer_->GetActiveCamera (); + cam->SetPosition (pos[0], pos[1], pos[2]); + cam->SetFocalPoint (view[0], view[1], view[2]); + cam->SetViewUp (up[0], up[1], up[2]); + renderer_->Render (); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z) +{ + //rens_->InitTraversal (); + + + vtkSmartPointer cam = renderer_->GetActiveCamera (); + cam->SetPosition (pos_x, pos_y, pos_z); + cam->SetViewUp (up_x, up_y, up_z); + renderer_->Render (); + +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setCameraParameters (const cv::Matx33f& intrinsics, const cv::Affine3f& extrinsics) +{ + // Position = extrinsic translation + cv::Vec3f pos_vec = extrinsics.translation(); + + + // Rotate the view vector + cv::Matx33f rotation = extrinsics.rotation(); + cv::Vec3f y_axis (0.f, 1.f, 0.f); + cv::Vec3f up_vec (rotation * y_axis); + + // Compute the new focal point + cv::Vec3f z_axis (0.f, 0.f, 1.f); + cv::Vec3f focal_vec = pos_vec + rotation * z_axis; + + // Get the width and height of the image - assume the calibrated centers are at the center of the image + Eigen::Vector2i window_size; + window_size[0] = static_cast (intrinsics(0, 2)); + window_size[1] = static_cast (intrinsics(1, 2)); + + // Compute the vertical field of view based on the focal length and image heigh + double fovy = 2 * atan (window_size[1] / (2. * intrinsics (1, 1))) * 180.0 / M_PI; + + //rens_->InitTraversal (); + + + vtkSmartPointer cam = renderer_->GetActiveCamera (); + cam->SetPosition (pos_vec[0], pos_vec[1], pos_vec[2]); + cam->SetFocalPoint (focal_vec[0], focal_vec[1], focal_vec[2]); + cam->SetViewUp (up_vec[0], up_vec[1], up_vec[2]); + cam->SetUseHorizontalViewAngle (0); + cam->SetViewAngle (fovy); + cam->SetClippingRange (0.01, 1000.01); + window_->SetSize (window_size[0], window_size[1]); + + renderer_->Render (); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setCameraParameters (const temp_viz::Camera &camera) +{ + //rens_->InitTraversal (); + + + vtkSmartPointer cam = renderer_->GetActiveCamera (); + cam->SetPosition (camera.pos[0], camera.pos[1], camera.pos[2]); + cam->SetFocalPoint (camera.focal[0], camera.focal[1], camera.focal[2]); + cam->SetViewUp (camera.view_up[0], camera.view_up[1], camera.view_up[2]); + cam->SetClippingRange (camera.clip.val); + cam->SetUseHorizontalViewAngle (0); + cam->SetViewAngle (camera.fovy * 180.0 / M_PI); + + window_->SetSize (static_cast (camera.window_size[0]), static_cast (camera.window_size[1])); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setCameraClipDistances (double near, double far) +{ + //rens_->InitTraversal (); + + vtkSmartPointer cam = renderer_->GetActiveCamera (); + cam->SetClippingRange (near, far); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setCameraFieldOfView (double fovy) +{ + //rens_->InitTraversal (); + + vtkSmartPointer cam = renderer_->GetActiveCamera (); + cam->SetUseHorizontalViewAngle (0); + cam->SetViewAngle (fovy * 180.0 / M_PI); + +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) +{ + vtkSmartPointer camera_pose; + static CloudActorMap::iterator it = cloud_actor_map_->find (id); + if (it != cloud_actor_map_->end ()) + camera_pose = it->second.viewpoint_transformation_; + else + return; + + // Prevent a segfault + if (!camera_pose) + return; + + // set all renderer to this viewpoint + //rens_->InitTraversal (); + + + vtkSmartPointer cam = renderer_->GetActiveCamera (); + cam->SetPosition (camera_pose->GetElement (0, 3), + camera_pose->GetElement (1, 3), + camera_pose->GetElement (2, 3)); + + cam->SetFocalPoint (camera_pose->GetElement (0, 3) - camera_pose->GetElement (0, 2), + camera_pose->GetElement (1, 3) - camera_pose->GetElement (1, 2), + camera_pose->GetElement (2, 3) - camera_pose->GetElement (2, 2)); + + cam->SetViewUp (camera_pose->GetElement (0, 1), + camera_pose->GetElement (1, 1), + camera_pose->GetElement (2, 1)); + + renderer_->SetActiveCamera (cam); + renderer_->ResetCameraClippingRange (); + renderer_->Render (); +} + + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addCylinder (const temp_viz::ModelCoefficients &coefficients, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addCylinder] A shape with id <"< already exists! Please choose a different id and retry." << std::endl; + return (false); + } + + vtkSmartPointer data = createCylinder (coefficients); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetLighting (false); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addCube (const temp_viz::ModelCoefficients &coefficients, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addCube] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; + return (false); + } + + vtkSmartPointer data = createCube (coefficients); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetLighting (false); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addCube (const cv::Vec3f& translation, const cv::Vec3f quaternion, double width, double height, double depth, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addCube] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; + return (false); + } + + Eigen::Vector3f t(translation[0], translation[1], translation[2]); + Eigen::Quaternionf q(quaternion[0], quaternion[1], quaternion[2], quaternion[3]); + + vtkSmartPointer data = createCube (t, q, width, height, depth); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetLighting (false); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addCube (float x_min, float x_max, float y_min, float y_max, float z_min, float z_max, + const Color& color , const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addCube] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; + + vtkSmartPointer data = createCube (x_min, x_max, y_min, y_max, z_min, z_max); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetLighting (false); + + Color c = vtkcolor(color); + actor->GetProperty ()->SetColor (c.val); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, const std::string & id) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addModelFromPolyData] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; + return (false); + } + + vtkSmartPointer actor; + createActorFromVTKDataSet (polydata, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const std::string & id) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addModelFromPolyData] A shape with id <"< already exists! Please choose a different id and retry." << std::endl; + return (false); + } + + vtkSmartPointer trans_filter = vtkSmartPointer::New (); + trans_filter->SetTransform (transform); + trans_filter->SetInput (polydata); + trans_filter->Update(); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (trans_filter->GetOutput (), actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, const std::string &id) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addModelFromPLYFile] A shape with id <"< already exists! Please choose a different id and retry.." << std::endl, false; + + vtkSmartPointer reader = vtkSmartPointer::New (); + reader->SetFileName (filename.c_str ()); + + vtkSmartPointer actor; + createActorFromVTKDataSet (reader->GetOutput (), actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + renderer_->AddActor(actor); + + (*shape_actor_map_)[id] = actor; + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, vtkSmartPointer transform, const std::string &id) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addModelFromPLYFile] A shape with id <"< already exists! Please choose a different id and retry." << std::endl, false; + + vtkSmartPointer reader = vtkSmartPointer::New (); + reader->SetFileName (filename.c_str ()); + + vtkSmartPointer trans_filter = vtkSmartPointer::New (); + trans_filter->SetTransform (transform); + trans_filter->SetInputConnection (reader->GetOutputPort ()); + + vtkSmartPointer actor; + createActorFromVTKDataSet (trans_filter->GetOutput (), actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + renderer_->AddActor(actor); + + (*shape_actor_map_)[id] = actor; + return (true); +} + + +//////////////////////////////////////////////////////////////////////////////////////////// +/** \brief Add a plane from a set of given model coefficients + * \param coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0) + * \param id the plane id/name (default: "plane") + * \param viewport (optional) the id of the new viewport (default: 0) + */ +bool temp_viz::Viz3d::VizImpl::addPlane (const temp_viz::ModelCoefficients &coefficients, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addPlane] A shape with id <"< already exists! Please choose a different id and retry." << std::endl; + return (false); + } + + vtkSmartPointer data = createPlane (coefficients); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + // actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetLighting (false); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +bool temp_viz::Viz3d::VizImpl::addPlane (const temp_viz::ModelCoefficients &coefficients, double x, double y, double z, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addPlane] A shape with id <" << id << "> already exists! Please choose a different id and retry.\n" << std::endl; + return (false); + } + + vtkSmartPointer data = createPlane (coefficients, x, y, z); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetLighting (false); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addCircle (const temp_viz::ModelCoefficients &coefficients, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addCircle] A shape with id <"< already exists! Please choose a different id and retry.\n" << std::endl; + return (false); + } + + vtkSmartPointer data = create2DCircle (coefficients); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetLighting (false); + + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize, const std::string &id) +{ + std::string tid = id.empty() ? text : id; + + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (tid); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addText] A text with id <"< already exists! Please choose a different id and retry.\n" << std::endl, false; + + // Create an Actor + vtkSmartPointer actor = vtkSmartPointer::New (); + actor->SetPosition (xpos, ypos); + actor->SetInput (text.c_str ()); + + vtkSmartPointer tprop = actor->GetTextProperty (); + tprop->SetFontSize (fontsize); + tprop->SetFontFamilyToArial (); + tprop->SetJustificationToLeft (); + tprop->BoldOn (); + + Color c = vtkcolor(color); + tprop->SetColor (c.val); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[tid] = actor; + return (true); +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::updateText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize, const std::string &id) +{ + std::string tid = id.empty() ? text : id; + + ShapeActorMap::iterator am_it = shape_actor_map_->find (tid); + if (am_it == shape_actor_map_->end ()) + return false; + + // Retrieve the Actor + vtkTextActor *actor = vtkTextActor::SafeDownCast (am_it->second); + + actor->SetPosition (xpos, ypos); + actor->SetInput (text.c_str ()); + + vtkTextProperty* tprop = actor->GetTextProperty (); + tprop->SetFontSize (fontsize); + + Color c = vtkcolor(color); + tprop->SetColor (c.val); + + actor->Modified (); + + return (true); +} + +bool temp_viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& mesh, const std::string &id) +{ + CV_Assert(mesh.cloud.rows == 1 && mesh.cloud.type() == CV_32FC3); + + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addPolylineFromPolygonMesh] A shape with id <"<< id << "> already exists! Please choose a different id and retry.\n" << std::endl, false; + + vtkSmartPointer poly_points = vtkSmartPointer::New (); + poly_points->SetNumberOfPoints (mesh.cloud.size().area()); + + const cv::Point3f *cdata = mesh.cloud.ptr(); + for (int i = 0; i < mesh.cloud.cols; ++i) + poly_points->InsertPoint (i, cdata[i].x, cdata[i].y,cdata[i].z); + + + // Create a cell array to store the lines in and add the lines to it + vtkSmartPointer cells = vtkSmartPointer::New (); + vtkSmartPointer polyData; + allocVtkPolyData (polyData); + + for (size_t i = 0; i < mesh.polygons.size (); i++) + { + vtkSmartPointer polyLine = vtkSmartPointer::New(); + polyLine->GetPointIds()->SetNumberOfIds(mesh.polygons[i].vertices.size()); + for(unsigned int k = 0; k < mesh.polygons[i].vertices.size(); k++) + { + polyLine->GetPointIds()->SetId(k,mesh. polygons[i].vertices[k]); + } + + cells->InsertNextCell (polyLine); + } + + // Add the points to the dataset + polyData->SetPoints (poly_points); + + // Add the lines to the dataset + polyData->SetLines (cells); + + // Setup actor and mapper + vtkSmartPointer < vtkPolyDataMapper > mapper = vtkSmartPointer::New (); + mapper->SetInput (polyData); + + vtkSmartPointer actor = vtkSmartPointer::New (); + actor->SetMapper (mapper); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + return (true); +} + + +/////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setRepresentationToSurfaceForAllActors () +{ + vtkActorCollection * actors = renderer_->GetActors (); + actors->InitTraversal (); + vtkActor * actor; + while ((actor = actors->GetNextActor ()) != NULL) + actor->GetProperty ()->SetRepresentationToSurface (); +} + +/////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setRepresentationToPointsForAllActors () +{ + vtkActorCollection * actors = renderer_->GetActors (); + actors->InitTraversal (); + vtkActor * actor; + while ((actor = actors->GetNextActor ()) != NULL) + actor->GetProperty ()->SetRepresentationToPoints (); +} + +/////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::setRepresentationToWireframeForAllActors () +{ + vtkActorCollection * actors = renderer_->GetActors (); + actors->InitTraversal (); + vtkActor *actor; + while ((actor = actors->GetNextActor ()) != NULL) + actor->GetProperty ()->SetRepresentationToWireframe (); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::updateCells (vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points) +{ + // If no init cells and cells has not been initialized... + if (!cells) + cells = vtkSmartPointer::New (); + + // If we have less values then we need to recreate the array + if (cells->GetNumberOfTuples () < nr_points) + { + cells = vtkSmartPointer::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::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 temp_viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) +{ + polydata = vtkSmartPointer::New (); +} +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) +{ + polydata = vtkSmartPointer::New (); +} +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) +{ + polydata = vtkSmartPointer::New (); +} + + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix) +{ + // set rotation + Eigen::Matrix3f rot = orientation.toRotationMatrix (); + for (int i = 0; i < 3; i++) + for (int k = 0; k < 3; k++) + vtk_matrix->SetElement (i, k, rot (i, k)); + + // set translation + vtk_matrix->SetElement (0, 3, origin (0)); + vtk_matrix->SetElement (1, 3, origin (1)); + vtk_matrix->SetElement (2, 3, origin (2)); + vtk_matrix->SetElement (3, 3, 1.0f); +} + +void temp_viz::convertToVtkMatrix (const cv::Matx44f &m, vtkSmartPointer &vtk_matrix) +{ + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + vtk_matrix->SetElement (i, k, m (i, k)); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m) +{ + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + m (i,k) = static_cast (vtk_matrix->GetElement (i, k)); +} diff --git a/modules/viz/test/test_main.cpp b/modules/viz/test/test_main.cpp new file mode 100644 index 000000000..6b2499344 --- /dev/null +++ b/modules/viz/test/test_main.cpp @@ -0,0 +1,3 @@ +#include "test_precomp.hpp" + +CV_TEST_MAIN("cv") diff --git a/modules/viz/test/test_precomp.cpp b/modules/viz/test/test_precomp.cpp new file mode 100644 index 000000000..5956e13e3 --- /dev/null +++ b/modules/viz/test/test_precomp.cpp @@ -0,0 +1 @@ +#include "test_precomp.hpp" diff --git a/modules/viz/test/test_precomp.hpp b/modules/viz/test/test_precomp.hpp new file mode 100644 index 000000000..6c0f493d4 --- /dev/null +++ b/modules/viz/test/test_precomp.hpp @@ -0,0 +1,16 @@ +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + +#ifndef __OPENCV_TEST_PRECOMP_HPP__ +#define __OPENCV_TEST_PRECOMP_HPP__ + +#include "opencv2/ts.hpp" +#include "opencv2/core/core_c.h" +#include + +#endif diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp new file mode 100644 index 000000000..922090c83 --- /dev/null +++ b/modules/viz/test/test_viz3d.cpp @@ -0,0 +1,133 @@ +/*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) 2000-2008, Intel Corporation, all rights reserved. + // Copyright (C) 2008-2013, Willow Garage Inc., 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. + // + //M*/ +#include "test_precomp.hpp" +#include +#include +#include + +#include +#include + +#include +#include + + +cv::Mat cvcloud_load() +{ + cv::Mat cloud(1, 20000, CV_32FC3); + std::ifstream ifs("d:/cloud_dragon.ply"); + + std::string str; + for(size_t i = 0; i < 11; ++i) + std::getline(ifs, str); + + cv::Point3f* data = cloud.ptr(); + for(size_t i = 0; i < 20000; ++i) + ifs >> data[i].x >> data[i].y >> data[i].z; + + return cloud; +} + +TEST(Viz_viz3d, accuracy) +{ + temp_viz::Viz3d v("abc"); + //v.spin(); + + v.setBackgroundColor(); + + v.addCoordinateSystem(1.0, cv::Affine3f::Identity()); + + cv::Mat cloud = cvcloud_load(); + + + cv::Mat colors(cloud.size(), CV_8UC3, cv::Scalar(0, 255, 0)); + v.addPointCloud(cloud, colors); + cv::Mat normals(cloud.size(), CV_32FC3, cv::Scalar(0, 10, 0)); + + v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); + + + temp_viz::ModelCoefficients mc; + mc.values.resize(4); + mc.values[0] = mc.values[1] = mc.values[2] = mc.values[3] = 1; + v.addPlane(mc); + + + temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("d:/horse.ply"); + v.addPolygonMesh(*mesh, "pq"); + + v.spinOnce(1000, true); + + v.removeCoordinateSystem(); + + for(int i = 0; i < mesh->cloud.cols; ++i) + mesh->cloud.ptr()[i] += cv::Point3f(1, 1, 1); + + v.updatePolygonMesh(*mesh, "pq"); + + + for(int i = 0; i < mesh->cloud.cols; ++i) + mesh->cloud.ptr()[i] -= cv::Point3f(2, 2, 2); + v.addPolylineFromPolygonMesh(*mesh); + + + v.addText("===Abd sadfljsadlk", 100, 100, cv::Scalar(255, 0, 0), 15); + for(int i = 0; i < cloud.cols; ++i) + cloud.ptr()[i].x *=2; + + colors.setTo(cv::Scalar(255, 0, 0)); + + v.addSphere(cv::Point3f(0, 0, 0), 0.3, temp_viz::Color::blue()); + + cv::Mat cvpoly(1, 5, CV_32FC3); + cv::Point3f* pdata = cvpoly.ptr(); + pdata[0] = cv::Point3f(0, 0, 0); + pdata[1] = cv::Point3f(0, 1, 1); + pdata[2] = cv::Point3f(3, 1, 2); + pdata[3] = cv::Point3f(0, 2, 4); + pdata[4] = cv::Point3f(7, 2, 3); + v.addPolygon(cvpoly, temp_viz::Color::white()); + + v.updatePointCloud(cloud, colors); + v.spin(); +} + From e75057956a69798cfda568d1f497237a1397c371 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 29 May 2013 18:37:53 +0200 Subject: [PATCH 002/205] fix linux compilation errors --- modules/viz/src/q/common.h | 2 +- modules/viz/src/viz3d_impl.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/viz/src/q/common.h b/modules/viz/src/q/common.h index 5562bf4f6..e9cb64bda 100644 --- a/modules/viz/src/q/common.h +++ b/modules/viz/src/q/common.h @@ -108,7 +108,7 @@ namespace temp_viz * the projection matrix * the view matrix. However, additional * matrices like a camera disortion matrix can also be added. */ - void cvtWindowCoordinates (const Point3f& pt, Matx44d& composite_mat, Vec4d& window_cord) const + void cvtWindowCoordinates (const Point3f& pt, const Matx44d& composite_mat, Vec4d& window_cord) const { Vec4d pte (pt.x, pt.y, pt.z, 1); window_cord = composite_mat * pte; diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 20d8a06f0..223b2bd1f 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -409,7 +409,7 @@ bool temp_viz::Viz3d::VizImpl::addLine (const cv::Point3f &pt1, const cv::Point3 -inline bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) +bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); @@ -596,7 +596,7 @@ inline bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const } -inline bool temp_viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) +bool temp_viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); @@ -776,7 +776,7 @@ bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3 #include //////////////////////////////////////////////////////////////////////////////////////////// -inline bool temp_viz::Viz3d::VizImpl::addSphere (const cv::Point3f& center, float radius, const Color& color, const std::string &id) +bool temp_viz::Viz3d::VizImpl::addSphere (const cv::Point3f& center, float radius, const Color& color, const std::string &id) { // Check to see if this ID entry already exists (has it been already added to the visualizer?) ShapeActorMap::iterator am_it = shape_actor_map_->find (id); @@ -817,7 +817,7 @@ inline bool temp_viz::Viz3d::VizImpl::addSphere (const cv::Point3f& center, floa } //////////////////////////////////////////////////////////////////////////////////////////// -inline bool temp_viz::Viz3d::VizImpl::updateSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id) +bool temp_viz::Viz3d::VizImpl::updateSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id) { // Check to see if this ID entry already exists (has it been already added to the visualizer?) ShapeActorMap::iterator am_it = shape_actor_map_->find (id); @@ -841,7 +841,7 @@ inline bool temp_viz::Viz3d::VizImpl::updateSphere (const cv::Point3f ¢er, f } ////////////////////////////////////////////////// -inline bool temp_viz::Viz3d::VizImpl::addText3D (const std::string &text, const cv::Point3f& position, const Color& color, double textScale, const std::string &id) +bool temp_viz::Viz3d::VizImpl::addText3D (const std::string &text, const cv::Point3f& position, const Color& color, double textScale, const std::string &id) { std::string tid; if (id.empty ()) @@ -884,7 +884,7 @@ inline bool temp_viz::Viz3d::VizImpl::addText3D (const std::string &text, const return (true); } -inline bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) +bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) { CV_Assert(cloud.type() == CV_32FC3 && cloud.rows == 1); From e10582ce4f51a80b592d4e40ae44ec120ed9291c Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 29 May 2013 20:58:57 +0200 Subject: [PATCH 003/205] Initial implementation of keyboard callback registration mechanism without boost --- modules/viz/include/opencv2/viz/viz3d.hpp | 3 ++ modules/viz/src/interactor_style.cpp | 26 ++++++++++-- modules/viz/src/q/interactor_style.h | 31 +++++++++++--- modules/viz/src/q/viz3d_impl.hpp | 49 +++++++++++++++-------- modules/viz/src/viz3d.cpp | 5 +++ modules/viz/src/viz_main.cpp | 13 +++--- 6 files changed, 95 insertions(+), 32 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index e48f5202f..9386094d7 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -10,6 +10,7 @@ #include #include +#include namespace temp_viz { @@ -57,6 +58,8 @@ namespace temp_viz void spin (); void spinOnce (int time = 1, bool force_redraw = false); + + void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = NULL); private: Viz3d(const Viz3d&); diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index d13ad3c35..32fe6a104 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -35,6 +35,10 @@ void temp_viz::InteractorStyle::Initialize () init_ = true; stereo_anaglyph_mask_default_ = true; + + // Initialize the keyboard callback as none + keyboardCallback_ = NULL; + keyboard_callback_cookie_ = NULL; } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -144,9 +148,17 @@ boost::signals2::connection temp_viz::InteractorStyle::registerMouseCallback (bo } ////////////////////////////////////////////////////////////////////////////////////////////// -boost::signals2::connection temp_viz::InteractorStyle::registerKeyboardCallback (boost::function callback) +// boost::signals2::connection temp_viz::InteractorStyle::registerKeyboardCallback (boost::function callback) +// { +// return (keyboard_signal_.connect (callback)); +// } + +////////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void *cookie) { - return (keyboard_signal_.connect (callback)); + /* Register the new callback function by assigning it to the internal callback function pointer */ + keyboardCallback_ = callback; + keyboard_callback_cookie_ = NULL; } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -508,7 +520,10 @@ temp_viz::InteractorStyle::OnKeyDown () } KeyboardEvent event (true, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - keyboard_signal_ (event); + // Check if there is a keyboard callback registered + if (keyboardCallback_ != NULL) + keyboardCallback_(event, keyboard_callback_cookie_); + //keyboard_signal_ (event); renderer_->Render (); Interactor->Render (); @@ -518,7 +533,10 @@ temp_viz::InteractorStyle::OnKeyDown () void temp_viz::InteractorStyle::OnKeyUp () { KeyboardEvent event (false, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - keyboard_signal_ (event); + // Check if there is a keyboard callback registered + if (keyboardCallback_ != NULL) + keyboardCallback_(event, keyboard_callback_cookie_); +// keyboard_signal_ (event); Superclass::OnKeyUp (); } diff --git a/modules/viz/src/q/interactor_style.h b/modules/viz/src/q/interactor_style.h index 91493eda6..6c99d88e1 100644 --- a/modules/viz/src/q/interactor_style.h +++ b/modules/viz/src/q/interactor_style.h @@ -68,13 +68,27 @@ namespace temp_viz */ boost::signals2::connection registerMouseCallback (boost::function cb); - /** \brief Register a callback boost::function for keyboard events - * \param[in] cb a boost function that will be registered as a callback for a keyboard event - * \return a connection object that allows to disconnect the callback function. + /** \brief Register a callback function for keyboard events + * \param[in] callback a function that will be registered as a callback for a keyboard event + * \param[in] cookie user data passed to the callback function */ - boost::signals2::connection registerKeyboardCallback (boost::function cb); - - + void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void * cookie = NULL); + + + // TODO Implement callback function as a method of an instance + /** \brief Register a callback function for keyboard input + * \param[in] callback function that will be registered as a callback for a keyboard event + * \param[in] instance the instance that the callback function belongs to + * \param[in] cookie for passing user data to callback + */ +// template inline void registerKeyboardCallback(void (T::*callback)(const cv::KeyboardEvent&, void*), T& instance, void* cookie = NULL) +// { +// registerKeyboardCallback(callback, cookie); +// // Set the instance for calling the callback +// keyboard_callback_instance_ = (void *) &instance; +// +// } + /** \brief Save the current rendered image to disk, as a PNG screenshot. * \param[in] file the name of the PNG file */ @@ -146,5 +160,10 @@ namespace temp_viz /** \brief The keyboard modifier to use. Default: Alt. */ KeyboardModifier modifier_; + + /** \brief Keyboard-Callback function */ + void (*keyboardCallback_)(const cv::KeyboardEvent&, void*); + void *keyboard_callback_cookie_; + void *keyboard_callback_instance_; }; } diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 1d946f1e1..a6e3de594 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -22,23 +22,41 @@ public: virtual ~VizImpl (); void setFullScreen (bool mode); void setWindowName (const std::string &name); + + /** \brief Register a callback function for keyboard input + * \param[in] callback function that will be registered as a callback for a keyboard event + * \param[in] cookie for passing user data to callback + */ + void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = NULL); + + // TODO Implement callback function as a method of an instance + /** \brief Register a callback function for keyboard input + * \param[in] callback function that will be registered as a callback for a keyboard event + * \param[in] instance the instance that the callback function belongs to + * \param[in] cookie for passing user data to callback + */ + +// template inline void registerKeyboardCallback(void (T::*callback)(const cv::KeyboardEvent&, void*), T& instance, void* cookie = NULL) +// { } - /** \brief Register a callback boost::function for keyboard events - * \param[in] cb a boost function that will be registered as a callback for a keyboard event - * \return a connection object that allows to disconnect the callback function. - */ - boost::signals2::connection registerKeyboardCallback (boost::function cb); - inline boost::signals2::connection registerKeyboardCallback (void (*callback) (const cv::KeyboardEvent&, void*), void* cookie = NULL) - { return (registerKeyboardCallback (boost::bind (callback, _1, cookie))); } - /** \brief Register a callback function for keyboard events - * \param[in] callback the member function that will be registered as a callback for a keyboard event - * \param[in] instance instance to the class that implements the callback function - * \param[in] cookie user data that is passed to the callback - * \return a connection object that allows to disconnect the callback function. - */ - template inline boost::signals2::connection registerKeyboardCallback (void (T::*callback) (const cv::KeyboardEvent&, void*), T& instance, void* cookie = NULL) - { return (registerKeyboardCallback (boost::bind (callback, boost::ref (instance), _1, cookie))); } + +// /** \brief Register a callback boost::function for keyboard events +// * \param[in] cb a boost function that will be registered as a callback for a keyboard event +// * \return a connection object that allows to disconnect the callback function. +// */ +// void registerKeyboardCallback (boost::function cb); +// inline boost::signals2::connection registerKeyboardCallback (void (*callback) (const cv::KeyboardEvent&, void*), void* cookie = NULL) +// { return (registerKeyboardCallback (boost::bind (callback, _1, cookie))); } +// +// /** \brief Register a callback function for keyboard events +// * \param[in] callback the member function that will be registered as a callback for a keyboard event +// * \param[in] instance instance to the class that implements the callback function +// * \param[in] cookie user data that is passed to the callback +// * \return a connection object that allows to disconnect the callback function. +// */ +// template inline boost::signals2::connection registerKeyboardCallback (void (T::*callback) (const cv::KeyboardEvent&, void*), T& instance, void* cookie = NULL) +// { return (registerKeyboardCallback (boost::bind (callback, boost::ref (instance), _1, cookie))); } /** \brief Register a callback function for mouse events * \param[in] cb a boost function that will be registered as a callback for a mouse event @@ -446,7 +464,6 @@ private: void allocVtkPolyData (vtkSmartPointer &polydata); void allocVtkPolyData (vtkSmartPointer &polydata); void allocVtkUnstructuredGrid (vtkSmartPointer &polydata); - }; //void getTransformationMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternionf& orientation, Eigen::Matrix4f &transformation); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 9e35e42e9..ed219f48c 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -92,3 +92,8 @@ bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) { return impl_->removeCoordinateSystem(id); } + +void temp_viz::Viz3d::registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie) +{ + impl_->registerKeyboardCallback(callback, cookie); +} \ No newline at end of file diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 2c2fe5245..a64d62f9d 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -94,18 +94,19 @@ temp_viz::Viz3d::VizImpl::~VizImpl () ///////////////////////////////////////////////////////////////////////////////////////////// void temp_viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } -///////////////////////////////////////////////////////////////////////////////////////////// -boost::signals2::connection temp_viz::Viz3d::VizImpl::registerKeyboardCallback (boost::function callback) -{ - return (style_->registerKeyboardCallback (callback)); -} - ///////////////////////////////////////////////////////////////////////////////////////////// boost::signals2::connection temp_viz::Viz3d::VizImpl::registerMouseCallback (boost::function callback) { return (style_->registerMouseCallback (callback)); } +///////////////////////////////////////////////////////////////////////////////////////////// +void temp_viz::Viz3d::VizImpl::registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie) +{ + // Register the callback function in the interactor style + style_->registerKeyboardCallback(callback, cookie); +} + ///////////////////////////////////////////////////////////////////////////////////////////// void temp_viz::Viz3d::VizImpl::spin () { From 6603cc4405977ed9458fc4310774f003d06e985d Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 30 May 2013 20:01:33 +0200 Subject: [PATCH 004/205] boost dependency has been removed --- modules/viz/CMakeLists.txt | 19 ------ modules/viz/include/opencv2/viz/viz3d.hpp | 3 +- modules/viz/src/interactor_style.cpp | 73 +++++++++++++---------- modules/viz/src/precomp.hpp | 4 +- modules/viz/src/q/interactor_style.h | 38 ++++-------- modules/viz/src/q/viz3d_impl.hpp | 48 ++------------- modules/viz/src/viz3d.cpp | 5 ++ modules/viz/src/viz_main.cpp | 5 +- 8 files changed, 70 insertions(+), 125 deletions(-) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 0509478fd..b45060371 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -36,26 +36,7 @@ macro(find_vtk) endif() endmacro() -macro(find_boost) - # Disable the config mode of find_package(Boost) - set(Boost_NO_BOOST_CMAKE ON) - set(Boost_USE_STATIC_LIBS ON) - - find_package(Boost 1.49.0 REQUIRED COMPONENTS system thread) - - if(Boost_FOUND) - set(HAVE_BOOST ON) - - # Obtain diagnostic information about Boost's automatic linking outputted during compilation time. - add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) - include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) - link_directories(${Boost_LIBRARY_DIRS}) - message(STATUS "Boost found (include: ${Boost_INCLUDE_DIRS})") - endif() -endmacro() - find_vtk() -find_boost() find_package(OpenGL) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 9386094d7..fe0851a60 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -59,7 +59,8 @@ namespace temp_viz void spin (); void spinOnce (int time = 1, bool force_redraw = false); - void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = NULL); + void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = 0); + void registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie = 0); private: Viz3d(const Viz3d&); diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 32fe6a104..00a1ed172 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -36,9 +36,13 @@ void temp_viz::InteractorStyle::Initialize () init_ = true; stereo_anaglyph_mask_default_ = true; - // Initialize the keyboard callback as none - keyboardCallback_ = NULL; - keyboard_callback_cookie_ = NULL; + // 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; } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -142,23 +146,19 @@ void temp_viz::InteractorStyle::OnChar () } ////////////////////////////////////////////////////////////////////////////////////////////// -boost::signals2::connection temp_viz::InteractorStyle::registerMouseCallback (boost::function callback) +void temp_viz::InteractorStyle::registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie) { - return (mouse_signal_.connect (callback)); + // Register the callback function and store the user data + mouseCallback_ = callback; + mouse_callback_cookie_ = cookie; } -////////////////////////////////////////////////////////////////////////////////////////////// -// boost::signals2::connection temp_viz::InteractorStyle::registerKeyboardCallback (boost::function callback) -// { -// return (keyboard_signal_.connect (callback)); -// } - ////////////////////////////////////////////////////////////////////////////////////////////// void temp_viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void *cookie) { - /* Register the new callback function by assigning it to the internal callback function pointer */ + // Register the callback function and store the user data keyboardCallback_ = callback; - keyboard_callback_cookie_ = NULL; + keyboard_callback_cookie_ = cookie; } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -521,9 +521,8 @@ temp_viz::InteractorStyle::OnKeyDown () KeyboardEvent event (true, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); // Check if there is a keyboard callback registered - if (keyboardCallback_ != NULL) + if (keyboardCallback_) keyboardCallback_(event, keyboard_callback_cookie_); - //keyboard_signal_ (event); renderer_->Render (); Interactor->Render (); @@ -534,9 +533,9 @@ void temp_viz::InteractorStyle::OnKeyUp () { KeyboardEvent event (false, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); // Check if there is a keyboard callback registered - if (keyboardCallback_ != NULL) + if (keyboardCallback_) keyboardCallback_(event, keyboard_callback_cookie_); -// keyboard_signal_ (event); + Superclass::OnKeyUp (); } @@ -545,7 +544,8 @@ void temp_viz::InteractorStyle::OnMouseMove () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseMove, MouseEvent::NoButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); Superclass::OnMouseMove (); } @@ -555,7 +555,8 @@ void temp_viz::InteractorStyle::OnLeftButtonDown () Vec2i p(Interactor->GetEventPosition()); MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; MouseEvent event (type, MouseEvent::LeftButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); Superclass::OnLeftButtonDown (); } @@ -564,7 +565,8 @@ void temp_viz::InteractorStyle::OnLeftButtonUp () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); Superclass::OnLeftButtonUp (); } @@ -575,7 +577,8 @@ void temp_viz::InteractorStyle::OnMiddleButtonDown () MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; MouseEvent event (type, MouseEvent::MiddleButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); Superclass::OnMiddleButtonDown (); } @@ -584,7 +587,8 @@ void temp_viz::InteractorStyle::OnMiddleButtonUp () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); Superclass::OnMiddleButtonUp (); } @@ -595,7 +599,8 @@ void temp_viz::InteractorStyle::OnRightButtonDown () MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; MouseEvent event (type, MouseEvent::RightButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); Superclass::OnRightButtonDown (); } @@ -604,7 +609,8 @@ void temp_viz::InteractorStyle::OnRightButtonUp () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); Superclass::OnRightButtonUp (); } @@ -613,9 +619,11 @@ void temp_viz::InteractorStyle::OnMouseWheelForward () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); - if (Interactor->GetRepeatCount ()) - mouse_signal_ (event); + // If a mouse callback registered, call it! + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + if (Interactor->GetRepeatCount () && mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); if (Interactor->GetAltKey ()) { @@ -643,10 +651,13 @@ void temp_viz::InteractorStyle::OnMouseWheelBackward () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); - mouse_signal_ (event); - if (Interactor->GetRepeatCount ()) - mouse_signal_ (event); - + // If a mouse callback registered, call it! + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if (Interactor->GetRepeatCount () && mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + if (Interactor->GetAltKey ()) { // zoom diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index ec60d5021..5e7395173 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -4,11 +4,11 @@ #include #include - +/* #include #include #include -#include +#include */ #include diff --git a/modules/viz/src/q/interactor_style.h b/modules/viz/src/q/interactor_style.h index 6c99d88e1..3a196a728 100644 --- a/modules/viz/src/q/interactor_style.h +++ b/modules/viz/src/q/interactor_style.h @@ -56,38 +56,22 @@ namespace temp_viz */ inline void setCloudActorMap (const cv::Ptr& actors) { actors_ = actors; } - /** \brief Pass a set of renderers to the interactor style. * \param[in] rens the vtkRendererCollection to use */ void setRenderer (vtkSmartPointer& ren) { renderer_ = ren; } /** \brief Register a callback function for mouse events - * \param[in] cb a boost function that will be registered as a callback for a mouse event - * \return a connection object that allows to disconnect the callback function. - */ - boost::signals2::connection registerMouseCallback (boost::function cb); + * \param[in] ccallback function that will be registered as a callback for a mouse event + * \param[in] cookie for passing user data to callback + */ + void registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie = 0); /** \brief Register a callback function for keyboard events * \param[in] callback a function that will be registered as a callback for a keyboard event * \param[in] cookie user data passed to the callback function */ - void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void * cookie = NULL); - - - // TODO Implement callback function as a method of an instance - /** \brief Register a callback function for keyboard input - * \param[in] callback function that will be registered as a callback for a keyboard event - * \param[in] instance the instance that the callback function belongs to - * \param[in] cookie for passing user data to callback - */ -// template inline void registerKeyboardCallback(void (T::*callback)(const cv::KeyboardEvent&, void*), T& instance, void* cookie = NULL) -// { -// registerKeyboardCallback(callback, cookie); -// // Set the instance for calling the callback -// keyboard_callback_instance_ = (void *) &instance; -// -// } + void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void * cookie = 0); /** \brief Save the current rendered image to disk, as a PNG screenshot. * \param[in] file the name of the PNG file @@ -127,9 +111,6 @@ namespace temp_viz /** \brief Internal window to image filter. Needed by \a snapshot_writer_. */ vtkSmartPointer wif_; - boost::signals2::signal mouse_signal_; - boost::signals2::signal keyboard_signal_; - /** \brief Interactor style internal method. Gets called whenever a key is pressed. */ virtual void OnChar (); @@ -161,9 +142,14 @@ namespace temp_viz /** \brief The keyboard modifier to use. Default: Alt. */ KeyboardModifier modifier_; - /** \brief Keyboard-Callback function */ + /** \brief KeyboardEvent callback function pointer*/ void (*keyboardCallback_)(const cv::KeyboardEvent&, void*); + /** \brief KeyboardEvent callback user data*/ void *keyboard_callback_cookie_; - void *keyboard_callback_instance_; + + /** \brief MouseEvent callback function pointer */ + void (*mouseCallback_)(const cv::MouseEvent&, void*); + /** \brief MouseEvent callback user data */ + void *mouse_callback_cookie_; }; } diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index a6e3de594..5e72280a5 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -27,53 +27,13 @@ public: * \param[in] callback function that will be registered as a callback for a keyboard event * \param[in] cookie for passing user data to callback */ - void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = NULL); + void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = 0); - // TODO Implement callback function as a method of an instance - /** \brief Register a callback function for keyboard input - * \param[in] callback function that will be registered as a callback for a keyboard event - * \param[in] instance the instance that the callback function belongs to - * \param[in] cookie for passing user data to callback - */ - -// template inline void registerKeyboardCallback(void (T::*callback)(const cv::KeyboardEvent&, void*), T& instance, void* cookie = NULL) -// { } - - - -// /** \brief Register a callback boost::function for keyboard events -// * \param[in] cb a boost function that will be registered as a callback for a keyboard event -// * \return a connection object that allows to disconnect the callback function. -// */ -// void registerKeyboardCallback (boost::function cb); -// inline boost::signals2::connection registerKeyboardCallback (void (*callback) (const cv::KeyboardEvent&, void*), void* cookie = NULL) -// { return (registerKeyboardCallback (boost::bind (callback, _1, cookie))); } -// -// /** \brief Register a callback function for keyboard events -// * \param[in] callback the member function that will be registered as a callback for a keyboard event -// * \param[in] instance instance to the class that implements the callback function -// * \param[in] cookie user data that is passed to the callback -// * \return a connection object that allows to disconnect the callback function. -// */ -// template inline boost::signals2::connection registerKeyboardCallback (void (T::*callback) (const cv::KeyboardEvent&, void*), T& instance, void* cookie = NULL) -// { return (registerKeyboardCallback (boost::bind (callback, boost::ref (instance), _1, cookie))); } - /** \brief Register a callback function for mouse events - * \param[in] cb a boost function that will be registered as a callback for a mouse event - * \return a connection object that allows to disconnect the callback function. + * \param[in] ccallback function that will be registered as a callback for a mouse event + * \param[in] cookie for passing user data to callback */ - boost::signals2::connection registerMouseCallback (boost::function cb); - inline boost::signals2::connection registerMouseCallback (void (*callback) (const cv::MouseEvent&, void*), void* cookie = NULL) - { return (registerMouseCallback (boost::bind (callback, _1, cookie))); } - - /** \brief Register a callback function for mouse events - * \param[in] callback the member function that will be registered as a callback for a mouse event - * \param[in] instance instance to the class that implements the callback function - * \param[in] cookie user data that is passed to the callback - * \return a connection object that allows to disconnect the callback function. - */ - template inline boost::signals2::connection registerMouseCallback (void (T::*callback) (const cv::MouseEvent&, void*), T& instance, void* cookie = NULL) - { return (registerMouseCallback (boost::bind (callback, boost::ref (instance), _1, cookie))); } + void registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie = 0); void spin (); void spinOnce (int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index ed219f48c..974013d2f 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -96,4 +96,9 @@ bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) void temp_viz::Viz3d::registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie) { impl_->registerKeyboardCallback(callback, cookie); +} + +void temp_viz::Viz3d::registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie) +{ + impl_->registerMouseCallback(callback, cookie); } \ No newline at end of file diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index a64d62f9d..1ea8368af 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -95,9 +95,10 @@ temp_viz::Viz3d::VizImpl::~VizImpl () void temp_viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } ///////////////////////////////////////////////////////////////////////////////////////////// -boost::signals2::connection temp_viz::Viz3d::VizImpl::registerMouseCallback (boost::function callback) +void temp_viz::Viz3d::VizImpl::registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie) { - return (style_->registerMouseCallback (callback)); + // Register the callback function in the interactor style + style_->registerMouseCallback(callback, cookie); } ///////////////////////////////////////////////////////////////////////////////////////////// From ace0933bedc56fd05c762a29abbc3fb039791c46 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 31 May 2013 13:40:23 +0400 Subject: [PATCH 005/205] fixed compilation (included ctime in precomp.hpp) --- modules/viz/src/interactor_style.cpp | 17 ++--------------- modules/viz/src/precomp.hpp | 4 +++- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 00a1ed172..dc2420046 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -1,19 +1,6 @@ -#include +#include "precomp.hpp" + #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include //#include diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 5e7395173..c3f595644 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include /* @@ -145,7 +147,7 @@ #include #include -#include + #include #include From d11d07aaf58aa0e80dc62546b067854aff2b905f Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 7 Jun 2013 11:18:26 +0200 Subject: [PATCH 006/205] showPointCloud initial implementation together with test --- modules/viz/include/opencv2/viz/viz3d.hpp | 11 +- modules/viz/src/q/viz3d_impl.hpp | 10 +- modules/viz/src/viz3d.cpp | 9 +- modules/viz/src/viz3d_impl.cpp | 346 +++++++--------------- modules/viz/test/test_viz3d.cpp | 120 +++++--- 5 files changed, 195 insertions(+), 301 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index fe0851a60..2e89e5f90 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -26,22 +26,15 @@ namespace temp_viz void setBackgroundColor(const Color& color = Color::black()); void addCoordinateSystem(double scale, const Affine3f& t, const String &id = "coordinate"); - - void addPointCloud(const Mat& cloud, const Mat& colors, const String& id = "cloud", const Mat& mask = Mat()); + + void showPointCloud(const std::string& id, cv::InputArray cloud, cv::InputArray colors, const cv::Affine3f& pose = cv::Affine3f::Identity()); bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); - - - bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); bool removeCoordinateSystem (const String &id = "coordinate"); - - bool updatePointCloud (const Mat& cloud, const Mat& colors, const String& id = "cloud", const Mat& mask = Mat()); - - bool addPolygonMesh (const Mesh3d& mesh, const String &id = "polygon"); bool updatePolygonMesh (const Mesh3d& mesh, const String &id = "polygon"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 5e72280a5..17b643c2e 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -96,8 +96,14 @@ public: bool addText3D (const std::string &text, const cv::Point3f &position, const Color& color, double textScale = 1.0, const std::string &id = ""); bool addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level = 100, float scale = 0.02f, const std::string &id = "cloud"); - void addPointCloud(const cv::Mat& cloud, const cv::Mat& colors, const std::string& id = "cloud", const cv::Mat& mask = cv::Mat()); - bool updatePointCloud (const cv::Mat& cloud, const cv::Mat& colors, const std::string& id = "cloud", const cv::Mat& mask = cv::Mat()); + + /** \brief If the id exists, updates the point cloud; otherwise, adds a new point cloud to the scene + * \param[in] id a variable to identify the point cloud + * \param[in] cloud cloud input in x,y,z coordinates + * \param[in] colors color input in the same order of the points or single uniform color + * \param[in] pose transform to be applied on the point cloud + */ + void showPointCloud(const std::string& id, cv::InputArray cloud, cv::InputArray colors, const cv::Affine3f& pose = cv::Affine3f::Identity()); bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 974013d2f..4b2e3b19e 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -23,9 +23,9 @@ void temp_viz::Viz3d::addCoordinateSystem(double scale, const Affine3f& t, const impl_->addCoordinateSystem(scale, t, id); } -void temp_viz::Viz3d::addPointCloud(const Mat& cloud, const Mat& colors, const String& id, const Mat& mask) +void temp_viz::Viz3d::showPointCloud(const std::string& id, cv::InputArray cloud, cv::InputArray colors, const cv::Affine3f& pose) { - impl_->addPointCloud(cloud, colors, id, mask); + impl_->showPointCloud(id, cloud, colors, pose); } bool temp_viz::Viz3d::addPointCloudNormals (const Mat &cloud, const Mat& normals, int level, float scale, const String& id) @@ -33,11 +33,6 @@ bool temp_viz::Viz3d::addPointCloudNormals (const Mat &cloud, const Mat& normals return impl_->addPointCloudNormals(cloud, normals, level, scale, id); } -bool temp_viz::Viz3d::updatePointCloud(const Mat& cloud, const Mat& colors, const String& id, const Mat& mask) -{ - return impl_->updatePointCloud(cloud, colors, id, mask); -} - bool temp_viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String &id) { return impl_->addPolygonMesh(mesh, Mat(), id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 223b2bd1f..692e9960d 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -27,207 +27,86 @@ void temp_viz::Viz3d::VizImpl::setWindowName (const std::string &name) void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } -void temp_viz::Viz3d::VizImpl::addPointCloud(const cv::Mat& cloud, const cv::Mat& colors, const std::string& id, const cv::Mat& mask) -{ - CV_Assert(cloud.type() == CV_32FC3 && colors.type() == CV_8UC3 && colors.size() == cloud.size()); - CV_Assert(mask.empty() || (mask.type() == CV_8U && mask.size() == cloud.size())); +void temp_viz::Viz3d::VizImpl::showPointCloud(const std::string& id, cv::InputArray cloud, cv::InputArray colors, const cv::Affine3f& pose) +{ + cv::Mat cloudMat = cloud.getMat(); + cv::Mat colorsMat = colors.getMat(); + CV_Assert(cloudMat.type() == CV_32FC3 && colorsMat.type() == CV_8UC3 && cloudMat.size() == colorsMat.size()); + vtkSmartPointer polydata; - - allocVtkPolyData(polydata); - //polydata = vtkSmartPointer::New (); - vtkSmartPointer vertices = vtkSmartPointer::New (); - polydata->SetVerts (vertices); - + vtkSmartPointer vertices; + vtkSmartPointer points; vtkSmartPointer initcells; - vtkIdType nr_points = cloud.size().area(); - vtkSmartPointer points = polydata->GetPoints (); - - if (!points) - { - points = vtkSmartPointer::New (); - points->SetDataTypeToFloat (); - polydata->SetPoints (points); - } - points->SetNumberOfPoints (nr_points); - - // Get a pointer to the beginning of the data array - float *data = (static_cast (points->GetData ()))->GetPointer (0); - - if (mask.empty()) - { - int j = 0; - for(int y = 0; y < cloud.rows; ++y) - { - const cv::Point3f* crow = cloud.ptr(y); - for(int x = 0; x < cloud.cols; ++x) - memcpy (&data[j++ * 3], &crow[x], sizeof(cv::Point3f)); - } - } - else - { - int j = 0; - for(int y = 0; y < cloud.rows; ++y) - { - const cv::Point3f* crow = cloud.ptr(y); - const unsigned char* mrow = mask.ptr(y); - for(int x = 0; x < cloud.cols; ++x) - if (mrow[x]) - memcpy (&data[j++ * 3], &crow[x], sizeof(cv::Point3f)); - } - nr_points = j; - points->SetNumberOfPoints (nr_points); - } - - vtkSmartPointer cells = vertices->GetData (); - updateCells (cells, initcells, nr_points); - - // Set the cells and the vertices - vertices->SetCells (nr_points, cells); - - ///////////////////////////////////////////////////////////////////////////////// - - // use the given geometry handler - polydata->Update (); - - // Get the colors from the handler - bool has_colors = false; - double minmax[2]; - vtkSmartPointer scalars = vtkSmartPointer::New (); - scalars->SetNumberOfComponents (3); - reinterpret_cast(&(*scalars))->SetNumberOfTuples (nr_points); - - // Get a random color - unsigned char* colors_data = new unsigned char[nr_points * 3]; - - if (mask.empty()) - { - int j = 0; - for(int y = 0; y < colors.rows; ++y) - { - const cv::Vec3b* crow = colors.ptr(y); - for(int x = 0; x < colors.cols; ++x) - memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); - } - } - else - { - int j = 0; - for(int y = 0; y < colors.rows; ++y) - { - const cv::Vec3b* crow = colors.ptr(y); - const unsigned char* mrow = mask.ptr(y); - for(int x = 0; x < colors.cols; ++x) - if (mrow[x]) - memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); - } - } - - reinterpret_cast(&(*scalars))->SetArray (colors_data, 3 * nr_points, 0); - - ///////////////////////////////////////// - has_colors = true; - - if (has_colors) - { - polydata->GetPointData ()->SetScalars (scalars); - scalars->GetRange (minmax); - } - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (polydata, actor); - if (has_colors) - actor->GetMapper ()->SetScalarRange (minmax); - - // Add it to all renderers - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*cloud_actor_map_)[id].actor = actor; - (*cloud_actor_map_)[id].cells = initcells; - - const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); - const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); - - // Save the viewpoint transformation matrix to the global actor map - vtkSmartPointer transformation = vtkSmartPointer::New(); - convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); - (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; -} - - -bool temp_viz::Viz3d::VizImpl::updatePointCloud (const cv::Mat& cloud, const cv::Mat& colors, const std::string& id, const cv::Mat& mask) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) + vtkIdType nr_points; + + // If the cloud already exists, update otherwise create new one CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - if (am_it == cloud_actor_map_->end ()) - return (false); - - // Get the current poly data - vtkSmartPointer polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); - if (!polydata) - return (false); - vtkSmartPointer vertices = polydata->GetVerts (); - vtkSmartPointer points = polydata->GetPoints (); - // Copy the new point array in - vtkIdType nr_points = cloud.size().area(); - points->SetNumberOfPoints (nr_points); - - // Get a pointer to the beginning of the data array - float *data = (static_cast (points->GetData ()))->GetPointer (0); - - if (mask.empty()) + bool isAdd = (am_it == cloud_actor_map_->end()); + if (isAdd) { - int j = 0; - for(int y = 0; y < cloud.rows; ++y) - { - const cv::Point3f* crow = cloud.ptr(y); - for(int x = 0; x < cloud.cols; ++x) - memcpy (&data[j++ * 3], &crow[x], sizeof(cv::Point3f)); - } + // Add as new cloud + allocVtkPolyData(polydata); + //polydata = vtkSmartPointer::New (); + vertices = vtkSmartPointer::New (); + polydata->SetVerts (vertices); + + nr_points = cloudMat.size().area(); + points = polydata->GetPoints (); + + if (!points) + { + points = vtkSmartPointer::New (); + points->SetDataTypeToFloat (); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); } else { - int j = 0; - for(int y = 0; y < cloud.rows; ++y) - { - const cv::Point3f* crow = cloud.ptr(y); - const unsigned char* mrow = mask.ptr(y); - for(int x = 0; x < cloud.cols; ++x) - if (mrow[x]) - memcpy (&data[j++ * 3], &crow[x], sizeof(cv::Point3f)); - } - nr_points = j; - points->SetNumberOfPoints (nr_points); + // Update the cloud + // Get the current poly data + polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); + vertices = polydata->GetVerts (); + points = polydata->GetPoints (); + // Copy the new point array in + nr_points = cloudMat.size().area(); + points->SetNumberOfPoints (nr_points); } - + + + // Get a pointer to the beginning of the data array + float *data = (static_cast (points->GetData ()))->GetPointer (0); + + // Scan through the data and apply mask where point is NAN + int j = 0; + + // If a point is NaN, ignore it + for(int y = 0; y < cloudMat.rows; ++y) + { + const cv::Point3f* crow = cloudMat.ptr(y); + for(int x = 0; x < cloudMat.cols; ++x) + if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) + { + // Points are transformed based on pose parameter + cv::Point3f transformed_point = pose * crow[x]; + memcpy (&data[j++ * 3], &transformed_point, sizeof(cv::Point3f)); + } + } + nr_points = j; + points->SetNumberOfPoints (nr_points); + vtkSmartPointer cells = vertices->GetData (); - updateCells (cells, am_it->second.cells, nr_points); - - + + if (isAdd) + updateCells(cells, initcells, nr_points); + else + updateCells (cells, am_it->second.cells, nr_points); + // Set the cells and the vertices vertices->SetCells (nr_points, cells); - -#if 1 + // Get the colors from the handler - // vtkSmartPointer scalars; - // color_handler.getColor (scalars); - // double minmax[2]; - // scalars->GetRange (minmax); - - // // Update the data - // polydata->GetPointData ()->SetScalars (scalars); - // polydata->Update (); - - // am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff (); - // am_it->second.actor->GetMapper ()->SetScalarRange (minmax); - - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - - // Get the colors from the handler - bool has_colors = false; double minmax[2]; vtkSmartPointer scalars = vtkSmartPointer::New (); scalars->SetNumberOfComponents (3); @@ -235,60 +114,57 @@ bool temp_viz::Viz3d::VizImpl::updatePointCloud (const cv::Mat& cloud, const cv: // Get a random color unsigned char* colors_data = new unsigned char[nr_points * 3]; - - if (mask.empty()) + + j = 0; + for(int y = 0; y < colorsMat.rows; ++y) { - int j = 0; - for(int y = 0; y < colors.rows; ++y) - { - const cv::Vec3b* crow = colors.ptr(y); - for(int x = 0; x < colors.cols; ++x) - memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); - } + const cv::Vec3b* crow = colorsMat.ptr(y); + const cv::Point3f* cloud_row = cloudMat.ptr(y); + for(int x = 0; x < colorsMat.cols; ++x) + if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) + memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); + } + + reinterpret_cast(&(*scalars))->SetArray (colors_data, 3 * nr_points, 0); + + // Assign the colors + polydata->GetPointData ()->SetScalars (scalars); + scalars->GetRange (minmax); + + // If this is the new point cloud, a new actor is created + if (isAdd) + { + vtkSmartPointer actor; + createActorFromVTKDataSet (polydata, actor); + + actor->GetMapper ()->SetScalarRange (minmax); + + // Add it to all renderers + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*cloud_actor_map_)[id].actor = actor; + (*cloud_actor_map_)[id].cells = initcells; + + const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); + const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); + + // Save the viewpoint transformation matrix to the global actor map + vtkSmartPointer transformation = vtkSmartPointer::New(); + convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); +// convertToVtkMatrix (pose.matrix, transformation); + + std::cout << transformation->GetElement(0,3) << endl; + + (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; } else { - int j = 0; - for(int y = 0; y < colors.rows; ++y) - { - const cv::Vec3b* crow = colors.ptr(y); - const unsigned char* mrow = mask.ptr(y); - for(int x = 0; x < colors.cols; ++x) - if (mrow[x]) - memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); - } + // Update the mapper + reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); } - - reinterpret_cast(&(*scalars))->SetArray (colors_data, 3 * nr_points, 0); - - ///////////////////////////////////////// - has_colors = true; - - if (has_colors) - { - polydata->GetPointData ()->SetScalars (scalars); - scalars->GetRange (minmax); - } - -#else - vtkSmartPointer scalars; - polydata->GetPointData ()->SetScalars (scalars); - polydata->Update (); - double minmax[2]; - minmax[0] = std::numeric_limits::min (); - minmax[1] = std::numeric_limits::max (); - am_it->second.actor->GetMapper ()->ImmediateModeRenderingOff (); - am_it->second.actor->GetMapper ()->SetScalarRange (minmax); -#endif - - - // Update the mapper - reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); - return (true); } - - bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level, float scale, const std::string &id) { CV_Assert(cloud.size() == normals.size() && cloud.type() == CV_32FC3 && normals.type() == CV_32FC3); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 922090c83..925b54c3c 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -78,56 +78,80 @@ TEST(Viz_viz3d, accuracy) cv::Mat cloud = cvcloud_load(); - cv::Mat colors(cloud.size(), CV_8UC3, cv::Scalar(0, 255, 0)); - v.addPointCloud(cloud, colors); - cv::Mat normals(cloud.size(), CV_32FC3, cv::Scalar(0, 10, 0)); - - v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); - - - temp_viz::ModelCoefficients mc; - mc.values.resize(4); - mc.values[0] = mc.values[1] = mc.values[2] = mc.values[3] = 1; - v.addPlane(mc); - - + + float angle_x = 0.0f; + float angle_y = 0.0f; + float angle_z = 0.0f; + float pos_x = 0.0f; + float pos_y = 0.0f; + float pos_z = 0.0f; temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("d:/horse.ply"); v.addPolygonMesh(*mesh, "pq"); - - v.spinOnce(1000, true); - - v.removeCoordinateSystem(); - - for(int i = 0; i < mesh->cloud.cols; ++i) - mesh->cloud.ptr()[i] += cv::Point3f(1, 1, 1); - - v.updatePolygonMesh(*mesh, "pq"); - - - for(int i = 0; i < mesh->cloud.cols; ++i) - mesh->cloud.ptr()[i] -= cv::Point3f(2, 2, 2); - v.addPolylineFromPolygonMesh(*mesh); - - - v.addText("===Abd sadfljsadlk", 100, 100, cv::Scalar(255, 0, 0), 15); - for(int i = 0; i < cloud.cols; ++i) - cloud.ptr()[i].x *=2; - - colors.setTo(cv::Scalar(255, 0, 0)); - - v.addSphere(cv::Point3f(0, 0, 0), 0.3, temp_viz::Color::blue()); - - cv::Mat cvpoly(1, 5, CV_32FC3); - cv::Point3f* pdata = cvpoly.ptr(); - pdata[0] = cv::Point3f(0, 0, 0); - pdata[1] = cv::Point3f(0, 1, 1); - pdata[2] = cv::Point3f(3, 1, 2); - pdata[3] = cv::Point3f(0, 2, 4); - pdata[4] = cv::Point3f(7, 2, 3); - v.addPolygon(cvpoly, temp_viz::Color::white()); - - v.updatePointCloud(cloud, colors); - v.spin(); + while(1) + { + // Creating new point cloud with id cloud1 + cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); + v.showPointCloud("cloud1", cloud, colors, cloudPosition); + + angle_x += 0.1; + angle_y -= 0.1; + angle_z += 0.1; + pos_x = std::sin(angle_x); + pos_y = std::sin(angle_x); + pos_z = std::sin(angle_x); + + v.spinOnce(1,true); + } + +// cv::Mat normals(cloud.size(), CV_32FC3, cv::Scalar(0, 10, 0)); +// +// v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); +// +// +// temp_viz::ModelCoefficients mc; +// mc.values.resize(4); +// mc.values[0] = mc.values[1] = mc.values[2] = mc.values[3] = 1; +// v.addPlane(mc); +// +// +// temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("horse.ply"); +// v.addPolygonMesh(*mesh, "pq"); +// +// v.spinOnce(1000, true); +// +// v.removeCoordinateSystem(); +// +// for(int i = 0; i < mesh->cloud.cols; ++i) +// mesh->cloud.ptr()[i] += cv::Point3f(1, 1, 1); +// +// v.updatePolygonMesh(*mesh, "pq"); +// +// +// for(int i = 0; i < mesh->cloud.cols; ++i) +// mesh->cloud.ptr()[i] -= cv::Point3f(2, 2, 2); +// v.addPolylineFromPolygonMesh(*mesh); +// +// +// v.addText("===Abd sadfljsadlk", 100, 100, cv::Scalar(255, 0, 0), 15); +// for(int i = 0; i < cloud.cols; ++i) +// cloud.ptr()[i].x *=2; +// +// colors.setTo(cv::Scalar(255, 0, 0)); +// +// v.addSphere(cv::Point3f(0, 0, 0), 0.3, temp_viz::Color::blue()); +// +// cv::Mat cvpoly(1, 5, CV_32FC3); +// cv::Point3f* pdata = cvpoly.ptr(); +// pdata[0] = cv::Point3f(0, 0, 0); +// pdata[1] = cv::Point3f(0, 1, 1); +// pdata[2] = cv::Point3f(3, 1, 2); +// pdata[3] = cv::Point3f(0, 2, 4); +// pdata[4] = cv::Point3f(7, 2, 3); +// v.addPolygon(cvpoly, temp_viz::Color::white()); +// +// // Updating cloud1 +// v.showPointCloud("cloud1", cloud, colors); +// v.spin(); } From e58b0b3507601f9c0de7dbf1cab5c4b88d5d84d8 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 7 Jun 2013 12:14:40 +0200 Subject: [PATCH 007/205] removed cv keywords and redundant lines from showPointCloud --- modules/viz/include/opencv2/viz/types.hpp | 3 +++ modules/viz/include/opencv2/viz/viz3d.hpp | 2 +- modules/viz/src/q/viz3d_impl.hpp | 2 +- modules/viz/src/viz3d.cpp | 2 +- modules/viz/src/viz3d_impl.cpp | 21 +++++++++------------ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 6085da2f2..fd504a784 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -16,14 +16,17 @@ namespace temp_viz typedef cv::Vec4d Vec4d; typedef cv::Vec2d Vec2d; typedef cv::Vec2i Vec2i; + typedef cv::Vec3b Vec3b; typedef cv::Matx33d Matx33d; typedef cv::Affine3f Affine3f; typedef cv::Affine3d Affine3d; typedef cv::Point3f Point3f; + typedef cv::Point3d Point3d; typedef cv::Matx44d Matx44d; typedef cv::Matx44f Matx44f; typedef cv::Size Size; typedef cv::Point Point; + typedef cv::InputArray InputArray; diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 2e89e5f90..3a861eeff 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -27,7 +27,7 @@ namespace temp_viz void addCoordinateSystem(double scale, const Affine3f& t, const String &id = "coordinate"); - void showPointCloud(const std::string& id, cv::InputArray cloud, cv::InputArray colors, const cv::Affine3f& pose = cv::Affine3f::Identity()); + void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 17b643c2e..169666141 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -103,7 +103,7 @@ public: * \param[in] colors color input in the same order of the points or single uniform color * \param[in] pose transform to be applied on the point cloud */ - void showPointCloud(const std::string& id, cv::InputArray cloud, cv::InputArray colors, const cv::Affine3f& pose = cv::Affine3f::Identity()); + void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 4b2e3b19e..e06c85ca0 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -23,7 +23,7 @@ void temp_viz::Viz3d::addCoordinateSystem(double scale, const Affine3f& t, const impl_->addCoordinateSystem(scale, t, id); } -void temp_viz::Viz3d::showPointCloud(const std::string& id, cv::InputArray cloud, cv::InputArray colors, const cv::Affine3f& pose) +void temp_viz::Viz3d::showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose) { impl_->showPointCloud(id, cloud, colors, pose); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 692e9960d..615f035e8 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -28,10 +28,10 @@ void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } -void temp_viz::Viz3d::VizImpl::showPointCloud(const std::string& id, cv::InputArray cloud, cv::InputArray colors, const cv::Affine3f& pose) +void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose) { - cv::Mat cloudMat = cloud.getMat(); - cv::Mat colorsMat = colors.getMat(); + Mat cloudMat = cloud.getMat(); + Mat colorsMat = colors.getMat(); CV_Assert(cloudMat.type() == CV_32FC3 && colorsMat.type() == CV_8UC3 && cloudMat.size() == colorsMat.size()); vtkSmartPointer polydata; @@ -84,13 +84,13 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const std::string& id, cv::InputAr // If a point is NaN, ignore it for(int y = 0; y < cloudMat.rows; ++y) { - const cv::Point3f* crow = cloudMat.ptr(y); + const Point3f* crow = cloudMat.ptr(y); for(int x = 0; x < cloudMat.cols; ++x) if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) { // Points are transformed based on pose parameter - cv::Point3f transformed_point = pose * crow[x]; - memcpy (&data[j++ * 3], &transformed_point, sizeof(cv::Point3f)); + Point3f transformed_point = pose * crow[x]; + memcpy (&data[j++ * 3], &transformed_point, sizeof(Point3f)); } } nr_points = j; @@ -118,11 +118,11 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const std::string& id, cv::InputAr j = 0; for(int y = 0; y < colorsMat.rows; ++y) { - const cv::Vec3b* crow = colorsMat.ptr(y); - const cv::Point3f* cloud_row = cloudMat.ptr(y); + const Vec3b* crow = colorsMat.ptr(y); + const Point3f* cloud_row = cloudMat.ptr(y); for(int x = 0; x < colorsMat.cols; ++x) if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) - memcpy (&colors_data[j++ * 3], &crow[x], sizeof(cv::Vec3b)); + memcpy (&colors_data[j++ * 3], &crow[x], sizeof(Vec3b)); } reinterpret_cast(&(*scalars))->SetArray (colors_data, 3 * nr_points, 0); @@ -152,9 +152,6 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const std::string& id, cv::InputAr // Save the viewpoint transformation matrix to the global actor map vtkSmartPointer transformation = vtkSmartPointer::New(); convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); -// convertToVtkMatrix (pose.matrix, transformation); - - std::cout << transformation->GetElement(0,3) << endl; (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; } From aecff5237b62f04036acc1652b3ea0eecba5a689 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 7 Jun 2013 16:07:23 +0200 Subject: [PATCH 008/205] CV_64FC3 support --- modules/viz/src/viz3d_impl.cpp | 89 +++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 615f035e8..a2d9a25fb 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -32,7 +32,7 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray cloud { Mat cloudMat = cloud.getMat(); Mat colorsMat = colors.getMat(); - CV_Assert(cloudMat.type() == CV_32FC3 && colorsMat.type() == CV_8UC3 && cloudMat.size() == colorsMat.size()); + CV_Assert((cloudMat.type() == CV_32FC3 || cloudMat.type() == CV_64FC3) && colorsMat.type() == CV_8UC3 && cloudMat.size() == colorsMat.size()); vtkSmartPointer polydata; vtkSmartPointer vertices; @@ -57,7 +57,10 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray cloud if (!points) { points = vtkSmartPointer::New (); - points->SetDataTypeToFloat (); + if (cloudMat.type() == CV_32FC3) + points->SetDataTypeToFloat (); + else if (cloudMat.type() == CV_64FC3) + points->SetDataTypeToDouble (); polydata->SetPoints (points); } points->SetNumberOfPoints (nr_points); @@ -69,30 +72,54 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray cloud polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); vertices = polydata->GetVerts (); points = polydata->GetPoints (); + // Update the point data type based on the cloud + if (cloudMat.type() == CV_32FC3) + points->SetDataTypeToFloat (); + else if (cloudMat.type() == CV_64FC3) + points->SetDataTypeToDouble (); // Copy the new point array in nr_points = cloudMat.size().area(); points->SetNumberOfPoints (nr_points); } - - // Get a pointer to the beginning of the data array - float *data = (static_cast (points->GetData ()))->GetPointer (0); - - // Scan through the data and apply mask where point is NAN int j = 0; - - // If a point is NaN, ignore it - for(int y = 0; y < cloudMat.rows; ++y) + if (cloudMat.type() == CV_32FC3) { - const Point3f* crow = cloudMat.ptr(y); - for(int x = 0; x < cloudMat.cols; ++x) - if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) - { - // Points are transformed based on pose parameter - Point3f transformed_point = pose * crow[x]; - memcpy (&data[j++ * 3], &transformed_point, sizeof(Point3f)); - } + // Get a pointer to the beginning of the data array + float *data = (static_cast (points->GetData ()))->GetPointer (0); + + // Scan through the data and apply mask where point is NAN + for(int y = 0; y < cloudMat.rows; ++y) + { + const Point3f* crow = cloudMat.ptr(y); + for(int x = 0; x < cloudMat.cols; ++x) + if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) + { + // Points are transformed based on pose parameter + Point3f transformed_point = pose * crow[x]; + memcpy (&data[j++ * 3], &transformed_point, sizeof(Point3f)); + } + } } + else if (cloudMat.type() == CV_64FC3) + { + // Get a pointer to the beginning of the data array + double *data = (static_cast (points->GetData ()))->GetPointer (0); + + // If a point is NaN, ignore it + for(int y = 0; y < cloudMat.rows; ++y) + { + const Point3d* crow = cloudMat.ptr(y); + for(int x = 0; x < cloudMat.cols; ++x) + if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) + { + // Points are transformed based on pose parameter + Point3d transformed_point = pose * crow[x]; + memcpy (&data[j++ * 3], &transformed_point, sizeof(Point3d)); + } + } + } + nr_points = j; points->SetNumberOfPoints (nr_points); @@ -116,13 +143,27 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray cloud unsigned char* colors_data = new unsigned char[nr_points * 3]; j = 0; - for(int y = 0; y < colorsMat.rows; ++y) + if (cloudMat.type() == CV_32FC3) { - const Vec3b* crow = colorsMat.ptr(y); - const Point3f* cloud_row = cloudMat.ptr(y); - for(int x = 0; x < colorsMat.cols; ++x) - if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) - memcpy (&colors_data[j++ * 3], &crow[x], sizeof(Vec3b)); + for(int y = 0; y < colorsMat.rows; ++y) + { + const Vec3b* crow = colorsMat.ptr(y); + const Point3f* cloud_row = cloudMat.ptr(y); + for(int x = 0; x < colorsMat.cols; ++x) + if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) + memcpy (&colors_data[j++ * 3], &crow[x], sizeof(Vec3b)); + } + } + else if (cloudMat.type() == CV_64FC3) + { + for(int y = 0; y < colorsMat.rows; ++y) + { + const Vec3b* crow = colorsMat.ptr(y); + const Point3d* cloud_row = cloudMat.ptr(y); + for(int x = 0; x < colorsMat.cols; ++x) + if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) + memcpy (&colors_data[j++ * 3], &crow[x], sizeof(Vec3b)); + } } reinterpret_cast(&(*scalars))->SetArray (colors_data, 3 * nr_points, 0); From 909c45f1b9138c522aa50a10c3aafdf33001836d Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 10 Jun 2013 12:32:03 +0400 Subject: [PATCH 009/205] little refactoring --- modules/viz/src/precomp.hpp | 10 ++ modules/viz/src/viz3d_impl.cpp | 255 +++++++++++++++----------------- modules/viz/test/test_viz3d.cpp | 28 ++-- 3 files changed, 146 insertions(+), 147 deletions(-) diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index c3f595644..9076a3bb4 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -153,6 +154,15 @@ + + + +#include +#include +#include + + + #if defined __GNUC__ && defined __DEPRECATED_DISABLED__ #define __DEPRECATED #undef __DEPRECATED_DISABLED__ diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index a2d9a25fb..14f438cff 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1,15 +1,5 @@ -#include +#include "precomp.hpp" #include - -#include -#include -#include -#include -#include -#include -#include -#include - #include void temp_viz::Viz3d::VizImpl::setFullScreen (bool mode) @@ -28,178 +18,175 @@ void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } -void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose) +void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _cloud, InputArray _colors, const Affine3f& pose) { - Mat cloudMat = cloud.getMat(); - Mat colorsMat = colors.getMat(); - CV_Assert((cloudMat.type() == CV_32FC3 || cloudMat.type() == CV_64FC3) && colorsMat.type() == CV_8UC3 && cloudMat.size() == colorsMat.size()); - + Mat cloud = _cloud.getMat(); + Mat colors = _colors.getMat(); + CV_Assert((cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3)); + CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); + vtkSmartPointer polydata; vtkSmartPointer vertices; vtkSmartPointer points; vtkSmartPointer initcells; vtkIdType nr_points; - + // If the cloud already exists, update otherwise create new one CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - bool isAdd = (am_it == cloud_actor_map_->end()); - if (isAdd) + bool exits = (am_it == cloud_actor_map_->end()); + if (exits) { - // Add as new cloud - allocVtkPolyData(polydata); - //polydata = vtkSmartPointer::New (); - vertices = vtkSmartPointer::New (); - polydata->SetVerts (vertices); + // Add as new cloud + allocVtkPolyData(polydata); + //polydata = vtkSmartPointer::New (); + vertices = vtkSmartPointer::New (); + polydata->SetVerts (vertices); - nr_points = cloudMat.size().area(); - points = polydata->GetPoints (); + nr_points = cloud.total(); + points = polydata->GetPoints (); - if (!points) - { - points = vtkSmartPointer::New (); - if (cloudMat.type() == CV_32FC3) - points->SetDataTypeToFloat (); - else if (cloudMat.type() == CV_64FC3) - points->SetDataTypeToDouble (); - polydata->SetPoints (points); - } - points->SetNumberOfPoints (nr_points); + if (!points) + { + points = vtkSmartPointer::New (); + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat(); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble(); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); } else { - // Update the cloud - // Get the current poly data - polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); - vertices = polydata->GetVerts (); - points = polydata->GetPoints (); - // Update the point data type based on the cloud - if (cloudMat.type() == CV_32FC3) - points->SetDataTypeToFloat (); - else if (cloudMat.type() == CV_64FC3) - points->SetDataTypeToDouble (); - // Copy the new point array in - nr_points = cloudMat.size().area(); - points->SetNumberOfPoints (nr_points); + // Update the cloud + // Get the current poly data + polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); + vertices = polydata->GetVerts (); + points = polydata->GetPoints (); + // Update the point data type based on the cloud + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat (); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble (); + // Copy the new point array in + nr_points = cloud.total(); + points->SetNumberOfPoints (nr_points); } - + int j = 0; - if (cloudMat.type() == CV_32FC3) + if (cloud.type() == CV_32FC3) { - // Get a pointer to the beginning of the data array - float *data = (static_cast (points->GetData ()))->GetPointer (0); - - // Scan through the data and apply mask where point is NAN - for(int y = 0; y < cloudMat.rows; ++y) - { - const Point3f* crow = cloudMat.ptr(y); - for(int x = 0; x < cloudMat.cols; ++x) - if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) - { - // Points are transformed based on pose parameter - Point3f transformed_point = pose * crow[x]; - memcpy (&data[j++ * 3], &transformed_point, sizeof(Point3f)); - } - } + // Get a pointer to the beginning of the data array + Point3f *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); + + // Scan through the data and apply mask where point is NAN + for(int y = 0; y < cloud.rows; ++y) + { + const Point3f* crow = cloud.ptr(y); + for(int x = 0; x < cloud.cols; ++x) + + //TODO implementa templated copy_if() or copy_non_nans() and use everywhere. + if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) + data[j++] = pose * crow[x]; + } } - else if (cloudMat.type() == CV_64FC3) + else if (cloud.type() == CV_64FC3) { - // Get a pointer to the beginning of the data array - double *data = (static_cast (points->GetData ()))->GetPointer (0); - - // If a point is NaN, ignore it - for(int y = 0; y < cloudMat.rows; ++y) - { - const Point3d* crow = cloudMat.ptr(y); - for(int x = 0; x < cloudMat.cols; ++x) - if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) - { - // Points are transformed based on pose parameter - Point3d transformed_point = pose * crow[x]; - memcpy (&data[j++ * 3], &transformed_point, sizeof(Point3d)); - } - } + // Get a pointer to the beginning of the data array + Point3d *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); + + // If a point is NaN, ignore it + for(int y = 0; y < cloud.rows; ++y) + { + const Point3d* crow = cloud.ptr(y); + for(int x = 0; x < cloud.cols; ++x) + if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) + data[j++] = pose * crow[x]; + } } - + nr_points = j; points->SetNumberOfPoints (nr_points); - + vtkSmartPointer cells = vertices->GetData (); - - if (isAdd) - updateCells(cells, initcells, nr_points); + + if (exits) + updateCells(cells, initcells, nr_points); else - updateCells (cells, am_it->second.cells, nr_points); - + updateCells (cells, am_it->second.cells, nr_points); + // Set the cells and the vertices vertices->SetCells (nr_points, cells); - + // Get the colors from the handler - double minmax[2]; + Vec2d minmax; vtkSmartPointer scalars = vtkSmartPointer::New (); scalars->SetNumberOfComponents (3); reinterpret_cast(&(*scalars))->SetNumberOfTuples (nr_points); // Get a random color - unsigned char* colors_data = new unsigned char[nr_points * 3]; - + Vec3b* colors_data = new Vec3b[nr_points]; + j = 0; - if (cloudMat.type() == CV_32FC3) + if (cloud.type() == CV_32FC3) { - for(int y = 0; y < colorsMat.rows; ++y) - { - const Vec3b* crow = colorsMat.ptr(y); - const Point3f* cloud_row = cloudMat.ptr(y); - for(int x = 0; x < colorsMat.cols; ++x) - if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) - memcpy (&colors_data[j++ * 3], &crow[x], sizeof(Vec3b)); - } + for(int y = 0; y < colors.rows; ++y) + { + const Vec3b* crow = colors.ptr(y); + const Point3f* cloud_row = cloud.ptr(y); + + for(int x = 0; x < colors.cols; ++x) + if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) + colors_data[j++] = crow[x]; + } } - else if (cloudMat.type() == CV_64FC3) + else if (cloud.type() == CV_64FC3) { - for(int y = 0; y < colorsMat.rows; ++y) - { - const Vec3b* crow = colorsMat.ptr(y); - const Point3d* cloud_row = cloudMat.ptr(y); - for(int x = 0; x < colorsMat.cols; ++x) - if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) - memcpy (&colors_data[j++ * 3], &crow[x], sizeof(Vec3b)); - } + for(int y = 0; y < colors.rows; ++y) + { + const Vec3b* crow = colors.ptr(y); + const Point3d* cloud_row = cloud.ptr(y); + + for(int x = 0; x < colors.cols; ++x) + if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) + colors_data[j++] = crow[x]; + } } - - reinterpret_cast(&(*scalars))->SetArray (colors_data, 3 * nr_points, 0); - + + reinterpret_cast(&(*scalars))->SetArray (reinterpret_cast(colors_data), 3 * nr_points, 0); + // Assign the colors polydata->GetPointData ()->SetScalars (scalars); - scalars->GetRange (minmax); + scalars->GetRange (minmax.val); // If this is the new point cloud, a new actor is created - if (isAdd) + if (exits) { - vtkSmartPointer actor; - createActorFromVTKDataSet (polydata, actor); - - actor->GetMapper ()->SetScalarRange (minmax); + vtkSmartPointer actor; + createActorFromVTKDataSet (polydata, actor); - // Add it to all renderers - renderer_->AddActor (actor); + actor->GetMapper ()->SetScalarRange (minmax.val); - // Save the pointer/ID pair to the global actor map - (*cloud_actor_map_)[id].actor = actor; - (*cloud_actor_map_)[id].cells = initcells; + // Add it to all renderers + renderer_->AddActor (actor); - const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); - const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); + // Save the pointer/ID pair to the global actor map + (*cloud_actor_map_)[id].actor = actor; + (*cloud_actor_map_)[id].cells = initcells; - // Save the viewpoint transformation matrix to the global actor map - vtkSmartPointer transformation = vtkSmartPointer::New(); - convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); - - (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; + const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); + const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); + + // Save the viewpoint transformation matrix to the global actor map + vtkSmartPointer transformation = vtkSmartPointer::New(); + convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); + + (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; } else { - // Update the mapper - reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); + // Update the mapper + reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); } } diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 925b54c3c..e72ef7598 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -88,20 +88,22 @@ TEST(Viz_viz3d, accuracy) float pos_z = 0.0f; temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("d:/horse.ply"); v.addPolygonMesh(*mesh, "pq"); - while(1) + + + while(1) //TODO implement and replace with !viz.wasStopped() { - // Creating new point cloud with id cloud1 - cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); - v.showPointCloud("cloud1", cloud, colors, cloudPosition); - - angle_x += 0.1; - angle_y -= 0.1; - angle_z += 0.1; - pos_x = std::sin(angle_x); - pos_y = std::sin(angle_x); - pos_z = std::sin(angle_x); - - v.spinOnce(1,true); + // Creating new point cloud with id cloud1 + cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); + v.showPointCloud("cloud1", cloud, colors, cloudPosition); + + angle_x += 0.1f; + angle_y -= 0.1f; + angle_z += 0.1f; + pos_x = std::sin(angle_x); + pos_y = std::sin(angle_x); + pos_z = std::sin(angle_x); + + v.spinOnce(10); } // cv::Mat normals(cloud.size(), CV_32FC3, cv::Scalar(0, 10, 0)); From 0f5da429c5d128711607dc633d5101b2d2cdded5 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 10 Jun 2013 12:42:11 +0400 Subject: [PATCH 010/205] misprint --- modules/viz/src/viz3d_impl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 14f438cff..91e4d6cb6 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -33,8 +33,8 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou // If the cloud already exists, update otherwise create new one CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - bool exits = (am_it == cloud_actor_map_->end()); - if (exits) + bool exist = (am_it == cloud_actor_map_->end()); + if (exist) { // Add as new cloud allocVtkPolyData(polydata); @@ -110,7 +110,7 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou vtkSmartPointer cells = vertices->GetData (); - if (exits) + if (exist) updateCells(cells, initcells, nr_points); else updateCells (cells, am_it->second.cells, nr_points); @@ -160,7 +160,7 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou scalars->GetRange (minmax.val); // If this is the new point cloud, a new actor is created - if (exits) + if (exist) { vtkSmartPointer actor; createActorFromVTKDataSet (polydata, actor); From c622ebf8908855f35e10fdb0717483748d800e38 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 10 Jun 2013 14:11:34 +0400 Subject: [PATCH 011/205] implemented wasStopped flag --- modules/viz/include/opencv2/viz/viz3d.hpp | 11 ++++++----- modules/viz/src/viz3d.cpp | 4 +++- modules/viz/test/test_viz3d.cpp | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 3a861eeff..046b9dc4d 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -26,8 +26,8 @@ namespace temp_viz void setBackgroundColor(const Color& color = Color::black()); void addCoordinateSystem(double scale, const Affine3f& t, const String &id = "coordinate"); - - void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); + + void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); @@ -51,10 +51,11 @@ namespace temp_viz void spin (); void spinOnce (int time = 1, bool force_redraw = false); - - void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = 0); - void registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie = 0); + void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = 0); + void registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie = 0); + + bool wasStopped() const; private: Viz3d(const Viz3d&); Viz3d& operator=(const Viz3d&); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index e06c85ca0..68fcf4870 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -96,4 +96,6 @@ void temp_viz::Viz3d::registerKeyboardCallback(void (*callback)(const cv::Keyboa void temp_viz::Viz3d::registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie) { impl_->registerMouseCallback(callback, cookie); -} \ No newline at end of file +} + +bool temp_viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index e72ef7598..3214a8179 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -90,7 +90,7 @@ TEST(Viz_viz3d, accuracy) v.addPolygonMesh(*mesh, "pq"); - while(1) //TODO implement and replace with !viz.wasStopped() + while(!v.wasStopped()) { // Creating new point cloud with id cloud1 cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); @@ -103,7 +103,7 @@ TEST(Viz_viz3d, accuracy) pos_y = std::sin(angle_x); pos_z = std::sin(angle_x); - v.spinOnce(10); + v.spinOnce(1, true); } // cv::Mat normals(cloud.size(), CV_32FC3, cv::Scalar(0, 10, 0)); From c4fe98977a5b17eed6cbde7c28439cab11c3a8f1 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 10 Jun 2013 12:02:18 +0200 Subject: [PATCH 012/205] implementation of * operator for Affine3f and point3d, initial implementation of isNaN --- modules/viz/include/opencv2/viz/types.hpp | 16 ++++++++++++++++ modules/viz/src/types.cpp | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index fd504a784..dbc5fc4b8 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -84,4 +85,19 @@ namespace temp_viz inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } + + Point3d operator*(const Affine3f& affine, const Point3d& point); + + inline bool isNaN( float x ) + { + union { float f; unsigned int u; } v = { x }; + return ((v.u & 0x7f800000) == 0x7f800000) && (v.u & 0x007fffff); + } + + inline bool isNaN( double x ) + { + union { double d; unsigned int u[2]; } v = { x }; + return (v.u[1] & 0x7ff00000) == 0x7ff00000 && + (v.u[0] != 0 || (v.u[1] & 0x000fffff) != 0); + } } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 0baed3a72..9586f6bc7 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -22,3 +22,12 @@ temp_viz::Color temp_viz::Color::white() { return Color(255, 255, 255); } temp_viz::Color temp_viz::Color::gray() { return Color(128, 128, 128); } +temp_viz::Point3d temp_viz::operator*(const temp_viz::Affine3f& affine, const temp_viz::Point3d& point) +{ + const temp_viz::Matx44f& m = affine.matrix; + temp_viz::Point3d result; + result.x = m.val[0] * point.x + m.val[1] * point.y + m.val[ 2] * point.z + m.val[ 3]; + result.y = m.val[4] * point.x + m.val[5] * point.y + m.val[ 6] * point.z + m.val[ 7]; + result.z = m.val[8] * point.x + m.val[9] * point.y + m.val[10] * point.z + m.val[11]; + return result; +} \ No newline at end of file From abdc022b20ea2aabfcdc06e2d8c4808cd4cd83ee Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 11 Jun 2013 10:48:48 +0200 Subject: [PATCH 013/205] implemented copy_non_nans, isnan --- modules/viz/include/opencv2/viz/types.hpp | 15 +++-- modules/viz/src/q/viz3d_impl.hpp | 82 +++++++++++++++++++++++ modules/viz/src/types.cpp | 10 +-- modules/viz/src/viz3d_impl.cpp | 65 ++++-------------- 4 files changed, 108 insertions(+), 64 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index dbc5fc4b8..06de8a46e 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -14,7 +14,9 @@ namespace temp_viz typedef std::string String; typedef cv::Vec3d Vec3d; + typedef cv::Vec3f Vec3f; typedef cv::Vec4d Vec4d; + typedef cv::Vec4f Vec4f; typedef cv::Vec2d Vec2d; typedef cv::Vec2i Vec2i; typedef cv::Vec3b Vec3b; @@ -86,18 +88,19 @@ namespace temp_viz template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } - Point3d operator*(const Affine3f& affine, const Point3d& point); + Vec3d operator*(const Affine3f& affine, const Vec3d& vec); inline bool isNaN( float x ) { - union { float f; unsigned int u; } v = { x }; - return ((v.u & 0x7f800000) == 0x7f800000) && (v.u & 0x007fffff); + unsigned int *u = (reinterpret_cast(&x)); + return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff); } inline bool isNaN( double x ) { - union { double d; unsigned int u[2]; } v = { x }; - return (v.u[1] & 0x7ff00000) == 0x7ff00000 && - (v.u[0] != 0 || (v.u[1] & 0x000fffff) != 0); + // Here u has two elements + unsigned int *u = (reinterpret_cast(&x)); + return (u[1] & 0x7ff00000) == 0x7ff00000 && + (u[0] != 0 || (u[1] & 0x000fffff) != 0); } } diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 169666141..95ead4a7a 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -446,6 +446,88 @@ void convertToVtkMatrix (const cv::Matx44f& m, vtkSmartPointer &vt void convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix); void convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m); + +template inline int copy_non_nan_loop(_Tp *d, InputArray _s, InputArray _c) +{ + Mat s = _s.getMat(); + Mat c = _c.getMat(); + CV_Assert(s.size() == c.size()); + int j = 0; + for(int y = 0; y < s.rows; ++y) + { + const _Ts* srow = s.ptr<_Ts>(y); + const _Tc* crow = c.ptr<_Tc>(y); + for(int x = 0; x < s.cols; ++x) + if (!isNaN(crow[x][0]) && !isNaN(crow[x][1]) && !isNaN(crow[x][2])) + { + d[j++] = _Tp((srow[x])[0], (srow[x])[1], (srow[x])[2]); + } + } + return j; +} + +/** \brief Assign a value to a variable if another variable is not NaN + * \param[in] d the destination variable + * \param[in] _s the source variable + * \param[in] _c the values to be controlled if NaN (can be different from _s) + * \param[out] j number of points that are copied + */ +template inline int copy_non_nans(_Tp *d, InputArray _s, InputArray _c) +{ + Mat s = _s.getMat(); + Mat c = _c.getMat(); + CV_Assert(s.size() == c.size()); + + int j = 0; + if (s.channels() > 3) + { + if (s.type() == CV_32FC4) + { + switch(c.type()) + { + case CV_32FC3: j = copy_non_nan_loop<_Tp, Vec4f, Vec3f>(d,_s,_c); break; + case CV_32FC4: j = copy_non_nan_loop<_Tp, Vec4f, Vec4f>(d,_s,_c); break; + case CV_64FC3: j = copy_non_nan_loop<_Tp, Vec4f, Vec3d>(d,_s,_c); break; + case CV_64FC4: j = copy_non_nan_loop<_Tp, Vec4f, Vec4d>(d,_s,_c); break; + } + } + else if (s.type() == CV_64FC4) + { + switch(c.type()) + { + case CV_32FC3: j = copy_non_nan_loop<_Tp, Vec4d, Vec3f>(d,_s,_c); break; + case CV_32FC4: j = copy_non_nan_loop<_Tp, Vec4d, Vec4f>(d,_s,_c); break; + case CV_64FC3: j = copy_non_nan_loop<_Tp, Vec4d, Vec3d>(d,_s,_c); break; + case CV_64FC4: j = copy_non_nan_loop<_Tp, Vec4d, Vec4d>(d,_s,_c); break; + } + } + } + else + { + switch(c.type()) + { + case CV_32FC3: j = copy_non_nan_loop<_Tp, _Tp, Vec3f>(d,_s,_c); break; + case CV_32FC4: j = copy_non_nan_loop<_Tp, _Tp, Vec4f>(d,_s,_c); break; + case CV_64FC3: j = copy_non_nan_loop<_Tp, _Tp, Vec3d>(d,_s,_c); break; + case CV_64FC4: j = copy_non_nan_loop<_Tp, _Tp, Vec4d>(d,_s,_c); break; + } + } + return j; +} + +/** \brief Transform points in an array + * \param[in] d the destination variable + * \param[in] lenth the length of the d array + * \param[in] pose affine transform to be applied on each point in d + */ +template inline void transform_non_nans(_Tp* d, int length, const Affine3f& pose = Affine3f::Identity()) +{ + for (int i = 0; i < length; ++i) + { + d[i] = pose * d[i]; + } +} + } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 9586f6bc7..138b52e45 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -22,12 +22,12 @@ temp_viz::Color temp_viz::Color::white() { return Color(255, 255, 255); } temp_viz::Color temp_viz::Color::gray() { return Color(128, 128, 128); } -temp_viz::Point3d temp_viz::operator*(const temp_viz::Affine3f& affine, const temp_viz::Point3d& point) +temp_viz::Vec3d temp_viz::operator*(const temp_viz::Affine3f& affine, const temp_viz::Vec3d& vec) { const temp_viz::Matx44f& m = affine.matrix; - temp_viz::Point3d result; - result.x = m.val[0] * point.x + m.val[1] * point.y + m.val[ 2] * point.z + m.val[ 3]; - result.y = m.val[4] * point.x + m.val[5] * point.y + m.val[ 6] * point.z + m.val[ 7]; - result.z = m.val[8] * point.x + m.val[9] * point.y + m.val[10] * point.z + m.val[11]; + temp_viz::Vec3d result; + result[0] = m.val[0] * vec[0] + m.val[1] * vec[1] + m.val[ 2] * vec[2] + m.val[ 3]; + result[1] = m.val[4] * vec[0] + m.val[5] * vec[1] + m.val[ 6] * vec[2] + m.val[ 7]; + result[2] = m.val[8] * vec[0] + m.val[9] * vec[1] + m.val[10] * vec[2] + m.val[11]; return result; } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 91e4d6cb6..e61549196 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -17,14 +17,13 @@ void temp_viz::Viz3d::VizImpl::setWindowName (const std::string &name) void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } - void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _cloud, InputArray _colors, const Affine3f& pose) { Mat cloud = _cloud.getMat(); Mat colors = _colors.getMat(); - CV_Assert((cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3)); + CV_Assert((cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4)); CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); - + vtkSmartPointer polydata; vtkSmartPointer vertices; vtkSmartPointer points; @@ -74,35 +73,20 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou } int j = 0; - if (cloud.type() == CV_32FC3) + + if (cloud.depth() == CV_32F) { // Get a pointer to the beginning of the data array - Point3f *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); - - // Scan through the data and apply mask where point is NAN - for(int y = 0; y < cloud.rows; ++y) - { - const Point3f* crow = cloud.ptr(y); - for(int x = 0; x < cloud.cols; ++x) - - //TODO implementa templated copy_if() or copy_non_nans() and use everywhere. - if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) - data[j++] = pose * crow[x]; - } + Vec3f *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); + j = copy_non_nans(data, cloud, cloud); + transform_non_nans(data,j,pose); } - else if (cloud.type() == CV_64FC3) + else if (cloud.depth() == CV_64F) { // Get a pointer to the beginning of the data array - Point3d *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); - - // If a point is NaN, ignore it - for(int y = 0; y < cloud.rows; ++y) - { - const Point3d* crow = cloud.ptr(y); - for(int x = 0; x < cloud.cols; ++x) - if (cvIsNaN(crow[x].x) != 1 && cvIsNaN(crow[x].y) != 1 && cvIsNaN(crow[x].z) != 1) - data[j++] = pose * crow[x]; - } + Vec3d *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); + j = copy_non_nans(data, cloud, cloud); + transform_non_nans(data,j,pose); } nr_points = j; @@ -126,32 +110,7 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou // Get a random color Vec3b* colors_data = new Vec3b[nr_points]; - - j = 0; - if (cloud.type() == CV_32FC3) - { - for(int y = 0; y < colors.rows; ++y) - { - const Vec3b* crow = colors.ptr(y); - const Point3f* cloud_row = cloud.ptr(y); - - for(int x = 0; x < colors.cols; ++x) - if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) - colors_data[j++] = crow[x]; - } - } - else if (cloud.type() == CV_64FC3) - { - for(int y = 0; y < colors.rows; ++y) - { - const Vec3b* crow = colors.ptr(y); - const Point3d* cloud_row = cloud.ptr(y); - - for(int x = 0; x < colors.cols; ++x) - if (cvIsNaN(cloud_row[x].x) != 1 && cvIsNaN(cloud_row[x].y) != 1 && cvIsNaN(cloud_row[x].z) != 1) - colors_data[j++] = crow[x]; - } - } + j = copy_non_nans(colors_data, colors, cloud); reinterpret_cast(&(*scalars))->SetArray (reinterpret_cast(colors_data), 3 * nr_points, 0); From 1ae5918fa88684f1a7ffb479b4bee613d65be7d5 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Tue, 11 Jun 2013 18:38:20 +0400 Subject: [PATCH 014/205] refactoring of copy_non_nans --- modules/viz/include/opencv2/viz/types.hpp | 25 +++--- modules/viz/src/q/viz3d_impl.hpp | 104 +++++++++++----------- modules/viz/src/viz3d_impl.cpp | 8 +- 3 files changed, 69 insertions(+), 68 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 06de8a46e..aa18d18cf 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include @@ -30,6 +29,8 @@ namespace temp_viz typedef cv::Size Size; typedef cv::Point Point; typedef cv::InputArray InputArray; + using cv::Point3_; + using cv::Vec; @@ -90,17 +91,21 @@ namespace temp_viz Vec3d operator*(const Affine3f& affine, const Vec3d& vec); - inline bool isNaN( float x ) + inline bool isNan(float x) { - unsigned int *u = (reinterpret_cast(&x)); - return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff); + unsigned int *u = reinterpret_cast(&x); + return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff); } - inline bool isNaN( double x ) + inline bool isNan(double x) { - // Here u has two elements - unsigned int *u = (reinterpret_cast(&x)); - return (u[1] & 0x7ff00000) == 0x7ff00000 && - (u[0] != 0 || (u[1] & 0x000fffff) != 0); - } + unsigned int *u = reinterpret_cast(&x); + return (u[1] & 0x7ff00000) == 0x7ff00000 && (u[0] != 0 || (u[1] & 0x000fffff) != 0); + } + + template inline bool isNan(const Vec<_Tp, cn>& v) + { return isNan(v.val[0]) || isNan(v.val[1]) || isNan(v.val[2]); } + + template inline bool isNan(const Point3_<_Tp>& p) + { return isNan(p.x) || isNan(p.y) || isNan(p.z); } } diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 95ead4a7a..be663b75a 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -24,9 +24,9 @@ public: void setWindowName (const std::string &name); /** \brief Register a callback function for keyboard input - * \param[in] callback function that will be registered as a callback for a keyboard event - * \param[in] cookie for passing user data to callback - */ + * \param[in] callback function that will be registered as a callback for a keyboard event + * \param[in] cookie for passing user data to callback + */ void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = 0); /** \brief Register a callback function for mouse events @@ -96,13 +96,13 @@ public: bool addText3D (const std::string &text, const cv::Point3f &position, const Color& color, double textScale = 1.0, const std::string &id = ""); bool addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level = 100, float scale = 0.02f, const std::string &id = "cloud"); - + /** \brief If the id exists, updates the point cloud; otherwise, adds a new point cloud to the scene - * \param[in] id a variable to identify the point cloud - * \param[in] cloud cloud input in x,y,z coordinates - * \param[in] colors color input in the same order of the points or single uniform color - * \param[in] pose transform to be applied on the point cloud - */ + * \param[in] id a variable to identify the point cloud + * \param[in] cloud cloud input in x,y,z coordinates + * \param[in] colors color input in the same order of the points or single uniform color + * \param[in] pose transform to be applied on the point cloud + */ void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); @@ -447,70 +447,66 @@ void convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion< void convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m); -template inline int copy_non_nan_loop(_Tp *d, InputArray _s, InputArray _c) + + +template inline int copy_non_nan_loop(_Tp *d, const Mat& s, const Mat& c) { - Mat s = _s.getMat(); - Mat c = _c.getMat(); CV_Assert(s.size() == c.size()); int j = 0; for(int y = 0; y < s.rows; ++y) { - const _Ts* srow = s.ptr<_Ts>(y); - const _Tc* crow = c.ptr<_Tc>(y); - for(int x = 0; x < s.cols; ++x) - if (!isNaN(crow[x][0]) && !isNaN(crow[x][1]) && !isNaN(crow[x][2])) - { - d[j++] = _Tp((srow[x])[0], (srow[x])[1], (srow[x])[2]); - } + const _Ts* srow = s.ptr<_Ts>(y); + const _Tc* crow = c.ptr<_Tc>(y); + for(int x = 0; x < s.cols; ++x) + if (!isNan(crow[x])) + d[j++] = _Tp((srow[x])[0], (srow[x])[1], (srow[x])[2]); } return j; } /** \brief Assign a value to a variable if another variable is not NaN * \param[in] d the destination variable - * \param[in] _s the source variable - * \param[in] _c the values to be controlled if NaN (can be different from _s) + * \param[in] s the source variable + * \param[in] c the values to be controlled if NaN (can be different from s) * \param[out] j number of points that are copied - */ -template inline int copy_non_nans(_Tp *d, InputArray _s, InputArray _c) + */ +template inline int copy_non_nans(_Tp *d, const Mat& s, const Mat& c) { - Mat s = _s.getMat(); - Mat c = _c.getMat(); CV_Assert(s.size() == c.size()); int j = 0; if (s.channels() > 3) { - if (s.type() == CV_32FC4) - { - switch(c.type()) - { - case CV_32FC3: j = copy_non_nan_loop<_Tp, Vec4f, Vec3f>(d,_s,_c); break; - case CV_32FC4: j = copy_non_nan_loop<_Tp, Vec4f, Vec4f>(d,_s,_c); break; - case CV_64FC3: j = copy_non_nan_loop<_Tp, Vec4f, Vec3d>(d,_s,_c); break; - case CV_64FC4: j = copy_non_nan_loop<_Tp, Vec4f, Vec4d>(d,_s,_c); break; - } - } - else if (s.type() == CV_64FC4) - { - switch(c.type()) - { - case CV_32FC3: j = copy_non_nan_loop<_Tp, Vec4d, Vec3f>(d,_s,_c); break; - case CV_32FC4: j = copy_non_nan_loop<_Tp, Vec4d, Vec4f>(d,_s,_c); break; - case CV_64FC3: j = copy_non_nan_loop<_Tp, Vec4d, Vec3d>(d,_s,_c); break; - case CV_64FC4: j = copy_non_nan_loop<_Tp, Vec4d, Vec4d>(d,_s,_c); break; - } - } + if (s.type() == CV_32FC4) + { + switch(c.type()) + { + case CV_32FC3: j = copy_non_nan_loop<_Tp, Vec4f, Vec3f>(d, s, c); break; + case CV_32FC4: j = copy_non_nan_loop<_Tp, Vec4f, Vec4f>(d, s, c); break; + case CV_64FC3: j = copy_non_nan_loop<_Tp, Vec4f, Vec3d>(d, s, c); break; + case CV_64FC4: j = copy_non_nan_loop<_Tp, Vec4f, Vec4d>(d, s, c); break; + } + } + else if (s.type() == CV_64FC4) + { + switch(c.type()) + { + case CV_32FC3: j = copy_non_nan_loop<_Tp, Vec4d, Vec3f>(d, s, c); break; + case CV_32FC4: j = copy_non_nan_loop<_Tp, Vec4d, Vec4f>(d, s, c); break; + case CV_64FC3: j = copy_non_nan_loop<_Tp, Vec4d, Vec3d>(d, s, c); break; + case CV_64FC4: j = copy_non_nan_loop<_Tp, Vec4d, Vec4d>(d, s, c); break; + } + } } else { - switch(c.type()) - { - case CV_32FC3: j = copy_non_nan_loop<_Tp, _Tp, Vec3f>(d,_s,_c); break; - case CV_32FC4: j = copy_non_nan_loop<_Tp, _Tp, Vec4f>(d,_s,_c); break; - case CV_64FC3: j = copy_non_nan_loop<_Tp, _Tp, Vec3d>(d,_s,_c); break; - case CV_64FC4: j = copy_non_nan_loop<_Tp, _Tp, Vec4d>(d,_s,_c); break; - } + switch(c.type()) + { + case CV_32FC3: j = copy_non_nan_loop<_Tp, _Tp, Vec3f>(d, s, c); break; + case CV_32FC4: j = copy_non_nan_loop<_Tp, _Tp, Vec4f>(d, s, c); break; + case CV_64FC3: j = copy_non_nan_loop<_Tp, _Tp, Vec3d>(d, s, c); break; + case CV_64FC4: j = copy_non_nan_loop<_Tp, _Tp, Vec4d>(d, s, c); break; + } } return j; } @@ -519,12 +515,12 @@ template inline int copy_non_nans(_Tp *d, InputArray _s, InputArra * \param[in] d the destination variable * \param[in] lenth the length of the d array * \param[in] pose affine transform to be applied on each point in d - */ + */ template inline void transform_non_nans(_Tp* d, int length, const Affine3f& pose = Affine3f::Identity()) { for (int i = 0; i < length; ++i) { - d[i] = pose * d[i]; + d[i] = pose * d[i]; } } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index e61549196..24bfed138 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -78,15 +78,15 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou { // Get a pointer to the beginning of the data array Vec3f *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); - j = copy_non_nans(data, cloud, cloud); - transform_non_nans(data,j,pose); + j = copy_non_nans(data, cloud, cloud); + transform_non_nans(data,j,pose); } else if (cloud.depth() == CV_64F) { // Get a pointer to the beginning of the data array Vec3d *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); - j = copy_non_nans(data, cloud, cloud); - transform_non_nans(data,j,pose); + j = copy_non_nans(data, cloud, cloud); + transform_non_nans(data,j,pose); } nr_points = j; From 1b51ee385bff79bba6943cdbec6bd35704cbe6c9 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Tue, 11 Jun 2013 21:30:19 +0400 Subject: [PATCH 015/205] refactored showPointCloud to for shorter code. Implemented NanFilter::copy() function --- modules/viz/include/opencv2/viz/types.hpp | 9 +- modules/viz/src/q/viz3d_impl.hpp | 119 +++++++++------------- modules/viz/src/types.cpp | 9 -- modules/viz/src/viz3d.cpp | 1 + modules/viz/src/viz3d_impl.cpp | 65 +++++++----- 5 files changed, 99 insertions(+), 104 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index aa18d18cf..2328dc073 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -31,6 +31,10 @@ namespace temp_viz typedef cv::InputArray InputArray; using cv::Point3_; using cv::Vec; + using cv::Mat_; + using cv::DataDepth; + using cv::DataType; + @@ -87,9 +91,10 @@ namespace temp_viz inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } + + template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } - - Vec3d operator*(const Affine3f& affine, const Vec3d& vec); + inline bool isNan(float x) { diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index be663b75a..616da8a01 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -447,84 +447,65 @@ void convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion< void convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m); - - -template inline int copy_non_nan_loop(_Tp *d, const Mat& s, const Mat& c) +struct NanFilter { - CV_Assert(s.size() == c.size()); - int j = 0; - for(int y = 0; y < s.rows; ++y) + template + struct Impl { - const _Ts* srow = s.ptr<_Ts>(y); - const _Tc* crow = c.ptr<_Tc>(y); - for(int x = 0; x < s.cols; ++x) - if (!isNan(crow[x])) - d[j++] = _Tp((srow[x])[0], (srow[x])[1], (srow[x])[2]); - } - return j; -} + typedef Vec<_Tp, 3> _Out; -/** \brief Assign a value to a variable if another variable is not NaN - * \param[in] d the destination variable - * \param[in] s the source variable - * \param[in] c the values to be controlled if NaN (can be different from s) - * \param[out] j number of points that are copied - */ -template inline int copy_non_nans(_Tp *d, const Mat& s, const Mat& c) -{ - CV_Assert(s.size() == c.size()); - - int j = 0; - if (s.channels() > 3) - { - if (s.type() == CV_32FC4) + static _Out* copy(const Mat& source, _Out* output, const Mat& nan_mask) { - switch(c.type()) + CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size()); + CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4); + CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth()); + + int s_chs = source.channels(); + int m_chs = nan_mask.channels(); + + for(int y = 0; y < source.rows; ++y) { - case CV_32FC3: j = copy_non_nan_loop<_Tp, Vec4f, Vec3f>(d, s, c); break; - case CV_32FC4: j = copy_non_nan_loop<_Tp, Vec4f, Vec4f>(d, s, c); break; - case CV_64FC3: j = copy_non_nan_loop<_Tp, Vec4f, Vec3d>(d, s, c); break; - case CV_64FC4: j = copy_non_nan_loop<_Tp, Vec4f, Vec4d>(d, s, c); break; - } - } - else if (s.type() == CV_64FC4) - { - switch(c.type()) - { - case CV_32FC3: j = copy_non_nan_loop<_Tp, Vec4d, Vec3f>(d, s, c); break; - case CV_32FC4: j = copy_non_nan_loop<_Tp, Vec4d, Vec4f>(d, s, c); break; - case CV_64FC3: j = copy_non_nan_loop<_Tp, Vec4d, Vec3d>(d, s, c); break; - case CV_64FC4: j = copy_non_nan_loop<_Tp, Vec4d, Vec4d>(d, s, c); break; - } - } - } - else - { - switch(c.type()) - { - case CV_32FC3: j = copy_non_nan_loop<_Tp, _Tp, Vec3f>(d, s, c); break; - case CV_32FC4: j = copy_non_nan_loop<_Tp, _Tp, Vec4f>(d, s, c); break; - case CV_64FC3: j = copy_non_nan_loop<_Tp, _Tp, Vec3d>(d, s, c); break; - case CV_64FC4: j = copy_non_nan_loop<_Tp, _Tp, Vec4d>(d, s, c); break; - } - } - return j; -} + const _Tp* srow = source.ptr<_Tp>(y); + const _Msk* mrow = nan_mask.ptr<_Msk>(y); -/** \brief Transform points in an array - * \param[in] d the destination variable - * \param[in] lenth the length of the d array - * \param[in] pose affine transform to be applied on each point in d - */ -template inline void transform_non_nans(_Tp* d, int length, const Affine3f& pose = Affine3f::Identity()) + for(int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) + if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) + *output++ = _Out(srow); + } + return output; + } + }; + + template + static inline Vec<_Tp, 3>* copy(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask) + { + CV_Assert(nan_mask.depth() == CV_32F || nan_mask.depth() == CV_64F); + + typedef Vec<_Tp, 3>* (*copy_func)(const Mat&, Vec<_Tp, 3>*, const Mat&); + const static copy_func table[2] = { &NanFilter::Impl<_Tp, float>::copy, &NanFilter::Impl<_Tp, double>::copy }; + + return table[nan_mask.depth() - 5](source, output, nan_mask); + } +}; + +struct ApplyAffine { - for (int i = 0; i < length; ++i) + const Affine3f& affine_; + ApplyAffine(const Affine3f& affine) : affine_(affine) {} + + template Point3_<_Tp> operator()(const Point3_<_Tp>& p) { return affine * p; } + + template Vec<_Tp, 3> operator()(const Vec<_Tp, 3>& v) { - d[i] = pose * d[i]; + const float* m = affine_.matrix.val; + + Vec<_Tp, 3> result; + result[0] = m[0] * v[0] + m[1] * v[1] + m[ 2] * v[2] + m[ 3]; + result[1] = m[4] * v[0] + m[5] * v[1] + m[ 6] * v[2] + m[ 7]; + result[2] = m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11]; + return result; } -} +}; } - - diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 138b52e45..0baed3a72 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -22,12 +22,3 @@ temp_viz::Color temp_viz::Color::white() { return Color(255, 255, 255); } temp_viz::Color temp_viz::Color::gray() { return Color(128, 128, 128); } -temp_viz::Vec3d temp_viz::operator*(const temp_viz::Affine3f& affine, const temp_viz::Vec3d& vec) -{ - const temp_viz::Matx44f& m = affine.matrix; - temp_viz::Vec3d result; - result[0] = m.val[0] * vec[0] + m.val[1] * vec[1] + m.val[ 2] * vec[2] + m.val[ 3]; - result[1] = m.val[4] * vec[0] + m.val[5] * vec[1] + m.val[ 6] * vec[2] + m.val[ 7]; - result[2] = m.val[8] * vec[0] + m.val[9] * vec[1] + m.val[10] * vec[2] + m.val[11]; - return result; -} \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 68fcf4870..2047c0980 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -99,3 +99,4 @@ void temp_viz::Viz3d::registerMouseCallback(void (*callback)(const cv::MouseEven } bool temp_viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } + diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 24bfed138..1ad067889 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -2,6 +2,27 @@ #include #include +namespace temp_viz +{ + template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); + + template<> Vec3f* vtkpoints_data(vtkSmartPointer& points) + { + CV_Assert(points->GetDataType() == VTK_FLOAT); + vtkDataArray *data = points->GetData(); + float *pointer = static_cast(data)->GetPointer(0); + return reinterpret_cast(pointer); + } + + template<> Vec3d* vtkpoints_data(vtkSmartPointer& points) + { + CV_Assert(points->GetDataType() == VTK_DOUBLE); + vtkDataArray *data = points->GetData(); + double *pointer = static_cast(data)->GetPointer(0); + return reinterpret_cast(pointer); + } +} + void temp_viz::Viz3d::VizImpl::setFullScreen (bool mode) { if (window_) @@ -21,14 +42,14 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou { Mat cloud = _cloud.getMat(); Mat colors = _colors.getMat(); - CV_Assert((cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4)); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); vtkSmartPointer polydata; vtkSmartPointer vertices; vtkSmartPointer points; vtkSmartPointer initcells; - vtkIdType nr_points; + vtkIdType nr_points = cloud.total(); // If the cloud already exists, update otherwise create new one CloudActorMap::iterator am_it = cloud_actor_map_->find (id); @@ -41,7 +62,6 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou vertices = vtkSmartPointer::New (); polydata->SetVerts (vertices); - nr_points = cloud.total(); points = polydata->GetPoints (); if (!points) @@ -67,29 +87,28 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou points->SetDataTypeToFloat (); else if (cloud.depth() == CV_64F) points->SetDataTypeToDouble (); - // Copy the new point array in - nr_points = cloud.total(); + points->SetNumberOfPoints (nr_points); } - int j = 0; - if (cloud.depth() == CV_32F) { // Get a pointer to the beginning of the data array - Vec3f *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); - j = copy_non_nans(data, cloud, cloud); - transform_non_nans(data,j,pose); + Vec3f *data_beg = vtkpoints_data(points); + Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); + std::transform(data_beg, data_end, data_beg, ApplyAffine(pose)); + nr_points = data_end - data_beg; + } else if (cloud.depth() == CV_64F) { // Get a pointer to the beginning of the data array - Vec3d *data = reinterpret_cast((static_cast (points->GetData ()))->GetPointer (0)); - j = copy_non_nans(data, cloud, cloud); - transform_non_nans(data,j,pose); + Vec3d *data_beg = vtkpoints_data(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + std::transform(data_beg, data_end, data_beg, ApplyAffine(pose)); + nr_points = data_end - data_beg; } - nr_points = j; points->SetNumberOfPoints (nr_points); vtkSmartPointer cells = vertices->GetData (); @@ -102,19 +121,17 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou // Set the cells and the vertices vertices->SetCells (nr_points, cells); - // Get the colors from the handler - Vec2d minmax; - vtkSmartPointer scalars = vtkSmartPointer::New (); - scalars->SetNumberOfComponents (3); - reinterpret_cast(&(*scalars))->SetNumberOfTuples (nr_points); - // Get a random color Vec3b* colors_data = new Vec3b[nr_points]; - j = copy_non_nans(colors_data, colors, cloud); + NanFilter::copy(colors, colors_data, cloud); - reinterpret_cast(&(*scalars))->SetArray (reinterpret_cast(colors_data), 3 * nr_points, 0); + vtkSmartPointer scalars = vtkSmartPointer::New (); + scalars->SetNumberOfComponents (3); + scalars->SetNumberOfTuples (nr_points); + scalars->SetArray (colors_data->val, 3 * nr_points, 0); // Assign the colors + Vec2d minmax; polydata->GetPointData ()->SetScalars (scalars); scalars->GetRange (minmax.val); @@ -133,8 +150,8 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou (*cloud_actor_map_)[id].actor = actor; (*cloud_actor_map_)[id].cells = initcells; - const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); - const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); + const Eigen::Vector4f sensor_origin = Eigen::Vector4f::Zero (); + const Eigen::Quaternionf sensor_orientation = Eigen::Quaternionf::Identity (); // Save the viewpoint transformation matrix to the global actor map vtkSmartPointer transformation = vtkSmartPointer::New(); From 01086323b068a399e39e09a0ed5df5bab94b6bd7 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 12 Jun 2013 09:29:04 +0200 Subject: [PATCH 016/205] mistype fix --- modules/viz/src/q/viz3d_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 616da8a01..bf67701cd 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -493,7 +493,7 @@ struct ApplyAffine const Affine3f& affine_; ApplyAffine(const Affine3f& affine) : affine_(affine) {} - template Point3_<_Tp> operator()(const Point3_<_Tp>& p) { return affine * p; } + template Point3_<_Tp> operator()(const Point3_<_Tp>& p) { return affine_ * p; } template Vec<_Tp, 3> operator()(const Vec<_Tp, 3>& v) { From 46cf22cdfff9d0f067a14a35558493b29e8124b6 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 12 Jun 2013 10:55:07 +0200 Subject: [PATCH 017/205] showPointCloud with single color --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/q/viz3d_impl.hpp | 1 + modules/viz/src/viz3d.cpp | 5 +++++ modules/viz/src/viz3d_impl.cpp | 9 ++++++++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 046b9dc4d..d7e47074d 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -28,6 +28,7 @@ namespace temp_viz void addCoordinateSystem(double scale, const Affine3f& t, const String &id = "coordinate"); void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); + void showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose = Affine3f::Identity()); bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index bf67701cd..7afa86a7a 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -104,6 +104,7 @@ public: * \param[in] pose transform to be applied on the point cloud */ void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); + void showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose = Affine3f::Identity()); bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 2047c0980..dfade9926 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -28,6 +28,11 @@ void temp_viz::Viz3d::showPointCloud(const String& id, InputArray cloud, InputAr impl_->showPointCloud(id, cloud, colors, pose); } +void temp_viz::Viz3d::showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose) +{ + impl_->showPointCloud(id, cloud, color, pose); +} + bool temp_viz::Viz3d::addPointCloudNormals (const Mat &cloud, const Mat& normals, int level, float scale, const String& id) { return impl_->addPointCloudNormals(cloud, normals, level, scale, id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 1ad067889..2ee07ffe7 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -114,7 +114,7 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou vtkSmartPointer cells = vertices->GetData (); if (exist) - updateCells(cells, initcells, nr_points); + updateCells (cells, initcells, nr_points); else updateCells (cells, am_it->second.cells, nr_points); @@ -166,6 +166,13 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou } } +void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _cloud, const Color& color, const Affine3f& pose) +{ + // Generate an array of colors from single color + Mat colors(_cloud.size(), CV_8UC3, color); + showPointCloud(id, _cloud, colors, pose); +} + bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level, float scale, const std::string &id) { CV_Assert(cloud.size() == normals.size() && cloud.type() == CV_32FC3 && normals.type() == CV_32FC3); From 0e90c0fff26e7b5afc58c56549bf5fb1a36bfcde Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 12 Jun 2013 10:56:46 +0200 Subject: [PATCH 018/205] updated test for single color --- modules/viz/test/test_viz3d.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 3214a8179..5c9141f98 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -89,12 +89,15 @@ TEST(Viz_viz3d, accuracy) temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("d:/horse.ply"); v.addPolygonMesh(*mesh, "pq"); + int col_blue = 0; + int col_green = 0; + int col_red = 0; while(!v.wasStopped()) { // Creating new point cloud with id cloud1 cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); - v.showPointCloud("cloud1", cloud, colors, cloudPosition); + v.showPointCloud("cloud1", cloud, temp_viz::Color(col_blue, col_green, col_red), cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; @@ -102,6 +105,9 @@ TEST(Viz_viz3d, accuracy) pos_x = std::sin(angle_x); pos_y = std::sin(angle_x); pos_z = std::sin(angle_x); + col_blue = int(angle_x * 10) % 256; + col_green = int(angle_x * 20) % 256; + col_red = int(angle_x * 30) % 256; v.spinOnce(1, true); } From f91b1a1771980b629210f84c3735dca8658d8383 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 12 Jun 2013 17:38:39 +0200 Subject: [PATCH 019/205] showPointCloud with single color without duplicating color --- modules/viz/src/viz3d_impl.cpp | 120 +++++++++++++++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 10 ++- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 2ee07ffe7..f1c425e93 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -163,14 +163,128 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou { // Update the mapper reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); + am_it->second.actor->GetMapper ()->ScalarVisibilityOn(); + am_it->second.actor->Modified (); } } void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _cloud, const Color& color, const Affine3f& pose) { - // Generate an array of colors from single color - Mat colors(_cloud.size(), CV_8UC3, color); - showPointCloud(id, _cloud, colors, pose); + Mat cloud = _cloud.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + + vtkSmartPointer polydata; + vtkSmartPointer vertices; + vtkSmartPointer points; + vtkSmartPointer initcells; + vtkIdType nr_points = cloud.total(); + + // If the cloud already exists, update otherwise create new one + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + bool exist = (am_it == cloud_actor_map_->end()); + if (exist) + { + // Add as new cloud + allocVtkPolyData(polydata); + //polydata = vtkSmartPointer::New (); + vertices = vtkSmartPointer::New (); + polydata->SetVerts (vertices); + + points = polydata->GetPoints (); + + if (!points) + { + points = vtkSmartPointer::New (); + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat(); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble(); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); + } + else + { + // Update the cloud + // Get the current poly data + polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); + vertices = polydata->GetVerts (); + points = polydata->GetPoints (); + // Update the point data type based on the cloud + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat (); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble (); + + points->SetNumberOfPoints (nr_points); + } + + if (cloud.depth() == CV_32F) + { + // Get a pointer to the beginning of the data array + Vec3f *data_beg = vtkpoints_data(points); + Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); + std::transform(data_beg, data_end, data_beg, ApplyAffine(pose)); + nr_points = data_end - data_beg; + + } + else if (cloud.depth() == CV_64F) + { + // Get a pointer to the beginning of the data array + Vec3d *data_beg = vtkpoints_data(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + std::transform(data_beg, data_end, data_beg, ApplyAffine(pose)); + nr_points = data_end - data_beg; + } + + points->SetNumberOfPoints (nr_points); + + vtkSmartPointer cells = vertices->GetData (); + + if (exist) + updateCells (cells, initcells, nr_points); + else + updateCells (cells, am_it->second.cells, nr_points); + + // Set the cells and the vertices + vertices->SetCells (nr_points, cells); + + // Get a random color + Color c = vtkcolor(color); + polydata->GetPointData ()->SetScalars (0); + + // If this is the new point cloud, a new actor is created + if (exist) + { + vtkSmartPointer actor; + createActorFromVTKDataSet (polydata, actor, false); + + actor->GetProperty ()->SetColor(c.val); + + // Add it to all renderers + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*cloud_actor_map_)[id].actor = actor; + (*cloud_actor_map_)[id].cells = initcells; + + const Eigen::Vector4f sensor_origin = Eigen::Vector4f::Zero (); + const Eigen::Quaternionf sensor_orientation = Eigen::Quaternionf::Identity (); + + // Save the viewpoint transformation matrix to the global actor map + vtkSmartPointer transformation = vtkSmartPointer::New(); + convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); + + (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; + } + else + { + // Update the mapper + reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); + am_it->second.actor->GetProperty ()->SetColor(c.val); + am_it->second.actor->GetMapper ()->ScalarVisibilityOff(); + am_it->second.actor->Modified (); + } } bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level, float scale, const std::string &id) diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 5c9141f98..0af79b7cd 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -92,12 +92,18 @@ TEST(Viz_viz3d, accuracy) int col_blue = 0; int col_green = 0; int col_red = 0; + + bool alternate = true; while(!v.wasStopped()) { // Creating new point cloud with id cloud1 cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); - v.showPointCloud("cloud1", cloud, temp_viz::Color(col_blue, col_green, col_red), cloudPosition); + if (!alternate) + v.showPointCloud("cloud1", cloud, temp_viz::Color(255, 0, 0), cloudPosition); + else + v.showPointCloud("cloud1", cloud, colors, cloudPosition); + alternate = !alternate; angle_x += 0.1f; angle_y -= 0.1f; @@ -109,7 +115,7 @@ TEST(Viz_viz3d, accuracy) col_green = int(angle_x * 20) % 256; col_red = int(angle_x * 30) % 256; - v.spinOnce(1, true); + v.spinOnce(10, true); } // cv::Mat normals(cloud.size(), CV_32FC3, cv::Scalar(0, 10, 0)); From c65d88887503539e296c98ae5f87280d2f3533e3 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 14 Jun 2013 14:19:45 +0400 Subject: [PATCH 020/205] little refactoring --- modules/viz/include/opencv2/viz/events.hpp | 38 +++++++++++----------- modules/viz/include/opencv2/viz/viz3d.hpp | 4 +-- modules/viz/src/interactor_style.cpp | 28 ++++++++-------- modules/viz/src/q/interactor_style.h | 38 +++++++++++----------- modules/viz/src/q/viz3d_impl.hpp | 14 ++++---- modules/viz/src/viz3d.cpp | 4 +-- modules/viz/src/viz_main.cpp | 4 +-- modules/viz/test/test_precomp.hpp | 6 +++- modules/viz/test/test_viz3d.cpp | 7 ---- 9 files changed, 71 insertions(+), 72 deletions(-) diff --git a/modules/viz/include/opencv2/viz/events.hpp b/modules/viz/include/opencv2/viz/events.hpp index c39580af1..410364e9c 100644 --- a/modules/viz/include/opencv2/viz/events.hpp +++ b/modules/viz/include/opencv2/viz/events.hpp @@ -3,7 +3,7 @@ #include #include -namespace cv +namespace temp_viz { class KeyboardEvent { @@ -13,13 +13,13 @@ namespace cv static const unsigned int Shift = 4; /** \brief Constructor - * \param[in] action true for key was pressed, false for released - * \param[in] key_sym the key-name that caused the action - * \param[in] key the key code that caused the action - * \param[in] alt whether the alt key was pressed at the time where this event was triggered - * \param[in] ctrl whether the ctrl was pressed at the time where this event was triggered - * \param[in] shift whether the shift was pressed at the time where this event was triggered - */ + * \param[in] action true for key was pressed, false for released + * \param[in] key_sym the key-name that caused the action + * \param[in] key the key code that caused the action + * \param[in] alt whether the alt key was pressed at the time where this event was triggered + * \param[in] ctrl whether the ctrl was pressed at the time where this event was triggered + * \param[in] shift whether the shift was pressed at the time where this event was triggered + */ KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); bool isAltPressed () const; @@ -28,7 +28,7 @@ namespace cv unsigned char getKeyCode () const; - const std::string& getKeySym () const; + const String& getKeySym () const; bool keyDown () const; bool keyUp () const; @@ -37,7 +37,7 @@ namespace cv bool action_; unsigned int modifiers_; unsigned char key_code_; - std::string key_sym_; + String key_sym_; }; class MouseEvent @@ -75,7 +75,7 @@ namespace cv //////////////////////////////////////////////////////////////////// /// Implementation -inline cv::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) +inline temp_viz::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) : action_ (_action), modifiers_ (0), key_code_(key), key_sym_ (_key_sym) { if (alt) @@ -88,15 +88,15 @@ inline cv::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_s modifiers_ |= Shift; } -inline bool cv::KeyboardEvent::isAltPressed () const { return (modifiers_ & Alt) != 0; } -inline bool cv::KeyboardEvent::isCtrlPressed () const { return (modifiers_ & Ctrl) != 0; } -inline bool cv::KeyboardEvent::isShiftPressed () const { return (modifiers_ & Shift) != 0; } -inline unsigned char cv::KeyboardEvent::getKeyCode () const { return key_code_; } -inline const std::string& cv::KeyboardEvent::getKeySym () const { return (key_sym_); } -inline bool cv::KeyboardEvent::keyDown () const { return action_; } -inline bool cv::KeyboardEvent::keyUp () const { return !action_; } +inline bool temp_viz::KeyboardEvent::isAltPressed () const { return (modifiers_ & Alt) != 0; } +inline bool temp_viz::KeyboardEvent::isCtrlPressed () const { return (modifiers_ & Ctrl) != 0; } +inline bool temp_viz::KeyboardEvent::isShiftPressed () const { return (modifiers_ & Shift) != 0; } +inline unsigned char temp_viz::KeyboardEvent::getKeyCode () const { return key_code_; } +inline const temp_viz::String& temp_viz::KeyboardEvent::getKeySym () const { return key_sym_; } +inline bool temp_viz::KeyboardEvent::keyDown () const { return action_; } +inline bool temp_viz::KeyboardEvent::keyUp () const { return !action_; } -inline cv::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) +inline temp_viz::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) : type(_type), button(_button), pointer(_p), key_state(0) { if (alt) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index d7e47074d..fb64fbe62 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -53,8 +53,8 @@ namespace temp_viz void spin (); void spinOnce (int time = 1, bool force_redraw = false); - void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = 0); - void registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie = 0); + void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie = 0); + void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); bool wasStopped() const; private: diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index dc2420046..a58e3883d 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -133,7 +133,7 @@ void temp_viz::InteractorStyle::OnChar () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie) +void temp_viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) { // Register the callback function and store the user data mouseCallback_ = callback; @@ -141,7 +141,7 @@ void temp_viz::InteractorStyle::registerMouseCallback(void (*callback)(const cv: } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void *cookie) +void temp_viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie) { // Register the callback function and store the user data keyboardCallback_ = callback; @@ -290,17 +290,19 @@ temp_viz::InteractorStyle::OnKeyDown () case 'c': case 'C': { vtkSmartPointer cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); - double clip[2], focal[3], pos[3], view[3]; - cam->GetClippingRange (clip); - cam->GetFocalPoint (focal); - cam->GetPosition (pos); - cam->GetViewUp (view); - int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); - int *win_size = Interactor->GetRenderWindow ()->GetSize (); - std::cerr << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << - pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << - cam->GetViewAngle () / 180.0 * M_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] - << endl; + + Vec2d clip; + Vec3d focal, pose, view; + cam->GetClippingRange (clip.val); + cam->GetFocalPoint (focal.val); + cam->GetPosition (pose.val); + cam->GetViewUp (view.val); + Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition ()); + Vec2i win_size(Interactor->GetRenderWindow()->GetSize ()); + std::cerr << Mat(clip, false).reshape(1, 1) << "/" << Mat(focal, false).reshape(1, 1) << "/" << + Mat(pose, false).reshape(1, 1) << "/" << Mat(view, false).reshape(1, 1) << "/" << + cam->GetViewAngle () / 180.0 * M_PI << "/" << + Mat(win_size, false).reshape(1,1) << "/" << Mat(win_pos, false).reshape(1,1) << endl; break; } case '=': diff --git a/modules/viz/src/q/interactor_style.h b/modules/viz/src/q/interactor_style.h index 3a196a728..e6c8c3b86 100644 --- a/modules/viz/src/q/interactor_style.h +++ b/modules/viz/src/q/interactor_style.h @@ -16,7 +16,7 @@ namespace temp_viz * - j, J : take a .PNG snapshot of the current window view * - c, C : display current camera/window parameters * - f, F : fly to point mode - * - e, E : exit the interactor\ + * - e, E : exit the interactor * - q, Q : stop and call VTK's TerminateApp * - + / - : increment/decrement overall point size * - r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}] @@ -52,8 +52,8 @@ namespace temp_viz virtual void Initialize (); /** \brief Pass a pointer to the actor map - * \param[in] actors the actor map that will be used with this style - */ + * \param[in] actors the actor map that will be used with this style + */ inline void setCloudActorMap (const cv::Ptr& actors) { actors_ = actors; } /** \brief Pass a set of renderers to the interactor style. @@ -62,17 +62,17 @@ namespace temp_viz void setRenderer (vtkSmartPointer& ren) { renderer_ = ren; } /** \brief Register a callback function for mouse events - * \param[in] ccallback function that will be registered as a callback for a mouse event - * \param[in] cookie for passing user data to callback - */ - void registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie = 0); + * \param[in] ccallback function that will be registered as a callback for a mouse event + * \param[in] cookie for passing user data to callback + */ + void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); /** \brief Register a callback function for keyboard events * \param[in] callback a function that will be registered as a callback for a keyboard event * \param[in] cookie user data passed to the callback function */ - void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void * cookie = 0); - + void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0); + /** \brief Save the current rendered image to disk, as a PNG screenshot. * \param[in] file the name of the PNG file */ @@ -141,15 +141,15 @@ namespace temp_viz /** \brief The keyboard modifier to use. Default: Alt. */ KeyboardModifier modifier_; - - /** \brief KeyboardEvent callback function pointer*/ - void (*keyboardCallback_)(const cv::KeyboardEvent&, void*); - /** \brief KeyboardEvent callback user data*/ - void *keyboard_callback_cookie_; - - /** \brief MouseEvent callback function pointer */ - void (*mouseCallback_)(const cv::MouseEvent&, void*); - /** \brief MouseEvent callback user data */ - void *mouse_callback_cookie_; + + /** \brief KeyboardEvent callback function pointer*/ + void (*keyboardCallback_)(const KeyboardEvent&, void*); + /** \brief KeyboardEvent callback user data*/ + void *keyboard_callback_cookie_; + + /** \brief MouseEvent callback function pointer */ + void (*mouseCallback_)(const MouseEvent&, void*); + /** \brief MouseEvent callback user data */ + void *mouse_callback_cookie_; }; } diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 7afa86a7a..6bc219262 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -27,13 +27,13 @@ public: * \param[in] callback function that will be registered as a callback for a keyboard event * \param[in] cookie for passing user data to callback */ - void registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie = 0); + void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie = 0); /** \brief Register a callback function for mouse events * \param[in] ccallback function that will be registered as a callback for a mouse event * \param[in] cookie for passing user data to callback */ - void registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie = 0); + void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); void spin (); void spinOnce (int time = 1, bool force_redraw = false); @@ -494,16 +494,16 @@ struct ApplyAffine const Affine3f& affine_; ApplyAffine(const Affine3f& affine) : affine_(affine) {} - template Point3_<_Tp> operator()(const Point3_<_Tp>& p) { return affine_ * p; } + template Point3_<_Tp> operator()(const Point3_<_Tp>& p) const { return affine_ * p; } - template Vec<_Tp, 3> operator()(const Vec<_Tp, 3>& v) + template Vec<_Tp, 3> operator()(const Vec<_Tp, 3>& v) const { const float* m = affine_.matrix.val; Vec<_Tp, 3> result; - result[0] = m[0] * v[0] + m[1] * v[1] + m[ 2] * v[2] + m[ 3]; - result[1] = m[4] * v[0] + m[5] * v[1] + m[ 6] * v[2] + m[ 7]; - result[2] = m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11]; + result[0] = (_Tp)(m[0] * v[0] + m[1] * v[1] + m[ 2] * v[2] + m[ 3]); + result[1] = (_Tp)(m[4] * v[0] + m[5] * v[1] + m[ 6] * v[2] + m[ 7]); + result[2] = (_Tp)(m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11]); return result; } }; diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index dfade9926..80f24490b 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -93,12 +93,12 @@ bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) return impl_->removeCoordinateSystem(id); } -void temp_viz::Viz3d::registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie) +void temp_viz::Viz3d::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) { impl_->registerKeyboardCallback(callback, cookie); } -void temp_viz::Viz3d::registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie) +void temp_viz::Viz3d::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) { impl_->registerMouseCallback(callback, cookie); } diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 1ea8368af..af6add432 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -95,14 +95,14 @@ temp_viz::Viz3d::VizImpl::~VizImpl () void temp_viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::registerMouseCallback(void (*callback)(const cv::MouseEvent&, void*), void* cookie) +void temp_viz::Viz3d::VizImpl::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) { // Register the callback function in the interactor style style_->registerMouseCallback(callback, cookie); } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::registerKeyboardCallback(void (*callback)(const cv::KeyboardEvent&, void*), void* cookie) +void temp_viz::Viz3d::VizImpl::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) { // Register the callback function in the interactor style style_->registerKeyboardCallback(callback, cookie); diff --git a/modules/viz/test/test_precomp.hpp b/modules/viz/test/test_precomp.hpp index 6c0f493d4..0e6b22cc5 100644 --- a/modules/viz/test/test_precomp.hpp +++ b/modules/viz/test/test_precomp.hpp @@ -10,7 +10,11 @@ #define __OPENCV_TEST_PRECOMP_HPP__ #include "opencv2/ts.hpp" -#include "opencv2/core/core_c.h" +#include +#include + #include +#include +#include #endif diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 0af79b7cd..4c7c87550 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -41,16 +41,9 @@ //M*/ #include "test_precomp.hpp" #include -#include -#include - -#include -#include - #include #include - cv::Mat cvcloud_load() { cv::Mat cloud(1, 20000, CV_32FC3); From 909f905b57b5d87aa6cd2e79ee37189bf8ebc2b3 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 14 Jun 2013 14:22:03 +0400 Subject: [PATCH 021/205] --amend --- modules/viz/src/interactor_style.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index a58e3883d..3a8abb13b 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -297,12 +297,13 @@ temp_viz::InteractorStyle::OnKeyDown () cam->GetFocalPoint (focal.val); cam->GetPosition (pose.val); cam->GetViewUp (view.val); - Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition ()); - Vec2i win_size(Interactor->GetRenderWindow()->GetSize ()); + Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition()); + Vec2i win_size(Interactor->GetRenderWindow()->GetSize()); + std::cerr << Mat(clip, false).reshape(1, 1) << "/" << Mat(focal, false).reshape(1, 1) << "/" << - Mat(pose, false).reshape(1, 1) << "/" << Mat(view, false).reshape(1, 1) << "/" << - cam->GetViewAngle () / 180.0 * M_PI << "/" << - Mat(win_size, false).reshape(1,1) << "/" << Mat(win_pos, false).reshape(1,1) << endl; + Mat(pose, false).reshape(1, 1) << "/" << Mat(view, false).reshape(1, 1) << "/" << + cam->GetViewAngle () / 180.0 * M_PI << "/" << + Mat(win_size, false).reshape(1,1) << "/" << Mat(win_pos, false).reshape(1,1) << endl; break; } case '=': From b387581d4f89bf96906c9c95b18022da2268618d Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 17 Jun 2013 16:32:52 +0200 Subject: [PATCH 022/205] initial refactoring --- modules/viz/src/q/shapes.h | 11 ++++++- modules/viz/src/shapes.cpp | 65 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/modules/viz/src/q/shapes.h b/modules/viz/src/q/shapes.h index 3ff63750d..9233ec45f 100644 --- a/modules/viz/src/q/shapes.h +++ b/modules/viz/src/q/shapes.h @@ -8,7 +8,16 @@ namespace temp_viz { CV_EXPORTS vtkSmartPointer createLine (const cv::Point3f& pt1, const cv::Point3f& pt2); CV_EXPORTS vtkSmartPointer createSphere (const cv::Point3f ¢er, float radius, int sphere_resolution = 10); - + CV_EXPORTS vtkSmartPointer createCylinder (const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30); + CV_EXPORTS vtkSmartPointer createPlane (const Vec4f& coefs); + CV_EXPORTS vtkSmartPointer createPlane (const Vec4f& coefs, const Point3f& pt); + CV_EXPORTS vtkSmartPointer create2DCircle (const Point3f& pt, double radius); + CV_EXPORTS vtkSmartPointer createCube(const Point3f& pt_min, const Point3f& pt_max); +// CV_EXPORTS vtkSmartPointer createCube (const Point3f& pt, const Quaternionf& qt, ); +// CV_EXPORTS vtkSmartPointer createCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation, double width, double height, double depth); +// CV_EXPORTS vtkSmartPointer createCube (double x_min, double x_max, double y_min, double y_max, double z_min, double z_max); +// +// /** \brief Create a cylinder shape from a set of model coefficients. * \param[in] coefficients the model coefficients (point_on_axis, axis_direction, radius) * \param[in] numsides (optional) the number of sides used for rendering the cylinder diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index 955cf3883..baa4cbde3 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -5,6 +5,71 @@ inline float rad2deg (float alpha) inline double rad2deg (double alpha){return (alpha * 57.29578);} +vtkSmartPointer temp_viz::createCylinder (const cv::Point3f& pt_on_axis, const cv::Point3f& axis_direction, double radius, int numsides) +{ + const cv::Point3f pt2 = pt_on_axis + axis_direction; + vtkSmartPointer line = vtkSmartPointer::New (); + line->SetPoint1 (pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); + line->SetPoint2 (pt2.x, pt2.y, pt2.z); + + vtkSmartPointer tuber = vtkSmartPointer::New (); + tuber->SetInputConnection (line->GetOutputPort ()); + tuber->SetRadius (radius); + tuber->SetNumberOfSides (numsides); + return (tuber->GetOutput ()); +} + +vtkSmartPointer temp_viz::createPlane (const cv::Vec4f& coefs) +{ + vtkSmartPointer plane = vtkSmartPointer::New (); + plane->SetNormal (coefs[0], coefs[1], coefs[2]); + double norm = cv::norm (cv::Vec3f (coefs[0], coefs[1], coefs[2])); + plane->Push (-coefs[3] / norm); + return (plane->GetOutput ()); +} + +vtkSmartPointer temp_viz::createPlane(const cv::Vec4f& coefs, const cv::Point3f& pt) +{ + vtkSmartPointer plane = vtkSmartPointer::New (); + cv::Point3f coefs3 (coefs[0], coefs[1], coefs[2]); + double norm_sqr = 1.0 / coefs3.dot (coefs3); + plane->SetNormal (coefs[0], coefs[1], coefs[2]); + + double t = coefs3.dot (pt) + coefs[3]; + cv::Vec3f p_center; + p_center = pt - coefs3 * t * norm_sqr; + plane->SetCenter (p_center[0], p_center[1], p_center[2]); + + return (plane->GetOutput ()); +} + +vtkSmartPointer temp_viz::create2DCircle (const cv::Point3f& pt, double radius) +{ + vtkSmartPointer disk = vtkSmartPointer::New (); + // Maybe the resolution should be lower e.g. 50 or 25 + disk->SetCircumferentialResolution (100); + disk->SetInnerRadius (radius - 0.001); + disk->SetOuterRadius (radius + 0.001); + disk->SetCircumferentialResolution (20); + + // Set the circle origin + vtkSmartPointer t = vtkSmartPointer::New (); + t->Identity (); + t->Translate (pt.x, pt.y, pt.z); + + vtkSmartPointer tf = vtkSmartPointer::New (); + tf->SetTransform (t); + tf->SetInputConnection (disk->GetOutputPort ()); + + return (tf->GetOutput ()); +} + +vtkSmartPointer temp_viz::createCube(const cv::Point3f& pt_min, const cv::Point3f& pt_max) +{ + vtkSmartPointer cube = vtkSmartPointer::New (); + cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); + return (cube->GetOutput ()); +} //////////////////////////////////////////////////////////////////////////////////////////// vtkSmartPointer temp_viz::createCylinder (const temp_viz::ModelCoefficients &coefficients, int numsides) From 26a68232078eee2a66c265561f4d9c3f211ce43e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 21 Jun 2013 12:48:27 +0200 Subject: [PATCH 023/205] showLine implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 2 + modules/viz/src/q/viz3d_impl.hpp | 3 +- modules/viz/src/viz3d.cpp | 5 +++ modules/viz/src/viz3d_impl.cpp | 49 ++++++++++++++--------- modules/viz/test/test_viz3d.cpp | 7 ++-- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index d7e47074d..ab76302cb 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -31,6 +31,8 @@ namespace temp_viz void showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose = Affine3f::Identity()); bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); + + void showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 7afa86a7a..af43a9b50 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -137,9 +137,10 @@ public: // This tends to close the window... interactor_->TerminateApp (); } + + void showLine (const String &id, const cv::Point3f &pt1, const cv::Point3f &pt2, const Color &color); bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); - bool addLine (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, const std::string &id = "line"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color_line, const Color& color_text, const std::string &id = "arrow"); bool addSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id = "sphere"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index dfade9926..7e0d324df 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -78,6 +78,11 @@ void temp_viz::Viz3d::spinOnce (int time, bool force_redraw) impl_->spinOnce(time, force_redraw); } +void temp_viz::Viz3d::showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +{ + impl_->showLine(id, pt1, pt2, color); +} + bool temp_viz::Viz3d::addPlane (const ModelCoefficients &coefficients, const String &id) { return impl_->addPlane(coefficients, id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 2ee07ffe7..8fc4d632d 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -266,33 +266,42 @@ bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const } -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addLine (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, const std::string &id) +void temp_viz::Viz3d::VizImpl::showLine (const String &id, const cv::Point3f &pt1, const cv::Point3f &pt2, const Color &color) { - // Check to see if this ID entry already exists (has it been already added to the visualizer?) + // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addLine] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; + bool exists = (am_it != shape_actor_map_->end()); + + // If it exists just update + if (exists) + { + vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); + reinterpret_cast(actor->GetMapper ())->SetInput(createLine(pt1,pt2)); + Color c = vtkcolor(color); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->Modified (); + } + else + { + // Create new line + vtkSmartPointer data = createLine (pt1, pt2); - vtkSmartPointer data = createLine (pt1, pt2); + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); + Color c = vtkcolor(color); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + renderer_->AddActor (actor); - Color c = vtkcolor(color); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } } - - bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 5c9141f98..e74ee1301 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -86,18 +86,19 @@ TEST(Viz_viz3d, accuracy) float pos_x = 0.0f; float pos_y = 0.0f; float pos_z = 0.0f; - temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("d:/horse.ply"); - v.addPolygonMesh(*mesh, "pq"); +// temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("d:/horse.ply"); +// v.addPolygonMesh(*mesh, "pq"); int col_blue = 0; int col_green = 0; int col_red = 0; - + while(!v.wasStopped()) { // Creating new point cloud with id cloud1 cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); v.showPointCloud("cloud1", cloud, temp_viz::Color(col_blue, col_green, col_red), cloudPosition); + v.showLine("line1", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); angle_x += 0.1f; angle_y -= 0.1f; From f94c2414e65914c406683ad68e0f9ed4abf896c1 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 21 Jun 2013 14:00:22 +0200 Subject: [PATCH 024/205] showPlane implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 2 + modules/viz/src/q/viz3d_impl.hpp | 24 +-------- modules/viz/src/viz3d.cpp | 8 +-- modules/viz/src/viz3d_impl.cpp | 63 +++++++++++++++++++++++ modules/viz/src/viz_main.cpp | 56 -------------------- modules/viz/test/test_viz3d.cpp | 12 +++-- 6 files changed, 80 insertions(+), 85 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index ab76302cb..9d0e60f68 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -33,6 +33,8 @@ namespace temp_viz bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); void showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); + void showPlane(const String &id, const Vec4f &coefs); + void showPlane(const String &id, const Vec4f &coefs, const Point3f &pt); bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index af43a9b50..bff67e71f 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -139,6 +139,8 @@ public: } void showLine (const String &id, const cv::Point3f &pt1, const cv::Point3f &pt2, const Color &color); + void showPlane (const String &id, const cv::Vec4f &coefs); + void showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt); bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); @@ -178,28 +180,6 @@ public: */ bool addCylinder (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "cylinder"); - /** \brief Add a plane from a set of given model coefficients - * \param[in] coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0) - * \param[in] id the plane id/name (default: "plane") - * - * \code - * // The following are given (or computed using sample consensus techniques) - * // See SampleConsensusModelPlane for more information - - * - * temp_viz::ModelCoefficients plane_coeff; - * plane_coeff.values.resize (4); // We need 4 values - * plane_coeff.values[0] = plane_parameters.x (); - * plane_coeff.values[1] = plane_parameters.y (); - * plane_coeff.values[2] = plane_parameters.z (); - * plane_coeff.values[3] = plane_parameters.w (); - * - * addPlane (plane_coeff); - * \endcode - */ - bool addPlane (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "plane"); - bool addPlane (const temp_viz::ModelCoefficients &coefficients, double x, double y, double z, const std::string &id = "plane"); - /** \brief Add a circle from a set of given model coefficients * \param[in] coefficients the model coefficients (x, y, radius) * \param[in] id the circle id/name (default: "circle") diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 7e0d324df..5f0342a40 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -83,14 +83,14 @@ void temp_viz::Viz3d::showLine(const String &id, const Point3f &pt1, const Point impl_->showLine(id, pt1, pt2, color); } -bool temp_viz::Viz3d::addPlane (const ModelCoefficients &coefficients, const String &id) +void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs) { - return impl_->addPlane(coefficients, id); + impl_->showPlane(id, coefs); } -bool temp_viz::Viz3d::addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String& id) +void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs, const Point3f &pt) { - return impl_->addPlane(coefficients, x, y, z, id); + impl_->showPlane(id, coefs, pt); } bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 8fc4d632d..15938f820 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -302,6 +302,69 @@ void temp_viz::Viz3d::VizImpl::showLine (const String &id, const cv::Point3f &pt } } +void temp_viz::Viz3d::VizImpl::showPlane (const String &id, const cv::Vec4f &coefs) +{ + // Check if this Id already exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + + // If it exists just update + if (exists) + { + vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); + reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coefs)); + actor->Modified (); + } + else + { + // Create a plane + vtkSmartPointer data = createPlane (coefs); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + // actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetLighting (false); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } +} + +void temp_viz::Viz3d::VizImpl::showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt) +{ + // Check if this Id already exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + + // If it exists just update + if (exists) + { + vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); + reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coefs, pt)); + actor->Modified (); + } + else + { + // Create a plane + vtkSmartPointer data = createPlane (coefs, pt); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + // actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetLighting (false); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } +} + + bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 1ea8368af..7abb00d10 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -1088,62 +1088,6 @@ bool temp_viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, return (true); } - -//////////////////////////////////////////////////////////////////////////////////////////// -/** \brief Add a plane from a set of given model coefficients - * \param coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0) - * \param id the plane id/name (default: "plane") - * \param viewport (optional) the id of the new viewport (default: 0) - */ -bool temp_viz::Viz3d::VizImpl::addPlane (const temp_viz::ModelCoefficients &coefficients, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addPlane] A shape with id <"< already exists! Please choose a different id and retry." << std::endl; - return (false); - } - - vtkSmartPointer data = createPlane (coefficients); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - // actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetLighting (false); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - -bool temp_viz::Viz3d::VizImpl::addPlane (const temp_viz::ModelCoefficients &coefficients, double x, double y, double z, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addPlane] A shape with id <" << id << "> already exists! Please choose a different id and retry.\n" << std::endl; - return (false); - } - - vtkSmartPointer data = createPlane (coefficients, x, y, z); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetLighting (false); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - ///////////////////////////////////////////////////////////////////////////////////////////// bool temp_viz::Viz3d::VizImpl::addCircle (const temp_viz::ModelCoefficients &coefficients, const std::string &id) { diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index e74ee1301..17a6dc476 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -93,19 +93,25 @@ TEST(Viz_viz3d, accuracy) int col_green = 0; int col_red = 0; + v.showPlane("plane1", cv::Vec4f(1.0f,1.0f,1.0f,1.0f)); + while(!v.wasStopped()) { // Creating new point cloud with id cloud1 cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); v.showPointCloud("cloud1", cloud, temp_viz::Color(col_blue, col_green, col_red), cloudPosition); v.showLine("line1", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); - + v.showLine("line2", cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0f-pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); + v.showLine("line3", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, 1.0f-pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); + v.showLine("line4", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, 1.0f-pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); + v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z)); + angle_x += 0.1f; angle_y -= 0.1f; angle_z += 0.1f; pos_x = std::sin(angle_x); - pos_y = std::sin(angle_x); - pos_z = std::sin(angle_x); + pos_y = std::sin(angle_y); + pos_z = std::sin(angle_z); col_blue = int(angle_x * 10) % 256; col_green = int(angle_x * 20) % 256; col_red = int(angle_x * 30) % 256; From 93fe2f6e4d20b38d5e0a43c38adced41912bbc24 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 21 Jun 2013 14:09:12 +0200 Subject: [PATCH 025/205] showPlane with color --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 ++-- modules/viz/src/q/viz3d_impl.hpp | 4 ++-- modules/viz/src/viz3d.cpp | 8 ++++---- modules/viz/src/viz3d_impl.cpp | 16 ++++++++++++---- modules/viz/test/test_viz3d.cpp | 4 +--- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 9d0e60f68..806f78247 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -33,8 +33,8 @@ namespace temp_viz bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); void showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); - void showPlane(const String &id, const Vec4f &coefs); - void showPlane(const String &id, const Vec4f &coefs, const Point3f &pt); + void showPlane(const String &id, const Vec4f &coefs, const Color &color); + void showPlane(const String &id, const Vec4f &coefs, const Point3f &pt, const Color &color); bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index bff67e71f..fb1855de9 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -139,8 +139,8 @@ public: } void showLine (const String &id, const cv::Point3f &pt1, const cv::Point3f &pt2, const Color &color); - void showPlane (const String &id, const cv::Vec4f &coefs); - void showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt); + void showPlane (const String &id, const cv::Vec4f &coefs, const Color &color); + void showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt, const Color &color); bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 5f0342a40..ec8cf73c9 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -83,14 +83,14 @@ void temp_viz::Viz3d::showLine(const String &id, const Point3f &pt1, const Point impl_->showLine(id, pt1, pt2, color); } -void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs) +void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs, const Color &color) { - impl_->showPlane(id, coefs); + impl_->showPlane(id, coefs, color); } -void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs, const Point3f &pt) +void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs, const Point3f &pt, const Color &color) { - impl_->showPlane(id, coefs, pt); + impl_->showPlane(id, coefs, pt, color); } bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 15938f820..dfa64d931 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -302,17 +302,19 @@ void temp_viz::Viz3d::VizImpl::showLine (const String &id, const cv::Point3f &pt } } -void temp_viz::Viz3d::VizImpl::showPlane (const String &id, const cv::Vec4f &coefs) +void temp_viz::Viz3d::VizImpl::showPlane (const String &id, const cv::Vec4f &coefs, const Color &color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); bool exists = (am_it != shape_actor_map_->end()); - + Color c = vtkcolor(color); // If it exists just update if (exists) { vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coefs)); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); actor->Modified (); } else @@ -326,6 +328,8 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String &id, const cv::Vec4f &coe // actor->GetProperty ()->SetRepresentationToWireframe (); actor->GetProperty ()->SetRepresentationToSurface (); actor->GetProperty ()->SetLighting (false); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); renderer_->AddActor(actor); // Save the pointer/ID pair to the global actor map @@ -333,17 +337,19 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String &id, const cv::Vec4f &coe } } -void temp_viz::Viz3d::VizImpl::showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt) +void temp_viz::Viz3d::VizImpl::showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt, const Color &color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); bool exists = (am_it != shape_actor_map_->end()); - + Color c = vtkcolor(color); // If it exists just update if (exists) { vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coefs, pt)); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); actor->Modified (); } else @@ -357,6 +363,8 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String &id ,const cv::Vec4f &coe // actor->GetProperty ()->SetRepresentationToWireframe (); actor->GetProperty ()->SetRepresentationToSurface (); actor->GetProperty ()->SetLighting (false); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); renderer_->AddActor(actor); // Save the pointer/ID pair to the global actor map diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 17a6dc476..3d3d2c108 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -93,8 +93,6 @@ TEST(Viz_viz3d, accuracy) int col_green = 0; int col_red = 0; - v.showPlane("plane1", cv::Vec4f(1.0f,1.0f,1.0f,1.0f)); - while(!v.wasStopped()) { // Creating new point cloud with id cloud1 @@ -104,7 +102,7 @@ TEST(Viz_viz3d, accuracy) v.showLine("line2", cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0f-pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); v.showLine("line3", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, 1.0f-pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); v.showLine("line4", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, 1.0f-pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); - v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z)); + v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z), temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); angle_x += 0.1f; angle_y -= 0.1f; From 55683e7b3b9e84e40f03fc25ef86e7e1f04477c6 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 26 Jun 2013 10:46:26 +0200 Subject: [PATCH 026/205] showCube implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/q/viz3d_impl.hpp | 1 + modules/viz/src/viz3d.cpp | 5 ++++ modules/viz/src/viz3d_impl.cpp | 35 +++++++++++++++++++++++ modules/viz/test/test_viz3d.cpp | 1 + 5 files changed, 43 insertions(+) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 806f78247..624798b81 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -35,6 +35,7 @@ namespace temp_viz void showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); void showPlane(const String &id, const Vec4f &coefs, const Color &color); void showPlane(const String &id, const Vec4f &coefs, const Point3f &pt, const Color &color); + void showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index fb1855de9..3ba3e19ca 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -141,6 +141,7 @@ public: void showLine (const String &id, const cv::Point3f &pt1, const cv::Point3f &pt2, const Color &color); void showPlane (const String &id, const cv::Vec4f &coefs, const Color &color); void showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt, const Color &color); + void showCube (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index ec8cf73c9..c5bd70c8d 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -93,6 +93,11 @@ void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs, const Poin impl_->showPlane(id, coefs, pt, color); } +void temp_viz::Viz3d::showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +{ + impl_->showCube(id, pt1, pt2, color); +} + bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) { return impl_->removeCoordinateSystem(id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index dfa64d931..6c32a5529 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -372,6 +372,41 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String &id ,const cv::Vec4f &coe } } +void temp_viz::Viz3d::VizImpl::showCube (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +{ + // Check if this Id already exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + Color c = vtkcolor(color); + // If it exists just update + if (exists) + { + vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); + reinterpret_cast(actor->GetMapper ())->SetInput(createCube(pt1, pt2)); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->Modified (); + } + else + { + // Create a plane + vtkSmartPointer data = createCube (pt1, pt2); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + // actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetLighting (false); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } +} + bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 3d3d2c108..4c3490ce0 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -103,6 +103,7 @@ TEST(Viz_viz3d, accuracy) v.showLine("line3", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, 1.0f-pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); v.showLine("line4", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, 1.0f-pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z), temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); + v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); angle_x += 0.1f; angle_y -= 0.1f; From 98edabd42cee3b0d336a4edf0ffb86c8e930174a Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 26 Jun 2013 11:13:34 +0200 Subject: [PATCH 027/205] showCylinder implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 9 +++--- modules/viz/src/q/viz3d_impl.hpp | 1 + modules/viz/src/viz3d.cpp | 5 ++++ modules/viz/src/viz3d_impl.cpp | 34 +++++++++++++++++++++++ modules/viz/test/test_viz3d.cpp | 2 ++ 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 624798b81..3db89969b 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -32,10 +32,11 @@ namespace temp_viz bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); - void showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); - void showPlane(const String &id, const Vec4f &coefs, const Color &color); - void showPlane(const String &id, const Vec4f &coefs, const Point3f &pt, const Color &color); - void showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); + void showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); + void showPlane(const String &id, const Vec4f &coefs, const Color &color = Color(255,255,255)); + void showPlane(const String &id, const Vec4f &coefs, const Point3f &pt, const Color &color = Color(255,255,255)); + void showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); + void showCylinder(const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color = Color(255,255,255)); bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 3ba3e19ca..07e7508a1 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -142,6 +142,7 @@ public: void showPlane (const String &id, const cv::Vec4f &coefs, const Color &color); void showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt, const Color &color); void showCube (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); + void showCylinder (const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color); bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index c5bd70c8d..c9bf0d920 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -98,6 +98,11 @@ void temp_viz::Viz3d::showCube(const String &id, const Point3f &pt1, const Point impl_->showCube(id, pt1, pt2, color); } +void temp_viz::Viz3d::showCylinder(const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color) +{ + impl_->showCylinder(id, pt_on_axis, axis_direction, radius, num_sides, color); +} + bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) { return impl_->removeCoordinateSystem(id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 6c32a5529..63187c52d 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -407,6 +407,40 @@ void temp_viz::Viz3d::VizImpl::showCube (const String &id, const Point3f &pt1, c } } +void temp_viz::Viz3d::VizImpl::showCylinder (const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color) +{ + // Check if this Id already exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + Color c = vtkcolor(color); + // If it exists just update + if (exists) + { + vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); + reinterpret_cast(actor->GetMapper ())->SetInput(createCylinder(pt_on_axis, axis_direction, radius, num_sides)); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->Modified (); + } + else + { + // Create a plane + vtkSmartPointer data = createCylinder(pt_on_axis, axis_direction, radius, num_sides); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + // actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetLighting (false); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } +} bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 4c3490ce0..1fd51318e 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -104,6 +104,8 @@ TEST(Viz_viz3d, accuracy) v.showLine("line4", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, 1.0f-pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z), temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); + v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); + angle_x += 0.1f; angle_y -= 0.1f; From fd6eeac6aa692a9c1a2e3e38f7a8080b87039afe Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 26 Jun 2013 11:32:12 +0200 Subject: [PATCH 028/205] showCylinder and showCircle implementations --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/q/viz3d_impl.hpp | 1 + modules/viz/src/viz3d.cpp | 5 ++++ modules/viz/src/viz3d_impl.cpp | 35 +++++++++++++++++++++++ modules/viz/test/test_viz3d.cpp | 2 +- 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 3db89969b..0f5937a7b 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -37,6 +37,7 @@ namespace temp_viz void showPlane(const String &id, const Vec4f &coefs, const Point3f &pt, const Color &color = Color(255,255,255)); void showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); void showCylinder(const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color = Color(255,255,255)); + void showCircle(const String &id, const Point3f &pt, double radius, const Color &color = Color(255,255,255)); bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 07e7508a1..e5a6cbaa1 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -143,6 +143,7 @@ public: void showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt, const Color &color); void showCube (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); void showCylinder (const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color); + void showCircle (const String &id, const Point3f &pt, double radius, const Color &color); bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index c9bf0d920..887d10062 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -103,6 +103,11 @@ void temp_viz::Viz3d::showCylinder(const String &id, const Point3f &pt_on_axis, impl_->showCylinder(id, pt_on_axis, axis_direction, radius, num_sides, color); } +void temp_viz::Viz3d::showCircle(const String &id, const Point3f &pt, double radius, const Color &color) +{ + impl_->showCircle(id, pt, radius, color); +} + bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) { return impl_->removeCoordinateSystem(id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 63187c52d..0c9718f57 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -442,6 +442,41 @@ void temp_viz::Viz3d::VizImpl::showCylinder (const String &id, const Point3f &pt } } +void temp_viz::Viz3d::VizImpl::showCircle (const String &id, const Point3f &pt, double radius, const Color &color) +{ + // Check if this Id already exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + Color c = vtkcolor(color); + // If it exists just update + if (exists) + { + vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); + reinterpret_cast(actor->GetMapper ())->SetInput(create2DCircle(pt, radius)); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->Modified (); + } + else + { + // Create a plane + vtkSmartPointer data = create2DCircle(pt, radius); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + // actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetLighting (false); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } +} + bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 1fd51318e..1d09a1644 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -105,7 +105,7 @@ TEST(Viz_viz3d, accuracy) v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z), temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); - + v.showCircle("circle1", cv::Point3f(0,0,0), fabs(pos_x), temp_viz::Color(0,255,0)); angle_x += 0.1f; angle_y -= 0.1f; From 17bdc29d5b3271056c9b4f85fff1a35e1bb920cf Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 26 Jun 2013 12:52:43 +0200 Subject: [PATCH 029/205] setShapePose and getShapePose implementations --- modules/viz/include/opencv2/viz/viz3d.hpp | 3 ++ modules/viz/src/q/viz3d_impl.hpp | 3 ++ modules/viz/src/viz3d.cpp | 10 +++++ modules/viz/src/viz3d_impl.cpp | 45 +++++++++++++++++++++++ modules/viz/src/viz_main.cpp | 7 ++++ modules/viz/test/test_viz3d.cpp | 19 +++++----- 6 files changed, 78 insertions(+), 9 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 0f5937a7b..386d71141 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -38,6 +38,9 @@ namespace temp_viz void showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); void showCylinder(const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color = Color(255,255,255)); void showCircle(const String &id, const Point3f &pt, double radius, const Color &color = Color(255,255,255)); + + Affine3f getShapePose(const String &id); + bool setShapePose(const String &id, const Affine3f &pose); bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index e5a6cbaa1..29c3de624 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -144,6 +144,8 @@ public: void showCube (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); void showCylinder (const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color); void showCircle (const String &id, const Point3f &pt, double radius, const Color &color); + Affine3f getShapePose (const String &id); + bool setShapePose (const String &id, const Affine3f &pose); bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); @@ -422,6 +424,7 @@ private: //void convertToVtkMatrix (const Eigen::Matrix4f &m, vtkSmartPointer &vtk_matrix); void convertToVtkMatrix (const cv::Matx44f& m, vtkSmartPointer &vtk_matrix); +void convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m); /** \brief Convert origin and orientation to vtkMatrix4x4 * \param[in] origin the point cloud origin diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 887d10062..5aa0fe20c 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -108,6 +108,16 @@ void temp_viz::Viz3d::showCircle(const String &id, const Point3f &pt, double rad impl_->showCircle(id, pt, radius, color); } +cv::Affine3f temp_viz::Viz3d::getShapePose(const String &id) +{ + return impl_->getShapePose(id); +} + +bool temp_viz::Viz3d::setShapePose(const String &id, const Affine3f &pose) +{ + return impl_->setShapePose(id, pose); +} + bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) { return impl_->removeCoordinateSystem(id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 0c9718f57..0a93e9c6b 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -477,6 +477,51 @@ void temp_viz::Viz3d::VizImpl::showCircle (const String &id, const Point3f &pt, } } +cv::Affine3f temp_viz::Viz3d::VizImpl::getShapePose (const String &id) +{ + // Get the shape with the id and return the pose + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + + if (!exists) + { + std::cout << "[getShapePose] A shape with id " << id << " does not exist!" << std::endl; + return Affine3f(); + } + + vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + + Matx44f pose_mat; + convertToCvMatrix(matrix, pose_mat); + + Affine3f pose; + pose.matrix = pose_mat; + return pose; +} + +bool temp_viz::Viz3d::VizImpl::setShapePose (const String &id, const Affine3f &pose) +{ + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + + if (!exists) + { + return false; + } + + vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second); + vtkSmartPointer matrix = vtkSmartPointer::New (); + + convertToVtkMatrix (pose.matrix, matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); + + return (true); +} + bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 7abb00d10..a55247b7b 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -1335,6 +1335,13 @@ void temp_viz::convertToVtkMatrix (const cv::Matx44f &m, vtkSmartPointerSetElement (i, k, m (i, k)); } +void temp_viz::convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m) +{ + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + m(i,k) = vtk_matrix->GetElement (i, k); +} + ////////////////////////////////////////////////////////////////////////////////////////////// void temp_viz::convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m) { diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 1d09a1644..5307c4ad7 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -92,20 +92,21 @@ TEST(Viz_viz3d, accuracy) int col_blue = 0; int col_green = 0; int col_red = 0; + v.showCircle("circle1", cv::Point3f(0,0,0), fabs(1.0f), temp_viz::Color(0,255,0)); while(!v.wasStopped()) { // Creating new point cloud with id cloud1 cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); - v.showPointCloud("cloud1", cloud, temp_viz::Color(col_blue, col_green, col_red), cloudPosition); - v.showLine("line1", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); - v.showLine("line2", cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0f-pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); - v.showLine("line3", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, 1.0f-pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); - v.showLine("line4", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, 1.0f-pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); - v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z), temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); - v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); - v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); - v.showCircle("circle1", cv::Point3f(0,0,0), fabs(pos_x), temp_viz::Color(0,255,0)); +// v.showPointCloud("cloud1", cloud, temp_viz::Color(col_blue, col_green, col_red), cloudPosition); +// v.showLine("line1", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); +// v.showLine("line2", cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0f-pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); +// v.showLine("line3", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, 1.0f-pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); +// v.showLine("line4", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, 1.0f-pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); +// v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z), temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); +// v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); +// v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); + v.setShapePose("circle1", cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; From c4a07b7531c06a64a58e93be97b41bd20d902a91 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 27 Jun 2013 11:51:36 +0300 Subject: [PATCH 030/205] createSphere and showSphere implementations --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/q/shapes.h | 1 + modules/viz/src/q/viz3d_impl.hpp | 2 ++ modules/viz/src/shapes.cpp | 13 ++++++++ modules/viz/src/viz3d.cpp | 5 +++ modules/viz/src/viz3d_impl.cpp | 37 ++++++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 4 ++- 7 files changed, 61 insertions(+), 2 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 386d71141..3a1a14a75 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -38,6 +38,7 @@ namespace temp_viz void showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); void showCylinder(const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color = Color(255,255,255)); void showCircle(const String &id, const Point3f &pt, double radius, const Color &color = Color(255,255,255)); + void showSphere (const String &id, const Point3f &pt, double radius, const Color &color = Color(255,255,255)); Affine3f getShapePose(const String &id); bool setShapePose(const String &id, const Affine3f &pose); diff --git a/modules/viz/src/q/shapes.h b/modules/viz/src/q/shapes.h index 9233ec45f..e0665e056 100644 --- a/modules/viz/src/q/shapes.h +++ b/modules/viz/src/q/shapes.h @@ -13,6 +13,7 @@ namespace temp_viz CV_EXPORTS vtkSmartPointer createPlane (const Vec4f& coefs, const Point3f& pt); CV_EXPORTS vtkSmartPointer create2DCircle (const Point3f& pt, double radius); CV_EXPORTS vtkSmartPointer createCube(const Point3f& pt_min, const Point3f& pt_max); + CV_EXPORTS vtkSmartPointer createSphere (const Point3f& pt, double radius); // CV_EXPORTS vtkSmartPointer createCube (const Point3f& pt, const Quaternionf& qt, ); // CV_EXPORTS vtkSmartPointer createCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation, double width, double height, double depth); // CV_EXPORTS vtkSmartPointer createCube (double x_min, double x_max, double y_min, double y_max, double z_min, double z_max); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 29c3de624..2b768949f 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -144,6 +144,8 @@ public: void showCube (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); void showCylinder (const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color); void showCircle (const String &id, const Point3f &pt, double radius, const Color &color); + void showSphere (const String &id, const Point3f &pt, double radius, const Color &color); + Affine3f getShapePose (const String &id); bool setShapePose (const String &id, const Affine3f &pose); diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index baa4cbde3..586b6b5a1 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -71,6 +71,19 @@ vtkSmartPointer temp_viz::createCube(const cv::Point3f& pt_min, cons return (cube->GetOutput ()); } +vtkSmartPointer temp_viz::createSphere (const Point3f& pt, double radius) +{ + vtkSmartPointer sphere = vtkSmartPointer::New (); + sphere->SetRadius (radius); + sphere->SetCenter (pt.x, pt.y, pt.z); + sphere->SetPhiResolution (10); + sphere->SetThetaResolution (10); + sphere->LatLongTessellationOff (); + sphere->Update (); + + return (sphere->GetOutput ()); +} + //////////////////////////////////////////////////////////////////////////////////////////// vtkSmartPointer temp_viz::createCylinder (const temp_viz::ModelCoefficients &coefficients, int numsides) { diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 5aa0fe20c..d209ae5d2 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -108,6 +108,11 @@ void temp_viz::Viz3d::showCircle(const String &id, const Point3f &pt, double rad impl_->showCircle(id, pt, radius, color); } +void temp_viz::Viz3d::showSphere (const String &id, const Point3f &pt, double radius, const Color &color) +{ + impl_->showSphere(id, pt, radius, color); +} + cv::Affine3f temp_viz::Viz3d::getShapePose(const String &id) { return impl_->getShapePose(id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 0a93e9c6b..f9d1ff40e 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -477,6 +477,41 @@ void temp_viz::Viz3d::VizImpl::showCircle (const String &id, const Point3f &pt, } } +void temp_viz::Viz3d::VizImpl::showSphere (const String &id, const Point3f &pt, double radius, const Color &color) +{ + // Check if this Id already exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + Color c = vtkcolor(color); + // If it exists just update + if (exists) + { + vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); + reinterpret_cast(actor->GetMapper ())->SetInput(createSphere(pt, radius)); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->Modified (); + } + else + { + // Create a plane + vtkSmartPointer data = createSphere(pt, radius); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + // actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetLighting (false); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } +} + cv::Affine3f temp_viz::Viz3d::VizImpl::getShapePose (const String &id) { // Get the shape with the id and return the pose @@ -485,7 +520,7 @@ cv::Affine3f temp_viz::Viz3d::VizImpl::getShapePose (const String &id) if (!exists) { - std::cout << "[getShapePose] A shape with id " << id << " does not exist!" << std::endl; + std::cout << "[getShapePose] A shape with id <" << id << "> does not exist!" << std::endl; return Affine3f(); } diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 5307c4ad7..fa1d60486 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -92,7 +92,8 @@ TEST(Viz_viz3d, accuracy) int col_blue = 0; int col_green = 0; int col_red = 0; - v.showCircle("circle1", cv::Point3f(0,0,0), fabs(1.0f), temp_viz::Color(0,255,0)); + v.showCircle("circle1", cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); + v.showSphere("sphere1", cv::Point3f(0,0,0), 0.5, temp_viz::Color(0,0,255)); while(!v.wasStopped()) { @@ -107,6 +108,7 @@ TEST(Viz_viz3d, accuracy) // v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); // v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); v.setShapePose("circle1", cloudPosition); + v.setShapePose("sphere1", cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; From 4a19ff3a7c1a65d99fa974800d2b2011f31b5975 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 27 Jun 2013 12:33:19 +0300 Subject: [PATCH 031/205] createArrow and showArrow implementation without label --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/precomp.hpp | 1 + modules/viz/src/q/shapes.h | 1 + modules/viz/src/q/viz3d_impl.hpp | 1 + modules/viz/src/shapes.cpp | 55 +++++++++++++++++++++++ modules/viz/src/viz3d.cpp | 5 +++ modules/viz/src/viz3d_impl.cpp | 36 +++++++++++++++ modules/viz/test/test_viz3d.cpp | 2 + 8 files changed, 102 insertions(+) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 3a1a14a75..2b3e6e734 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -39,6 +39,7 @@ namespace temp_viz void showCylinder(const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color = Color(255,255,255)); void showCircle(const String &id, const Point3f &pt, double radius, const Color &color = Color(255,255,255)); void showSphere (const String &id, const Point3f &pt, double radius, const Color &color = Color(255,255,255)); + void showArrow (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); Affine3f getShapePose(const String &id); bool setShapePose(const String &id, const Affine3f &pose); diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 9076a3bb4..de7104455 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/modules/viz/src/q/shapes.h b/modules/viz/src/q/shapes.h index e0665e056..1ebc6ae80 100644 --- a/modules/viz/src/q/shapes.h +++ b/modules/viz/src/q/shapes.h @@ -14,6 +14,7 @@ namespace temp_viz CV_EXPORTS vtkSmartPointer create2DCircle (const Point3f& pt, double radius); CV_EXPORTS vtkSmartPointer createCube(const Point3f& pt_min, const Point3f& pt_max); CV_EXPORTS vtkSmartPointer createSphere (const Point3f& pt, double radius); + CV_EXPORTS vtkSmartPointer createArrow (const Point3f& pt1, const Point3f& pt2); // CV_EXPORTS vtkSmartPointer createCube (const Point3f& pt, const Quaternionf& qt, ); // CV_EXPORTS vtkSmartPointer createCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation, double width, double height, double depth); // CV_EXPORTS vtkSmartPointer createCube (double x_min, double x_max, double y_min, double y_max, double z_min, double z_max); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 2b768949f..50d50bb2c 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -145,6 +145,7 @@ public: void showCylinder (const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color); void showCircle (const String &id, const Point3f &pt, double radius, const Color &color); void showSphere (const String &id, const Point3f &pt, double radius, const Color &color); + void showArrow (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); Affine3f getShapePose (const String &id); bool setShapePose (const String &id, const Affine3f &pose); diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index 586b6b5a1..3f9fcd23e 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -84,6 +84,61 @@ vtkSmartPointer temp_viz::createSphere (const Point3f& pt, double ra return (sphere->GetOutput ()); } +vtkSmartPointer temp_viz::createArrow (const Point3f& pt1, const Point3f& pt2) +{ + vtkSmartPointer arrowSource = vtkSmartPointer::New (); + + float startPoint[3], endPoint[3]; + startPoint[0] = pt1.x; + startPoint[1] = pt1.y; + startPoint[2] = pt1.z; + endPoint[0] = pt2.x; + endPoint[1] = pt2.y; + endPoint[2] = pt2.z; + float normalizedX[3], normalizedY[3], normalizedZ[3]; + + // The X axis is a vector from start to end + vtkMath::Subtract(endPoint, startPoint, normalizedX); + float length = vtkMath::Norm(normalizedX); + vtkMath::Normalize(normalizedX); + + // The Z axis is an arbitrary vecotr cross X + float arbitrary[3]; + arbitrary[0] = vtkMath::Random(-10,10); + arbitrary[1] = vtkMath::Random(-10,10); + arbitrary[2] = vtkMath::Random(-10,10); + vtkMath::Cross(normalizedX, arbitrary, normalizedZ); + vtkMath::Normalize(normalizedZ); + + // The Y axis is Z cross X + vtkMath::Cross(normalizedZ, normalizedX, normalizedY); + vtkSmartPointer matrix = vtkSmartPointer::New(); + + // Create the direction cosine matrix + matrix->Identity(); + for (unsigned int i = 0; i < 3; i++) + { + matrix->SetElement(i, 0, normalizedX[i]); + matrix->SetElement(i, 1, normalizedY[i]); + matrix->SetElement(i, 2, normalizedZ[i]); + } + + // Apply the transforms + vtkSmartPointer transform = + vtkSmartPointer::New(); + transform->Translate(startPoint); + transform->Concatenate(matrix); + transform->Scale(length, length, length); + + // Transform the polydata + vtkSmartPointer transformPD = + vtkSmartPointer::New(); + transformPD->SetTransform(transform); + transformPD->SetInputConnection(arrowSource->GetOutputPort()); + + return (transformPD->GetOutput()); +} + //////////////////////////////////////////////////////////////////////////////////////////// vtkSmartPointer temp_viz::createCylinder (const temp_viz::ModelCoefficients &coefficients, int numsides) { diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index d209ae5d2..65d036d9e 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -113,6 +113,11 @@ void temp_viz::Viz3d::showSphere (const String &id, const Point3f &pt, double ra impl_->showSphere(id, pt, radius, color); } +void temp_viz::Viz3d::showArrow (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +{ + impl_->showArrow(id,pt1,pt2,color); +} + cv::Affine3f temp_viz::Viz3d::getShapePose(const String &id) { return impl_->getShapePose(id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index f9d1ff40e..af564b34c 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -512,6 +512,42 @@ void temp_viz::Viz3d::VizImpl::showSphere (const String &id, const Point3f &pt, } } +void temp_viz::Viz3d::VizImpl::showArrow (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +{ + // Check if this Id already exists + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + bool exists = (am_it != shape_actor_map_->end()); + Color c = vtkcolor(color); + + // If it exists just update + if (exists) + { + vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); + reinterpret_cast(actor->GetMapper ())->SetInput(createArrow(pt1,pt2)); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->Modified (); + } + else + { + // Create a plane + vtkSmartPointer data = createArrow(pt1,pt2); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + // actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetRepresentationToSurface (); + actor->GetProperty ()->SetLighting (false); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + renderer_->AddActor(actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } +} + cv::Affine3f temp_viz::Viz3d::VizImpl::getShapePose (const String &id) { // Get the shape with the id and return the pose diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index fa1d60486..8a7472c51 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -94,6 +94,7 @@ TEST(Viz_viz3d, accuracy) int col_red = 0; v.showCircle("circle1", cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); v.showSphere("sphere1", cv::Point3f(0,0,0), 0.5, temp_viz::Color(0,0,255)); + v.showArrow("arrow1", cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); while(!v.wasStopped()) { @@ -109,6 +110,7 @@ TEST(Viz_viz3d, accuracy) // v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); v.setShapePose("circle1", cloudPosition); v.setShapePose("sphere1", cloudPosition); + v.setShapePose("arrow1", cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; From 1830059969d6aa20b51d668c2e77b1971b504116 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 27 Jun 2013 13:05:52 +0300 Subject: [PATCH 032/205] removed redundant addShape methods --- modules/viz/src/q/shapes.h | 113 -------------------- modules/viz/src/q/viz3d_impl.hpp | 78 -------------- modules/viz/src/shapes.cpp | 172 ------------------------------- modules/viz/src/viz3d.cpp | 5 - modules/viz/src/viz3d_impl.cpp | 66 ------------ modules/viz/src/viz_main.cpp | 130 ----------------------- 6 files changed, 564 deletions(-) diff --git a/modules/viz/src/q/shapes.h b/modules/viz/src/q/shapes.h index 1ebc6ae80..be83cd59e 100644 --- a/modules/viz/src/q/shapes.h +++ b/modules/viz/src/q/shapes.h @@ -15,119 +15,6 @@ namespace temp_viz CV_EXPORTS vtkSmartPointer createCube(const Point3f& pt_min, const Point3f& pt_max); CV_EXPORTS vtkSmartPointer createSphere (const Point3f& pt, double radius); CV_EXPORTS vtkSmartPointer createArrow (const Point3f& pt1, const Point3f& pt2); -// CV_EXPORTS vtkSmartPointer createCube (const Point3f& pt, const Quaternionf& qt, ); -// CV_EXPORTS vtkSmartPointer createCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation, double width, double height, double depth); -// CV_EXPORTS vtkSmartPointer createCube (double x_min, double x_max, double y_min, double y_max, double z_min, double z_max); -// -// - /** \brief Create a cylinder shape from a set of model coefficients. - * \param[in] coefficients the model coefficients (point_on_axis, axis_direction, radius) - * \param[in] numsides (optional) the number of sides used for rendering the cylinder - * - * \code - * // The following are given (or computed using sample consensus techniques -- see SampleConsensusModelCylinder) - * // Eigen::Vector3f pt_on_axis, axis_direction; - * // float radius; - * - * temp_viz::ModelCoefficients cylinder_coeff; - * cylinder_coeff.values.resize (7); // We need 7 values - * cylinder_coeff.values[0] = pt_on_axis.x (); - * cylinder_coeff.values[1] = pt_on_axis.y (); - * cylinder_coeff.values[2] = pt_on_axis.z (); - * - * cylinder_coeff.values[3] = axis_direction.x (); - * cylinder_coeff.values[4] = axis_direction.y (); - * cylinder_coeff.values[5] = axis_direction.z (); - * - * cylinder_coeff.values[6] = radius; - * - * vtkSmartPointer data = temp_viz::createCylinder (cylinder_coeff, numsides); - * \endcode - * - * \ingroup visualization - */ - CV_EXPORTS vtkSmartPointer createCylinder (const temp_viz::ModelCoefficients &coefficients, int numsides = 30); - - - /** \brief Create a planar shape from a set of model coefficients. - * \param[in] coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0) - * - * \code - * // The following are given (or computed using sample consensus techniques -- see SampleConsensusModelPlane) - * // Eigen::Vector4f plane_parameters; - * - * temp_viz::ModelCoefficients plane_coeff; - * plane_coeff.values.resize (4); // We need 4 values - * plane_coeff.values[0] = plane_parameters.x (); - * plane_coeff.values[1] = plane_parameters.y (); - * plane_coeff.values[2] = plane_parameters.z (); - * plane_coeff.values[3] = plane_parameters.w (); - * - * vtkSmartPointer data = temp_viz::createPlane (plane_coeff); - * \endcode - * - * \ingroup visualization - */ - CV_EXPORTS vtkSmartPointer createPlane (const temp_viz::ModelCoefficients &coefficients); - - /** \brief Create a planar shape from a set of model coefficients. - * \param[in] coefficients the model coefficients (a, b, c, d with ax+by+cz+d=0) - * \param[in] x,y,z projection of this point on the plane is used to get the center of the plane. - * \ingroup visualization - */ - CV_EXPORTS vtkSmartPointer createPlane (const temp_viz::ModelCoefficients &coefficients, double x, double y, double z); - - /** \brief Create a 2d circle shape from a set of model coefficients. - * \param[in] coefficients the model coefficients (x, y, radius) - * \param[in] z (optional) specify a z value (default: 0) - * - * \code - * // The following are given (or computed using sample consensus techniques -- see SampleConsensusModelCircle2D) - * // float x, y, radius; - * - * temp_viz::ModelCoefficients circle_coeff; - * circle_coeff.values.resize (3); // We need 3 values - * circle_coeff.values[0] = x; - * circle_coeff.values[1] = y; - * circle_coeff.values[2] = radius; - * - * vtkSmartPointer data = temp_viz::create2DCircle (circle_coeff, z); - * \endcode - * - * \ingroup visualization - */ - CV_EXPORTS vtkSmartPointer create2DCircle (const temp_viz::ModelCoefficients &coefficients, double z = 0.0); - - - /** \brief Creaet a cube shape from a set of model coefficients. - * \param[in] coefficients the cube coefficients (Tx, Ty, Tz, Qx, Qy, Qz, Qw, width, height, depth) - * \ingroup visualization - */ - CV_EXPORTS vtkSmartPointer createCube (const temp_viz::ModelCoefficients &coefficients); - - /** \brief Creaet a cube shape from a set of model coefficients. - * - * \param[in] translation a translation to apply to the cube from 0,0,0 - * \param[in] rotation a quaternion-based rotation to apply to the cube - * \param[in] width the cube's width - * \param[in] height the cube's height - * \param[in] depth the cube's depth - * \ingroup visualization - */ - CV_EXPORTS vtkSmartPointer createCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation, double width, double height, double depth); - - /** \brief Create a cube from a set of bounding points - * \param[in] x_min is the minimum x value of the box - * \param[in] x_max is the maximum x value of the box - * \param[in] y_min is the minimum y value of the box - * \param[in] y_max is the maximum y value of the box - * \param[in] z_min is the minimum z value of the box - * \param[in] z_max is the maximum z value of the box - * \param[in] id the cube id/name (default: "cube") - * \param[in] viewport (optional) the id of the new viewport (default: 0) - */ - CV_EXPORTS vtkSmartPointer createCube (double x_min, double x_max, double y_min, double y_max, double z_min, double z_max); - /** \brief Allocate a new unstructured grid smartpointer. For internal use only. * \param[out] polydata the resultant unstructured grid. */ diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 50d50bb2c..cf6d7db3b 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -153,8 +153,6 @@ public: bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color_line, const Color& color_text, const std::string &id = "arrow"); - bool addSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id = "sphere"); - bool updateSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id = "sphere"); // Add a vtkPolydata as a mesh bool addModelFromPolyData (vtkSmartPointer polydata, const std::string & id = "PolyData"); @@ -162,82 +160,6 @@ public: bool addModelFromPLYFile (const std::string &filename, const std::string &id = "PLYModel"); bool addModelFromPLYFile (const std::string &filename, vtkSmartPointer transform, const std::string &id = "PLYModel"); - /** \brief Add a cylinder from a set of given model coefficients - * \param[in] coefficients the model coefficients (point_on_axis, axis_direction, radius) - * \param[in] id the cylinder id/name (default: "cylinder") - * - * \code - * // The following are given (or computed using sample consensus techniques) - * // See SampleConsensusModelCylinder for more information. - * // float radius; - * - * temp_viz::ModelCoefficients cylinder_coeff; - * cylinder_coeff.values.resize (7); // We need 7 values - * cylinder_coeff.values[0] = pt_on_axis.x (); - * cylinder_coeff.values[1] = pt_on_axis.y (); - * cylinder_coeff.values[2] = pt_on_axis.z (); - * - * cylinder_coeff.values[3] = axis_direction.x (); - * cylinder_coeff.values[4] = axis_direction.y (); - * cylinder_coeff.values[5] = axis_direction.z (); - * - * cylinder_coeff.values[6] = radius; - * - * addCylinder (cylinder_coeff); - * \endcode - */ - bool addCylinder (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "cylinder"); - - /** \brief Add a circle from a set of given model coefficients - * \param[in] coefficients the model coefficients (x, y, radius) - * \param[in] id the circle id/name (default: "circle") - * - * \code - * // The following are given (or computed using sample consensus techniques) - * // See SampleConsensusModelCircle2D for more information - * // float x, y, radius; - * - * temp_viz::ModelCoefficients circle_coeff; - * circle_coeff.values.resize (3); // We need 3 values - * circle_coeff.values[0] = x; - * circle_coeff.values[1] = y; - * circle_coeff.values[2] = radius; - * - * vtkSmartPointer data = temp_viz::create2DCircle (circle_coeff, z); - * \endcode - */ - bool addCircle (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "circle"); - - /** \brief Add a cube from a set of given model coefficients - * \param[in] coefficients the model coefficients (Tx, Ty, Tz, Qx, Qy, Qz, Qw, width, height, depth) - * \param[in] id the cube id/name (default: "cube") - */ - bool addCube (const temp_viz::ModelCoefficients &coefficients, const std::string &id = "cube"); - - /** \brief Add a cube from a set of given model coefficients - * \param[in] translation a translation to apply to the cube from 0,0,0 - * \param[in] rotation a quaternion-based rotation to apply to the cube - * \param[in] width the cube's width - * \param[in] height the cube's height - * \param[in] depth the cube's depth - * \param[in] id the cube id/name (default: "cube") - */ - bool addCube (const cv::Vec3f& translation, const cv::Vec3f quaternion, double width, double height, double depth, const std::string &id = "cube"); - - /** \brief Add a cube - * \param[in] x_min the min X coordinate - * \param[in] x_max the max X coordinate - * \param[in] y_min the min Y coordinate - * \param[in] y_max the max Y coordinate - * \param[in] z_min the min Z coordinate - * \param[in] z_max the max Z coordinate - * \param[in] r how much red (0.0 -> 1.0) - * \param[in] g how much green (0.0 -> 1.0) - * \param[in] b how much blue (0.0 -> 1.0) - * \param[in] id the cube id/name (default: "cube") - */ - bool addCube (float x_min, float x_max, float y_min, float y_max, float z_min, float z_max, const Color& color, const std::string &id = "cube"); - /** \brief Changes the visual representation for all actors to surface representation. */ void setRepresentationToSurfaceForAllActors (); diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index 3f9fcd23e..362b615df 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -139,178 +139,6 @@ vtkSmartPointer temp_viz::createArrow (const Point3f& pt1, const Poi return (transformPD->GetOutput()); } -//////////////////////////////////////////////////////////////////////////////////////////// -vtkSmartPointer temp_viz::createCylinder (const temp_viz::ModelCoefficients &coefficients, int numsides) -{ - vtkSmartPointer line = vtkSmartPointer::New (); - line->SetPoint1 (coefficients.values[0], coefficients.values[1], coefficients.values[2]); - line->SetPoint2 (coefficients.values[3]+coefficients.values[0], coefficients.values[4]+coefficients.values[1], coefficients.values[5]+coefficients.values[2]); - - vtkSmartPointer tuber = vtkSmartPointer::New (); - tuber->SetInputConnection (line->GetOutputPort ()); - tuber->SetRadius (coefficients.values[6]); - tuber->SetNumberOfSides (numsides); - - return (tuber->GetOutput ()); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -vtkSmartPointer temp_viz::createCube (const temp_viz::ModelCoefficients &coefficients) -{ - // coefficients = [Tx, Ty, Tz, Qx, Qy, Qz, Qw, width, height, depth] - vtkSmartPointer t = vtkSmartPointer::New (); - t->Identity (); - t->Translate (coefficients.values[0], coefficients.values[1], coefficients.values[2]); - - Eigen::AngleAxisf a (Eigen::Quaternionf (coefficients.values[6], coefficients.values[3], - coefficients.values[4], coefficients.values[5])); - t->RotateWXYZ (rad2deg (a.angle ()), a.axis ()[0], a.axis ()[1], a.axis ()[2]); - - vtkSmartPointer cube = vtkSmartPointer::New (); - cube->SetXLength (coefficients.values[7]); - cube->SetYLength (coefficients.values[8]); - cube->SetZLength (coefficients.values[9]); - - vtkSmartPointer tf = vtkSmartPointer::New (); - tf->SetTransform (t); - tf->SetInputConnection (cube->GetOutputPort ()); - - return (tf->GetOutput ()); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -vtkSmartPointer temp_viz::createCube (const Eigen::Vector3f &translation, const Eigen::Quaternionf &rotation, double width, double height, double depth) -{ - // coefficients = [Tx, Ty, Tz, Qx, Qy, Qz, Qw, width, height, depth] - vtkSmartPointer t = vtkSmartPointer::New (); - t->Identity (); - t->Translate (translation.x (), translation.y (), translation.z ()); - - Eigen::AngleAxisf a (rotation); - t->RotateWXYZ (rad2deg (a.angle ()), a.axis ()[0], a.axis ()[1], a.axis ()[2]); - - vtkSmartPointer cube = vtkSmartPointer::New (); - cube->SetXLength (width); - cube->SetYLength (height); - cube->SetZLength (depth); - - vtkSmartPointer tf = vtkSmartPointer::New (); - tf->SetTransform (t); - tf->SetInputConnection (cube->GetOutputPort ()); - - return (tf->GetOutput ()); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -vtkSmartPointer temp_viz::createCube (double x_min, double x_max, double y_min, double y_max, double z_min, double z_max) -{ - vtkSmartPointer t = vtkSmartPointer::New (); - vtkSmartPointer cube = vtkSmartPointer::New (); - cube->SetBounds (x_min, x_max, y_min, y_max, z_min, z_max); - return (cube->GetOutput ()); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -vtkSmartPointer temp_viz::createPlane (const temp_viz::ModelCoefficients &coefficients) -{ - vtkSmartPointer plane = vtkSmartPointer::New (); - plane->SetNormal (coefficients.values[0], coefficients.values[1], coefficients.values[2]); - - double norm_sqr = coefficients.values[0] * coefficients.values[0] - + coefficients.values[1] * coefficients.values[1] - + coefficients.values[2] * coefficients.values[2]; - - plane->Push (-coefficients.values[3] / sqrt(norm_sqr)); - return (plane->GetOutput ()); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -vtkSmartPointer temp_viz::createPlane (const temp_viz::ModelCoefficients &coefficients, double x, double y, double z) -{ - vtkSmartPointer plane = vtkSmartPointer::New (); - - - double norm_sqr = 1.0 / (coefficients.values[0] * coefficients.values[0] + - coefficients.values[1] * coefficients.values[1] + - coefficients.values[2] * coefficients.values[2] ); - -// double nx = coefficients.values [0] * norm; -// double ny = coefficients.values [1] * norm; -// double nz = coefficients.values [2] * norm; -// double d = coefficients.values [3] * norm; - -// plane->SetNormal (nx, ny, nz); - plane->SetNormal (coefficients.values[0], coefficients.values[1], coefficients.values[2]); - - double t = x * coefficients.values[0] + y * coefficients.values[1] + z * coefficients.values[2] + coefficients.values[3]; - x -= coefficients.values[0] * t * norm_sqr; - y -= coefficients.values[1] * t * norm_sqr; - z -= coefficients.values[2] * t * norm_sqr; - plane->SetCenter (x, y, z); - - return (plane->GetOutput ()); -} - - -//////////////////////////////////////////////////////////////////////////////////////////// -vtkSmartPointer temp_viz::create2DCircle (const temp_viz::ModelCoefficients &coefficients, double z) -{ - vtkSmartPointer disk = vtkSmartPointer::New (); - // Maybe the resolution should be lower e.g. 50 or 25 - disk->SetCircumferentialResolution (100); - disk->SetInnerRadius (coefficients.values[2] - 0.001); - disk->SetOuterRadius (coefficients.values[2] + 0.001); - disk->SetCircumferentialResolution (20); - - // An alternative to could be with - /* - vtkSmartPointer circle = vtkSmartPointer::New(); - circle->SetRadius (coefficients.values[2]); - circle->SetNumberOfSides (100); - - vtkSmartPointer tube = vtkSmartPointer::New(); - tube->SetInput (circle->GetOutput()); - tube->SetNumberOfSides (25); - tube->SetRadius (0.001); - */ - - // Set the circle origin - vtkSmartPointer t = vtkSmartPointer::New (); - t->Identity (); - t->Translate (coefficients.values[0], coefficients.values[1], z); - - vtkSmartPointer tf = vtkSmartPointer::New (); - tf->SetTransform (t); - tf->SetInputConnection (disk->GetOutputPort ()); - /* - tf->SetInputConnection (tube->GetOutputPort ()); - */ - - return (tf->GetOutput ()); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -vtkSmartPointer temp_viz::createSphere (const cv::Point3f& center, float radius, int sphere_resolution) -{ - // Set the sphere origin - vtkSmartPointer t = vtkSmartPointer::New (); - t->Identity (); - t->Translate (center.x, center.y, center.z); - - vtkSmartPointer s_sphere = vtkSmartPointer::New (); - s_sphere->SetRadius (radius); - s_sphere->SetPhiResolution (sphere_resolution); - s_sphere->SetThetaResolution (sphere_resolution); - s_sphere->LatLongTessellationOff (); - - vtkSmartPointer tf = vtkSmartPointer::New (); - tf->SetTransform (t); - tf->SetInputConnection (s_sphere->GetOutputPort ()); - tf->Update (); - - return (tf->GetOutput ()); -} - //////////////////////////////////////////////////////////////////////////////////////////// vtkSmartPointer temp_viz::createLine (const cv::Point3f& pt1, const cv::Point3f& pt2) { diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 65d036d9e..bb2974cd3 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -63,11 +63,6 @@ bool temp_viz::Viz3d::addPolygon(const Mat& cloud, const Color& color, const Str return impl_->addPolygon(cloud, color, id); } -bool temp_viz::Viz3d::addSphere (const cv::Point3f ¢er, double radius, const Color& color, const std::string &id) -{ - return impl_->addSphere(center, radius, color, id); -} - void temp_viz::Viz3d::spin() { impl_->spin(); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index af564b34c..a8aedc18e 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -958,72 +958,6 @@ bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3 return (true); } -#include -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addSphere (const cv::Point3f& center, float radius, const Color& color, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addSphere] A shape with id <"< already exists! Please choose a different id and retry." << std::endl, false; - - //vtkSmartPointer data = createSphere (center.getVector4fMap (), radius); - vtkSmartPointer data = vtkSmartPointer::New (); - data->SetRadius (radius); - data->SetCenter (center.x, center.y, center.z); - data->SetPhiResolution (10); - data->SetThetaResolution (10); - data->LatLongTessellationOff (); - data->Update (); - - // Setup actor and mapper - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInputConnection (data->GetOutputPort ()); - - // Create an Actor - vtkSmartPointer actor = vtkSmartPointer::New (); - actor->SetMapper (mapper); - //createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetInterpolationToFlat (); - - Color c = vtkcolor(color); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ImmediateModeRenderingOn (); - actor->GetMapper ()->StaticOn (); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetMapper ()->Update (); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::updateSphere (const cv::Point3f ¢er, float radius, const Color& color, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it == shape_actor_map_->end ()) - return (false); - - ////////////////////////////////////////////////////////////////////////// - // Get the actor pointer - vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second); - vtkAlgorithm *algo = actor->GetMapper ()->GetInput ()->GetProducerPort ()->GetProducer (); - vtkSphereSource *src = vtkSphereSource::SafeDownCast (algo); - - src->SetCenter(center.x, center.y, center.z); - src->SetRadius(radius); - src->Update (); - Color c = vtkcolor(color); - actor->GetProperty ()->SetColor (c.val); - actor->Modified (); - - return (true); -} - ////////////////////////////////////////////////// bool temp_viz::Viz3d::VizImpl::addText3D (const std::string &text, const cv::Point3f& position, const Color& color, double textScale, const std::string &id) { diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index a55247b7b..e03ace635 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -894,111 +894,6 @@ void temp_viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) renderer_->Render (); } - -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addCylinder (const temp_viz::ModelCoefficients &coefficients, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addCylinder] A shape with id <"< already exists! Please choose a different id and retry." << std::endl; - return (false); - } - - vtkSmartPointer data = createCylinder (coefficients); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetLighting (false); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addCube (const temp_viz::ModelCoefficients &coefficients, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addCube] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; - return (false); - } - - vtkSmartPointer data = createCube (coefficients); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetLighting (false); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addCube (const cv::Vec3f& translation, const cv::Vec3f quaternion, double width, double height, double depth, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addCube] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; - return (false); - } - - Eigen::Vector3f t(translation[0], translation[1], translation[2]); - Eigen::Quaternionf q(quaternion[0], quaternion[1], quaternion[2], quaternion[3]); - - vtkSmartPointer data = createCube (t, q, width, height, depth); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetLighting (false); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addCube (float x_min, float x_max, float y_min, float y_max, float z_min, float z_max, - const Color& color , const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addCube] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; - - vtkSmartPointer data = createCube (x_min, x_max, y_min, y_max, z_min, z_max); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetLighting (false); - - Color c = vtkcolor(color); - actor->GetProperty ()->SetColor (c.val); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - //////////////////////////////////////////////////////////////////////////////////////////// bool temp_viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, const std::string & id) { @@ -1088,31 +983,6 @@ bool temp_viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, return (true); } -///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addCircle (const temp_viz::ModelCoefficients &coefficients, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addCircle] A shape with id <"< already exists! Please choose a different id and retry.\n" << std::endl; - return (false); - } - - vtkSmartPointer data = create2DCircle (coefficients); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetLighting (false); - - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - ///////////////////////////////////////////////////////////////////////////////////////////// bool temp_viz::Viz3d::VizImpl::addText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize, const std::string &id) { From e0b7e63787fee2ff915f62957eefa98bce01297e Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 1 Jul 2013 23:29:33 +0400 Subject: [PATCH 033/205] getShapePose/setShapePose simplification little code beautification, formatting --- modules/viz/include/opencv2/viz/viz3d.hpp | 42 +++++------ modules/viz/src/interactor_style.cpp | 22 ++---- modules/viz/src/precomp.hpp | 20 +---- modules/viz/src/q/shapes.h | 27 +++---- modules/viz/src/q/viz3d_impl.hpp | 89 ++++++++++++----------- modules/viz/src/shapes.cpp | 44 +++++------ modules/viz/src/viz3d.cpp | 37 +++++----- modules/viz/src/viz3d_impl.cpp | 77 +++++++------------- modules/viz/src/viz_main.cpp | 21 +++++- 9 files changed, 170 insertions(+), 209 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 9d0f51636..46d0be04c 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -25,41 +25,41 @@ namespace temp_viz void setBackgroundColor(const Color& color = Color::black()); - void addCoordinateSystem(double scale, const Affine3f& t, const String &id = "coordinate"); + void addCoordinateSystem(double scale, const Affine3f& t, const String& id = "coordinate"); void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); void showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose = Affine3f::Identity()); - bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String &id = "cloud"); + bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String& id = "cloud"); - void showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); - void showPlane(const String &id, const Vec4f &coefs, const Color &color = Color(255,255,255)); - void showPlane(const String &id, const Vec4f &coefs, const Point3f &pt, const Color &color = Color(255,255,255)); - void showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); - void showCylinder(const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color = Color(255,255,255)); - void showCircle(const String &id, const Point3f &pt, double radius, const Color &color = Color(255,255,255)); - void showSphere (const String &id, const Point3f &pt, double radius, const Color &color = Color(255,255,255)); - void showArrow (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); + void showLine(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color = Color::white()); + void showPlane(const String& id, const Vec4f& coefs, const Color& color = Color::white()); + void showPlane(const String& id, const Vec4f& coefs, const Point3f& pt, const Color& color = Color::white()); + void showCube(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color = Color::white()); + void showCylinder(const String& id, const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int num_sides, const Color& color = Color::white()); + void showCircle(const String& id, const Point3f& pt, double radius, const Color& color = Color::white()); + void showSphere(const String& id, const Point3f& pt, double radius, const Color& color = Color::white()); + void showArrow(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color = Color::white()); - Affine3f getShapePose(const String &id); - bool setShapePose(const String &id, const Affine3f &pose); + Affine3f getShapePose(const String& id); + void setShapePose(const String& id, const Affine3f &pose); - bool addPlane (const ModelCoefficients &coefficients, const String &id = "plane"); - bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String &id = "plane"); - bool removeCoordinateSystem (const String &id = "coordinate"); + bool addPlane (const ModelCoefficients &coefficients, const String& id = "plane"); + bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String& id = "plane"); + bool removeCoordinateSystem (const String& id = "coordinate"); - bool addPolygonMesh (const Mesh3d& mesh, const String &id = "polygon"); - bool updatePolygonMesh (const Mesh3d& mesh, const String &id = "polygon"); + bool addPolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); + bool updatePolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); - bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String &id = "polyline"); + bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - bool addText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String &id = ""); + bool addText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String& id = ""); - bool addPolygon(const Mat& cloud, const Color& color, const String &id = "polygon"); + bool addPolygon(const Mat& cloud, const Color& color, const String& id = "polygon"); - bool addSphere (const Point3f ¢er, double radius, const Color& color, const String &id = "sphere"); + bool addSphere (const Point3f ¢er, double radius, const Color& color, const String& id = "sphere"); void spin (); diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 3a8abb13b..62d2d2084 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -154,13 +154,13 @@ temp_viz::InteractorStyle::OnKeyDown () { if (!init_) { - std::cout << "[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing" << std::endl; + std::cout << "Interactor style not initialized. Please call Initialize () before continuing" << std::endl; return; } if (!renderer_) { - std::cout << "[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing." << std::endl; + std::cout << "No renderer given! Use SetRendererCollection () before continuing." << std::endl; return; } @@ -186,21 +186,9 @@ temp_viz::InteractorStyle::OnKeyDown () bool keymod = false; switch (modifier_) { - case KB_MOD_ALT: - { - keymod = alt; - break; - } - case KB_MOD_CTRL: - { - keymod = ctrl; - break; - } - case KB_MOD_SHIFT: - { - keymod = shift; - break; - } + case KB_MOD_ALT: keymod = alt; break; + case KB_MOD_CTRL: keymod = ctrl; break; + case KB_MOD_SHIFT: keymod = shift; break; } std::string key (Interactor->GetKeySym ()); diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index de7104455..bb59ca949 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -6,12 +6,6 @@ #include #include -/* -#include -#include -#include -#include */ - #include #if defined __GNUC__ @@ -140,24 +134,13 @@ #include - #include #include #include - - - #include #include - #include #include - - - - - - #include #include #include @@ -168,3 +151,6 @@ #define __DEPRECATED #undef __DEPRECATED_DISABLED__ #endif + + +#include diff --git a/modules/viz/src/q/shapes.h b/modules/viz/src/q/shapes.h index be83cd59e..4055cd1b2 100644 --- a/modules/viz/src/q/shapes.h +++ b/modules/viz/src/q/shapes.h @@ -1,22 +1,19 @@ #pragma once -#include #include -#include "precomp.hpp" namespace temp_viz { - CV_EXPORTS vtkSmartPointer createLine (const cv::Point3f& pt1, const cv::Point3f& pt2); - CV_EXPORTS vtkSmartPointer createSphere (const cv::Point3f ¢er, float radius, int sphere_resolution = 10); - CV_EXPORTS vtkSmartPointer createCylinder (const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30); - CV_EXPORTS vtkSmartPointer createPlane (const Vec4f& coefs); - CV_EXPORTS vtkSmartPointer createPlane (const Vec4f& coefs, const Point3f& pt); - CV_EXPORTS vtkSmartPointer create2DCircle (const Point3f& pt, double radius); - CV_EXPORTS vtkSmartPointer createCube(const Point3f& pt_min, const Point3f& pt_max); - CV_EXPORTS vtkSmartPointer createSphere (const Point3f& pt, double radius); - CV_EXPORTS vtkSmartPointer createArrow (const Point3f& pt1, const Point3f& pt2); - /** \brief Allocate a new unstructured grid smartpointer. For internal use only. - * \param[out] polydata the resultant unstructured grid. - */ - CV_EXPORTS void allocVtkUnstructuredGrid (vtkSmartPointer &polydata); + vtkSmartPointer createLine (const cv::Point3f& pt1, const cv::Point3f& pt2); + vtkSmartPointer createSphere (const cv::Point3f ¢er, float radius, int sphere_resolution = 10); + vtkSmartPointer createCylinder (const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30); + vtkSmartPointer createPlane (const Vec4f& coefs); + vtkSmartPointer createPlane (const Vec4f& coefs, const Point3f& pt); + vtkSmartPointer create2DCircle (const Point3f& pt, double radius); + vtkSmartPointer createCube(const Point3f& pt_min, const Point3f& pt_max); + vtkSmartPointer createSphere (const Point3f& pt, double radius); + vtkSmartPointer createArrow (const Point3f& pt1, const Point3f& pt2); + + //brief Allocate a new unstructured grid smartpointer. For internal use only. + void allocVtkUnstructuredGrid (vtkSmartPointer &polydata); } diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 008489ccd..d80881c92 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -17,11 +17,11 @@ class CV_EXPORTS Viz3d::VizImpl public: typedef cv::Ptr Ptr; - VizImpl (const std::string &name = std::string()); + VizImpl (const String &name = String()); virtual ~VizImpl (); void setFullScreen (bool mode); - void setWindowName (const std::string &name); + void setWindowName (const String &name); /** \brief Register a callback function for keyboard input * \param[in] callback function that will be registered as a callback for a keyboard event @@ -68,34 +68,34 @@ public: * | * y */ - void addCoordinateSystem (double scale, const cv::Affine3f& t, const std::string &id = "coordinate"); + void addCoordinateSystem (double scale, const Affine3f& t, const String& id = "coordinate"); /** \brief Removes a previously added 3D axes (coordinate system) */ - bool removeCoordinateSystem (const std::string &id = "coordinate"); - bool removePointCloud (const std::string &id = "cloud"); - inline bool removePolygonMesh (const std::string &id = "polygon") + bool removeCoordinateSystem (const String& id = "coordinate"); + bool removePointCloud (const String& id = "cloud"); + inline bool removePolygonMesh (const String& id = "polygon") { // Polygon Meshes are represented internally as point clouds with special cell array structures since 1.4 return removePointCloud (id); } - bool removeShape (const std::string &id = "cloud"); + bool removeShape (const String& id = "cloud"); - bool removeText3D (const std::string &id = "cloud"); + bool removeText3D (const String& id = "cloud"); bool removeAllPointClouds (); bool removeAllShapes (); void setBackgroundColor (const Color& color); - bool addText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize = 10, const std::string &id = ""); - bool updateText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize = 10, const std::string &id = ""); + bool addText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String& id = ""); + bool updateText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String& id = ""); /** \brief Set the pose of an existing shape. Returns false if the shape doesn't exist, true if the pose was succesfully updated. */ - bool updateShapePose (const std::string &id, const cv::Affine3f& pose); + bool updateShapePose (const String& id, const Affine3f& pose); - bool addText3D (const std::string &text, const cv::Point3f &position, const Color& color, double textScale = 1.0, const std::string &id = ""); + bool addText3D (const String &text, const Point3f &position, const Color& color, double textScale = 1.0, const String& id = ""); - bool addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level = 100, float scale = 0.02f, const std::string &id = "cloud"); + bool addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level = 100, float scale = 0.02f, const String& id = "cloud"); /** \brief If the id exists, updates the point cloud; otherwise, adds a new point cloud to the scene * \param[in] id a variable to identify the point cloud @@ -106,23 +106,23 @@ public: void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); void showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose = Affine3f::Identity()); - bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); - bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id = "polygon"); + bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); + bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); - bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const std::string &id = "polyline"); + bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - void setPointCloudColor (const Color& color, const std::string &id = "cloud"); - bool setPointCloudRenderingProperties (int property, double value, const std::string &id = "cloud"); - bool getPointCloudRenderingProperties (int property, double &value, const std::string &id = "cloud"); + void setPointCloudColor (const Color& color, const String& id = "cloud"); + bool setPointCloudRenderingProperties (int property, double value, const String& id = "cloud"); + bool getPointCloudRenderingProperties (int property, double &value, const String& id = "cloud"); - bool setShapeRenderingProperties (int property, double value, const std::string &id); - void setShapeColor (const Color& color, const std::string &id); + bool setShapeRenderingProperties (int property, double value, const String& id); + void setShapeColor (const Color& color, const String& id); /** \brief Set whether the point cloud is selected or not * \param[in] selected whether the cloud is selected or not (true = selected) * \param[in] id the point cloud object id (default: cloud) */ - bool setPointCloudSelected (const bool selected, const std::string &id = "cloud" ); + bool setPointCloudSelected (const bool selected, const String& id = "cloud" ); /** \brief Returns true when the user tried to close the window */ bool wasStopped () const { if (interactor_ != NULL) return (stopped_); else return true; } @@ -138,27 +138,27 @@ public: interactor_->TerminateApp (); } - void showLine (const String &id, const cv::Point3f &pt1, const cv::Point3f &pt2, const Color &color); - void showPlane (const String &id, const cv::Vec4f &coefs, const Color &color); - void showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt, const Color &color); - void showCube (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); - void showCylinder (const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color); - void showCircle (const String &id, const Point3f &pt, double radius, const Color &color); - void showSphere (const String &id, const Point3f &pt, double radius, const Color &color); - void showArrow (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color); + void showLine (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color); + void showPlane (const String& id, const cv::Vec4f &coefs, const Color& color); + void showPlane (const String& id ,const cv::Vec4f &coefs, const Point3f& pt, const Color& color); + void showCube (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color); + void showCylinder (const String& id, const Point3f& pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color& color); + void showCircle (const String& id, const Point3f& pt, double radius, const Color& color); + void showSphere (const String& id, const Point3f& pt, double radius, const Color& color); + void showArrow (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color); - Affine3f getShapePose (const String &id); - bool setShapePose (const String &id, const Affine3f &pose); + Affine3f getShapePose (const String& id); + void setShapePose (const String& id, const Affine3f& pose); - bool addPolygon(const cv::Mat& cloud, const Color& color, const std::string &id = "polygon"); - bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color, bool display_length, const std::string &id = "arrow"); - bool addArrow (const cv::Point3f &pt1, const cv::Point3f &pt2, const Color& color_line, const Color& color_text, const std::string &id = "arrow"); + bool addPolygon(const cv::Mat& cloud, const Color& color, const String& id = "polygon"); + bool addArrow (const Point3f& pt1, const Point3f& pt2, const Color& color, bool display_length, const String& id = "arrow"); + bool addArrow (const Point3f& pt1, const Point3f& pt2, const Color& color_line, const Color& color_text, const String& id = "arrow"); // Add a vtkPolydata as a mesh - bool addModelFromPolyData (vtkSmartPointer polydata, const std::string & id = "PolyData"); - bool addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const std::string &id = "PolyData"); - bool addModelFromPLYFile (const std::string &filename, const std::string &id = "PLYModel"); - bool addModelFromPLYFile (const std::string &filename, vtkSmartPointer transform, const std::string &id = "PLYModel"); + bool addModelFromPolyData (vtkSmartPointer polydata, const String& id = "PolyData"); + bool addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const String& id = "PolyData"); + bool addModelFromPLYFile (const String &filename, const String& id = "PLYModel"); + bool addModelFromPLYFile (const String &filename, vtkSmartPointer transform, const String& id = "PLYModel"); /** \brief Changes the visual representation for all actors to surface representation. */ void setRepresentationToSurfaceForAllActors (); @@ -187,7 +187,7 @@ public: /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset. * \param[in] id the point cloud object id (default: cloud) */ - void resetCameraViewpoint (const std::string &id = "cloud"); + void resetCameraViewpoint (const String& id = "cloud"); /** \brief Set the camera pose given by position, viewpoint and up vector * \param[in] pos_x the x coordinate of the camera location @@ -217,7 +217,7 @@ public: * \param[in] intrinsics the intrinsics that will be used to compute the VTK camera parameters * \param[in] extrinsics the extrinsics that will be used to compute the VTK camera parameters */ - void setCameraParameters (const cv::Matx33f& intrinsics, const cv::Affine3f& extrinsics); + void setCameraParameters (const cv::Matx33f& intrinsics, const Affine3f& extrinsics); /** \brief Set the camera parameters by given a full camera data structure. * \param[in] camera camera structure containing all the camera parameters. @@ -237,8 +237,8 @@ public: void getCameras (Camera& camera); /** \brief Get the current viewing pose. */ - cv::Affine3f getViewerPose (); - void saveScreenshot (const std::string &file); + Affine3f getViewerPose (); + void saveScreenshot (const String &file); /** \brief Return a pointer to the underlying VTK Render Window used. */ //vtkSmartPointer getRenderWindow () { return (window_); } @@ -351,6 +351,9 @@ private: void convertToVtkMatrix (const cv::Matx44f& m, vtkSmartPointer &vtk_matrix); void convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m); +vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m); +cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix); + /** \brief Convert origin and orientation to vtkMatrix4x4 * \param[in] origin the point cloud origin * \param[in] orientation the point cloud orientation diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index 362b615df..7fa9a2cd8 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -1,9 +1,7 @@ -#include +#include "precomp.hpp" -inline float rad2deg (float alpha) -{ return (alpha * 57.29578f); } - -inline double rad2deg (double alpha){return (alpha * 57.29578);} +inline float rad2deg(float alpha) { return (alpha * 57.29578f); } +inline double rad2deg(double alpha) { return (alpha * 57.29578); } vtkSmartPointer temp_viz::createCylinder (const cv::Point3f& pt_on_axis, const cv::Point3f& axis_direction, double radius, int numsides) { @@ -23,21 +21,20 @@ vtkSmartPointer temp_viz::createPlane (const cv::Vec4f& coefs) { vtkSmartPointer plane = vtkSmartPointer::New (); plane->SetNormal (coefs[0], coefs[1], coefs[2]); - double norm = cv::norm (cv::Vec3f (coefs[0], coefs[1], coefs[2])); + double norm = cv::norm(cv::Vec3f(coefs.val)); plane->Push (-coefs[3] / norm); - return (plane->GetOutput ()); + return plane->GetOutput (); } vtkSmartPointer temp_viz::createPlane(const cv::Vec4f& coefs, const cv::Point3f& pt) { vtkSmartPointer plane = vtkSmartPointer::New (); - cv::Point3f coefs3 (coefs[0], coefs[1], coefs[2]); + cv::Point3f coefs3(coefs[0], coefs[1], coefs[2]); double norm_sqr = 1.0 / coefs3.dot (coefs3); - plane->SetNormal (coefs[0], coefs[1], coefs[2]); + plane->SetNormal(coefs[0], coefs[1], coefs[2]); - double t = coefs3.dot (pt) + coefs[3]; - cv::Vec3f p_center; - p_center = pt - coefs3 * t * norm_sqr; + double t = coefs3.dot(pt) + coefs[3]; + cv::Vec3f p_center = pt - coefs3 * t * norm_sqr; plane->SetCenter (p_center[0], p_center[1], p_center[2]); return (plane->GetOutput ()); @@ -61,14 +58,14 @@ vtkSmartPointer temp_viz::create2DCircle (const cv::Point3f& pt, dou tf->SetTransform (t); tf->SetInputConnection (disk->GetOutputPort ()); - return (tf->GetOutput ()); + return tf->GetOutput (); } vtkSmartPointer temp_viz::createCube(const cv::Point3f& pt_min, const cv::Point3f& pt_max) { vtkSmartPointer cube = vtkSmartPointer::New (); cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); - return (cube->GetOutput ()); + return cube->GetOutput (); } vtkSmartPointer temp_viz::createSphere (const Point3f& pt, double radius) @@ -81,7 +78,7 @@ vtkSmartPointer temp_viz::createSphere (const Point3f& pt, double ra sphere->LatLongTessellationOff (); sphere->Update (); - return (sphere->GetOutput ()); + return sphere->GetOutput (); } vtkSmartPointer temp_viz::createArrow (const Point3f& pt1, const Point3f& pt2) @@ -136,22 +133,21 @@ vtkSmartPointer temp_viz::createArrow (const Point3f& pt1, const Poi transformPD->SetTransform(transform); transformPD->SetInputConnection(arrowSource->GetOutputPort()); - return (transformPD->GetOutput()); + return transformPD->GetOutput(); } -//////////////////////////////////////////////////////////////////////////////////////////// vtkSmartPointer temp_viz::createLine (const cv::Point3f& pt1, const cv::Point3f& pt2) { - vtkSmartPointer line = vtkSmartPointer::New (); - line->SetPoint1 (pt1.x, pt1.y, pt1.z); - line->SetPoint2 (pt2.x, pt2.y, pt2.z); - line->Update (); - return line->GetOutput (); + vtkSmartPointer line = vtkSmartPointer::New (); + line->SetPoint1 (pt1.x, pt1.y, pt1.z); + line->SetPoint2 (pt2.x, pt2.y, pt2.z); + line->Update (); + return line->GetOutput (); } -////////////////////////////////////////////////////////////////////////////////////////////// + void temp_viz::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) { - polydata = vtkSmartPointer::New (); + polydata = vtkSmartPointer::New (); } diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 5d5f51f70..3df43fab6 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -9,16 +9,15 @@ temp_viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_nam temp_viz::Viz3d::~Viz3d() { - + delete impl_; } - void temp_viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } -void temp_viz::Viz3d::addCoordinateSystem(double scale, const Affine3f& t, const String &id) +void temp_viz::Viz3d::addCoordinateSystem(double scale, const Affine3f& t, const String& id) { impl_->addCoordinateSystem(scale, t, id); } @@ -38,22 +37,22 @@ bool temp_viz::Viz3d::addPointCloudNormals (const Mat &cloud, const Mat& normals return impl_->addPointCloudNormals(cloud, normals, level, scale, id); } -bool temp_viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String &id) +bool temp_viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String& id) { return impl_->addPolygonMesh(mesh, Mat(), id); } -bool temp_viz::Viz3d::updatePolygonMesh (const Mesh3d& mesh, const String &id) +bool temp_viz::Viz3d::updatePolygonMesh (const Mesh3d& mesh, const String& id) { return impl_->updatePolygonMesh(mesh, Mat(), id); } -bool temp_viz::Viz3d::addPolylineFromPolygonMesh (const Mesh3d& mesh, const String &id) +bool temp_viz::Viz3d::addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id) { return impl_->addPolylineFromPolygonMesh(mesh, id); } -bool temp_viz::Viz3d::addText (const String &text, int xpos, int ypos, const Color& color, int fontsize, const String &id) +bool temp_viz::Viz3d::addText (const String &text, int xpos, int ypos, const Color& color, int fontsize, const String& id) { return impl_->addText(text, xpos, ypos, color, fontsize, id); } @@ -73,57 +72,57 @@ void temp_viz::Viz3d::spinOnce (int time, bool force_redraw) impl_->spinOnce(time, force_redraw); } -void temp_viz::Viz3d::showLine(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +void temp_viz::Viz3d::showLine(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) { impl_->showLine(id, pt1, pt2, color); } -void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs, const Color &color) +void temp_viz::Viz3d::showPlane(const String& id, const Vec4f &coefs, const Color& color) { impl_->showPlane(id, coefs, color); } -void temp_viz::Viz3d::showPlane(const String &id, const Vec4f &coefs, const Point3f &pt, const Color &color) +void temp_viz::Viz3d::showPlane(const String& id, const Vec4f &coefs, const Point3f& pt, const Color& color) { impl_->showPlane(id, coefs, pt, color); } -void temp_viz::Viz3d::showCube(const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +void temp_viz::Viz3d::showCube(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) { impl_->showCube(id, pt1, pt2, color); } -void temp_viz::Viz3d::showCylinder(const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color) +void temp_viz::Viz3d::showCylinder(const String& id, const Point3f& pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color& color) { impl_->showCylinder(id, pt_on_axis, axis_direction, radius, num_sides, color); } -void temp_viz::Viz3d::showCircle(const String &id, const Point3f &pt, double radius, const Color &color) +void temp_viz::Viz3d::showCircle(const String& id, const Point3f& pt, double radius, const Color& color) { impl_->showCircle(id, pt, radius, color); } -void temp_viz::Viz3d::showSphere (const String &id, const Point3f &pt, double radius, const Color &color) +void temp_viz::Viz3d::showSphere (const String& id, const Point3f& pt, double radius, const Color& color) { impl_->showSphere(id, pt, radius, color); } -void temp_viz::Viz3d::showArrow (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +void temp_viz::Viz3d::showArrow (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) { impl_->showArrow(id,pt1,pt2,color); } -cv::Affine3f temp_viz::Viz3d::getShapePose(const String &id) +cv::Affine3f temp_viz::Viz3d::getShapePose(const String& id) { return impl_->getShapePose(id); } -bool temp_viz::Viz3d::setShapePose(const String &id, const Affine3f &pose) +void temp_viz::Viz3d::setShapePose(const String& id, const Affine3f &pose) { - return impl_->setShapePose(id, pose); + impl_->setShapePose(id, pose); } -bool temp_viz::Viz3d::removeCoordinateSystem (const String &id) +bool temp_viz::Viz3d::removeCoordinateSystem (const String& id) { return impl_->removeCoordinateSystem(id); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 598304ae8..7c97b20d7 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -53,7 +53,7 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou // If the cloud already exists, update otherwise create new one CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - bool exist = (am_it == cloud_actor_map_->end()); + bool exist = am_it == cloud_actor_map_->end(); if (exist) { // Add as new cloud @@ -181,7 +181,7 @@ void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _clou // If the cloud already exists, update otherwise create new one CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - bool exist = (am_it == cloud_actor_map_->end()); + bool exist = am_it == cloud_actor_map_->end(); if (exist) { // Add as new cloud @@ -292,7 +292,7 @@ bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const CV_Assert(cloud.size() == normals.size() && cloud.type() == CV_32FC3 && normals.type() == CV_32FC3); if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) - return (false); + return false; vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer lines = vtkSmartPointer::New(); @@ -380,11 +380,11 @@ bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const } -void temp_viz::Viz3d::VizImpl::showLine (const String &id, const cv::Point3f &pt1, const cv::Point3f &pt2, const Color &color) +void temp_viz::Viz3d::VizImpl::showLine (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); + bool exists = am_it != shape_actor_map_->end(); // If it exists just update if (exists) @@ -416,11 +416,11 @@ void temp_viz::Viz3d::VizImpl::showLine (const String &id, const cv::Point3f &pt } } -void temp_viz::Viz3d::VizImpl::showPlane (const String &id, const cv::Vec4f &coefs, const Color &color) +void temp_viz::Viz3d::VizImpl::showPlane (const String& id, const cv::Vec4f &coefs, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); + bool exists = am_it != shape_actor_map_->end(); Color c = vtkcolor(color); // If it exists just update if (exists) @@ -451,11 +451,11 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String &id, const cv::Vec4f &coe } } -void temp_viz::Viz3d::VizImpl::showPlane (const String &id ,const cv::Vec4f &coefs, const cv::Point3f &pt, const Color &color) +void temp_viz::Viz3d::VizImpl::showPlane (const String& id ,const cv::Vec4f &coefs, const Point3f& pt, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); + bool exists = am_it != shape_actor_map_->end(); Color c = vtkcolor(color); // If it exists just update if (exists) @@ -486,11 +486,11 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String &id ,const cv::Vec4f &coe } } -void temp_viz::Viz3d::VizImpl::showCube (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +void temp_viz::Viz3d::VizImpl::showCube (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); + bool exists = am_it != shape_actor_map_->end(); Color c = vtkcolor(color); // If it exists just update if (exists) @@ -521,11 +521,11 @@ void temp_viz::Viz3d::VizImpl::showCube (const String &id, const Point3f &pt1, c } } -void temp_viz::Viz3d::VizImpl::showCylinder (const String &id, const Point3f &pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color &color) +void temp_viz::Viz3d::VizImpl::showCylinder (const String& id, const Point3f& pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); + bool exists = am_it != shape_actor_map_->end(); Color c = vtkcolor(color); // If it exists just update if (exists) @@ -556,11 +556,11 @@ void temp_viz::Viz3d::VizImpl::showCylinder (const String &id, const Point3f &pt } } -void temp_viz::Viz3d::VizImpl::showCircle (const String &id, const Point3f &pt, double radius, const Color &color) +void temp_viz::Viz3d::VizImpl::showCircle (const String& id, const Point3f& pt, double radius, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); + bool exists = am_it != shape_actor_map_->end(); Color c = vtkcolor(color); // If it exists just update if (exists) @@ -591,11 +591,11 @@ void temp_viz::Viz3d::VizImpl::showCircle (const String &id, const Point3f &pt, } } -void temp_viz::Viz3d::VizImpl::showSphere (const String &id, const Point3f &pt, double radius, const Color &color) +void temp_viz::Viz3d::VizImpl::showSphere (const String& id, const Point3f& pt, double radius, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); + bool exists = am_it != shape_actor_map_->end(); Color c = vtkcolor(color); // If it exists just update if (exists) @@ -626,11 +626,11 @@ void temp_viz::Viz3d::VizImpl::showSphere (const String &id, const Point3f &pt, } } -void temp_viz::Viz3d::VizImpl::showArrow (const String &id, const Point3f &pt1, const Point3f &pt2, const Color &color) +void temp_viz::Viz3d::VizImpl::showArrow (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); + bool exists = am_it != shape_actor_map_->end(); Color c = vtkcolor(color); // If it exists just update @@ -662,49 +662,24 @@ void temp_viz::Viz3d::VizImpl::showArrow (const String &id, const Point3f &pt1, } } -cv::Affine3f temp_viz::Viz3d::VizImpl::getShapePose (const String &id) +cv::Affine3f temp_viz::Viz3d::VizImpl::getShapePose (const String& id) { - // Get the shape with the id and return the pose ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); - - if (!exists) - { - std::cout << "[getShapePose] A shape with id <" << id << "> does not exist!" << std::endl; - return Affine3f(); - } - vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second); - - vtkSmartPointer matrix = actor->GetUserMatrix(); - - Matx44f pose_mat; - convertToCvMatrix(matrix, pose_mat); - - Affine3f pose; - pose.matrix = pose_mat; - return pose; + CV_Assert(am_it != shape_actor_map_->end()); + vtkLODActor* actor = vtkLODActor::SafeDownCast(am_it->second); + return Affine3f(convertToMatx(actor->GetUserMatrix())); } -bool temp_viz::Viz3d::VizImpl::setShapePose (const String &id, const Affine3f &pose) +void temp_viz::Viz3d::VizImpl::setShapePose (const String& id, const Affine3f &pose) { ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = (am_it != shape_actor_map_->end()); - - if (!exists) - { - return false; - } + CV_Assert(am_it != shape_actor_map_->end()); vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second); - vtkSmartPointer matrix = vtkSmartPointer::New (); - - convertToVtkMatrix (pose.matrix, matrix); - + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); actor->SetUserMatrix (matrix); actor->Modified (); - - return (true); } bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index d35a88153..4552790ab 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -97,14 +97,12 @@ void temp_viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_ ///////////////////////////////////////////////////////////////////////////////////////////// void temp_viz::Viz3d::VizImpl::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) { - // Register the callback function in the interactor style style_->registerMouseCallback(callback, cookie); } ///////////////////////////////////////////////////////////////////////////////////////////// void temp_viz::Viz3d::VizImpl::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) { - // Register the callback function in the interactor style style_->registerKeyboardCallback(callback, cookie); } @@ -1205,6 +1203,15 @@ void temp_viz::convertToVtkMatrix (const cv::Matx44f &m, vtkSmartPointerSetElement (i, k, m (i, k)); } +vtkSmartPointer temp_viz::convertToVtkMatrix (const cv::Matx44f &m) +{ + vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + vtk_matrix->SetElement(i, k, m(i, k)); + return vtk_matrix; +} + void temp_viz::convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m) { for (int i = 0; i < 4; i++) @@ -1212,6 +1219,16 @@ void temp_viz::convertToCvMatrix (const vtkSmartPointer &vtk_matri m(i,k) = vtk_matrix->GetElement (i, k); } + +cv::Matx44f temp_viz::convertToMatx(const vtkSmartPointer& vtk_matrix) +{ + cv::Matx44f m; + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + m(i, k) = vtk_matrix->GetElement (i, k); + return m; +} + ////////////////////////////////////////////////////////////////////////////////////////////// void temp_viz::convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m) { From 54c7dfab83f9c47662fc20657aedf989d17cb5bc Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 3 Jul 2013 18:48:11 +0300 Subject: [PATCH 034/205] initial base widget implementation --- modules/viz/include/opencv2/viz/types.hpp | 18 +++ .../include/opencv2/viz/widget_accessor.hpp | 12 ++ modules/viz/src/types.cpp | 137 +++++++++++++++++- modules/viz/test/test_viz3d.cpp | 1 - 4 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 modules/viz/include/opencv2/viz/widget_accessor.hpp diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 2328dc073..3698d556b 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -113,4 +113,22 @@ namespace temp_viz template inline bool isNan(const Point3_<_Tp>& p) { return isNan(p.x) || isNan(p.y) || isNan(p.z); } + + class Widget + { + public: + Widget(); + Widget(const String &id); + Widget(const Widget &other); + + void setId(const String &id); + void setColor(const Color &color); + void setPose(const Affine3f &pose); + void updatePose(const Affine3f &pose); + Affine3f getPose() const; + private: + class Impl; + cv::Ptr impl_; + friend struct WidgetAccessor; + }; } diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp new file mode 100644 index 000000000..2c0437c5a --- /dev/null +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "precomp.hpp" +#include "types.hpp" + +namespace temp_viz +{ + struct WidgetAccessor + { + static CV_EXPORTS vtkSmartPointer getActor(const Widget &widget); + }; +} \ No newline at end of file diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 0baed3a72..d717c305e 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -1,7 +1,5 @@ #include - - ////////////////////////////////////////////////////////////////////////////////////////////////////// /// cv::Color @@ -22,3 +20,138 @@ temp_viz::Color temp_viz::Color::white() { return Color(255, 255, 255); } temp_viz::Color temp_viz::Color::gray() { return Color(128, 128, 128); } +class temp_viz::Widget::Impl +{ +public: + String id; + vtkSmartPointer actor; + + Impl() + { + actor = vtkSmartPointer:: New(); + } + + vtkSmartPointer getActor() + { + return actor; + } + + void setId(const String &id) + { + this->id = id; + } + + const temp_viz::String & getString() const + { + return id; + } + + void setColor(const Color & color) + { + Color c = vtkcolor(color); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetProperty ()->SetColor (c.val); + actor->GetProperty ()->SetEdgeColor (c.val); + actor->GetProperty ()->SetAmbient (0.8); + actor->GetProperty ()->SetDiffuse (0.8); + actor->GetProperty ()->SetSpecular (0.8); + actor->GetProperty ()->SetLighting (0); + actor->Modified (); + } + + void setPose(const Affine3f &pose) + { + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified (); + } + + void updatePose(const Affine3f &pose) + { + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv; + convertToCvMatrix(matrix, matrix_cv); + matrix = convertToVtkMatrix ((pose * Affine3f(matrix_cv)).matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); + } + + Affine3f getPose() const + { + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv; + convertToCvMatrix(matrix, matrix_cv); + return Affine3f(matrix_cv); + } + +protected: + + vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m) const + { + vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + vtk_matrix->SetElement(i, k, m(i, k)); + return vtk_matrix; + } + + void convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m) const + { + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + m(i,k) = vtk_matrix->GetElement (i, k); + } + +}; + +temp_viz::Widget::Widget() +{ + impl_ = new Impl(); + impl_->setId("id"); +} + +temp_viz::Widget::Widget(const String &id) +{ + impl_ = new Impl(); + impl_->setId("id"); +} + +temp_viz::Widget::Widget(const Widget &other) +{ + impl_ = other.impl_; +} + +void temp_viz::Widget::setId(const String &id) +{ + impl_->setId(id); +} + +void temp_viz::Widget::setColor(const Color &color) +{ + impl_->setColor(color); +} + +void temp_viz::Widget::setPose(const Affine3f &pose) +{ + impl_->setPose(pose); +} + +void temp_viz::Widget::updatePose(const Affine3f &pose) +{ + impl_->updatePose(pose); +} + +temp_viz::Affine3f temp_viz::Widget::getPose() const +{ + return impl_->getPose(); +} + +// TODO Check if HAVE_VTK +#include "opencv2/viz/widget_accessor.hpp" + +vtkSmartPointer temp_viz::WidgetAccessor::getActor(const temp_viz::Widget &widget) +{ + return widget.impl_->actor; +} + diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 8a7472c51..c80845f1f 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -50,7 +50,6 @@ #include #include - cv::Mat cvcloud_load() { cv::Mat cloud(1, 20000, CV_32FC3); From c8d2b5ff446e080eeb21fa26214f9ba9f5cdd1ac Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 3 Jul 2013 20:53:03 +0300 Subject: [PATCH 035/205] fix vtkActor to vtkLODActor, initial implementation LineWidget, showWidget --- modules/viz/include/opencv2/viz/types.hpp | 9 ++- modules/viz/include/opencv2/viz/viz3d.hpp | 2 + .../include/opencv2/viz/widget_accessor.hpp | 5 +- modules/viz/src/q/viz3d_impl.hpp | 6 ++ modules/viz/src/q/viz_types.h | 9 +++ modules/viz/src/types.cpp | 55 +++++++++---------- modules/viz/src/viz3d.cpp | 4 ++ modules/viz/src/viz3d_impl.cpp | 15 +++++ modules/viz/src/viz_main.cpp | 1 + modules/viz/test/test_viz3d.cpp | 3 + 10 files changed, 74 insertions(+), 35 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 3698d556b..27fc07426 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -118,17 +118,22 @@ namespace temp_viz { public: Widget(); - Widget(const String &id); Widget(const Widget &other); - void setId(const String &id); void setColor(const Color &color); void setPose(const Affine3f &pose); void updatePose(const Affine3f &pose); Affine3f getPose() const; + private: class Impl; cv::Ptr impl_; friend struct WidgetAccessor; }; + + class LineWidget : public Widget + { + public: + LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color); + }; } diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 46d0be04c..a610e07ad 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -69,6 +69,8 @@ namespace temp_viz void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); bool wasStopped() const; + + void showWidget(const String &id, const Widget &widget); private: Viz3d(const Viz3d&); Viz3d& operator=(const Viz3d&); diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index 2c0437c5a..58907e14b 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -1,12 +1,11 @@ #pragma once -#include "precomp.hpp" -#include "types.hpp" +#include namespace temp_viz { struct WidgetAccessor { - static CV_EXPORTS vtkSmartPointer getActor(const Widget &widget); + static CV_EXPORTS vtkSmartPointer getActor(const Widget &widget); }; } \ No newline at end of file diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index d80881c92..9544a3142 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -245,6 +245,9 @@ public: void setPosition (int x, int y); void setSize (int xw, int yw); + + void showWidget(const String &id, const Widget &widget); + void all_data(); private: vtkSmartPointer interactor_; @@ -311,6 +314,9 @@ private: /** \brief Internal list with actor pointers and name IDs for shapes. */ cv::Ptr shape_actor_map_; + + /** \brief Internal list with actor pointers and name IDs for all widget actors */ + cv::Ptr widget_actor_map_; /** \brief Boolean that holds whether or not the camera parameters were manually initialized*/ bool camera_set_; diff --git a/modules/viz/src/q/viz_types.h b/modules/viz/src/q/viz_types.h index 1acfa4b1a..3dbb44f18 100644 --- a/modules/viz/src/q/viz_types.h +++ b/modules/viz/src/q/viz_types.h @@ -15,8 +15,17 @@ namespace temp_viz /** \brief Internal cell array. Used for optimizing updatePointCloud. */ vtkSmartPointer cells; }; + + // TODO This will be used to contain both cloud and shape actors + struct CV_EXPORTS WidgetActor + { + vtkSmartPointer actor; + vtkSmartPointer viewpoint_transformation_; + vtkSmartPointer cells; + }; typedef std::map CloudActorMap; typedef std::map > ShapeActorMap; + typedef std::map WidgetActorMap; } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index d717c305e..5670f759a 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -24,28 +24,18 @@ class temp_viz::Widget::Impl { public: String id; - vtkSmartPointer actor; + vtkSmartPointer actor; Impl() { - actor = vtkSmartPointer:: New(); + actor = vtkSmartPointer::New (); } - vtkSmartPointer getActor() + vtkSmartPointer getActor() { return actor; } - void setId(const String &id) - { - this->id = id; - } - - const temp_viz::String & getString() const - { - return id; - } - void setColor(const Color & color) { Color c = vtkcolor(color); @@ -85,11 +75,22 @@ public: return Affine3f(matrix_cv); } + void setActorMapperInput(const vtkSmartPointer &data) + { + vtkSmartPointer mapper = reinterpret_cast(actor->GetMapper ()); + if (mapper == 0) + { + mapper = vtkSmartPointer::New (); + actor->SetMapper(mapper); + } + mapper->SetInput (data); + } + protected: vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m) const { - vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); + vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) vtk_matrix->SetElement(i, k, m(i, k)); @@ -101,20 +102,12 @@ protected: for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) m(i,k) = vtk_matrix->GetElement (i, k); - } - + } }; temp_viz::Widget::Widget() { impl_ = new Impl(); - impl_->setId("id"); -} - -temp_viz::Widget::Widget(const String &id) -{ - impl_ = new Impl(); - impl_->setId("id"); } temp_viz::Widget::Widget(const Widget &other) @@ -122,11 +115,6 @@ temp_viz::Widget::Widget(const Widget &other) impl_ = other.impl_; } -void temp_viz::Widget::setId(const String &id) -{ - impl_->setId(id); -} - void temp_viz::Widget::setColor(const Color &color) { impl_->setColor(color); @@ -147,11 +135,18 @@ temp_viz::Affine3f temp_viz::Widget::getPose() const return impl_->getPose(); } -// TODO Check if HAVE_VTK #include "opencv2/viz/widget_accessor.hpp" -vtkSmartPointer temp_viz::WidgetAccessor::getActor(const temp_viz::Widget &widget) +vtkSmartPointer temp_viz::WidgetAccessor::getActor(const temp_viz::Widget &widget) { return widget.impl_->actor; } +temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) : Widget() +{ + // Create the line and set actor's data + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(createLine(pt1,pt2)); + temp_viz::WidgetAccessor::getActor(*this)->SetMapper(mapper); + setColor(color); +} \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 3df43fab6..dcd0bf7f1 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -139,3 +139,7 @@ void temp_viz::Viz3d::registerMouseCallback(void (*callback)(const MouseEvent&, bool temp_viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } +void temp_viz::Viz3d::showWidget(const String &id, const Widget &widget) +{ + impl_->showWidget(id, widget); +} diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 7c97b20d7..e25bca009 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1168,3 +1168,18 @@ bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& co return (true); } + +#include "opencv2/viz/widget_accessor.hpp" + +void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = !(wam_itr == widget_actor_map_->end()); + if (exists) + { + // Remove it if it exists and add it again + removeActorFromRenderer(wam_itr->second.actor); + } + renderer_->AddActor(WidgetAccessor::getActor(widget)); + (*widget_actor_map_)[id].actor = WidgetAccessor::getActor(widget); +} diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 4552790ab..eeb72c415 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -17,6 +17,7 @@ temp_viz::Viz3d::VizImpl::VizImpl (const std::string &name) : style_ (vtkSmartPointer::New ()) , cloud_actor_map_ (new CloudActorMap) , shape_actor_map_ (new ShapeActorMap) + , widget_actor_map_ (new WidgetActorMap) , s_lastDone_(0.0) { renderer_ = vtkSmartPointer::New (); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index c80845f1f..31b85f9e0 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -94,6 +94,8 @@ TEST(Viz_viz3d, accuracy) v.showCircle("circle1", cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); v.showSphere("sphere1", cv::Point3f(0,0,0), 0.5, temp_viz::Color(0,0,255)); v.showArrow("arrow1", cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); + temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0,1.0,1.0), temp_viz::Color(0,255,0)); + v.showWidget("line", lw); while(!v.wasStopped()) { @@ -110,6 +112,7 @@ TEST(Viz_viz3d, accuracy) v.setShapePose("circle1", cloudPosition); v.setShapePose("sphere1", cloudPosition); v.setShapePose("arrow1", cloudPosition); + lw.setColor(temp_viz::Color(col_blue, col_green, col_red)); angle_x += 0.1f; angle_y -= 0.1f; From daa2a205a41fa44c4d8895d9e3f77c02d7aa9f14 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 3 Jul 2013 22:27:09 +0300 Subject: [PATCH 036/205] remove redundant methods, implement assignment operator for widget --- modules/viz/include/opencv2/viz/types.hpp | 5 ++++- modules/viz/src/types.cpp | 23 ++++++++++++----------- modules/viz/test/test_viz3d.cpp | 4 +++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 27fc07426..39432e2e5 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -119,6 +119,9 @@ namespace temp_viz public: Widget(); Widget(const Widget &other); + Widget& operator =(const Widget &other); + + void copyTo(Widget &dst); void setColor(const Color &color); void setPose(const Affine3f &pose); @@ -134,6 +137,6 @@ namespace temp_viz class LineWidget : public Widget { public: - LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color); + LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); }; } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 5670f759a..8500d2afe 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -75,17 +75,6 @@ public: return Affine3f(matrix_cv); } - void setActorMapperInput(const vtkSmartPointer &data) - { - vtkSmartPointer mapper = reinterpret_cast(actor->GetMapper ()); - if (mapper == 0) - { - mapper = vtkSmartPointer::New (); - actor->SetMapper(mapper); - } - mapper->SetInput (data); - } - protected: vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m) const @@ -115,6 +104,18 @@ temp_viz::Widget::Widget(const Widget &other) impl_ = other.impl_; } +temp_viz::Widget& temp_viz::Widget::operator =(const Widget &other) +{ + if (this != &other) + impl_ = other.impl_; + return *this; +} + +void temp_viz::Widget::copyTo(Widget &dst) +{ + // TODO Deep copy the data if there is any +} + void temp_viz::Widget::setColor(const Color &color) { impl_->setColor(color); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 31b85f9e0..1bce1a356 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -97,6 +97,8 @@ TEST(Viz_viz3d, accuracy) temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0,1.0,1.0), temp_viz::Color(0,255,0)); v.showWidget("line", lw); + temp_viz::LineWidget lw2 = lw; + while(!v.wasStopped()) { // Creating new point cloud with id cloud1 @@ -112,7 +114,7 @@ TEST(Viz_viz3d, accuracy) v.setShapePose("circle1", cloudPosition); v.setShapePose("sphere1", cloudPosition); v.setShapePose("arrow1", cloudPosition); - lw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); angle_x += 0.1f; angle_y -= 0.1f; From efa7f09048d581f90c01aa65ce2d1203cd2174f5 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Thu, 4 Jul 2013 13:54:00 +0400 Subject: [PATCH 037/205] slight refactoring of widget system code --- modules/viz/include/opencv2/viz.hpp | 3 + modules/viz/include/opencv2/viz/types.hpp | 34 +---- modules/viz/include/opencv2/viz/viz3d.hpp | 5 +- .../include/opencv2/viz/widget_accessor.hpp | 12 +- modules/viz/include/opencv2/viz/widgets.hpp | 38 +++++ modules/viz/src/precomp.hpp | 2 + modules/viz/src/simple_widgets.cpp | 18 +++ modules/viz/src/types.cpp | 131 ------------------ modules/viz/src/viz3d.cpp | 8 +- modules/viz/src/viz3d_impl.cpp | 12 +- modules/viz/src/widget.cpp | 110 +++++++++++++++ modules/viz/test/test_viz3d.cpp | 2 +- 12 files changed, 195 insertions(+), 180 deletions(-) create mode 100644 modules/viz/include/opencv2/viz/widgets.hpp create mode 100644 modules/viz/src/simple_widgets.cpp create mode 100644 modules/viz/src/widget.cpp diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 3e1663df5..2ec8fbb86 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -1,3 +1,6 @@ #pragma once +#include +#include #include + diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 39432e2e5..b28996a9e 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -36,8 +36,6 @@ namespace temp_viz using cv::DataType; - - struct CV_EXPORTS ModelCoefficients { std::vector values; @@ -81,6 +79,8 @@ namespace temp_viz std::vector polygons; }; + ///////////////////////////////////////////////////////////////////////////// + /// Utility functions inline Color vtkcolor(const Color& color) { @@ -90,11 +90,7 @@ namespace temp_viz } inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } - - - template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } - inline bool isNan(float x) { @@ -113,30 +109,4 @@ namespace temp_viz template inline bool isNan(const Point3_<_Tp>& p) { return isNan(p.x) || isNan(p.y) || isNan(p.z); } - - class Widget - { - public: - Widget(); - Widget(const Widget &other); - Widget& operator =(const Widget &other); - - void copyTo(Widget &dst); - - void setColor(const Color &color); - void setPose(const Affine3f &pose); - void updatePose(const Affine3f &pose); - Affine3f getPose() const; - - private: - class Impl; - cv::Ptr impl_; - friend struct WidgetAccessor; - }; - - class LineWidget : public Widget - { - public: - LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color(255,255,255)); - }; } diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index a610e07ad..5c88f431e 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -10,6 +10,7 @@ #include #include +#include #include namespace temp_viz @@ -33,8 +34,8 @@ namespace temp_viz bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String& id = "cloud"); void showLine(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color = Color::white()); - void showPlane(const String& id, const Vec4f& coefs, const Color& color = Color::white()); - void showPlane(const String& id, const Vec4f& coefs, const Point3f& pt, const Color& color = Color::white()); + void showPlane(const String& id, const Vec4f& coeffs, const Color& color = Color::white()); + void showPlane(const String& id, const Vec4f& coeffs, const Point3f& pt, const Color& color = Color::white()); void showCube(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color = Color::white()); void showCylinder(const String& id, const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int num_sides, const Color& color = Color::white()); void showCircle(const String& id, const Point3f& pt, double radius, const Color& color = Color::white()); diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index 58907e14b..3df7773ed 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -1,11 +1,15 @@ #pragma once -#include +#include +#include +#include namespace temp_viz { - struct WidgetAccessor + //The class is only that depends on VTK in its interface. + //It is indended for those user who want to develop own widgets system using VTK library API. + struct CV_EXPORTS WidgetAccessor { - static CV_EXPORTS vtkSmartPointer getActor(const Widget &widget); + static vtkSmartPointer getActor(const Widget &widget); }; -} \ No newline at end of file +} diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp new file mode 100644 index 000000000..b66853310 --- /dev/null +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include + + +namespace temp_viz +{ + ///////////////////////////////////////////////////////////////////////////// + /// brief The base class for all widgets + class CV_EXPORTS Widget + { + public: + Widget(); + Widget(const Widget &other); + Widget& operator =(const Widget &other); + + void copyTo(Widget &dst); + + void setColor(const Color &color); + void setPose(const Affine3f &pose); + void updatePose(const Affine3f &pose); + Affine3f getPose() const; + + private: + class Impl; + cv::Ptr impl_; + friend struct WidgetAccessor; + }; + + + class CV_EXPORTS LineWidget : public Widget + { + public: + LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + }; + + +} diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index bb59ca949..f6779d3ce 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -154,3 +154,5 @@ #include +#include "opencv2/viz/widget_accessor.hpp" +#include diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp new file mode 100644 index 000000000..0fedd8c4c --- /dev/null +++ b/modules/viz/src/simple_widgets.cpp @@ -0,0 +1,18 @@ +#include "precomp.hpp" + + +temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) +{ + vtkSmartPointer line = vtkSmartPointer::New(); + line->SetPoint1 (pt1.x, pt1.y, pt1.z); + line->SetPoint2 (pt2.x, pt2.y, pt2.z); + line->Update (); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(line->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + + setColor(color); +} diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 8500d2afe..ebebf2cb5 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -20,134 +20,3 @@ temp_viz::Color temp_viz::Color::white() { return Color(255, 255, 255); } temp_viz::Color temp_viz::Color::gray() { return Color(128, 128, 128); } -class temp_viz::Widget::Impl -{ -public: - String id; - vtkSmartPointer actor; - - Impl() - { - actor = vtkSmartPointer::New (); - } - - vtkSmartPointer getActor() - { - return actor; - } - - void setColor(const Color & color) - { - Color c = vtkcolor(color); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetProperty ()->SetColor (c.val); - actor->GetProperty ()->SetEdgeColor (c.val); - actor->GetProperty ()->SetAmbient (0.8); - actor->GetProperty ()->SetDiffuse (0.8); - actor->GetProperty ()->SetSpecular (0.8); - actor->GetProperty ()->SetLighting (0); - actor->Modified (); - } - - void setPose(const Affine3f &pose) - { - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); - } - - void updatePose(const Affine3f &pose) - { - vtkSmartPointer matrix = actor->GetUserMatrix(); - Matx44f matrix_cv; - convertToCvMatrix(matrix, matrix_cv); - matrix = convertToVtkMatrix ((pose * Affine3f(matrix_cv)).matrix); - - actor->SetUserMatrix (matrix); - actor->Modified (); - } - - Affine3f getPose() const - { - vtkSmartPointer matrix = actor->GetUserMatrix(); - Matx44f matrix_cv; - convertToCvMatrix(matrix, matrix_cv); - return Affine3f(matrix_cv); - } - -protected: - - vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m) const - { - vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - vtk_matrix->SetElement(i, k, m(i, k)); - return vtk_matrix; - } - - void convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m) const - { - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - m(i,k) = vtk_matrix->GetElement (i, k); - } -}; - -temp_viz::Widget::Widget() -{ - impl_ = new Impl(); -} - -temp_viz::Widget::Widget(const Widget &other) -{ - impl_ = other.impl_; -} - -temp_viz::Widget& temp_viz::Widget::operator =(const Widget &other) -{ - if (this != &other) - impl_ = other.impl_; - return *this; -} - -void temp_viz::Widget::copyTo(Widget &dst) -{ - // TODO Deep copy the data if there is any -} - -void temp_viz::Widget::setColor(const Color &color) -{ - impl_->setColor(color); -} - -void temp_viz::Widget::setPose(const Affine3f &pose) -{ - impl_->setPose(pose); -} - -void temp_viz::Widget::updatePose(const Affine3f &pose) -{ - impl_->updatePose(pose); -} - -temp_viz::Affine3f temp_viz::Widget::getPose() const -{ - return impl_->getPose(); -} - -#include "opencv2/viz/widget_accessor.hpp" - -vtkSmartPointer temp_viz::WidgetAccessor::getActor(const temp_viz::Widget &widget) -{ - return widget.impl_->actor; -} - -temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) : Widget() -{ - // Create the line and set actor's data - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(createLine(pt1,pt2)); - temp_viz::WidgetAccessor::getActor(*this)->SetMapper(mapper); - setColor(color); -} \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index dcd0bf7f1..76e7459eb 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -77,14 +77,14 @@ void temp_viz::Viz3d::showLine(const String& id, const Point3f& pt1, const Point impl_->showLine(id, pt1, pt2, color); } -void temp_viz::Viz3d::showPlane(const String& id, const Vec4f &coefs, const Color& color) +void temp_viz::Viz3d::showPlane(const String& id, const Vec4f &coeffs, const Color& color) { - impl_->showPlane(id, coefs, color); + impl_->showPlane(id, coeffs, color); } -void temp_viz::Viz3d::showPlane(const String& id, const Vec4f &coefs, const Point3f& pt, const Color& color) +void temp_viz::Viz3d::showPlane(const String& id, const Vec4f &coeffs, const Point3f& pt, const Color& color) { - impl_->showPlane(id, coefs, pt, color); + impl_->showPlane(id, coeffs, pt, color); } void temp_viz::Viz3d::showCube(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index e25bca009..627ec48d9 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -416,7 +416,7 @@ void temp_viz::Viz3d::VizImpl::showLine (const String& id, const Point3f& pt1, c } } -void temp_viz::Viz3d::VizImpl::showPlane (const String& id, const cv::Vec4f &coefs, const Color& color) +void temp_viz::Viz3d::VizImpl::showPlane (const String& id, const cv::Vec4f &coeffs, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); @@ -426,7 +426,7 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String& id, const cv::Vec4f &coe if (exists) { vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coefs)); + reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coeffs)); actor->GetProperty ()->SetColor (c.val); actor->GetMapper ()->ScalarVisibilityOff (); actor->Modified (); @@ -434,7 +434,7 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String& id, const cv::Vec4f &coe else { // Create a plane - vtkSmartPointer data = createPlane (coefs); + vtkSmartPointer data = createPlane (coeffs); // Create an Actor vtkSmartPointer actor; @@ -451,7 +451,7 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String& id, const cv::Vec4f &coe } } -void temp_viz::Viz3d::VizImpl::showPlane (const String& id ,const cv::Vec4f &coefs, const Point3f& pt, const Color& color) +void temp_viz::Viz3d::VizImpl::showPlane (const String& id ,const cv::Vec4f &coeffs, const Point3f& pt, const Color& color) { // Check if this Id already exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); @@ -461,7 +461,7 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String& id ,const cv::Vec4f &coe if (exists) { vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coefs, pt)); + reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coeffs, pt)); actor->GetProperty ()->SetColor (c.val); actor->GetMapper ()->ScalarVisibilityOff (); actor->Modified (); @@ -469,7 +469,7 @@ void temp_viz::Viz3d::VizImpl::showPlane (const String& id ,const cv::Vec4f &coe else { // Create a plane - vtkSmartPointer data = createPlane (coefs, pt); + vtkSmartPointer data = createPlane (coeffs, pt); // Create an Actor vtkSmartPointer actor; diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp new file mode 100644 index 000000000..cbc18d119 --- /dev/null +++ b/modules/viz/src/widget.cpp @@ -0,0 +1,110 @@ +#include "precomp.hpp" + +class temp_viz::Widget::Impl +{ +public: + vtkSmartPointer actor; + + Impl() : actor(vtkSmartPointer::New()) {} + + void setColor(const Color& color) + { + Color c = vtkcolor(color); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetProperty ()->SetColor (c.val); + actor->GetProperty ()->SetEdgeColor (c.val); + actor->GetProperty ()->SetAmbient (0.8); + actor->GetProperty ()->SetDiffuse (0.8); + actor->GetProperty ()->SetSpecular (0.8); + actor->GetProperty ()->SetLighting (0); + actor->Modified (); + } + + void setPose(const Affine3f& pose) + { + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified (); + } + + void updatePose(const Affine3f& pose) + { + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv = convertToMatx(matrix); + + Affine3f updated_pose = pose * Affine3f(matrix_cv); + matrix = convertToVtkMatrix(updated_pose.matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); + } + + Affine3f getPose() const + { + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv = convertToMatx(matrix); + return Affine3f(matrix_cv); + } + +protected: + + static vtkSmartPointer convertToVtkMatrix (const cv::Matx44f& m) + { + vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + vtk_matrix->SetElement(i, k, m(i, k)); + return vtk_matrix; + } + + static cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix) + { + cv::Matx44f m; + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + m(i, k) = vtk_matrix->GetElement (i, k); + return m; + } +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// stream accessor implementaion + +vtkSmartPointer temp_viz::WidgetAccessor::getActor(const Widget& widget) +{ + return widget.impl_->actor; +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// widget implementaion + +temp_viz::Widget::Widget() +{ + impl_ = new Impl(); +} + +temp_viz::Widget::Widget(const Widget& other) +{ + impl_ = other.impl_; +} + +temp_viz::Widget& temp_viz::Widget::operator =(const Widget &other) +{ + if (this != &other) + impl_ = other.impl_; + return *this; +} + +void temp_viz::Widget::copyTo(Widget& /*dst*/) +{ + // TODO Deep copy the data if there is any +} + +void temp_viz::Widget::setColor(const Color& color) { impl_->setColor(color); } +void temp_viz::Widget::setPose(const Affine3f& pose) { impl_->setPose(pose); } +void temp_viz::Widget::updatePose(const Affine3f& pose) { impl_->updatePose(pose); } +temp_viz::Affine3f temp_viz::Widget::getPose() const { return impl_->getPose(); } + + + diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 1bce1a356..8c7ecb17c 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -47,7 +47,7 @@ #include #include -#include +#include #include cv::Mat cvcloud_load() From 141cfd562c6fb9f09c3cb9d40d0baa8fb464a7a1 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Thu, 4 Jul 2013 15:11:04 +0400 Subject: [PATCH 038/205] widget_accessor.hpp - minimize dependencies --- modules/viz/include/opencv2/viz/widget_accessor.hpp | 8 +++++--- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/types.cpp | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index 3df7773ed..4b1c5ef15 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -1,15 +1,17 @@ #pragma once -#include +#include #include #include namespace temp_viz { + class Widget; + //The class is only that depends on VTK in its interface. - //It is indended for those user who want to develop own widgets system using VTK library API. + //It is indended for those users who want to develop own widgets system using VTK library API. struct CV_EXPORTS WidgetAccessor { - static vtkSmartPointer getActor(const Widget &widget); + static vtkSmartPointer getActor(const Widget &widget); }; } diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index b66853310..5d1cfe847 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -6,7 +6,7 @@ namespace temp_viz { ///////////////////////////////////////////////////////////////////////////// - /// brief The base class for all widgets + /// The base class for all widgets class CV_EXPORTS Widget { public: diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index ebebf2cb5..765913614 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -1,7 +1,7 @@ #include ////////////////////////////////////////////////////////////////////////////////////////////////////// -/// cv::Color +/// cv::viz::Color temp_viz::Color::Color() : Scalar(0, 0, 0) {} temp_viz::Color::Color(double gray) : Scalar(gray, gray, gray) {} From 158ed299c1c8d7182fa733f53ad7b07deb3a27e6 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 15:57:49 +0300 Subject: [PATCH 039/205] reference counting in widget --- modules/viz/include/opencv2/viz/widgets.hpp | 8 ++++- modules/viz/src/widget.cpp | 34 ++++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 5d1cfe847..9a0b15260 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -14,6 +14,8 @@ namespace temp_viz Widget(const Widget &other); Widget& operator =(const Widget &other); + ~Widget(); + void copyTo(Widget &dst); void setColor(const Color &color); @@ -23,7 +25,11 @@ namespace temp_viz private: class Impl; - cv::Ptr impl_; + Impl* impl_; + + void create(); + void release(); + friend struct WidgetAccessor; }; diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index cbc18d119..f61379af0 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -4,6 +4,7 @@ class temp_viz::Widget::Impl { public: vtkSmartPointer actor; + int ref_counter; Impl() : actor(vtkSmartPointer::New()) {} @@ -79,23 +80,34 @@ vtkSmartPointer temp_viz::WidgetAccessor::getActor(const Widget& wi /////////////////////////////////////////////////////////////////////////////////////////////// /// widget implementaion -temp_viz::Widget::Widget() +temp_viz::Widget::Widget() : impl_(0) { - impl_ = new Impl(); + create(); } -temp_viz::Widget::Widget(const Widget& other) +temp_viz::Widget::Widget(const Widget& other) : impl_(other.impl_) { - impl_ = other.impl_; + if (impl_) + CV_XADD(&impl_->ref_counter, 1); } temp_viz::Widget& temp_viz::Widget::operator =(const Widget &other) { if (this != &other) + { + release(); impl_ = other.impl_; + if (impl_) + CV_XADD(&impl_->ref_counter, 1); + } return *this; } +temp_viz::Widget::~Widget() +{ + release(); +} + void temp_viz::Widget::copyTo(Widget& /*dst*/) { // TODO Deep copy the data if there is any @@ -106,5 +118,19 @@ void temp_viz::Widget::setPose(const Affine3f& pose) { impl_->setPose(pose); } void temp_viz::Widget::updatePose(const Affine3f& pose) { impl_->updatePose(pose); } temp_viz::Affine3f temp_viz::Widget::getPose() const { return impl_->getPose(); } +void temp_viz::Widget::create() +{ + if (impl_) + release(); + impl_ = new Impl(); + impl_->ref_counter = 1; +} +void temp_viz::Widget::release() +{ + if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) + { + delete impl_; + } +} From ba89a6a34a66f69dcb95653251dbf2e965b46c18 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 16:05:05 +0300 Subject: [PATCH 040/205] line widget set/get line width --- modules/viz/include/opencv2/viz/widgets.hpp | 3 +++ modules/viz/src/simple_widgets.cpp | 12 ++++++++++++ modules/viz/test/test_viz3d.cpp | 1 + 3 files changed, 16 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 9a0b15260..2da99fae2 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -38,6 +38,9 @@ namespace temp_viz { public: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + + void setLineWidth(float line_width); + float getLineWidth(); }; diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 0fedd8c4c..f059974ce 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -16,3 +16,15 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C setColor(color); } + +void temp_viz::LineWidget::setLineWidth(float line_width) +{ + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->GetProperty()->SetLineWidth(line_width); +} + +float temp_viz::LineWidget::getLineWidth() +{ + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + return actor->GetProperty()->GetLineWidth(); +} \ No newline at end of file diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 8c7ecb17c..856c105ed 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -115,6 +115,7 @@ TEST(Viz_viz3d, accuracy) v.setShapePose("sphere1", cloudPosition); v.setShapePose("arrow1", cloudPosition); lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); + lw.setLineWidth(lw.getLineWidth()+pos_x * 10); angle_x += 0.1f; angle_y -= 0.1f; From 3d3e3fd4702661fdae9c7cb995ea953333ecb71a Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 16:15:20 +0300 Subject: [PATCH 041/205] plane widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 7 ++++ modules/viz/src/simple_widgets.cpp | 42 ++++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 4 ++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 2da99fae2..fc2660d7b 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -42,6 +42,13 @@ namespace temp_viz void setLineWidth(float line_width); float getLineWidth(); }; + + class CV_EXPORTS PlaneWidget : public Widget + { + public: + PlaneWidget(const Vec4f& coefs, const Color &color = Color::white()); + PlaneWidget(const Vec4f& coefs, const Point3f& pt, const Color &color = Color::white()); + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index f059974ce..27e478964 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -1,6 +1,7 @@ #include "precomp.hpp" - +/////////////////////////////////////////////////////////////////////////////////////////////// +/// line widget implementation temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) { vtkSmartPointer line = vtkSmartPointer::New(); @@ -27,4 +28,43 @@ float temp_viz::LineWidget::getLineWidth() { vtkSmartPointer actor = WidgetAccessor::getActor(*this); return actor->GetProperty()->GetLineWidth(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// plane widget implementation + +temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Color &color) +{ + vtkSmartPointer plane = vtkSmartPointer::New (); + plane->SetNormal (coefs[0], coefs[1], coefs[2]); + double norm = cv::norm(cv::Vec3f(coefs.val)); + plane->Push (-coefs[3] / norm); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(plane->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + + setColor(color); +} + +temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, const Color &color) +{ + vtkSmartPointer plane = vtkSmartPointer::New (); + cv::Point3f coefs3(coefs[0], coefs[1], coefs[2]); + double norm_sqr = 1.0 / coefs3.dot (coefs3); + plane->SetNormal(coefs[0], coefs[1], coefs[2]); + + double t = coefs3.dot(pt) + coefs[3]; + cv::Vec3f p_center = pt - coefs3 * t * norm_sqr; + plane->SetCenter (p_center[0], p_center[1], p_center[2]); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(plane->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + + setColor(color); } \ No newline at end of file diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 856c105ed..f3ddfc7e3 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -95,7 +95,9 @@ TEST(Viz_viz3d, accuracy) v.showSphere("sphere1", cv::Point3f(0,0,0), 0.5, temp_viz::Color(0,0,255)); v.showArrow("arrow1", cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0,1.0,1.0), temp_viz::Color(0,255,0)); + temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0)); v.showWidget("line", lw); + v.showWidget("plane", pw); temp_viz::LineWidget lw2 = lw; @@ -117,6 +119,8 @@ TEST(Viz_viz3d, accuracy) lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); lw.setLineWidth(lw.getLineWidth()+pos_x * 10); + pw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + angle_x += 0.1f; angle_y -= 0.1f; angle_z += 0.1f; From d80a965f97460a035a60c88fe2db0f6be5b363be Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 16:32:06 +0300 Subject: [PATCH 042/205] sphere widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 6 ++++++ modules/viz/src/simple_widgets.cpp | 22 +++++++++++++++++++++ modules/viz/test/test_viz3d.cpp | 8 ++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index fc2660d7b..69c2c5624 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -49,6 +49,12 @@ namespace temp_viz PlaneWidget(const Vec4f& coefs, const Color &color = Color::white()); PlaneWidget(const Vec4f& coefs, const Point3f& pt, const Color &color = Color::white()); }; + + class CV_EXPORTS SphereWidget : public Widget + { + public: + SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 27e478964..dcca437ba 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -66,5 +66,27 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, const vtkSmartPointer actor = WidgetAccessor::getActor(*this); actor->SetMapper(mapper); + setColor(color); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// sphere widget implementation + +temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution, const Color &color) +{ + vtkSmartPointer sphere = vtkSmartPointer::New (); + sphere->SetRadius (radius); + sphere->SetCenter (center.x, center.y, center.z); + sphere->SetPhiResolution (sphere_resolution); + sphere->SetThetaResolution (sphere_resolution); + sphere->LatLongTessellationOff (); + sphere->Update (); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(sphere->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + setColor(color); } \ No newline at end of file diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index f3ddfc7e3..cf666d802 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -92,12 +92,14 @@ TEST(Viz_viz3d, accuracy) int col_green = 0; int col_red = 0; v.showCircle("circle1", cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); - v.showSphere("sphere1", cv::Point3f(0,0,0), 0.5, temp_viz::Color(0,0,255)); v.showArrow("arrow1", cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0,1.0,1.0), temp_viz::Color(0,255,0)); temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0)); + temp_viz::SphereWidget sw(cv::Point3f(0,0,0), 0.5); + v.showWidget("line", lw); v.showWidget("plane", pw); + v.showWidget("sphere", sw); temp_viz::LineWidget lw2 = lw; @@ -114,13 +116,15 @@ TEST(Viz_viz3d, accuracy) // v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); // v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); v.setShapePose("circle1", cloudPosition); - v.setShapePose("sphere1", cloudPosition); v.setShapePose("arrow1", cloudPosition); lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); lw.setLineWidth(lw.getLineWidth()+pos_x * 10); pw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + sw.setPose(cloudPosition); + pw.setPose(cloudPosition); + angle_x += 0.1f; angle_y -= 0.1f; angle_z += 0.1f; From f97c3c8b06278e61767accf3d135f071936147db Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 16:54:46 +0300 Subject: [PATCH 043/205] circle widget and arrow widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 11 +++ modules/viz/src/simple_widgets.cpp | 97 ++++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 12 ++- 3 files changed, 115 insertions(+), 5 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 69c2c5624..3535f486a 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -55,6 +55,17 @@ namespace temp_viz public: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); }; + + class CV_EXPORTS ArrowWidget : public Widget + { + public: + ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color = Color::white()); + }; + class CV_EXPORTS CircleWidget : public Widget + { + public: + CircleWidget(const Point3f& pt, double radius, const Color &color = Color::white()); + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index dcca437ba..51edc9b13 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -89,4 +89,99 @@ temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, in actor->SetMapper(mapper); setColor(color); -} \ No newline at end of file +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// arrow widget implementation + +temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color) +{ + vtkSmartPointer arrowSource = vtkSmartPointer::New (); + + float startPoint[3], endPoint[3]; + startPoint[0] = pt1.x; + startPoint[1] = pt1.y; + startPoint[2] = pt1.z; + endPoint[0] = pt2.x; + endPoint[1] = pt2.y; + endPoint[2] = pt2.z; + float normalizedX[3], normalizedY[3], normalizedZ[3]; + + // The X axis is a vector from start to end + vtkMath::Subtract(endPoint, startPoint, normalizedX); + float length = vtkMath::Norm(normalizedX); + vtkMath::Normalize(normalizedX); + + // The Z axis is an arbitrary vecotr cross X + float arbitrary[3]; + arbitrary[0] = vtkMath::Random(-10,10); + arbitrary[1] = vtkMath::Random(-10,10); + arbitrary[2] = vtkMath::Random(-10,10); + vtkMath::Cross(normalizedX, arbitrary, normalizedZ); + vtkMath::Normalize(normalizedZ); + + // The Y axis is Z cross X + vtkMath::Cross(normalizedZ, normalizedX, normalizedY); + vtkSmartPointer matrix = vtkSmartPointer::New(); + + // Create the direction cosine matrix + matrix->Identity(); + for (unsigned int i = 0; i < 3; i++) + { + matrix->SetElement(i, 0, normalizedX[i]); + matrix->SetElement(i, 1, normalizedY[i]); + matrix->SetElement(i, 2, normalizedZ[i]); + } + + // Apply the transforms + vtkSmartPointer transform = + vtkSmartPointer::New(); + transform->Translate(startPoint); + transform->Concatenate(matrix); + transform->Scale(length, length, length); + + // Transform the polydata + vtkSmartPointer transformPD = + vtkSmartPointer::New(); + transformPD->SetTransform(transform); + transformPD->SetInputConnection(arrowSource->GetOutputPort()); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(transformPD->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + + setColor(color); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// circle widget implementation + +temp_viz::CircleWidget::CircleWidget(const Point3f& pt, double radius, const Color &color) +{ + vtkSmartPointer disk = vtkSmartPointer::New (); + // Maybe the resolution should be lower e.g. 50 or 25 + disk->SetCircumferentialResolution (100); + disk->SetInnerRadius (radius - 0.001); + disk->SetOuterRadius (radius + 0.001); + disk->SetCircumferentialResolution (20); + + // Set the circle origin + vtkSmartPointer t = vtkSmartPointer::New (); + t->Identity (); + t->Translate (pt.x, pt.y, pt.z); + + vtkSmartPointer tf = vtkSmartPointer::New (); + tf->SetTransform (t); + tf->SetInputConnection (disk->GetOutputPort ()); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(tf->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + + setColor(color); +} + diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index cf666d802..55e590e16 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -91,15 +91,18 @@ TEST(Viz_viz3d, accuracy) int col_blue = 0; int col_green = 0; int col_red = 0; - v.showCircle("circle1", cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); - v.showArrow("arrow1", cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); +// v.showCircle("circle1", cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0,1.0,1.0), temp_viz::Color(0,255,0)); temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0)); temp_viz::SphereWidget sw(cv::Point3f(0,0,0), 0.5); + temp_viz::ArrowWidget aw(cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); + temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); v.showWidget("line", lw); v.showWidget("plane", pw); v.showWidget("sphere", sw); + v.showWidget("arrow", aw); + v.showWidget("circle", cw); temp_viz::LineWidget lw2 = lw; @@ -115,8 +118,7 @@ TEST(Viz_viz3d, accuracy) // v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z), temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); // v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); // v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); - v.setShapePose("circle1", cloudPosition); - v.setShapePose("arrow1", cloudPosition); +// v.setShapePose("circle1", cloudPosition); lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); lw.setLineWidth(lw.getLineWidth()+pos_x * 10); @@ -124,6 +126,8 @@ TEST(Viz_viz3d, accuracy) sw.setPose(cloudPosition); pw.setPose(cloudPosition); + aw.setPose(cloudPosition); + cw.setPose(cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; From f07486b563d92bf1864992eec5342bad4cd77de3 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 17:44:41 +0300 Subject: [PATCH 044/205] cylinder widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 6 +++++ modules/viz/src/simple_widgets.cpp | 25 ++++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 6 ++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 3535f486a..a731dcf93 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -67,5 +67,11 @@ namespace temp_viz public: CircleWidget(const Point3f& pt, double radius, const Color &color = Color::white()); }; + + class CV_EXPORTS CylinderWidget : public Widget + { + public: + CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 51edc9b13..36b22d99d 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -158,7 +158,7 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const /////////////////////////////////////////////////////////////////////////////////////////////// /// circle widget implementation -temp_viz::CircleWidget::CircleWidget(const Point3f& pt, double radius, const Color &color) +temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, const temp_viz::Color& color) { vtkSmartPointer disk = vtkSmartPointer::New (); // Maybe the resolution should be lower e.g. 50 or 25 @@ -185,3 +185,26 @@ temp_viz::CircleWidget::CircleWidget(const Point3f& pt, double radius, const Col setColor(color); } +/////////////////////////////////////////////////////////////////////////////////////////////// +/// cylinder widget implementation + +temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides, const Color &color) +{ + const cv::Point3f pt2 = pt_on_axis + axis_direction; + vtkSmartPointer line = vtkSmartPointer::New (); + line->SetPoint1 (pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); + line->SetPoint2 (pt2.x, pt2.y, pt2.z); + + vtkSmartPointer tuber = vtkSmartPointer::New (); + tuber->SetInputConnection (line->GetOutputPort ()); + tuber->SetRadius (radius); + tuber->SetNumberOfSides (numsides); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(tuber->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + + setColor(color); +} diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 55e590e16..66a78b1b3 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -92,17 +92,19 @@ TEST(Viz_viz3d, accuracy) int col_green = 0; int col_red = 0; // v.showCircle("circle1", cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); - temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0,1.0,1.0), temp_viz::Color(0,255,0)); + temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(4.0,4.0,4.0), temp_viz::Color(0,255,0)); temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0)); temp_viz::SphereWidget sw(cv::Point3f(0,0,0), 0.5); temp_viz::ArrowWidget aw(cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); + temp_viz::CylinderWidget cyw(cv::Point3f(0,0,0), cv::Point3f(-1,-1,-1), 0.5, 30, temp_viz::Color(0,255,0)); v.showWidget("line", lw); v.showWidget("plane", pw); v.showWidget("sphere", sw); v.showWidget("arrow", aw); v.showWidget("circle", cw); + v.showWidget("cylinder", cyw); temp_viz::LineWidget lw2 = lw; @@ -128,6 +130,8 @@ TEST(Viz_viz3d, accuracy) pw.setPose(cloudPosition); aw.setPose(cloudPosition); cw.setPose(cloudPosition); + cyw.setPose(cloudPosition); + lw.setPose(cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; From 03cc439b08b78075c77c6738c3aa0f25c629b787 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 17:59:11 +0300 Subject: [PATCH 045/205] cube widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 6 ++++++ modules/viz/src/simple_widgets.cpp | 17 +++++++++++++++++ modules/viz/test/test_viz3d.cpp | 3 +++ 3 files changed, 26 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index a731dcf93..9f83d3c7b 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -73,5 +73,11 @@ namespace temp_viz public: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); }; + + class CV_EXPORTS CubeWidget : public Widget + { + public: + CubeWidget(const Point3f& pt_min, const Point3f& pt_max, const Color &color = Color::white()); + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 36b22d99d..7f7db1b6c 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -208,3 +208,20 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 setColor(color); } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// cylinder widget implementation + +temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, const Color &color) +{ + vtkSmartPointer cube = vtkSmartPointer::New (); + cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput(cube->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + + setColor(color); +} diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 66a78b1b3..720145a22 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -98,6 +98,7 @@ TEST(Viz_viz3d, accuracy) temp_viz::ArrowWidget aw(cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); temp_viz::CylinderWidget cyw(cv::Point3f(0,0,0), cv::Point3f(-1,-1,-1), 0.5, 30, temp_viz::Color(0,255,0)); + temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1), temp_viz::Color(0,0,255)); v.showWidget("line", lw); v.showWidget("plane", pw); @@ -105,6 +106,7 @@ TEST(Viz_viz3d, accuracy) v.showWidget("arrow", aw); v.showWidget("circle", cw); v.showWidget("cylinder", cyw); + v.showWidget("cube", cuw); temp_viz::LineWidget lw2 = lw; @@ -132,6 +134,7 @@ TEST(Viz_viz3d, accuracy) cw.setPose(cloudPosition); cyw.setPose(cloudPosition); lw.setPose(cloudPosition); + cuw.setPose(cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; From ecdd8513fd937162ef932ecd26de57c1268dbccd Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 18:19:06 +0300 Subject: [PATCH 046/205] coordinate system widget implementation, update pose fix --- modules/viz/include/opencv2/viz/widgets.hpp | 6 +++ modules/viz/src/simple_widgets.cpp | 50 +++++++++++++++++++++ modules/viz/src/widget.cpp | 5 +++ modules/viz/test/test_viz3d.cpp | 18 +++----- 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 9f83d3c7b..122c0c7bf 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -79,5 +79,11 @@ namespace temp_viz public: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, const Color &color = Color::white()); }; + + class CV_EXPORTS CoordinateSystemWidget : public Widget + { + public: + CoordinateSystemWidget(double scale, const Affine3f& affine); + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 7f7db1b6c..45e5a9755 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -1,4 +1,5 @@ #include "precomp.hpp" +#include /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation @@ -225,3 +226,52 @@ temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, c setColor(color); } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// coordinate system widget implementation + +temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Affine3f& affine) +{ + vtkSmartPointer axes = vtkSmartPointer::New (); + axes->SetOrigin (0, 0, 0); + axes->SetScaleFactor (scale); + + vtkSmartPointer axes_colors = vtkSmartPointer::New (); + axes_colors->Allocate (6); + axes_colors->InsertNextValue (0.0); + axes_colors->InsertNextValue (0.0); + axes_colors->InsertNextValue (0.5); + axes_colors->InsertNextValue (0.5); + axes_colors->InsertNextValue (1.0); + axes_colors->InsertNextValue (1.0); + + vtkSmartPointer axes_data = axes->GetOutput (); + axes_data->Update (); + axes_data->GetPointData ()->SetScalars (axes_colors); + + vtkSmartPointer axes_tubes = vtkSmartPointer::New (); + axes_tubes->SetInput (axes_data); + axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); + axes_tubes->SetNumberOfSides (6); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetScalarModeToUsePointData (); + mapper->SetInput(axes_tubes->GetOutput ()); + + vtkSmartPointer actor = WidgetAccessor::getActor(*this); + actor->SetMapper(mapper); + + cv::Vec3d t = affine.translation(); + actor->SetPosition (t[0], t[1], t[2]); + + cv::Matx33f m = affine.rotation(); + + cv::Vec3f rvec; + cv::Rodrigues(m, rvec); + + float r_angle = cv::norm(rvec); + rvec *= 1.f/r_angle; + + actor->SetOrientation(0,0,0); + actor->RotateWXYZ(r_angle*180/CV_PI,rvec[0], rvec[1], rvec[2]); +} diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index f61379af0..0657c5414 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -31,6 +31,11 @@ public: void updatePose(const Affine3f& pose) { vtkSmartPointer matrix = actor->GetUserMatrix(); + if (!matrix) + { + setPose(pose); + return ; + } Matx44f matrix_cv = convertToMatx(matrix); Affine3f updated_pose = pose * Affine3f(matrix_cv); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 720145a22..6cb27dbc2 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -73,8 +73,6 @@ TEST(Viz_viz3d, accuracy) v.setBackgroundColor(); - v.addCoordinateSystem(1.0, cv::Affine3f::Identity()); - cv::Mat cloud = cvcloud_load(); cv::Mat colors(cloud.size(), CV_8UC3, cv::Scalar(0, 255, 0)); @@ -91,7 +89,7 @@ TEST(Viz_viz3d, accuracy) int col_blue = 0; int col_green = 0; int col_red = 0; -// v.showCircle("circle1", cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); + temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(4.0,4.0,4.0), temp_viz::Color(0,255,0)); temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0)); temp_viz::SphereWidget sw(cv::Point3f(0,0,0), 0.5); @@ -99,6 +97,7 @@ TEST(Viz_viz3d, accuracy) temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); temp_viz::CylinderWidget cyw(cv::Point3f(0,0,0), cv::Point3f(-1,-1,-1), 0.5, 30, temp_viz::Color(0,255,0)); temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1), temp_viz::Color(0,0,255)); + temp_viz::CoordinateSystemWidget csw(1.0f, cv::Affine3f::Identity()); v.showWidget("line", lw); v.showWidget("plane", pw); @@ -107,6 +106,7 @@ TEST(Viz_viz3d, accuracy) v.showWidget("circle", cw); v.showWidget("cylinder", cyw); v.showWidget("cube", cuw); + v.showWidget("coordinateSystem", csw); temp_viz::LineWidget lw2 = lw; @@ -114,15 +114,7 @@ TEST(Viz_viz3d, accuracy) { // Creating new point cloud with id cloud1 cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); -// v.showPointCloud("cloud1", cloud, temp_viz::Color(col_blue, col_green, col_red), cloudPosition); -// v.showLine("line1", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); -// v.showLine("line2", cv::Point3f(0.0,0.0,0.0), cv::Point3f(1.0f-pos_x, pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); -// v.showLine("line3", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, 1.0f-pos_y, pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); -// v.showLine("line4", cv::Point3f(0.0,0.0,0.0), cv::Point3f(pos_x, pos_y, 1.0f-pos_z) , temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); -// v.showPlane("plane1", cv::Vec4f(pos_x*pos_y,pos_y,pos_z,pos_x+pos_y*pos_z), temp_viz::Color(255-col_blue, 255-col_green, 255-col_red)); -// v.showCube("cube1", cv::Point3f(pos_x, pos_y, pos_z), cv::Point3f(pos_x+0.5, pos_y+0.5, pos_z+0.5), temp_viz::Color(255,150,50)); -// v.showCylinder("cylinder1", cv::Point3f(0,0,0), cv::Point3f(pos_x, 1.0, 1.0), 0.5, 5*pos_x+3, temp_viz::Color(0,255,0)); -// v.setShapePose("circle1", cloudPosition); + lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); lw.setLineWidth(lw.getLineWidth()+pos_x * 10); @@ -134,7 +126,7 @@ TEST(Viz_viz3d, accuracy) cw.setPose(cloudPosition); cyw.setPose(cloudPosition); lw.setPose(cloudPosition); - cuw.setPose(cloudPosition); + cuw.setPose(cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; From 5bb95c4110e67e42c6118be9101c10151e8330be Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 18:36:26 +0300 Subject: [PATCH 047/205] remove widget implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/q/viz3d_impl.hpp | 2 ++ modules/viz/src/viz3d.cpp | 5 +++++ modules/viz/src/viz3d_impl.cpp | 18 ++++++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 5c88f431e..19fe4c03a 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -72,6 +72,7 @@ namespace temp_viz bool wasStopped() const; void showWidget(const String &id, const Widget &widget); + bool removeWidget(const String &id); private: Viz3d(const Viz3d&); Viz3d& operator=(const Viz3d&); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 9544a3142..2f09aea0b 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -247,6 +247,8 @@ public: void setSize (int xw, int yw); void showWidget(const String &id, const Widget &widget); + bool removeWidget(const String &id); + void all_data(); private: diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 76e7459eb..76392acf7 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -143,3 +143,8 @@ void temp_viz::Viz3d::showWidget(const String &id, const Widget &widget) { impl_->showWidget(id, widget); } + +bool temp_viz::Viz3d::removeWidget(const String &id) +{ + return impl_->removeWidget(id); +} diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 627ec48d9..22eaf21ba 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1183,3 +1183,21 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget renderer_->AddActor(WidgetAccessor::getActor(widget)); (*widget_actor_map_)[id].actor = WidgetAccessor::getActor(widget); } + +bool temp_viz::Viz3d::VizImpl::removeWidget(const String &id) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = !(wam_itr == widget_actor_map_->end()); + + if (!exists) + { + std::cout << "[removeWidget] A widget with id <" << id << "> does not exist!" << std::endl; + return false; + } + + if (!removeActorFromRenderer (wam_itr->second.actor)) + return false; + + widget_actor_map_->erase(wam_itr); + return true; +} From 4c3d1d583a3d09194db28e76bb76c55b95de7d00 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 18:47:52 +0300 Subject: [PATCH 048/205] remove ModelCoefficients, remove showShape methods from viz3d --- modules/viz/include/opencv2/viz/types.hpp | 7 - modules/viz/include/opencv2/viz/viz3d.hpp | 25 -- modules/viz/src/q/viz3d_impl.hpp | 47 ---- modules/viz/src/viz3d.cpp | 60 ----- modules/viz/src/viz3d_impl.cpp | 303 ---------------------- modules/viz/src/viz_main.cpp | 65 ----- 6 files changed, 507 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index b28996a9e..92b277857 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -35,13 +35,6 @@ namespace temp_viz using cv::DataDepth; using cv::DataType; - - struct CV_EXPORTS ModelCoefficients - { - std::vector values; - }; - - class CV_EXPORTS Color : public Scalar { public: diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 19fe4c03a..b4b697b90 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -26,43 +26,18 @@ namespace temp_viz void setBackgroundColor(const Color& color = Color::black()); - void addCoordinateSystem(double scale, const Affine3f& t, const String& id = "coordinate"); - void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); void showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose = Affine3f::Identity()); bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String& id = "cloud"); - - void showLine(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color = Color::white()); - void showPlane(const String& id, const Vec4f& coeffs, const Color& color = Color::white()); - void showPlane(const String& id, const Vec4f& coeffs, const Point3f& pt, const Color& color = Color::white()); - void showCube(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color = Color::white()); - void showCylinder(const String& id, const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int num_sides, const Color& color = Color::white()); - void showCircle(const String& id, const Point3f& pt, double radius, const Color& color = Color::white()); - void showSphere(const String& id, const Point3f& pt, double radius, const Color& color = Color::white()); - void showArrow(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color = Color::white()); - - Affine3f getShapePose(const String& id); - void setShapePose(const String& id, const Affine3f &pose); - - bool addPlane (const ModelCoefficients &coefficients, const String& id = "plane"); - bool addPlane (const ModelCoefficients &coefficients, double x, double y, double z, const String& id = "plane"); - bool removeCoordinateSystem (const String& id = "coordinate"); - bool addPolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); bool updatePolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - bool addText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String& id = ""); - - bool addPolygon(const Mat& cloud, const Color& color, const String& id = "polygon"); - bool addSphere (const Point3f ¢er, double radius, const Color& color, const String& id = "sphere"); - - void spin (); void spinOnce (int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 2f09aea0b..f4a85e218 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -38,41 +38,6 @@ public: void spin (); void spinOnce (int time = 1, bool force_redraw = false); - /** \brief Adds 3D axes describing a coordinate system to screen at x, y, z, Roll,Pitch,Yaw - * - * \param[in] scale the scale of the axes (default: 1) - * \param[in] t transformation matrix - * - * RPY Angles - * Rotate the reference frame by the angle roll about axis x - * Rotate the reference frame by the angle pitch about axis y - * Rotate the reference frame by the angle yaw about axis z - * - * Description: - * Sets the orientation of the Prop3D. Orientation is specified as - * X,Y and Z rotations in that order, but they are performed as - * RotateZ, RotateX, and finally RotateY. - * - * All axies use right hand rule. x=red axis, y=green axis, z=blue axis - * z direction is point into the screen. - * z - * \ - * \ - * \ - * -----------> x - * | - * | - * | - * | - * | - * | - * y - */ - void addCoordinateSystem (double scale, const Affine3f& t, const String& id = "coordinate"); - - /** \brief Removes a previously added 3D axes (coordinate system) - */ - bool removeCoordinateSystem (const String& id = "coordinate"); bool removePointCloud (const String& id = "cloud"); inline bool removePolygonMesh (const String& id = "polygon") { @@ -138,18 +103,6 @@ public: interactor_->TerminateApp (); } - void showLine (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color); - void showPlane (const String& id, const cv::Vec4f &coefs, const Color& color); - void showPlane (const String& id ,const cv::Vec4f &coefs, const Point3f& pt, const Color& color); - void showCube (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color); - void showCylinder (const String& id, const Point3f& pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color& color); - void showCircle (const String& id, const Point3f& pt, double radius, const Color& color); - void showSphere (const String& id, const Point3f& pt, double radius, const Color& color); - void showArrow (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color); - - Affine3f getShapePose (const String& id); - void setShapePose (const String& id, const Affine3f& pose); - bool addPolygon(const cv::Mat& cloud, const Color& color, const String& id = "polygon"); bool addArrow (const Point3f& pt1, const Point3f& pt2, const Color& color, bool display_length, const String& id = "arrow"); bool addArrow (const Point3f& pt1, const Point3f& pt2, const Color& color_line, const Color& color_text, const String& id = "arrow"); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 76392acf7..e3ebf85bf 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -17,11 +17,6 @@ void temp_viz::Viz3d::setBackgroundColor(const Color& color) impl_->setBackgroundColor(color); } -void temp_viz::Viz3d::addCoordinateSystem(double scale, const Affine3f& t, const String& id) -{ - impl_->addCoordinateSystem(scale, t, id); -} - void temp_viz::Viz3d::showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose) { impl_->showPointCloud(id, cloud, colors, pose); @@ -72,61 +67,6 @@ void temp_viz::Viz3d::spinOnce (int time, bool force_redraw) impl_->spinOnce(time, force_redraw); } -void temp_viz::Viz3d::showLine(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) -{ - impl_->showLine(id, pt1, pt2, color); -} - -void temp_viz::Viz3d::showPlane(const String& id, const Vec4f &coeffs, const Color& color) -{ - impl_->showPlane(id, coeffs, color); -} - -void temp_viz::Viz3d::showPlane(const String& id, const Vec4f &coeffs, const Point3f& pt, const Color& color) -{ - impl_->showPlane(id, coeffs, pt, color); -} - -void temp_viz::Viz3d::showCube(const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) -{ - impl_->showCube(id, pt1, pt2, color); -} - -void temp_viz::Viz3d::showCylinder(const String& id, const Point3f& pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color& color) -{ - impl_->showCylinder(id, pt_on_axis, axis_direction, radius, num_sides, color); -} - -void temp_viz::Viz3d::showCircle(const String& id, const Point3f& pt, double radius, const Color& color) -{ - impl_->showCircle(id, pt, radius, color); -} - -void temp_viz::Viz3d::showSphere (const String& id, const Point3f& pt, double radius, const Color& color) -{ - impl_->showSphere(id, pt, radius, color); -} - -void temp_viz::Viz3d::showArrow (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) -{ - impl_->showArrow(id,pt1,pt2,color); -} - -cv::Affine3f temp_viz::Viz3d::getShapePose(const String& id) -{ - return impl_->getShapePose(id); -} - -void temp_viz::Viz3d::setShapePose(const String& id, const Affine3f &pose) -{ - impl_->setShapePose(id, pose); -} - -bool temp_viz::Viz3d::removeCoordinateSystem (const String& id) -{ - return impl_->removeCoordinateSystem(id); -} - void temp_viz::Viz3d::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) { impl_->registerKeyboardCallback(callback, cookie); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 22eaf21ba..79d49a30a 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -379,309 +379,6 @@ bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const return (true); } - -void temp_viz::Viz3d::VizImpl::showLine (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) -{ - // Check if this Id already exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = am_it != shape_actor_map_->end(); - - // If it exists just update - if (exists) - { - vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createLine(pt1,pt2)); - Color c = vtkcolor(color); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } - else - { - // Create new line - vtkSmartPointer data = createLine (pt1, pt2); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - - Color c = vtkcolor(color); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } -} - -void temp_viz::Viz3d::VizImpl::showPlane (const String& id, const cv::Vec4f &coeffs, const Color& color) -{ - // Check if this Id already exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = am_it != shape_actor_map_->end(); - Color c = vtkcolor(color); - // If it exists just update - if (exists) - { - vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coeffs)); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } - else - { - // Create a plane - vtkSmartPointer data = createPlane (coeffs); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - // actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetLighting (false); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } -} - -void temp_viz::Viz3d::VizImpl::showPlane (const String& id ,const cv::Vec4f &coeffs, const Point3f& pt, const Color& color) -{ - // Check if this Id already exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = am_it != shape_actor_map_->end(); - Color c = vtkcolor(color); - // If it exists just update - if (exists) - { - vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createPlane(coeffs, pt)); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } - else - { - // Create a plane - vtkSmartPointer data = createPlane (coeffs, pt); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - // actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetLighting (false); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } -} - -void temp_viz::Viz3d::VizImpl::showCube (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) -{ - // Check if this Id already exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = am_it != shape_actor_map_->end(); - Color c = vtkcolor(color); - // If it exists just update - if (exists) - { - vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createCube(pt1, pt2)); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } - else - { - // Create a plane - vtkSmartPointer data = createCube (pt1, pt2); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - // actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetLighting (false); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } -} - -void temp_viz::Viz3d::VizImpl::showCylinder (const String& id, const Point3f& pt_on_axis, const Point3f &axis_direction, double radius, int num_sides, const Color& color) -{ - // Check if this Id already exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = am_it != shape_actor_map_->end(); - Color c = vtkcolor(color); - // If it exists just update - if (exists) - { - vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createCylinder(pt_on_axis, axis_direction, radius, num_sides)); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } - else - { - // Create a plane - vtkSmartPointer data = createCylinder(pt_on_axis, axis_direction, radius, num_sides); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - // actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetLighting (false); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } -} - -void temp_viz::Viz3d::VizImpl::showCircle (const String& id, const Point3f& pt, double radius, const Color& color) -{ - // Check if this Id already exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = am_it != shape_actor_map_->end(); - Color c = vtkcolor(color); - // If it exists just update - if (exists) - { - vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(create2DCircle(pt, radius)); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } - else - { - // Create a plane - vtkSmartPointer data = create2DCircle(pt, radius); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - // actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetLighting (false); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } -} - -void temp_viz::Viz3d::VizImpl::showSphere (const String& id, const Point3f& pt, double radius, const Color& color) -{ - // Check if this Id already exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = am_it != shape_actor_map_->end(); - Color c = vtkcolor(color); - // If it exists just update - if (exists) - { - vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createSphere(pt, radius)); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } - else - { - // Create a plane - vtkSmartPointer data = createSphere(pt, radius); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - // actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetLighting (false); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } -} - -void temp_viz::Viz3d::VizImpl::showArrow (const String& id, const Point3f& pt1, const Point3f& pt2, const Color& color) -{ - // Check if this Id already exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - bool exists = am_it != shape_actor_map_->end(); - Color c = vtkcolor(color); - - // If it exists just update - if (exists) - { - vtkSmartPointer actor = vtkLODActor::SafeDownCast (am_it->second); - reinterpret_cast(actor->GetMapper ())->SetInput(createArrow(pt1,pt2)); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } - else - { - // Create a plane - vtkSmartPointer data = createArrow(pt1,pt2); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - // actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetRepresentationToSurface (); - actor->GetProperty ()->SetLighting (false); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } -} - -cv::Affine3f temp_viz::Viz3d::VizImpl::getShapePose (const String& id) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - - CV_Assert(am_it != shape_actor_map_->end()); - vtkLODActor* actor = vtkLODActor::SafeDownCast(am_it->second); - return Affine3f(convertToMatx(actor->GetUserMatrix())); -} - -void temp_viz::Viz3d::VizImpl::setShapePose (const String& id, const Affine3f &pose) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - CV_Assert(am_it != shape_actor_map_->end()); - - vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second); - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); -} - bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index eeb72c415..42fe649e9 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -139,71 +139,6 @@ void temp_viz::Viz3d::VizImpl::spinOnce (int time, bool force_redraw) } } -///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::addCoordinateSystem (double scale, const cv::Affine3f& affine, const std::string &id) -{ - vtkSmartPointer axes = vtkSmartPointer::New (); - axes->SetOrigin (0, 0, 0); - axes->SetScaleFactor (scale); - - vtkSmartPointer axes_colors = vtkSmartPointer::New (); - axes_colors->Allocate (6); - axes_colors->InsertNextValue (0.0); - axes_colors->InsertNextValue (0.0); - axes_colors->InsertNextValue (0.5); - axes_colors->InsertNextValue (0.5); - axes_colors->InsertNextValue (1.0); - axes_colors->InsertNextValue (1.0); - - vtkSmartPointer axes_data = axes->GetOutput (); - axes_data->Update (); - axes_data->GetPointData ()->SetScalars (axes_colors); - - vtkSmartPointer axes_tubes = vtkSmartPointer::New (); - axes_tubes->SetInput (axes_data); - axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); - axes_tubes->SetNumberOfSides (6); - - vtkSmartPointer axes_mapper = vtkSmartPointer::New (); - axes_mapper->SetScalarModeToUsePointData (); - axes_mapper->SetInput (axes_tubes->GetOutput ()); - - vtkSmartPointer axes_actor = vtkSmartPointer::New (); - axes_actor->SetMapper (axes_mapper); - - cv::Vec3d t = affine.translation(); - axes_actor->SetPosition (t[0], t[1], t[2]); - - cv::Matx33f m = affine.rotation(); - - cv::Vec3f rvec; - cv::Rodrigues(m, rvec); - - float r_angle = cv::norm(rvec); - rvec *= 1.f/r_angle; - - axes_actor->SetOrientation(0,0,0); - axes_actor->RotateWXYZ(r_angle*180/CV_PI,rvec[0], rvec[1], rvec[2]); - renderer_->AddActor (axes_actor); - - (*shape_actor_map_)[id] = axes_actor; -} - -///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::removeCoordinateSystem (const std::string &id) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it == shape_actor_map_->end ()) - return false; - - // Remove it from all renderers - if (!removeActorFromRenderer(am_it->second)) - return false; - - shape_actor_map_->erase(am_it); - return true; -} - ///////////////////////////////////////////////////////////////////////////////////////////// bool temp_viz::Viz3d::VizImpl::removePointCloud (const std::string &id) { From 7e2643abff7e91b48faba57ce19ddba909bf80d3 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 4 Jul 2013 19:05:56 +0300 Subject: [PATCH 049/205] removed shape files --- modules/viz/src/precomp.hpp | 1 - modules/viz/src/q/shapes.h | 19 ---- modules/viz/src/shapes.cpp | 153 --------------------------------- modules/viz/src/viz3d_impl.cpp | 1 - modules/viz/src/viz_main.cpp | 1 - 5 files changed, 175 deletions(-) delete mode 100644 modules/viz/src/q/shapes.h delete mode 100644 modules/viz/src/shapes.cpp diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index f6779d3ce..ddbef3a49 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -153,6 +153,5 @@ #endif -#include #include "opencv2/viz/widget_accessor.hpp" #include diff --git a/modules/viz/src/q/shapes.h b/modules/viz/src/q/shapes.h deleted file mode 100644 index 4055cd1b2..000000000 --- a/modules/viz/src/q/shapes.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -namespace temp_viz -{ - vtkSmartPointer createLine (const cv::Point3f& pt1, const cv::Point3f& pt2); - vtkSmartPointer createSphere (const cv::Point3f ¢er, float radius, int sphere_resolution = 10); - vtkSmartPointer createCylinder (const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30); - vtkSmartPointer createPlane (const Vec4f& coefs); - vtkSmartPointer createPlane (const Vec4f& coefs, const Point3f& pt); - vtkSmartPointer create2DCircle (const Point3f& pt, double radius); - vtkSmartPointer createCube(const Point3f& pt_min, const Point3f& pt_max); - vtkSmartPointer createSphere (const Point3f& pt, double radius); - vtkSmartPointer createArrow (const Point3f& pt1, const Point3f& pt2); - - //brief Allocate a new unstructured grid smartpointer. For internal use only. - void allocVtkUnstructuredGrid (vtkSmartPointer &polydata); -} diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp deleted file mode 100644 index 7fa9a2cd8..000000000 --- a/modules/viz/src/shapes.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "precomp.hpp" - -inline float rad2deg(float alpha) { return (alpha * 57.29578f); } -inline double rad2deg(double alpha) { return (alpha * 57.29578); } - -vtkSmartPointer temp_viz::createCylinder (const cv::Point3f& pt_on_axis, const cv::Point3f& axis_direction, double radius, int numsides) -{ - const cv::Point3f pt2 = pt_on_axis + axis_direction; - vtkSmartPointer line = vtkSmartPointer::New (); - line->SetPoint1 (pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); - line->SetPoint2 (pt2.x, pt2.y, pt2.z); - - vtkSmartPointer tuber = vtkSmartPointer::New (); - tuber->SetInputConnection (line->GetOutputPort ()); - tuber->SetRadius (radius); - tuber->SetNumberOfSides (numsides); - return (tuber->GetOutput ()); -} - -vtkSmartPointer temp_viz::createPlane (const cv::Vec4f& coefs) -{ - vtkSmartPointer plane = vtkSmartPointer::New (); - plane->SetNormal (coefs[0], coefs[1], coefs[2]); - double norm = cv::norm(cv::Vec3f(coefs.val)); - plane->Push (-coefs[3] / norm); - return plane->GetOutput (); -} - -vtkSmartPointer temp_viz::createPlane(const cv::Vec4f& coefs, const cv::Point3f& pt) -{ - vtkSmartPointer plane = vtkSmartPointer::New (); - cv::Point3f coefs3(coefs[0], coefs[1], coefs[2]); - double norm_sqr = 1.0 / coefs3.dot (coefs3); - plane->SetNormal(coefs[0], coefs[1], coefs[2]); - - double t = coefs3.dot(pt) + coefs[3]; - cv::Vec3f p_center = pt - coefs3 * t * norm_sqr; - plane->SetCenter (p_center[0], p_center[1], p_center[2]); - - return (plane->GetOutput ()); -} - -vtkSmartPointer temp_viz::create2DCircle (const cv::Point3f& pt, double radius) -{ - vtkSmartPointer disk = vtkSmartPointer::New (); - // Maybe the resolution should be lower e.g. 50 or 25 - disk->SetCircumferentialResolution (100); - disk->SetInnerRadius (radius - 0.001); - disk->SetOuterRadius (radius + 0.001); - disk->SetCircumferentialResolution (20); - - // Set the circle origin - vtkSmartPointer t = vtkSmartPointer::New (); - t->Identity (); - t->Translate (pt.x, pt.y, pt.z); - - vtkSmartPointer tf = vtkSmartPointer::New (); - tf->SetTransform (t); - tf->SetInputConnection (disk->GetOutputPort ()); - - return tf->GetOutput (); -} - -vtkSmartPointer temp_viz::createCube(const cv::Point3f& pt_min, const cv::Point3f& pt_max) -{ - vtkSmartPointer cube = vtkSmartPointer::New (); - cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); - return cube->GetOutput (); -} - -vtkSmartPointer temp_viz::createSphere (const Point3f& pt, double radius) -{ - vtkSmartPointer sphere = vtkSmartPointer::New (); - sphere->SetRadius (radius); - sphere->SetCenter (pt.x, pt.y, pt.z); - sphere->SetPhiResolution (10); - sphere->SetThetaResolution (10); - sphere->LatLongTessellationOff (); - sphere->Update (); - - return sphere->GetOutput (); -} - -vtkSmartPointer temp_viz::createArrow (const Point3f& pt1, const Point3f& pt2) -{ - vtkSmartPointer arrowSource = vtkSmartPointer::New (); - - float startPoint[3], endPoint[3]; - startPoint[0] = pt1.x; - startPoint[1] = pt1.y; - startPoint[2] = pt1.z; - endPoint[0] = pt2.x; - endPoint[1] = pt2.y; - endPoint[2] = pt2.z; - float normalizedX[3], normalizedY[3], normalizedZ[3]; - - // The X axis is a vector from start to end - vtkMath::Subtract(endPoint, startPoint, normalizedX); - float length = vtkMath::Norm(normalizedX); - vtkMath::Normalize(normalizedX); - - // The Z axis is an arbitrary vecotr cross X - float arbitrary[3]; - arbitrary[0] = vtkMath::Random(-10,10); - arbitrary[1] = vtkMath::Random(-10,10); - arbitrary[2] = vtkMath::Random(-10,10); - vtkMath::Cross(normalizedX, arbitrary, normalizedZ); - vtkMath::Normalize(normalizedZ); - - // The Y axis is Z cross X - vtkMath::Cross(normalizedZ, normalizedX, normalizedY); - vtkSmartPointer matrix = vtkSmartPointer::New(); - - // Create the direction cosine matrix - matrix->Identity(); - for (unsigned int i = 0; i < 3; i++) - { - matrix->SetElement(i, 0, normalizedX[i]); - matrix->SetElement(i, 1, normalizedY[i]); - matrix->SetElement(i, 2, normalizedZ[i]); - } - - // Apply the transforms - vtkSmartPointer transform = - vtkSmartPointer::New(); - transform->Translate(startPoint); - transform->Concatenate(matrix); - transform->Scale(length, length, length); - - // Transform the polydata - vtkSmartPointer transformPD = - vtkSmartPointer::New(); - transformPD->SetTransform(transform); - transformPD->SetInputConnection(arrowSource->GetOutputPort()); - - return transformPD->GetOutput(); -} - -vtkSmartPointer temp_viz::createLine (const cv::Point3f& pt1, const cv::Point3f& pt2) -{ - vtkSmartPointer line = vtkSmartPointer::New (); - line->SetPoint1 (pt1.x, pt1.y, pt1.z); - line->SetPoint2 (pt2.x, pt2.y, pt2.z); - line->Update (); - return line->GetOutput (); -} - -void temp_viz::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) -{ - polydata = vtkSmartPointer::New (); -} - - diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 79d49a30a..ae2e06228 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1,5 +1,4 @@ #include "precomp.hpp" -#include #include namespace temp_viz diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 42fe649e9..0d56fe0a5 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -1,7 +1,6 @@ #include "precomp.hpp" #include -#include #include #include From 9d684a39da07b34fc70d498d53a0648a0d8c79dd Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 5 Jul 2013 14:13:23 +0400 Subject: [PATCH 050/205] Fixed ref counting bug, minor formatting --- modules/viz/src/precomp.hpp | 4 +++- modules/viz/src/simple_widgets.cpp | 7 ++----- modules/viz/src/viz3d_impl.cpp | 14 ++++---------- modules/viz/src/widget.cpp | 1 + 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index ddbef3a49..7f3588e6b 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -153,5 +152,8 @@ #endif +#include +#include #include "opencv2/viz/widget_accessor.hpp" #include +#include diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 45e5a9755..fa7026c9d 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -1,5 +1,4 @@ #include "precomp.hpp" -#include /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation @@ -135,15 +134,13 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const } // Apply the transforms - vtkSmartPointer transform = - vtkSmartPointer::New(); + vtkSmartPointer transform = vtkSmartPointer::New(); transform->Translate(startPoint); transform->Concatenate(matrix); transform->Scale(length, length, length); // Transform the polydata - vtkSmartPointer transformPD = - vtkSmartPointer::New(); + vtkSmartPointer transformPD = vtkSmartPointer::New(); transformPD->SetTransform(transform); transformPD->SetInputConnection(arrowSource->GetOutputPort()); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index ae2e06228..4d51964c7 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1,5 +1,4 @@ #include "precomp.hpp" -#include namespace temp_viz { @@ -865,12 +864,10 @@ bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& co return (true); } -#include "opencv2/viz/widget_accessor.hpp" - void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = !(wam_itr == widget_actor_map_->end()); + bool exists = wam_itr != widget_actor_map_->end(); if (exists) { // Remove it if it exists and add it again @@ -883,14 +880,11 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget bool temp_viz::Viz3d::VizImpl::removeWidget(const String &id) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = !(wam_itr == widget_actor_map_->end()); + bool exists = wam_itr != widget_actor_map_->end(); if (!exists) - { - std::cout << "[removeWidget] A widget with id <" << id << "> does not exist!" << std::endl; - return false; - } - + return std::cout << "[removeWidget] A widget with id <" << id << "> does not exist!" << std::endl, false; + if (!removeActorFromRenderer (wam_itr->second.actor)) return false; diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 0657c5414..d35b10d70 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -136,6 +136,7 @@ void temp_viz::Widget::release() if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) { delete impl_; + impl_ = 0; } } From 030400d50f42816452952cfffe7a2805545d7ed1 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sun, 7 Jul 2013 16:21:47 +0300 Subject: [PATCH 051/205] circle widget thickness property --- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/simple_widgets.cpp | 9 ++++----- modules/viz/test/test_viz3d.cpp | 14 +++++++------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 122c0c7bf..ea615a184 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -65,7 +65,7 @@ namespace temp_viz class CV_EXPORTS CircleWidget : public Widget { public: - CircleWidget(const Point3f& pt, double radius, const Color &color = Color::white()); + CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); }; class CV_EXPORTS CylinderWidget : public Widget diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index fa7026c9d..ffba14ec9 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -156,14 +156,13 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const /////////////////////////////////////////////////////////////////////////////////////////////// /// circle widget implementation -temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, const temp_viz::Color& color) +temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, double thickness, const temp_viz::Color& color) { vtkSmartPointer disk = vtkSmartPointer::New (); // Maybe the resolution should be lower e.g. 50 or 25 - disk->SetCircumferentialResolution (100); - disk->SetInnerRadius (radius - 0.001); - disk->SetOuterRadius (radius + 0.001); - disk->SetCircumferentialResolution (20); + disk->SetCircumferentialResolution (50); + disk->SetInnerRadius (radius - thickness); + disk->SetOuterRadius (radius + thickness); // Set the circle origin vtkSmartPointer t = vtkSmartPointer::New (); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 6cb27dbc2..f89635f48 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -94,18 +94,18 @@ TEST(Viz_viz3d, accuracy) temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0)); temp_viz::SphereWidget sw(cv::Point3f(0,0,0), 0.5); temp_viz::ArrowWidget aw(cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); - temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 1.0, temp_viz::Color(0,255,0)); + temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 0.5, 0.01, temp_viz::Color(0,255,0)); temp_viz::CylinderWidget cyw(cv::Point3f(0,0,0), cv::Point3f(-1,-1,-1), 0.5, 30, temp_viz::Color(0,255,0)); temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1), temp_viz::Color(0,0,255)); temp_viz::CoordinateSystemWidget csw(1.0f, cv::Affine3f::Identity()); - v.showWidget("line", lw); - v.showWidget("plane", pw); - v.showWidget("sphere", sw); - v.showWidget("arrow", aw); +// v.showWidget("line", lw); +// v.showWidget("plane", pw); +// v.showWidget("sphere", sw); +// v.showWidget("arrow", aw); v.showWidget("circle", cw); - v.showWidget("cylinder", cyw); - v.showWidget("cube", cuw); +// v.showWidget("cylinder", cyw); +// v.showWidget("cube", cuw); v.showWidget("coordinateSystem", csw); temp_viz::LineWidget lw2 = lw; From eafcdc004db0cbc550f1277a76ee3f825cca9444 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sun, 7 Jul 2013 21:19:21 +0300 Subject: [PATCH 052/205] plane widget size --- modules/viz/include/opencv2/viz/widgets.hpp | 4 ++-- modules/viz/src/simple_widgets.cpp | 12 +++++++----- modules/viz/test/test_viz3d.cpp | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index ea615a184..cc70d268a 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -46,8 +46,8 @@ namespace temp_viz class CV_EXPORTS PlaneWidget : public Widget { public: - PlaneWidget(const Vec4f& coefs, const Color &color = Color::white()); - PlaneWidget(const Vec4f& coefs, const Point3f& pt, const Color &color = Color::white()); + PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); + PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); }; class CV_EXPORTS SphereWidget : public Widget diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index ffba14ec9..bcc8beaf1 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -33,23 +33,24 @@ float temp_viz::LineWidget::getLineWidth() /////////////////////////////////////////////////////////////////////////////////////////////// /// plane widget implementation -temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Color &color) +temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color &color) { vtkSmartPointer plane = vtkSmartPointer::New (); plane->SetNormal (coefs[0], coefs[1], coefs[2]); double norm = cv::norm(cv::Vec3f(coefs.val)); plane->Push (-coefs[3] / norm); - + vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(plane->GetOutput ()); - + vtkSmartPointer actor = WidgetAccessor::getActor(*this); actor->SetMapper(mapper); - + actor->SetScale(size); + setColor(color); } -temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, const Color &color) +temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size, const Color &color) { vtkSmartPointer plane = vtkSmartPointer::New (); cv::Point3f coefs3(coefs[0], coefs[1], coefs[2]); @@ -65,6 +66,7 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, const vtkSmartPointer actor = WidgetAccessor::getActor(*this); actor->SetMapper(mapper); + actor->SetScale(size); setColor(color); } diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index f89635f48..d9d6837c0 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -91,7 +91,7 @@ TEST(Viz_viz3d, accuracy) int col_red = 0; temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(4.0,4.0,4.0), temp_viz::Color(0,255,0)); - temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0)); + temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0), 5.0); temp_viz::SphereWidget sw(cv::Point3f(0,0,0), 0.5); temp_viz::ArrowWidget aw(cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 0.5, 0.01, temp_viz::Color(0,255,0)); @@ -100,10 +100,10 @@ TEST(Viz_viz3d, accuracy) temp_viz::CoordinateSystemWidget csw(1.0f, cv::Affine3f::Identity()); // v.showWidget("line", lw); -// v.showWidget("plane", pw); + v.showWidget("plane", pw); // v.showWidget("sphere", sw); // v.showWidget("arrow", aw); - v.showWidget("circle", cw); +// v.showWidget("circle", cw); // v.showWidget("cylinder", cyw); // v.showWidget("cube", cuw); v.showWidget("coordinateSystem", csw); From c4f4727ee5f52f3542d2db4627fce7f0d9669926 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 8 Jul 2013 10:53:00 +0300 Subject: [PATCH 053/205] showWidget takes Affine3f as argument --- modules/viz/include/opencv2/viz/viz3d.hpp | 2 +- modules/viz/src/q/viz3d_impl.hpp | 2 +- modules/viz/src/viz3d.cpp | 4 ++-- modules/viz/src/viz3d_impl.cpp | 11 ++++++++--- modules/viz/test/test_viz3d.cpp | 4 +++- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index b4b697b90..2810d2ab1 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -46,7 +46,7 @@ namespace temp_viz bool wasStopped() const; - void showWidget(const String &id, const Widget &widget); + void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); bool removeWidget(const String &id); private: Viz3d(const Viz3d&); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index f4a85e218..89d8f6b23 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -199,7 +199,7 @@ public: void setPosition (int x, int y); void setSize (int xw, int yw); - void showWidget(const String &id, const Widget &widget); + void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); bool removeWidget(const String &id); void all_data(); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index e3ebf85bf..bed07a707 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -79,9 +79,9 @@ void temp_viz::Viz3d::registerMouseCallback(void (*callback)(const MouseEvent&, bool temp_viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } -void temp_viz::Viz3d::showWidget(const String &id, const Widget &widget) +void temp_viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { - impl_->showWidget(id, widget); + impl_->showWidget(id, widget, pose); } bool temp_viz::Viz3d::removeWidget(const String &id) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 4d51964c7..07a25abc7 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -864,7 +864,7 @@ bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& co return (true); } -void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget) +void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); @@ -873,8 +873,13 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget // Remove it if it exists and add it again removeActorFromRenderer(wam_itr->second.actor); } - renderer_->AddActor(WidgetAccessor::getActor(widget)); - (*widget_actor_map_)[id].actor = WidgetAccessor::getActor(widget); + // Get the actor and set the user matrix + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(widget)); + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified(); + renderer_->AddActor(actor); + (*widget_actor_map_)[id].actor = actor; } bool temp_viz::Viz3d::VizImpl::removeWidget(const String &id) diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index d9d6837c0..e574449cf 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -121,13 +121,15 @@ TEST(Viz_viz3d, accuracy) pw.setColor(temp_viz::Color(col_blue, col_green, col_red)); sw.setPose(cloudPosition); - pw.setPose(cloudPosition); +// pw.setPose(cloudPosition); aw.setPose(cloudPosition); cw.setPose(cloudPosition); cyw.setPose(cloudPosition); lw.setPose(cloudPosition); cuw.setPose(cloudPosition); + v.showWidget("plane", pw, cloudPosition); + angle_x += 0.1f; angle_y -= 0.1f; angle_z += 0.1f; From 653eda45f8b8cafe6fbc53e68748f9ba96a77e2f Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 8 Jul 2013 10:41:42 +0200 Subject: [PATCH 054/205] text widget implementation --- modules/viz/include/opencv2/viz/types.hpp | 1 + .../include/opencv2/viz/widget_accessor.hpp | 2 +- modules/viz/include/opencv2/viz/widgets.hpp | 15 ++++- modules/viz/src/simple_widgets.cpp | 38 +++++++++---- modules/viz/src/viz3d_impl.cpp | 15 +++-- modules/viz/src/widget.cpp | 57 +++++++++++++------ modules/viz/test/test_viz3d.cpp | 2 + 7 files changed, 94 insertions(+), 36 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 92b277857..d64debc81 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -22,6 +22,7 @@ namespace temp_viz typedef cv::Matx33d Matx33d; typedef cv::Affine3f Affine3f; typedef cv::Affine3d Affine3d; + typedef cv::Point2i Point2i; typedef cv::Point3f Point3f; typedef cv::Point3d Point3d; typedef cv::Matx44d Matx44d; diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index 4b1c5ef15..0cc39f7ff 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -12,6 +12,6 @@ namespace temp_viz //It is indended for those users who want to develop own widgets system using VTK library API. struct CV_EXPORTS WidgetAccessor { - static vtkSmartPointer getActor(const Widget &widget); + static vtkSmartPointer getActor(const Widget &widget); }; } diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index cc70d268a..eaf9e6286 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -22,13 +22,17 @@ namespace temp_viz void setPose(const Affine3f &pose); void updatePose(const Affine3f &pose); Affine3f getPose() const; - + + protected: + Widget(bool text_widget); + private: class Impl; Impl* impl_; void create(); void release(); + void create(bool text_widget); friend struct WidgetAccessor; }; @@ -85,5 +89,12 @@ namespace temp_viz public: CoordinateSystemWidget(double scale, const Affine3f& affine); }; - + + class CV_EXPORTS TextWidget : public Widget + { + public: + TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); + + // TODO Overload setColor method, and hide setPose, updatePose, getPose methods + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index bcc8beaf1..7ae822515 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -12,7 +12,7 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(line->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -20,13 +20,13 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C void temp_viz::LineWidget::setLineWidth(float line_width) { - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->GetProperty()->SetLineWidth(line_width); } float temp_viz::LineWidget::getLineWidth() { - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); return actor->GetProperty()->GetLineWidth(); } @@ -43,7 +43,7 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(plane->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); actor->SetScale(size); @@ -64,7 +64,7 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(plane->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); actor->SetScale(size); @@ -87,7 +87,7 @@ temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, in vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(sphere->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -149,7 +149,7 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(transformPD->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -178,7 +178,7 @@ temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(tf->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -202,7 +202,7 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(tuber->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -219,7 +219,7 @@ temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, c vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(cube->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -256,7 +256,7 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff mapper->SetScalarModeToUsePointData (); mapper->SetInput(axes_tubes->GetOutput ()); - vtkSmartPointer actor = WidgetAccessor::getActor(*this); + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); cv::Vec3d t = affine.translation(); @@ -273,3 +273,19 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff actor->SetOrientation(0,0,0); actor->RotateWXYZ(r_angle*180/CV_PI,rvec[0], rvec[1], rvec[2]); } + +temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) : Widget(true) +{ + vtkSmartPointer actor = vtkTextActor::SafeDownCast(WidgetAccessor::getActor(*this)); + actor->SetPosition (pos.x, pos.y); + actor->SetInput (text.c_str ()); + + vtkSmartPointer tprop = actor->GetTextProperty (); + tprop->SetFontSize (font_size); + tprop->SetFontFamilyToArial (); + tprop->SetJustificationToLeft (); + tprop->BoldOn (); + + Color c = vtkcolor(color); + tprop->SetColor (c.val); +} diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 07a25abc7..0eb0bd082 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -874,12 +874,15 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget removeActorFromRenderer(wam_itr->second.actor); } // Get the actor and set the user matrix - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(widget)); - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified(); - renderer_->AddActor(actor); - (*widget_actor_map_)[id].actor = actor; + vtkSmartPointer actor; + if (actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(widget))) + { + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified(); + } + renderer_->AddActor(WidgetAccessor::getActor(widget)); + (*widget_actor_map_)[id].actor = WidgetAccessor::getActor(widget); } bool temp_viz::Viz3d::VizImpl::removeWidget(const String &id) diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index d35b10d70..e51f86770 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -3,34 +3,45 @@ class temp_viz::Widget::Impl { public: - vtkSmartPointer actor; + vtkSmartPointer actor; int ref_counter; Impl() : actor(vtkSmartPointer::New()) {} + + Impl(bool text_widget) + { + if (text_widget) + actor = vtkSmartPointer::New(); + else + actor = vtkSmartPointer::New(); + } void setColor(const Color& color) { + vtkSmartPointer lod_actor = vtkLODActor::SafeDownCast(actor); Color c = vtkcolor(color); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetProperty ()->SetColor (c.val); - actor->GetProperty ()->SetEdgeColor (c.val); - actor->GetProperty ()->SetAmbient (0.8); - actor->GetProperty ()->SetDiffuse (0.8); - actor->GetProperty ()->SetSpecular (0.8); - actor->GetProperty ()->SetLighting (0); - actor->Modified (); + lod_actor->GetMapper ()->ScalarVisibilityOff (); + lod_actor->GetProperty ()->SetColor (c.val); + lod_actor->GetProperty ()->SetEdgeColor (c.val); + lod_actor->GetProperty ()->SetAmbient (0.8); + lod_actor->GetProperty ()->SetDiffuse (0.8); + lod_actor->GetProperty ()->SetSpecular (0.8); + lod_actor->GetProperty ()->SetLighting (0); + lod_actor->Modified (); } void setPose(const Affine3f& pose) { + vtkSmartPointer lod_actor = vtkLODActor::SafeDownCast(actor); vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); + lod_actor->SetUserMatrix (matrix); + lod_actor->Modified (); } void updatePose(const Affine3f& pose) { - vtkSmartPointer matrix = actor->GetUserMatrix(); + vtkSmartPointer lod_actor = vtkLODActor::SafeDownCast(actor); + vtkSmartPointer matrix = lod_actor->GetUserMatrix(); if (!matrix) { setPose(pose); @@ -41,13 +52,14 @@ public: Affine3f updated_pose = pose * Affine3f(matrix_cv); matrix = convertToVtkMatrix(updated_pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); + lod_actor->SetUserMatrix (matrix); + lod_actor->Modified (); } Affine3f getPose() const { - vtkSmartPointer matrix = actor->GetUserMatrix(); + vtkSmartPointer lod_actor = vtkLODActor::SafeDownCast(actor); + vtkSmartPointer matrix = lod_actor->GetUserMatrix(); Matx44f matrix_cv = convertToMatx(matrix); return Affine3f(matrix_cv); } @@ -77,7 +89,7 @@ protected: /////////////////////////////////////////////////////////////////////////////////////////////// /// stream accessor implementaion -vtkSmartPointer temp_viz::WidgetAccessor::getActor(const Widget& widget) +vtkSmartPointer temp_viz::WidgetAccessor::getActor(const Widget& widget) { return widget.impl_->actor; } @@ -90,6 +102,11 @@ temp_viz::Widget::Widget() : impl_(0) create(); } +temp_viz::Widget::Widget(bool text_widget) : impl_(0) +{ + create(text_widget); +} + temp_viz::Widget::Widget(const Widget& other) : impl_(other.impl_) { if (impl_) @@ -140,3 +157,11 @@ void temp_viz::Widget::release() } } +void temp_viz::Widget::create(bool text_widget) +{ + if (impl_) + release(); + impl_ = new Impl(text_widget); + impl_->ref_counter = 1; +} + diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index e574449cf..4c586524f 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -98,6 +98,7 @@ TEST(Viz_viz3d, accuracy) temp_viz::CylinderWidget cyw(cv::Point3f(0,0,0), cv::Point3f(-1,-1,-1), 0.5, 30, temp_viz::Color(0,255,0)); temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1), temp_viz::Color(0,0,255)); temp_viz::CoordinateSystemWidget csw(1.0f, cv::Affine3f::Identity()); + temp_viz::TextWidget tw("TEST", cv::Point2i(100,100), 20); // v.showWidget("line", lw); v.showWidget("plane", pw); @@ -107,6 +108,7 @@ TEST(Viz_viz3d, accuracy) // v.showWidget("cylinder", cyw); // v.showWidget("cube", cuw); v.showWidget("coordinateSystem", csw); + v.showWidget("text",tw); temp_viz::LineWidget lw2 = lw; From d394e233bb181fd0bbf6bce603fb1cc9cd7ce92a Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 8 Jul 2013 11:34:11 +0200 Subject: [PATCH 055/205] cube widget wireframe --- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/simple_widgets.cpp | 5 ++++- modules/viz/test/test_viz3d.cpp | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index eaf9e6286..3198a07ed 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -81,7 +81,7 @@ namespace temp_viz class CV_EXPORTS CubeWidget : public Widget { public: - CubeWidget(const Point3f& pt_min, const Point3f& pt_max, const Color &color = Color::white()); + CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); }; class CV_EXPORTS CoordinateSystemWidget : public Widget diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 7ae822515..8cc4867d8 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -211,7 +211,7 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 /////////////////////////////////////////////////////////////////////////////////////////////// /// cylinder widget implementation -temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, const Color &color) +temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame, const Color &color) { vtkSmartPointer cube = vtkSmartPointer::New (); cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); @@ -222,6 +222,9 @@ temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, c vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); + if (wire_frame) + actor->GetProperty ()->SetRepresentationToWireframe (); + setColor(color); } diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 4c586524f..0ec36770a 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -96,7 +96,7 @@ TEST(Viz_viz3d, accuracy) temp_viz::ArrowWidget aw(cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 0.5, 0.01, temp_viz::Color(0,255,0)); temp_viz::CylinderWidget cyw(cv::Point3f(0,0,0), cv::Point3f(-1,-1,-1), 0.5, 30, temp_viz::Color(0,255,0)); - temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1), temp_viz::Color(0,0,255)); + temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1)); temp_viz::CoordinateSystemWidget csw(1.0f, cv::Affine3f::Identity()); temp_viz::TextWidget tw("TEST", cv::Point2i(100,100), 20); @@ -106,7 +106,7 @@ TEST(Viz_viz3d, accuracy) // v.showWidget("arrow", aw); // v.showWidget("circle", cw); // v.showWidget("cylinder", cyw); -// v.showWidget("cube", cuw); + v.showWidget("cube", cuw); v.showWidget("coordinateSystem", csw); v.showWidget("text",tw); From 6e5ae98582e9aedf1cc1ba3e7f89ccee0d57e21b Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 8 Jul 2013 15:12:50 +0200 Subject: [PATCH 056/205] initial cloud widget implementation, fix safedowncasts --- modules/viz/include/opencv2/viz/widgets.hpp | 7 + modules/viz/src/simple_widgets.cpp | 265 +++++++++++++++++++- modules/viz/src/viz3d_impl.cpp | 2 +- modules/viz/src/widget.cpp | 8 +- modules/viz/test/test_viz3d.cpp | 19 +- 5 files changed, 278 insertions(+), 23 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 3198a07ed..eb3b4b719 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -97,4 +97,11 @@ namespace temp_viz // TODO Overload setColor method, and hide setPose, updatePose, getPose methods }; + + class CV_EXPORTS CloudWidget : public Widget + { + public: + CloudWidget(InputArray _cloud, InputArray _colors); + CloudWidget(InputArray _cloud, const Color &color = Color::white()); + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 8cc4867d8..ae3536ff5 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -1,5 +1,10 @@ #include "precomp.hpp" +namespace temp_viz +{ + template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) @@ -12,7 +17,7 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(line->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -20,13 +25,13 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C void temp_viz::LineWidget::setLineWidth(float line_width) { - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->GetProperty()->SetLineWidth(line_width); } float temp_viz::LineWidget::getLineWidth() { - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); return actor->GetProperty()->GetLineWidth(); } @@ -43,7 +48,7 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(plane->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); actor->SetScale(size); @@ -64,7 +69,7 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(plane->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); actor->SetScale(size); @@ -87,7 +92,7 @@ temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, in vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(sphere->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -149,7 +154,7 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(transformPD->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -178,7 +183,7 @@ temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(tf->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -202,7 +207,7 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(tuber->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); @@ -219,7 +224,7 @@ temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, b vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(cube->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); if (wire_frame) @@ -259,7 +264,7 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff mapper->SetScalarModeToUsePointData (); mapper->SetInput(axes_tubes->GetOutput ()); - vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); cv::Vec3d t = affine.translation(); @@ -277,9 +282,12 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff actor->RotateWXYZ(r_angle*180/CV_PI,rvec[0], rvec[1], rvec[2]); } +/////////////////////////////////////////////////////////////////////////////////////////////// +/// text widget implementation + temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) : Widget(true) { - vtkSmartPointer actor = vtkTextActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetPosition (pos.x, pos.y); actor->SetInput (text.c_str ()); @@ -292,3 +300,236 @@ temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int fon Color c = vtkcolor(color); tprop->SetColor (c.val); } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// point cloud widget implementation + +temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) +{ + Mat cloud = _cloud.getMat(); + Mat colors = _colors.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); + + vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer polydata = vtkSmartPointer::New (); + vtkSmartPointer vertices = vtkSmartPointer::New (); + + polydata->SetVerts (vertices); + + vtkSmartPointer points = polydata->GetPoints(); + vtkSmartPointer initcells; + vtkIdType nr_points = cloud.total(); + + points = polydata->GetPoints (); + + if (!points) + { + points = vtkSmartPointer::New (); + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat(); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble(); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); + + if (cloud.depth() == CV_32F) + { + // Get a pointer to the beginning of the data array + Vec3f *data_beg = vtkpoints_data(points); + Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + + } + else if (cloud.depth() == CV_64F) + { + // Get a pointer to the beginning of the data array + Vec3d *data_beg = vtkpoints_data(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + points->SetNumberOfPoints (nr_points); + + // Update cells + vtkSmartPointer cells = vertices->GetData (); + // If no init cells and cells has not been initialized... + if (!cells) + cells = vtkSmartPointer::New (); + + // If we have less values then we need to recreate the array + if (cells->GetNumberOfTuples () < nr_points) + { + cells = vtkSmartPointer::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::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); + } + + // Set the cells and the vertices + vertices->SetCells (nr_points, cells); + + Vec3b* colors_data = new Vec3b[nr_points]; + NanFilter::copy(colors, colors_data, cloud); + + vtkSmartPointer scalars = vtkSmartPointer::New (); + scalars->SetNumberOfComponents (3); + scalars->SetNumberOfTuples (nr_points); + scalars->SetArray (colors_data->val, 3 * nr_points, 0); + + // Assign the colors + polydata->GetPointData ()->SetScalars (scalars); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (polydata); + + cv::Vec3d minmax(scalars->GetRange()); + mapper->SetScalarRange(minmax.val); + mapper->SetScalarModeToUsePointData (); + + bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); + + mapper->SetInterpolateScalarsBeforeMapping (interpolation); + mapper->ScalarVisibilityOn (); + + mapper->ImmediateModeRenderingOff (); + + actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); + actor->GetProperty ()->SetInterpolationToFlat (); + actor->GetProperty ()->BackfaceCullingOn (); + actor->SetMapper (mapper); +} + +temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) +{ + Mat cloud = _cloud.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + + vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer polydata = vtkSmartPointer::New (); + vtkSmartPointer vertices = vtkSmartPointer::New (); + + polydata->SetVerts (vertices); + + vtkSmartPointer points = polydata->GetPoints(); + vtkSmartPointer initcells; + vtkIdType nr_points = cloud.total(); + + points = polydata->GetPoints (); + + if (!points) + { + points = vtkSmartPointer::New (); + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat(); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble(); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); + + if (cloud.depth() == CV_32F) + { + // Get a pointer to the beginning of the data array + Vec3f *data_beg = vtkpoints_data(points); + Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + + } + else if (cloud.depth() == CV_64F) + { + // Get a pointer to the beginning of the data array + Vec3d *data_beg = vtkpoints_data(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + points->SetNumberOfPoints (nr_points); + + // Update cells + vtkSmartPointer cells = vertices->GetData (); + // If no init cells and cells has not been initialized... + if (!cells) + cells = vtkSmartPointer::New (); + + // If we have less values then we need to recreate the array + if (cells->GetNumberOfTuples () < nr_points) + { + cells = vtkSmartPointer::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::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); + } + + // Set the cells and the vertices + vertices->SetCells (nr_points, cells); + + Color c = vtkcolor(color); + polydata->GetPointData ()->SetScalars (0); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (polydata); + + bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); + + mapper->SetInterpolateScalarsBeforeMapping (interpolation); + mapper->ScalarVisibilityOn (); + + mapper->ImmediateModeRenderingOff (); + + actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); + actor->GetProperty ()->SetInterpolationToFlat (); + actor->GetProperty ()->BackfaceCullingOn (); + actor->SetMapper (mapper); +} \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 0eb0bd082..bf3f4f95b 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -874,7 +874,7 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget removeActorFromRenderer(wam_itr->second.actor); } // Get the actor and set the user matrix - vtkSmartPointer actor; + vtkLODActor *actor; if (actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(widget))) { vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index e51f86770..f75827f8f 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -18,7 +18,7 @@ public: void setColor(const Color& color) { - vtkSmartPointer lod_actor = vtkLODActor::SafeDownCast(actor); + vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); Color c = vtkcolor(color); lod_actor->GetMapper ()->ScalarVisibilityOff (); lod_actor->GetProperty ()->SetColor (c.val); @@ -32,7 +32,7 @@ public: void setPose(const Affine3f& pose) { - vtkSmartPointer lod_actor = vtkLODActor::SafeDownCast(actor); + vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); lod_actor->SetUserMatrix (matrix); lod_actor->Modified (); @@ -40,7 +40,7 @@ public: void updatePose(const Affine3f& pose) { - vtkSmartPointer lod_actor = vtkLODActor::SafeDownCast(actor); + vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); vtkSmartPointer matrix = lod_actor->GetUserMatrix(); if (!matrix) { @@ -58,7 +58,7 @@ public: Affine3f getPose() const { - vtkSmartPointer lod_actor = vtkLODActor::SafeDownCast(actor); + vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); vtkSmartPointer matrix = lod_actor->GetUserMatrix(); Matx44f matrix_cv = convertToMatx(matrix); return Affine3f(matrix_cv); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 0ec36770a..2cbb09072 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -53,7 +53,7 @@ cv::Mat cvcloud_load() { cv::Mat cloud(1, 20000, CV_32FC3); - std::ifstream ifs("d:/cloud_dragon.ply"); + std::ifstream ifs("cloud_dragon.ply"); std::string str; for(size_t i = 0; i < 11; ++i) @@ -99,23 +99,29 @@ TEST(Viz_viz3d, accuracy) temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1)); temp_viz::CoordinateSystemWidget csw(1.0f, cv::Affine3f::Identity()); temp_viz::TextWidget tw("TEST", cv::Point2i(100,100), 20); + temp_viz::CloudWidget pcw(cloud, colors); + temp_viz::CloudWidget pcw2(cloud, temp_viz::Color(255,255,255)); // v.showWidget("line", lw); - v.showWidget("plane", pw); +// v.showWidget("plane", pw); // v.showWidget("sphere", sw); // v.showWidget("arrow", aw); // v.showWidget("circle", cw); // v.showWidget("cylinder", cyw); - v.showWidget("cube", cuw); +// v.showWidget("cube", cuw); v.showWidget("coordinateSystem", csw); - v.showWidget("text",tw); +// v.showWidget("text",tw); + v.showWidget("pcw",pcw); + v.showWidget("pcw2",pcw2); temp_viz::LineWidget lw2 = lw; +// v.showPointCloud("cld",cloud, colors); while(!v.wasStopped()) { // Creating new point cloud with id cloud1 cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); + cv::Affine3f cloudPosition2(angle_x, angle_y, angle_z, cv::Vec3f(pos_x+0.2, pos_y+0.2, pos_z+0.2)); lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); lw.setLineWidth(lw.getLineWidth()+pos_x * 10); @@ -129,8 +135,9 @@ TEST(Viz_viz3d, accuracy) cyw.setPose(cloudPosition); lw.setPose(cloudPosition); cuw.setPose(cloudPosition); - - v.showWidget("plane", pw, cloudPosition); + v.showWidget("pcw",pcw, cloudPosition); + v.showWidget("pcw2",pcw2, cloudPosition2); +// v.showWidget("plane", pw, cloudPosition); angle_x += 0.1f; angle_y -= 0.1f; From e76023be965b6f5a970b779cbaf1092a6a8a943f Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 8 Jul 2013 18:22:51 +0200 Subject: [PATCH 057/205] cloud normals widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 8 ++ modules/viz/src/simple_widgets.cpp | 133 +++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 31 +++-- 3 files changed, 159 insertions(+), 13 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index eb3b4b719..dd708491e 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -104,4 +104,12 @@ namespace temp_viz CloudWidget(InputArray _cloud, InputArray _colors); CloudWidget(InputArray _cloud, const Color &color = Color::white()); }; + + class CV_EXPORTS CloudNormalsWidget : public Widget + { + public: + CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level = 100, float scale = 0.02f); + private: + struct ApplyCloudNormals; + }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index ae3536ff5..700543628 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -524,12 +524,143 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); mapper->SetInterpolateScalarsBeforeMapping (interpolation); - mapper->ScalarVisibilityOn (); + mapper->ScalarVisibilityOff (); mapper->ImmediateModeRenderingOff (); actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); actor->GetProperty ()->SetInterpolationToFlat (); actor->GetProperty ()->BackfaceCullingOn (); + actor->GetProperty ()->SetColor(c.val); actor->SetMapper (mapper); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// cloud normals widget implementation + +struct temp_viz::CloudNormalsWidget::ApplyCloudNormals +{ + template + struct Impl + { + static vtkSmartPointer applyOrganized(const cv::Mat &cloud, const cv::Mat& normals, + int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + { + vtkIdType point_step = static_cast (sqrt (double (level))); + nr_normals = (static_cast ((cloud.cols - 1)/ point_step) + 1) * + (static_cast ((cloud.rows - 1) / point_step) + 1); + vtkSmartPointer lines = vtkSmartPointer::New(); + + pts = new _Tp[2 * nr_normals * 3]; + + int cch = cloud.channels(); + vtkIdType cell_count = 0; + for (vtkIdType y = 0; y < cloud.rows; y += point_step) + { + const _Tp *prow = cloud.ptr<_Tp>(y); + const _Tp *nrow = normals.ptr<_Tp>(y); + for (vtkIdType x = 0; x < cloud.cols; x += point_step + cch) + { + pts[2 * cell_count * 3 + 0] = prow[x]; + pts[2 * cell_count * 3 + 1] = prow[x+1]; + pts[2 * cell_count * 3 + 2] = prow[x+2]; + pts[2 * cell_count * 3 + 3] = prow[x] + nrow[x] * scale; + pts[2 * cell_count * 3 + 4] = prow[x+1] + nrow[x+1] * scale; + pts[2 * cell_count * 3 + 5] = prow[x+2] + nrow[x+2] * scale; + + lines->InsertNextCell (2); + lines->InsertCellPoint (2 * cell_count); + lines->InsertCellPoint (2 * cell_count + 1); + cell_count++; + } + } + return lines; + } + + static vtkSmartPointer applyUnorganized(const cv::Mat &cloud, const cv::Mat& normals, + int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + { + vtkSmartPointer lines = vtkSmartPointer::New(); + nr_normals = (cloud.size().area() - 1) / level + 1 ; + pts = new _Tp[2 * nr_normals * 3]; + + int cch = cloud.channels(); + const _Tp *p = cloud.ptr<_Tp>(); + const _Tp *n = normals.ptr<_Tp>(); + for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level * cch) + { + + pts[2 * j * 3 + 0] = p[i]; + pts[2 * j * 3 + 1] = p[i+1]; + pts[2 * j * 3 + 2] = p[i+2]; + pts[2 * j * 3 + 3] = p[i] + n[i] * scale; + pts[2 * j * 3 + 4] = p[i+1] + n[i+1] * scale; + pts[2 * j * 3 + 5] = p[i+2] + n[i+2] * scale; + + lines->InsertNextCell (2); + lines->InsertCellPoint (2 * j); + lines->InsertCellPoint (2 * j + 1); + } + return lines; + } + }; + + template + static inline vtkSmartPointer apply(const cv::Mat &cloud, const cv::Mat& normals, + int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + { + if (cloud.cols > 1 && cloud.rows > 1) + return ApplyCloudNormals::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals); + else + return ApplyCloudNormals::Impl<_Tp>::applyUnorganized(cloud, normals, level, scale, pts, nr_normals); + } +}; + +temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level, float scale) +{ + Mat cloud = _cloud.getMat(); + Mat normals = _normals.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type()); + + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer lines = vtkSmartPointer::New(); + vtkIdType nr_normals = 0; + + if (cloud.depth() == CV_32F) + { + points->SetDataTypeToFloat(); + + vtkSmartPointer data = vtkSmartPointer::New (); + data->SetNumberOfComponents (3); + + float* pts = 0; + lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals); + data->SetArray (&pts[0], 2 * nr_normals * 3, 0); + points->SetData (data); + } + else + { + points->SetDataTypeToDouble(); + + vtkSmartPointer data = vtkSmartPointer::New (); + data->SetNumberOfComponents (3); + + double* pts = 0; + lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals); + data->SetArray (&pts[0], 2 * nr_normals * 3, 0); + points->SetData (data); + } + + vtkSmartPointer polyData = vtkSmartPointer::New(); + polyData->SetPoints (points); + polyData->SetLines (lines); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (polyData); + mapper->SetColorModeToMapScalars(); + mapper->SetScalarModeToUsePointData(); + + vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + actor->SetMapper(mapper); } \ No newline at end of file diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 2cbb09072..ad4ceb822 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -52,16 +52,18 @@ cv::Mat cvcloud_load() { - cv::Mat cloud(1, 20000, CV_32FC3); + cv::Mat cloud(1, 20000, CV_64FC4); std::ifstream ifs("cloud_dragon.ply"); std::string str; for(size_t i = 0; i < 11; ++i) std::getline(ifs, str); - cv::Point3f* data = cloud.ptr(); - for(size_t i = 0; i < 20000; ++i) - ifs >> data[i].x >> data[i].y >> data[i].z; + cv::Vec4d* data = cloud.ptr(); + for(size_t i = 0; i < 20000; ++i){ + ifs >> data[i][0] >> data[i][1] >> data[i][2]; + data[i][3] = 1.0; + } return cloud; } @@ -100,7 +102,7 @@ TEST(Viz_viz3d, accuracy) temp_viz::CoordinateSystemWidget csw(1.0f, cv::Affine3f::Identity()); temp_viz::TextWidget tw("TEST", cv::Point2i(100,100), 20); temp_viz::CloudWidget pcw(cloud, colors); - temp_viz::CloudWidget pcw2(cloud, temp_viz::Color(255,255,255)); + temp_viz::CloudWidget pcw2(cloud, temp_viz::Color(0,255,255)); // v.showWidget("line", lw); // v.showWidget("plane", pw); @@ -111,12 +113,18 @@ TEST(Viz_viz3d, accuracy) // v.showWidget("cube", cuw); v.showWidget("coordinateSystem", csw); // v.showWidget("text",tw); - v.showWidget("pcw",pcw); +// v.showWidget("pcw",pcw); v.showWidget("pcw2",pcw2); temp_viz::LineWidget lw2 = lw; // v.showPointCloud("cld",cloud, colors); + cv::Mat normals(cloud.size(), cloud.type(), cv::Scalar(0, 10, 0)); + +// v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); + temp_viz::CloudNormalsWidget cnw(cloud, normals); + v.showWidget("n", cnw); + while(!v.wasStopped()) { // Creating new point cloud with id cloud1 @@ -134,9 +142,10 @@ TEST(Viz_viz3d, accuracy) cw.setPose(cloudPosition); cyw.setPose(cloudPosition); lw.setPose(cloudPosition); - cuw.setPose(cloudPosition); - v.showWidget("pcw",pcw, cloudPosition); - v.showWidget("pcw2",pcw2, cloudPosition2); + cuw.setPose(cloudPosition); +// cnw.setPose(cloudPosition); +// v.showWidget("pcw",pcw, cloudPosition); +// v.showWidget("pcw2",pcw2, cloudPosition2); // v.showWidget("plane", pw, cloudPosition); angle_x += 0.1f; @@ -152,9 +161,7 @@ TEST(Viz_viz3d, accuracy) v.spinOnce(1, true); } -// cv::Mat normals(cloud.size(), CV_32FC3, cv::Scalar(0, 10, 0)); -// -// v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); + // // // temp_viz::ModelCoefficients mc; From 658e4c5e971d78af560361d6094128e1e7ff02e9 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 8 Jul 2013 18:56:13 +0200 Subject: [PATCH 058/205] set/get/updateWidgetPose implemented, cloudNormals with color --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 ++ modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/q/viz3d_impl.hpp | 4 ++ modules/viz/src/simple_widgets.cpp | 3 +- modules/viz/src/viz3d.cpp | 15 +++++ modules/viz/src/viz3d_impl.cpp | 66 +++++++++++++++++++++ modules/viz/test/test_viz3d.cpp | 17 +++--- 7 files changed, 102 insertions(+), 9 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 2810d2ab1..65065bc7f 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -48,6 +48,10 @@ namespace temp_viz void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); bool removeWidget(const String &id); + + bool setWidgetPose(const String &id, const Affine3f &pose); + bool updateWidgetPose(const String &id, const Affine3f &pose); + Affine3f getWidgetPose(const String &id) const; private: Viz3d(const Viz3d&); Viz3d& operator=(const Viz3d&); diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index dd708491e..ecd239141 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -108,7 +108,7 @@ namespace temp_viz class CV_EXPORTS CloudNormalsWidget : public Widget { public: - CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level = 100, float scale = 0.02f); + CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); private: struct ApplyCloudNormals; }; diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 89d8f6b23..6595416bb 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -202,6 +202,10 @@ public: void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); bool removeWidget(const String &id); + bool setWidgetPose(const String &id, const Affine3f &pose); + bool updateWidgetPose(const String &id, const Affine3f &pose); + Affine3f getWidgetPose(const String &id) const; + void all_data(); private: diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 700543628..6c6cba83f 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -616,7 +616,7 @@ struct temp_viz::CloudNormalsWidget::ApplyCloudNormals } }; -temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level, float scale) +temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color) { Mat cloud = _cloud.getMat(); Mat normals = _normals.getMat(); @@ -663,4 +663,5 @@ temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _ vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); + setColor(color); } \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index bed07a707..ed9405e91 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -88,3 +88,18 @@ bool temp_viz::Viz3d::removeWidget(const String &id) { return impl_->removeWidget(id); } + +bool temp_viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) +{ + return impl_->setWidgetPose(id, pose); +} + +bool temp_viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) +{ + return impl_->updateWidgetPose(id, pose); +} + +temp_viz::Affine3f temp_viz::Viz3d::getWidgetPose(const String &id) const +{ + return impl_->getWidgetPose(id); +} diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index bf3f4f95b..c77fda74f 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -899,3 +899,69 @@ bool temp_viz::Viz3d::VizImpl::removeWidget(const String &id) widget_actor_map_->erase(wam_itr); return true; } + +bool temp_viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + if (!exists) + { + return std::cout << "[setWidgetPose] A widget with id <" << id << "> does not exist!" << std::endl, false; + } + vtkLODActor *actor; + if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) + { + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified (); + return true; + } + return false; +} + +bool temp_viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + if (!exists) + { + return std::cout << "[setWidgetPose] A widget with id <" << id << "> does not exist!" << std::endl, false; + } + vtkLODActor *actor; + if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) + { + vtkSmartPointer matrix = actor->GetUserMatrix(); + if (!matrix) + { + setWidgetPose(id, pose); + return true; + } + Matx44f matrix_cv = convertToMatx(matrix); + + Affine3f updated_pose = pose * Affine3f(matrix_cv); + matrix = convertToVtkMatrix(updated_pose.matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); + return true; + } + return false; +} + +temp_viz::Affine3f temp_viz::Viz3d::VizImpl::getWidgetPose(const String &id) const +{ + WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + if (!exists) + { + return Affine3f(); + } + vtkLODActor *actor; + if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) + { + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv = convertToMatx(matrix); + return Affine3f(matrix_cv); + } + return Affine3f(); +} \ No newline at end of file diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index ad4ceb822..76993d160 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -52,18 +52,16 @@ cv::Mat cvcloud_load() { - cv::Mat cloud(1, 20000, CV_64FC4); - std::ifstream ifs("cloud_dragon.ply"); + cv::Mat cloud(1, 20000, CV_32FC3); + std::ifstream ifs("d:/cloud_dragon.ply"); std::string str; for(size_t i = 0; i < 11; ++i) std::getline(ifs, str); - cv::Vec4d* data = cloud.ptr(); - for(size_t i = 0; i < 20000; ++i){ - ifs >> data[i][0] >> data[i][1] >> data[i][2]; - data[i][3] = 1.0; - } + cv::Point3f* data = cloud.ptr(); + for(size_t i = 0; i < 20000; ++i) + ifs >> data[i].x >> data[i].y >> data[i].z; return cloud; } @@ -148,6 +146,11 @@ TEST(Viz_viz3d, accuracy) // v.showWidget("pcw2",pcw2, cloudPosition2); // v.showWidget("plane", pw, cloudPosition); + v.setWidgetPose("n",cloudPosition); + v.setWidgetPose("pcw2", cloudPosition); + cnw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + pcw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); + angle_x += 0.1f; angle_y -= 0.1f; angle_z += 0.1f; From cc08149d7cf3079fa62b88dede882cf6fb2e97ac Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 8 Jul 2013 19:05:35 +0200 Subject: [PATCH 059/205] remove redundant statements --- modules/viz/src/simple_widgets.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 6c6cba83f..76c72e6c3 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -515,9 +515,6 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) // Set the cells and the vertices vertices->SetCells (nr_points, cells); - Color c = vtkcolor(color); - polydata->GetPointData ()->SetScalars (0); - vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput (polydata); @@ -531,8 +528,9 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); actor->GetProperty ()->SetInterpolationToFlat (); actor->GetProperty ()->BackfaceCullingOn (); - actor->GetProperty ()->SetColor(c.val); actor->SetMapper (mapper); + + setColor(color); } /////////////////////////////////////////////////////////////////////////////////////////////// From b50d777985ac682dc1f31db27450d56b09cd0071 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 8 Jul 2013 21:48:19 +0200 Subject: [PATCH 060/205] cloudwidget private implementation for duplicate code, add cv_assert(exists), fix bug point_step bug in CloudNormalsWidget --- modules/viz/include/opencv2/viz/widgets.hpp | 2 + modules/viz/src/simple_widgets.cpp | 260 +++++++------------- modules/viz/src/viz3d_impl.cpp | 22 +- 3 files changed, 104 insertions(+), 180 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index ecd239141..b5b9b65cd 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -103,6 +103,8 @@ namespace temp_viz public: CloudWidget(InputArray _cloud, InputArray _colors); CloudWidget(InputArray _cloud, const Color &color = Color::white()); + private: + struct CreateCloudWidget; }; class CV_EXPORTS CloudNormalsWidget : public Widget diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 76c72e6c3..640e85c98 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -304,6 +304,95 @@ temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int fon /////////////////////////////////////////////////////////////////////////////////////////////// /// point cloud widget implementation +struct temp_viz::CloudWidget::CreateCloudWidget +{ + static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) + { + vtkSmartPointer polydata = vtkSmartPointer::New (); + vtkSmartPointer vertices = vtkSmartPointer::New (); + + polydata->SetVerts (vertices); + + vtkSmartPointer points = polydata->GetPoints(); + vtkSmartPointer initcells; + nr_points = cloud.total(); + + points = polydata->GetPoints (); + + if (!points) + { + points = vtkSmartPointer::New (); + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat(); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble(); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); + + if (cloud.depth() == CV_32F) + { + // Get a pointer to the beginning of the data array + Vec3f *data_beg = vtkpoints_data(points); + Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + else if (cloud.depth() == CV_64F) + { + // Get a pointer to the beginning of the data array + Vec3d *data_beg = vtkpoints_data(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + points->SetNumberOfPoints (nr_points); + + // Update cells + vtkSmartPointer cells = vertices->GetData (); + // If no init cells and cells has not been initialized... + if (!cells) + cells = vtkSmartPointer::New (); + + // If we have less values then we need to recreate the array + if (cells->GetNumberOfTuples () < nr_points) + { + cells = vtkSmartPointer::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::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); + } + + // Set the cells and the vertices + vertices->SetCells (nr_points, cells); + return polydata; + } +}; + temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) { Mat cloud = _cloud.getMat(); @@ -312,89 +401,10 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); - vtkSmartPointer polydata = vtkSmartPointer::New (); - vtkSmartPointer vertices = vtkSmartPointer::New (); - - polydata->SetVerts (vertices); - - vtkSmartPointer points = polydata->GetPoints(); - vtkSmartPointer initcells; - vtkIdType nr_points = cloud.total(); - - points = polydata->GetPoints (); - - if (!points) - { - points = vtkSmartPointer::New (); - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat(); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble(); - polydata->SetPoints (points); - } - points->SetNumberOfPoints (nr_points); - - if (cloud.depth() == CV_32F) - { - // Get a pointer to the beginning of the data array - Vec3f *data_beg = vtkpoints_data(points); - Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); - nr_points = data_end - data_beg; - - } - else if (cloud.depth() == CV_64F) - { - // Get a pointer to the beginning of the data array - Vec3d *data_beg = vtkpoints_data(points); - Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); - nr_points = data_end - data_beg; - } - points->SetNumberOfPoints (nr_points); - - // Update cells - vtkSmartPointer cells = vertices->GetData (); - // If no init cells and cells has not been initialized... - if (!cells) - cells = vtkSmartPointer::New (); - - // If we have less values then we need to recreate the array - if (cells->GetNumberOfTuples () < nr_points) - { - cells = vtkSmartPointer::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::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); - } - - // Set the cells and the vertices - vertices->SetCells (nr_points, cells); + vtkIdType nr_points; + vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + // Filter colors Vec3b* colors_data = new Vec3b[nr_points]; NanFilter::copy(colors, colors_data, cloud); @@ -432,88 +442,8 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); - vtkSmartPointer polydata = vtkSmartPointer::New (); - vtkSmartPointer vertices = vtkSmartPointer::New (); - - polydata->SetVerts (vertices); - - vtkSmartPointer points = polydata->GetPoints(); - vtkSmartPointer initcells; - vtkIdType nr_points = cloud.total(); - - points = polydata->GetPoints (); - - if (!points) - { - points = vtkSmartPointer::New (); - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat(); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble(); - polydata->SetPoints (points); - } - points->SetNumberOfPoints (nr_points); - - if (cloud.depth() == CV_32F) - { - // Get a pointer to the beginning of the data array - Vec3f *data_beg = vtkpoints_data(points); - Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); - nr_points = data_end - data_beg; - - } - else if (cloud.depth() == CV_64F) - { - // Get a pointer to the beginning of the data array - Vec3d *data_beg = vtkpoints_data(points); - Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); - nr_points = data_end - data_beg; - } - points->SetNumberOfPoints (nr_points); - - // Update cells - vtkSmartPointer cells = vertices->GetData (); - // If no init cells and cells has not been initialized... - if (!cells) - cells = vtkSmartPointer::New (); - - // If we have less values then we need to recreate the array - if (cells->GetNumberOfTuples () < nr_points) - { - cells = vtkSmartPointer::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::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); - } - - // Set the cells and the vertices - vertices->SetCells (nr_points, cells); + vtkIdType nr_points; + vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput (polydata); @@ -557,7 +487,7 @@ struct temp_viz::CloudNormalsWidget::ApplyCloudNormals { const _Tp *prow = cloud.ptr<_Tp>(y); const _Tp *nrow = normals.ptr<_Tp>(y); - for (vtkIdType x = 0; x < cloud.cols; x += point_step + cch) + for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch) { pts[2 * cell_count * 3 + 0] = prow[x]; pts[2 * cell_count * 3 + 1] = prow[x+1]; diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index c77fda74f..11982b574 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -889,9 +889,7 @@ bool temp_viz::Viz3d::VizImpl::removeWidget(const String &id) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - - if (!exists) - return std::cout << "[removeWidget] A widget with id <" << id << "> does not exist!" << std::endl, false; + CV_Assert(exists); if (!removeActorFromRenderer (wam_itr->second.actor)) return false; @@ -904,10 +902,8 @@ bool temp_viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &p { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - if (!exists) - { - return std::cout << "[setWidgetPose] A widget with id <" << id << "> does not exist!" << std::endl, false; - } + CV_Assert(exists); + vtkLODActor *actor; if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) { @@ -923,10 +919,8 @@ bool temp_viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - if (!exists) - { - return std::cout << "[setWidgetPose] A widget with id <" << id << "> does not exist!" << std::endl, false; - } + CV_Assert(exists); + vtkLODActor *actor; if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) { @@ -952,10 +946,8 @@ temp_viz::Affine3f temp_viz::Viz3d::VizImpl::getWidgetPose(const String &id) con { WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - if (!exists) - { - return Affine3f(); - } + CV_Assert(exists); + vtkLODActor *actor; if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) { From d324c03b6ac419730b30dead788420ffbc095ade Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 9 Jul 2013 10:21:57 +0200 Subject: [PATCH 061/205] initial redesigning widgets --- .../include/opencv2/viz/widget_accessor.hpp | 1 + modules/viz/include/opencv2/viz/widgets.hpp | 64 ++-- modules/viz/src/simple_widgets.cpp | 28 +- modules/viz/src/widget.cpp | 345 +++++++++++------- 4 files changed, 272 insertions(+), 166 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index 0cc39f7ff..ec2a02030 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -13,5 +13,6 @@ namespace temp_viz struct CV_EXPORTS WidgetAccessor { static vtkSmartPointer getActor(const Widget &widget); + static void setVtkProp(Widget &widget, vtkSmartPointer actor); }; } diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index b5b9b65cd..b22be4040 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -13,32 +13,44 @@ namespace temp_viz Widget(); Widget(const Widget &other); Widget& operator =(const Widget &other); - + ~Widget(); - void copyTo(Widget &dst); - - void setColor(const Color &color); + private: + class Impl; + Impl *impl_; + friend struct WidgetAccessor; + + }; + + ///////////////////////////////////////////////////////////////////////////// + /// The base class for all 3D widgets + class CV_EXPORTS Widget3D : public Widget + { + public: + Widget3D(); + void setPose(const Affine3f &pose); void updatePose(const Affine3f &pose); Affine3f getPose() const; - protected: - Widget(bool text_widget); + void setColor(const Color &color); private: - class Impl; - Impl* impl_; + struct MatrixConverter; - void create(); - void release(); - void create(bool text_widget); - - friend struct WidgetAccessor; }; + + ///////////////////////////////////////////////////////////////////////////// + /// The base class for all 2D widgets + class CV_EXPORTS Widget2D : public Widget + { + public: + Widget2D(); + }; + - - class CV_EXPORTS LineWidget : public Widget + class CV_EXPORTS LineWidget : public Widget3D { public: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); @@ -47,58 +59,56 @@ namespace temp_viz float getLineWidth(); }; - class CV_EXPORTS PlaneWidget : public Widget + class CV_EXPORTS PlaneWidget : public Widget3D { public: PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); }; - class CV_EXPORTS SphereWidget : public Widget + class CV_EXPORTS SphereWidget : public Widget3D { public: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); }; - class CV_EXPORTS ArrowWidget : public Widget + class CV_EXPORTS ArrowWidget : public Widget3D { public: ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color = Color::white()); }; - class CV_EXPORTS CircleWidget : public Widget + class CV_EXPORTS CircleWidget : public Widget3D { public: CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); }; - class CV_EXPORTS CylinderWidget : public Widget + class CV_EXPORTS CylinderWidget : public Widget3D { public: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); }; - class CV_EXPORTS CubeWidget : public Widget + class CV_EXPORTS CubeWidget : public Widget3D { public: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); }; - class CV_EXPORTS CoordinateSystemWidget : public Widget + class CV_EXPORTS CoordinateSystemWidget : public Widget3D { public: CoordinateSystemWidget(double scale, const Affine3f& affine); }; - class CV_EXPORTS TextWidget : public Widget + class CV_EXPORTS TextWidget : public Widget2D { public: TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); - - // TODO Overload setColor method, and hide setPose, updatePose, getPose methods }; - class CV_EXPORTS CloudWidget : public Widget + class CV_EXPORTS CloudWidget : public Widget3D { public: CloudWidget(InputArray _cloud, InputArray _colors); @@ -107,7 +117,7 @@ namespace temp_viz struct CreateCloudWidget; }; - class CV_EXPORTS CloudNormalsWidget : public Widget + class CV_EXPORTS CloudNormalsWidget : public Widget3D { public: CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 640e85c98..8cb77ee44 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -9,6 +9,8 @@ namespace temp_viz /// line widget implementation temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer line = vtkSmartPointer::New(); line->SetPoint1 (pt1.x, pt1.y, pt1.z); line->SetPoint2 (pt2.x, pt2.y, pt2.z); @@ -40,6 +42,8 @@ float temp_viz::LineWidget::getLineWidth() temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color &color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer plane = vtkSmartPointer::New (); plane->SetNormal (coefs[0], coefs[1], coefs[2]); double norm = cv::norm(cv::Vec3f(coefs.val)); @@ -57,6 +61,8 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size, const Color &color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer plane = vtkSmartPointer::New (); cv::Point3f coefs3(coefs[0], coefs[1], coefs[2]); double norm_sqr = 1.0 / coefs3.dot (coefs3); @@ -81,6 +87,8 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution, const Color &color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer sphere = vtkSmartPointer::New (); sphere->SetRadius (radius); sphere->SetCenter (center.x, center.y, center.z); @@ -103,6 +111,8 @@ temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, in temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer arrowSource = vtkSmartPointer::New (); float startPoint[3], endPoint[3]; @@ -165,6 +175,8 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, double thickness, const temp_viz::Color& color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer disk = vtkSmartPointer::New (); // Maybe the resolution should be lower e.g. 50 or 25 disk->SetCircumferentialResolution (50); @@ -194,6 +206,8 @@ temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides, const Color &color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + const cv::Point3f pt2 = pt_on_axis + axis_direction; vtkSmartPointer line = vtkSmartPointer::New (); line->SetPoint1 (pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); @@ -218,6 +232,8 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame, const Color &color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer cube = vtkSmartPointer::New (); cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); @@ -238,6 +254,8 @@ temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, b temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Affine3f& affine) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer axes = vtkSmartPointer::New (); axes->SetOrigin (0, 0, 0); axes->SetScaleFactor (scale); @@ -285,8 +303,10 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff /////////////////////////////////////////////////////////////////////////////////////////////// /// text widget implementation -temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) : Widget(true) +temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) { + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetPosition (pos.x, pos.y); actor->SetInput (text.c_str ()); @@ -400,6 +420,8 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); @@ -441,6 +463,8 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) Mat cloud = _cloud.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); @@ -551,6 +575,8 @@ temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _ CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type()); + WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); + vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer lines = vtkSmartPointer::New(); vtkIdType nr_normals = 0; diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index f75827f8f..4fed46d1c 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -1,90 +1,132 @@ #include "precomp.hpp" +/////////////////////////////////////////////////////////////////////////////////////////////// +/// widget implementation + class temp_viz::Widget::Impl { public: vtkSmartPointer actor; - int ref_counter; - - Impl() : actor(vtkSmartPointer::New()) {} - Impl(bool text_widget) - { - if (text_widget) - actor = vtkSmartPointer::New(); - else - actor = vtkSmartPointer::New(); - } - - void setColor(const Color& color) - { - vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); - Color c = vtkcolor(color); - lod_actor->GetMapper ()->ScalarVisibilityOff (); - lod_actor->GetProperty ()->SetColor (c.val); - lod_actor->GetProperty ()->SetEdgeColor (c.val); - lod_actor->GetProperty ()->SetAmbient (0.8); - lod_actor->GetProperty ()->SetDiffuse (0.8); - lod_actor->GetProperty ()->SetSpecular (0.8); - lod_actor->GetProperty ()->SetLighting (0); - lod_actor->Modified (); - } - - void setPose(const Affine3f& pose) - { - vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - lod_actor->SetUserMatrix (matrix); - lod_actor->Modified (); - } - - void updatePose(const Affine3f& pose) - { - vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); - vtkSmartPointer matrix = lod_actor->GetUserMatrix(); - if (!matrix) - { - setPose(pose); - return ; - } - Matx44f matrix_cv = convertToMatx(matrix); - - Affine3f updated_pose = pose * Affine3f(matrix_cv); - matrix = convertToVtkMatrix(updated_pose.matrix); - - lod_actor->SetUserMatrix (matrix); - lod_actor->Modified (); - } - - Affine3f getPose() const - { - vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); - vtkSmartPointer matrix = lod_actor->GetUserMatrix(); - Matx44f matrix_cv = convertToMatx(matrix); - return Affine3f(matrix_cv); - } - -protected: - - static vtkSmartPointer convertToVtkMatrix (const cv::Matx44f& m) - { - vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - vtk_matrix->SetElement(i, k, m(i, k)); - return vtk_matrix; - } - - static cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix) - { - cv::Matx44f m; - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - m(i, k) = vtk_matrix->GetElement (i, k); - return m; - } + Impl() : actor(0) {} }; +temp_viz::Widget::Widget() : impl_(0) +{ + impl_ = new Impl(); +} + +temp_viz::Widget::Widget(const Widget &other) : impl_(other.impl_) +{ + +} + +temp_viz::Widget& temp_viz::Widget::operator =(const Widget &other) +{ + if (this != &other) + { + delete impl_; + impl_ = other.impl_; + } + return *this; +} + +temp_viz::Widget::~Widget() +{ + if (impl_) + { + delete impl_; + impl_ = 0; + } +} + + + +// class temp_viz::Widget::Impl +// { +// public: +// vtkSmartPointer actor; +// int ref_counter; +// +// Impl() : actor(vtkSmartPointer::New()) {} +// +// Impl(bool text_widget) +// { +// if (text_widget) +// actor = vtkSmartPointer::New(); +// else +// actor = vtkSmartPointer::New(); +// } +// +// void setColor(const Color& color) +// { +// vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); +// Color c = vtkcolor(color); +// lod_actor->GetMapper ()->ScalarVisibilityOff (); +// lod_actor->GetProperty ()->SetColor (c.val); +// lod_actor->GetProperty ()->SetEdgeColor (c.val); +// lod_actor->GetProperty ()->SetAmbient (0.8); +// lod_actor->GetProperty ()->SetDiffuse (0.8); +// lod_actor->GetProperty ()->SetSpecular (0.8); +// lod_actor->GetProperty ()->SetLighting (0); +// lod_actor->Modified (); +// } +// +// void setPose(const Affine3f& pose) +// { +// vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); +// vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); +// lod_actor->SetUserMatrix (matrix); +// lod_actor->Modified (); +// } +// +// void updatePose(const Affine3f& pose) +// { +// vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); +// vtkSmartPointer matrix = lod_actor->GetUserMatrix(); +// if (!matrix) +// { +// setPose(pose); +// return ; +// } +// Matx44f matrix_cv = convertToMatx(matrix); +// +// Affine3f updated_pose = pose * Affine3f(matrix_cv); +// matrix = convertToVtkMatrix(updated_pose.matrix); +// +// lod_actor->SetUserMatrix (matrix); +// lod_actor->Modified (); +// } +// +// Affine3f getPose() const +// { +// vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); +// vtkSmartPointer matrix = lod_actor->GetUserMatrix(); +// Matx44f matrix_cv = convertToMatx(matrix); +// return Affine3f(matrix_cv); +// } +// +// protected: +// +// static vtkSmartPointer convertToVtkMatrix (const cv::Matx44f& m) +// { +// vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); +// for (int i = 0; i < 4; i++) +// for (int k = 0; k < 4; k++) +// vtk_matrix->SetElement(i, k, m(i, k)); +// return vtk_matrix; +// } +// +// static cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix) +// { +// cv::Matx44f m; +// for (int i = 0; i < 4; i++) +// for (int k = 0; k < 4; k++) +// m(i, k) = vtk_matrix->GetElement (i, k); +// return m; +// } +// }; + /////////////////////////////////////////////////////////////////////////////////////////////// /// stream accessor implementaion @@ -94,74 +136,101 @@ vtkSmartPointer temp_viz::WidgetAccessor::getActor(const Widget& widget return widget.impl_->actor; } +void temp_viz::WidgetAccessor::setVtkProp(Widget& widget, vtkSmartPointer actor) +{ + widget.impl_->actor = actor; +} + /////////////////////////////////////////////////////////////////////////////////////////////// -/// widget implementaion +/// widget3D implementation -temp_viz::Widget::Widget() : impl_(0) +struct temp_viz::Widget3D::MatrixConverter { - create(); -} - -temp_viz::Widget::Widget(bool text_widget) : impl_(0) -{ - create(text_widget); -} - -temp_viz::Widget::Widget(const Widget& other) : impl_(other.impl_) -{ - if (impl_) - CV_XADD(&impl_->ref_counter, 1); -} - -temp_viz::Widget& temp_viz::Widget::operator =(const Widget &other) -{ - if (this != &other) + static cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix) { - release(); - impl_ = other.impl_; - if (impl_) - CV_XADD(&impl_->ref_counter, 1); + cv::Matx44f m; + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + m(i, k) = vtk_matrix->GetElement (i, k); + return m; } - return *this; -} - -temp_viz::Widget::~Widget() -{ - release(); -} - -void temp_viz::Widget::copyTo(Widget& /*dst*/) -{ - // TODO Deep copy the data if there is any -} - -void temp_viz::Widget::setColor(const Color& color) { impl_->setColor(color); } -void temp_viz::Widget::setPose(const Affine3f& pose) { impl_->setPose(pose); } -void temp_viz::Widget::updatePose(const Affine3f& pose) { impl_->updatePose(pose); } -temp_viz::Affine3f temp_viz::Widget::getPose() const { return impl_->getPose(); } - -void temp_viz::Widget::create() -{ - if (impl_) - release(); - impl_ = new Impl(); - impl_->ref_counter = 1; -} - -void temp_viz::Widget::release() -{ - if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) + + static vtkSmartPointer convertToVtkMatrix (const cv::Matx44f& m) { - delete impl_; - impl_ = 0; + vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + vtk_matrix->SetElement(i, k, m(i, k)); + return vtk_matrix; } -} +}; -void temp_viz::Widget::create(bool text_widget) +temp_viz::Widget3D::Widget3D() { - if (impl_) - release(); - impl_ = new Impl(text_widget); - impl_->ref_counter = 1; + } +void temp_viz::Widget3D::setPose(const Affine3f &pose) +{ + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(*this)); + CV_Assert(actor); + + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified (); +} + +void temp_viz::Widget3D::updatePose(const Affine3f &pose) +{ + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(*this)); + CV_Assert(actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + if (!matrix) + { + setPose(pose); + return ; + } + Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix); + + Affine3f updated_pose = pose * Affine3f(matrix_cv); + matrix = MatrixConverter::convertToVtkMatrix(updated_pose.matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); +} + +temp_viz::Affine3f temp_viz::Widget3D::getPose() const +{ + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(*this)); + CV_Assert(actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix); + return Affine3f(matrix_cv); +} + +void temp_viz::Widget3D::setColor(const Color &color) +{ + // Cast to actor instead of prop3d since prop3d doesn't provide getproperty + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getActor(*this)); + CV_Assert(actor); + + Color c = vtkcolor(color); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetProperty ()->SetColor (c.val); + actor->GetProperty ()->SetEdgeColor (c.val); + actor->GetProperty ()->SetAmbient (0.8); + actor->GetProperty ()->SetDiffuse (0.8); + actor->GetProperty ()->SetSpecular (0.8); + actor->GetProperty ()->SetLighting (0); + actor->Modified (); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// widget2D implementation + +temp_viz::Widget2D::Widget2D() +{ + +} From 195d60f4f886df758bcd608401d346d0a107af00 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 9 Jul 2013 11:07:21 +0200 Subject: [PATCH 062/205] fix widget delete bug --- modules/viz/include/opencv2/viz/widgets.hpp | 6 +- modules/viz/src/widget.cpp | 127 +++----------------- 2 files changed, 24 insertions(+), 109 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index b22be4040..cc53e734f 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -21,6 +21,8 @@ namespace temp_viz Impl *impl_; friend struct WidgetAccessor; + void create(); + void release(); }; ///////////////////////////////////////////////////////////////////////////// @@ -28,7 +30,7 @@ namespace temp_viz class CV_EXPORTS Widget3D : public Widget { public: - Widget3D(); + Widget3D() {} void setPose(const Affine3f &pose); void updatePose(const Affine3f &pose); @@ -46,7 +48,7 @@ namespace temp_viz class CV_EXPORTS Widget2D : public Widget { public: - Widget2D(); + Widget2D() {} }; diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 4fed46d1c..93dd2a68e 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -7,129 +7,55 @@ class temp_viz::Widget::Impl { public: vtkSmartPointer actor; + int ref_counter; Impl() : actor(0) {} }; temp_viz::Widget::Widget() : impl_(0) { - impl_ = new Impl(); + create(); } -temp_viz::Widget::Widget(const Widget &other) : impl_(other.impl_) +temp_viz::Widget::Widget(const Widget &other) : impl_(other.impl_) { - + if (impl_) CV_XADD(&impl_->ref_counter, 1); } temp_viz::Widget& temp_viz::Widget::operator =(const Widget &other) { if (this != &other) { - delete impl_; + release(); impl_ = other.impl_; + if (impl_) CV_XADD(&impl_->ref_counter, 1); } return *this; } temp_viz::Widget::~Widget() { - if (impl_) + release(); +} + +void temp_viz::Widget::create() +{ + if (impl_) release(); + impl_ = new Impl(); + impl_->ref_counter = 1; +} + +void temp_viz::Widget::release() +{ + if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) { delete impl_; impl_ = 0; } } - - -// class temp_viz::Widget::Impl -// { -// public: -// vtkSmartPointer actor; -// int ref_counter; -// -// Impl() : actor(vtkSmartPointer::New()) {} -// -// Impl(bool text_widget) -// { -// if (text_widget) -// actor = vtkSmartPointer::New(); -// else -// actor = vtkSmartPointer::New(); -// } -// -// void setColor(const Color& color) -// { -// vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); -// Color c = vtkcolor(color); -// lod_actor->GetMapper ()->ScalarVisibilityOff (); -// lod_actor->GetProperty ()->SetColor (c.val); -// lod_actor->GetProperty ()->SetEdgeColor (c.val); -// lod_actor->GetProperty ()->SetAmbient (0.8); -// lod_actor->GetProperty ()->SetDiffuse (0.8); -// lod_actor->GetProperty ()->SetSpecular (0.8); -// lod_actor->GetProperty ()->SetLighting (0); -// lod_actor->Modified (); -// } -// -// void setPose(const Affine3f& pose) -// { -// vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); -// vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); -// lod_actor->SetUserMatrix (matrix); -// lod_actor->Modified (); -// } -// -// void updatePose(const Affine3f& pose) -// { -// vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); -// vtkSmartPointer matrix = lod_actor->GetUserMatrix(); -// if (!matrix) -// { -// setPose(pose); -// return ; -// } -// Matx44f matrix_cv = convertToMatx(matrix); -// -// Affine3f updated_pose = pose * Affine3f(matrix_cv); -// matrix = convertToVtkMatrix(updated_pose.matrix); -// -// lod_actor->SetUserMatrix (matrix); -// lod_actor->Modified (); -// } -// -// Affine3f getPose() const -// { -// vtkLODActor *lod_actor = vtkLODActor::SafeDownCast(actor); -// vtkSmartPointer matrix = lod_actor->GetUserMatrix(); -// Matx44f matrix_cv = convertToMatx(matrix); -// return Affine3f(matrix_cv); -// } -// -// protected: -// -// static vtkSmartPointer convertToVtkMatrix (const cv::Matx44f& m) -// { -// vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); -// for (int i = 0; i < 4; i++) -// for (int k = 0; k < 4; k++) -// vtk_matrix->SetElement(i, k, m(i, k)); -// return vtk_matrix; -// } -// -// static cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix) -// { -// cv::Matx44f m; -// for (int i = 0; i < 4; i++) -// for (int k = 0; k < 4; k++) -// m(i, k) = vtk_matrix->GetElement (i, k); -// return m; -// } -// }; - - /////////////////////////////////////////////////////////////////////////////////////////////// -/// stream accessor implementaion +/// widget accessor implementaion vtkSmartPointer temp_viz::WidgetAccessor::getActor(const Widget& widget) { @@ -165,11 +91,6 @@ struct temp_viz::Widget3D::MatrixConverter } }; -temp_viz::Widget3D::Widget3D() -{ - -} - void temp_viz::Widget3D::setPose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(*this)); @@ -226,11 +147,3 @@ void temp_viz::Widget3D::setColor(const Color &color) actor->GetProperty ()->SetLighting (0); actor->Modified (); } - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// widget2D implementation - -temp_viz::Widget2D::Widget2D() -{ - -} From 318b1c00a9fd07c049907dc4b59d8c0979eb3067 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 9 Jul 2013 14:12:49 +0200 Subject: [PATCH 063/205] implement assignment operator and copy constructor for all widgets existing --- modules/viz/include/opencv2/viz/viz3d.hpp | 7 +- modules/viz/include/opencv2/viz/widgets.hpp | 28 +++++++ modules/viz/src/q/viz3d_impl.hpp | 7 +- modules/viz/src/simple_widgets.cpp | 66 ++++++++++++++++ modules/viz/src/viz3d.cpp | 17 ++-- modules/viz/src/viz3d_impl.cpp | 87 ++++++++++----------- modules/viz/src/widget.cpp | 38 ++++++++- 7 files changed, 193 insertions(+), 57 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 65065bc7f..a0181cb71 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -47,10 +47,11 @@ namespace temp_viz bool wasStopped() const; void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); - bool removeWidget(const String &id); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; - bool setWidgetPose(const String &id, const Affine3f &pose); - bool updateWidgetPose(const String &id, const Affine3f &pose); + void setWidgetPose(const String &id, const Affine3f &pose); + void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; private: Viz3d(const Viz3d&); diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index cc53e734f..9aea9725a 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -31,6 +31,8 @@ namespace temp_viz { public: Widget3D() {} + Widget3D(const Widget& other); + Widget3D& operator =(const Widget &other); void setPose(const Affine3f &pose); void updatePose(const Affine3f &pose); @@ -49,6 +51,8 @@ namespace temp_viz { public: Widget2D() {} + Widget2D(const Widget &other); + Widget2D& operator=(const Widget &other); }; @@ -56,6 +60,8 @@ namespace temp_viz { public: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + LineWidget(const Widget &other) : Widget3D(other) {} + LineWidget& operator=(const Widget &other); void setLineWidth(float line_width); float getLineWidth(); @@ -66,48 +72,64 @@ namespace temp_viz public: PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); + PlaneWidget(const Widget& other) : Widget3D(other) {} + PlaneWidget& operator=(const Widget& other); }; class CV_EXPORTS SphereWidget : public Widget3D { public: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); + SphereWidget(const Widget &other) : Widget3D(other) {} + SphereWidget& operator=(const Widget &other); }; class CV_EXPORTS ArrowWidget : public Widget3D { public: ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color = Color::white()); + ArrowWidget(const Widget &other) : Widget3D(other) {} + ArrowWidget& operator=(const Widget &other); }; class CV_EXPORTS CircleWidget : public Widget3D { public: CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); + CircleWidget(const Widget& other) : Widget3D(other) {} + CircleWidget& operator=(const Widget &other); }; class CV_EXPORTS CylinderWidget : public Widget3D { public: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); + CylinderWidget(const Widget& other) : Widget3D(other) {} + CylinderWidget& operator=(const Widget &other); }; class CV_EXPORTS CubeWidget : public Widget3D { public: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); + CubeWidget(const Widget& other) : Widget3D(other) {} + CubeWidget& operator=(const Widget &other); }; class CV_EXPORTS CoordinateSystemWidget : public Widget3D { public: CoordinateSystemWidget(double scale, const Affine3f& affine); + CoordinateSystemWidget(const Widget &other) : Widget3D(other) {} + CoordinateSystemWidget& operator=(const Widget &other); }; class CV_EXPORTS TextWidget : public Widget2D { public: TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); + TextWidget(const Widget& other) : Widget2D(other) {} + TextWidget& operator=(const Widget &other); }; class CV_EXPORTS CloudWidget : public Widget3D @@ -115,6 +137,9 @@ namespace temp_viz public: CloudWidget(InputArray _cloud, InputArray _colors); CloudWidget(InputArray _cloud, const Color &color = Color::white()); + CloudWidget(const Widget &other) : Widget3D(other) {} + CloudWidget& operator=(const Widget &other); + private: struct CreateCloudWidget; }; @@ -123,6 +148,9 @@ namespace temp_viz { public: CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); + CloudNormalsWidget(const Widget &other) : Widget3D(other) {} + CloudNormalsWidget& operator=(const Widget &other); + private: struct ApplyCloudNormals; }; diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index 6595416bb..a49bb4922 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -200,10 +200,11 @@ public: void setSize (int xw, int yw); void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); - bool removeWidget(const String &id); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; - bool setWidgetPose(const String &id, const Affine3f &pose); - bool updateWidgetPose(const String &id, const Affine3f &pose); + void setWidgetPose(const String &id, const Affine3f &pose); + void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; void all_data(); diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 8cb77ee44..82a529272 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -25,6 +25,12 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C setColor(color); } +temp_viz::LineWidget& temp_viz::LineWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; +} + void temp_viz::LineWidget::setLineWidth(float line_width) { vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); @@ -82,6 +88,12 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double setColor(color); } +temp_viz::PlaneWidget& temp_viz::PlaneWidget::operator=(const Widget& other) +{ + Widget3D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// sphere widget implementation @@ -106,6 +118,12 @@ temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, in setColor(color); } +temp_viz::SphereWidget& temp_viz::SphereWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// arrow widget implementation @@ -170,6 +188,12 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const setColor(color); } +temp_viz::ArrowWidget& temp_viz::ArrowWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// circle widget implementation @@ -201,6 +225,12 @@ temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, setColor(color); } +temp_viz::CircleWidget& temp_viz::CircleWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// cylinder widget implementation @@ -227,6 +257,12 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 setColor(color); } +temp_viz::CylinderWidget& temp_viz::CylinderWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// cylinder widget implementation @@ -249,6 +285,12 @@ temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, b setColor(color); } +temp_viz::CubeWidget& temp_viz::CubeWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// coordinate system widget implementation @@ -300,6 +342,12 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff actor->RotateWXYZ(r_angle*180/CV_PI,rvec[0], rvec[1], rvec[2]); } +temp_viz::CoordinateSystemWidget& temp_viz::CoordinateSystemWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// text widget implementation @@ -321,6 +369,12 @@ temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int fon tprop->SetColor (c.val); } +temp_viz::TextWidget& temp_viz::TextWidget::operator=(const Widget &other) +{ + Widget2D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// point cloud widget implementation @@ -487,6 +541,12 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) setColor(color); } +temp_viz::CloudWidget& temp_viz::CloudWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// cloud normals widget implementation @@ -618,4 +678,10 @@ temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _ vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); actor->SetMapper(mapper); setColor(color); +} + +temp_viz::CloudNormalsWidget& temp_viz::CloudNormalsWidget::operator=(const Widget &other) +{ + Widget3D::operator=(other); + return *this; } \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index ed9405e91..0460630ba 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -84,19 +84,24 @@ void temp_viz::Viz3d::showWidget(const String &id, const Widget &widget, const A impl_->showWidget(id, widget, pose); } -bool temp_viz::Viz3d::removeWidget(const String &id) +void temp_viz::Viz3d::removeWidget(const String &id) { - return impl_->removeWidget(id); + impl_->removeWidget(id); } -bool temp_viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) +temp_viz::Widget temp_viz::Viz3d::getWidget(const String &id) const { - return impl_->setWidgetPose(id, pose); + return impl_->getWidget(id); } -bool temp_viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) +void temp_viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { - return impl_->updateWidgetPose(id, pose); + impl_->setWidgetPose(id, pose); +} + +void temp_viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) +{ + impl_->updateWidgetPose(id, pose); } temp_viz::Affine3f temp_viz::Viz3d::getWidgetPose(const String &id) const diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 11982b574..ae7190afc 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -874,9 +874,10 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget removeActorFromRenderer(wam_itr->second.actor); } // Get the actor and set the user matrix - vtkLODActor *actor; - if (actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(widget))) + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(widget)); + if (actor) { + // If the actor is 3D, apply pose vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); actor->SetUserMatrix (matrix); actor->Modified(); @@ -885,61 +886,61 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget (*widget_actor_map_)[id].actor = WidgetAccessor::getActor(widget); } -bool temp_viz::Viz3d::VizImpl::removeWidget(const String &id) +void temp_viz::Viz3d::VizImpl::removeWidget(const String &id) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); CV_Assert(exists); - - if (!removeActorFromRenderer (wam_itr->second.actor)) - return false; - + CV_Assert(removeActorFromRenderer (wam_itr->second.actor)); widget_actor_map_->erase(wam_itr); - return true; } -bool temp_viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) +temp_viz::Widget temp_viz::Viz3d::VizImpl::getWidget(const String &id) const +{ + WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + Widget widget; + WidgetAccessor::setVtkProp(widget, wam_itr->second.actor); + return widget; +} + +void temp_viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); CV_Assert(exists); - vtkLODActor *actor; - if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) - { - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); - return true; - } - return false; + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + CV_Assert(actor); + + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified (); } -bool temp_viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) +void temp_viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); CV_Assert(exists); - vtkLODActor *actor; - if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + CV_Assert(actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + if (!matrix) { - vtkSmartPointer matrix = actor->GetUserMatrix(); - if (!matrix) - { - setWidgetPose(id, pose); - return true; - } - Matx44f matrix_cv = convertToMatx(matrix); - - Affine3f updated_pose = pose * Affine3f(matrix_cv); - matrix = convertToVtkMatrix(updated_pose.matrix); - - actor->SetUserMatrix (matrix); - actor->Modified (); - return true; + setWidgetPose(id, pose); + return ; } - return false; + Matx44f matrix_cv = convertToMatx(matrix); + Affine3f updated_pose = pose * Affine3f(matrix_cv); + matrix = convertToVtkMatrix(updated_pose.matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); } temp_viz::Affine3f temp_viz::Viz3d::VizImpl::getWidgetPose(const String &id) const @@ -948,12 +949,10 @@ temp_viz::Affine3f temp_viz::Viz3d::VizImpl::getWidgetPose(const String &id) con bool exists = wam_itr != widget_actor_map_->end(); CV_Assert(exists); - vtkLODActor *actor; - if ((actor = vtkLODActor::SafeDownCast(wam_itr->second.actor))) - { - vtkSmartPointer matrix = actor->GetUserMatrix(); - Matx44f matrix_cv = convertToMatx(matrix); - return Affine3f(matrix_cv); - } - return Affine3f(); + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + CV_Assert(actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv = convertToMatx(matrix); + return Affine3f(matrix_cv); } \ No newline at end of file diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 93dd2a68e..419cd350a 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -22,7 +22,7 @@ temp_viz::Widget::Widget(const Widget &other) : impl_(other.impl_) if (impl_) CV_XADD(&impl_->ref_counter, 1); } -temp_viz::Widget& temp_viz::Widget::operator =(const Widget &other) +temp_viz::Widget& temp_viz::Widget::operator=(const Widget &other) { if (this != &other) { @@ -91,6 +91,23 @@ struct temp_viz::Widget3D::MatrixConverter } }; +temp_viz::Widget3D::Widget3D(const Widget& other) : Widget(other) +{ + // Check if other's actor is castable to vtkProp3D + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(other)); + CV_Assert(actor); +} + +temp_viz::Widget3D& temp_viz::Widget3D::operator =(const Widget &other) +{ + // Check if other's actor is castable to vtkProp3D + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(other)); + CV_Assert(actor); + + Widget::operator=(other); + return *this; +} + void temp_viz::Widget3D::setPose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(*this)); @@ -147,3 +164,22 @@ void temp_viz::Widget3D::setColor(const Color &color) actor->GetProperty ()->SetLighting (0); actor->Modified (); } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// widget2D implementation + +temp_viz::Widget2D::Widget2D(const Widget &other) : Widget(other) +{ + // Check if other's actor is castable to vtkActor2D + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getActor(other)); + CV_Assert(actor); +} + +temp_viz::Widget2D& temp_viz::Widget2D::operator=(const Widget &other) +{ + // Check if other's actor is castable to vtkActor2D + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getActor(other)); + CV_Assert(actor); + Widget::operator=(other); + return *this; +} \ No newline at end of file From 10d955f18b7c6af94f9556aa8bb292dd6bd3dff3 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 9 Jul 2013 14:28:55 +0200 Subject: [PATCH 064/205] widget2d setcolor implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 2 ++ modules/viz/src/widget.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 9aea9725a..d70b76340 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -53,6 +53,8 @@ namespace temp_viz Widget2D() {} Widget2D(const Widget &other); Widget2D& operator=(const Widget &other); + + void setColor(const Color &color); }; diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 419cd350a..e7f346df4 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -182,4 +182,13 @@ temp_viz::Widget2D& temp_viz::Widget2D::operator=(const Widget &other) CV_Assert(actor); Widget::operator=(other); return *this; +} + +void temp_viz::Widget2D::setColor(const Color &color) +{ + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getActor(*this)); + CV_Assert(actor); + Color c = vtkcolor(color); + actor->GetProperty ()->SetColor (c.val); + actor->Modified (); } \ No newline at end of file From 200b254badd774337d969264f16616759e9f30eb Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 9 Jul 2013 15:18:44 +0200 Subject: [PATCH 065/205] rearrange widget constructors --- .../include/opencv2/viz/widget_accessor.hpp | 4 +- modules/viz/include/opencv2/viz/widgets.hpp | 3 + modules/viz/src/simple_widgets.cpp | 98 ++++++++++--------- modules/viz/src/viz3d_impl.cpp | 8 +- modules/viz/src/widget.cpp | 22 ++--- 5 files changed, 72 insertions(+), 63 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index ec2a02030..ddfd61b1c 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -12,7 +12,7 @@ namespace temp_viz //It is indended for those users who want to develop own widgets system using VTK library API. struct CV_EXPORTS WidgetAccessor { - static vtkSmartPointer getActor(const Widget &widget); - static void setVtkProp(Widget &widget, vtkSmartPointer actor); + static vtkSmartPointer getProp(const Widget &widget); + static void setProp(Widget &widget, vtkSmartPointer actor); }; } diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index d70b76340..23eb7b71c 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -132,6 +132,9 @@ namespace temp_viz TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); TextWidget(const Widget& other) : Widget2D(other) {} TextWidget& operator=(const Widget &other); + + void setText(const String &text); + String getText() const; }; class CV_EXPORTS CloudWidget : public Widget3D diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 82a529272..d1fab75d2 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -8,9 +8,7 @@ namespace temp_viz /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) -{ - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - +{ vtkSmartPointer line = vtkSmartPointer::New(); line->SetPoint1 (pt1.x, pt1.y, pt1.z); line->SetPoint2 (pt2.x, pt2.y, pt2.z); @@ -19,9 +17,10 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(line->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -33,13 +32,15 @@ temp_viz::LineWidget& temp_viz::LineWidget::operator=(const Widget &other) void temp_viz::LineWidget::setLineWidth(float line_width) { - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); actor->GetProperty()->SetLineWidth(line_width); } float temp_viz::LineWidget::getLineWidth() { - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); return actor->GetProperty()->GetLineWidth(); } @@ -47,9 +48,7 @@ float temp_viz::LineWidget::getLineWidth() /// plane widget implementation temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color &color) -{ - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - +{ vtkSmartPointer plane = vtkSmartPointer::New (); plane->SetNormal (coefs[0], coefs[1], coefs[2]); double norm = cv::norm(cv::Vec3f(coefs.val)); @@ -58,17 +57,16 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(plane->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); actor->SetScale(size); + WidgetAccessor::setProp(*this, actor); setColor(color); } temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size, const Color &color) { - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - vtkSmartPointer plane = vtkSmartPointer::New (); cv::Point3f coefs3(coefs[0], coefs[1], coefs[2]); double norm_sqr = 1.0 / coefs3.dot (coefs3); @@ -81,10 +79,11 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(plane->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); actor->SetScale(size); - + + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -99,8 +98,6 @@ temp_viz::PlaneWidget& temp_viz::PlaneWidget::operator=(const Widget& other) temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution, const Color &color) { - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - vtkSmartPointer sphere = vtkSmartPointer::New (); sphere->SetRadius (radius); sphere->SetCenter (center.x, center.y, center.z); @@ -112,9 +109,10 @@ temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, in vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(sphere->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -129,8 +127,6 @@ temp_viz::SphereWidget& temp_viz::SphereWidget::operator=(const Widget &other) temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color) { - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - vtkSmartPointer arrowSource = vtkSmartPointer::New (); float startPoint[3], endPoint[3]; @@ -182,9 +178,10 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(transformPD->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -199,8 +196,6 @@ temp_viz::ArrowWidget& temp_viz::ArrowWidget::operator=(const Widget &other) temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, double thickness, const temp_viz::Color& color) { - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - vtkSmartPointer disk = vtkSmartPointer::New (); // Maybe the resolution should be lower e.g. 50 or 25 disk->SetCircumferentialResolution (50); @@ -219,9 +214,10 @@ temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(tf->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -235,9 +231,7 @@ temp_viz::CircleWidget& temp_viz::CircleWidget::operator=(const Widget &other) /// cylinder widget implementation temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides, const Color &color) -{ - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - +{ const cv::Point3f pt2 = pt_on_axis + axis_direction; vtkSmartPointer line = vtkSmartPointer::New (); line->SetPoint1 (pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); @@ -251,9 +245,10 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(tuber->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New (); actor->SetMapper(mapper); + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -268,20 +263,19 @@ temp_viz::CylinderWidget& temp_viz::CylinderWidget::operator=(const Widget &othe temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame, const Color &color) { - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - vtkSmartPointer cube = vtkSmartPointer::New (); cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput(cube->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); if (wire_frame) actor->GetProperty ()->SetRepresentationToWireframe (); + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -296,8 +290,6 @@ temp_viz::CubeWidget& temp_viz::CubeWidget::operator=(const Widget &other) temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Affine3f& affine) { - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - vtkSmartPointer axes = vtkSmartPointer::New (); axes->SetOrigin (0, 0, 0); axes->SetScaleFactor (scale); @@ -324,7 +316,7 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff mapper->SetScalarModeToUsePointData (); mapper->SetInput(axes_tubes->GetOutput ()); - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); cv::Vec3d t = affine.translation(); @@ -340,6 +332,8 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff actor->SetOrientation(0,0,0); actor->RotateWXYZ(r_angle*180/CV_PI,rvec[0], rvec[1], rvec[2]); + + WidgetAccessor::setProp(*this, actor); } temp_viz::CoordinateSystemWidget& temp_viz::CoordinateSystemWidget::operator=(const Widget &other) @@ -353,9 +347,7 @@ temp_viz::CoordinateSystemWidget& temp_viz::CoordinateSystemWidget::operator=(co temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) { - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - - vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetPosition (pos.x, pos.y); actor->SetInput (text.c_str ()); @@ -367,6 +359,8 @@ temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int fon Color c = vtkcolor(color); tprop->SetColor (c.val); + + WidgetAccessor::setProp(*this, actor); } temp_viz::TextWidget& temp_viz::TextWidget::operator=(const Widget &other) @@ -375,6 +369,20 @@ temp_viz::TextWidget& temp_viz::TextWidget::operator=(const Widget &other) return *this; } +void temp_viz::TextWidget::setText(const String &text) +{ + vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + actor->SetInput(text.c_str()); +} + +temp_viz::String temp_viz::TextWidget::getText() const +{ + vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + return actor->GetInput(); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// point cloud widget implementation @@ -474,9 +482,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - - vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); @@ -510,6 +516,8 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) actor->GetProperty ()->SetInterpolationToFlat (); actor->GetProperty ()->BackfaceCullingOn (); actor->SetMapper (mapper); + + WidgetAccessor::setProp(*this, actor); } temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) @@ -517,9 +525,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) Mat cloud = _cloud.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - - vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); @@ -538,6 +544,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) actor->GetProperty ()->BackfaceCullingOn (); actor->SetMapper (mapper); + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -634,9 +641,7 @@ temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _ Mat normals = _normals.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type()); - - WidgetAccessor::setVtkProp(*this, vtkSmartPointer::New()); - + vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer lines = vtkSmartPointer::New(); vtkIdType nr_normals = 0; @@ -675,8 +680,9 @@ temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _ mapper->SetColorModeToMapScalars(); mapper->SetScalarModeToUsePointData(); - vtkLODActor * actor = vtkLODActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); + WidgetAccessor::setProp(*this, actor); setColor(color); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index ae7190afc..dd94dc343 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -874,7 +874,7 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget removeActorFromRenderer(wam_itr->second.actor); } // Get the actor and set the user matrix - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(widget)); + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget)); if (actor) { // If the actor is 3D, apply pose @@ -882,8 +882,8 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget actor->SetUserMatrix (matrix); actor->Modified(); } - renderer_->AddActor(WidgetAccessor::getActor(widget)); - (*widget_actor_map_)[id].actor = WidgetAccessor::getActor(widget); + renderer_->AddActor(WidgetAccessor::getProp(widget)); + (*widget_actor_map_)[id].actor = WidgetAccessor::getProp(widget); } void temp_viz::Viz3d::VizImpl::removeWidget(const String &id) @@ -902,7 +902,7 @@ temp_viz::Widget temp_viz::Viz3d::VizImpl::getWidget(const String &id) const CV_Assert(exists); Widget widget; - WidgetAccessor::setVtkProp(widget, wam_itr->second.actor); + WidgetAccessor::setProp(widget, wam_itr->second.actor); return widget; } diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index e7f346df4..b832d15df 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -57,12 +57,12 @@ void temp_viz::Widget::release() /////////////////////////////////////////////////////////////////////////////////////////////// /// widget accessor implementaion -vtkSmartPointer temp_viz::WidgetAccessor::getActor(const Widget& widget) +vtkSmartPointer temp_viz::WidgetAccessor::getProp(const Widget& widget) { return widget.impl_->actor; } -void temp_viz::WidgetAccessor::setVtkProp(Widget& widget, vtkSmartPointer actor) +void temp_viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer actor) { widget.impl_->actor = actor; } @@ -94,14 +94,14 @@ struct temp_viz::Widget3D::MatrixConverter temp_viz::Widget3D::Widget3D(const Widget& other) : Widget(other) { // Check if other's actor is castable to vtkProp3D - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(other)); + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(other)); CV_Assert(actor); } temp_viz::Widget3D& temp_viz::Widget3D::operator =(const Widget &other) { // Check if other's actor is castable to vtkProp3D - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(other)); + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(other)); CV_Assert(actor); Widget::operator=(other); @@ -110,7 +110,7 @@ temp_viz::Widget3D& temp_viz::Widget3D::operator =(const Widget &other) void temp_viz::Widget3D::setPose(const Affine3f &pose) { - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); @@ -120,7 +120,7 @@ void temp_viz::Widget3D::setPose(const Affine3f &pose) void temp_viz::Widget3D::updatePose(const Affine3f &pose) { - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); vtkSmartPointer matrix = actor->GetUserMatrix(); @@ -140,7 +140,7 @@ void temp_viz::Widget3D::updatePose(const Affine3f &pose) temp_viz::Affine3f temp_viz::Widget3D::getPose() const { - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); vtkSmartPointer matrix = actor->GetUserMatrix(); @@ -151,7 +151,7 @@ temp_viz::Affine3f temp_viz::Widget3D::getPose() const void temp_viz::Widget3D::setColor(const Color &color) { // Cast to actor instead of prop3d since prop3d doesn't provide getproperty - vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); Color c = vtkcolor(color); @@ -171,14 +171,14 @@ void temp_viz::Widget3D::setColor(const Color &color) temp_viz::Widget2D::Widget2D(const Widget &other) : Widget(other) { // Check if other's actor is castable to vtkActor2D - vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getActor(other)); + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(other)); CV_Assert(actor); } temp_viz::Widget2D& temp_viz::Widget2D::operator=(const Widget &other) { // Check if other's actor is castable to vtkActor2D - vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getActor(other)); + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(other)); CV_Assert(actor); Widget::operator=(other); return *this; @@ -186,7 +186,7 @@ temp_viz::Widget2D& temp_viz::Widget2D::operator=(const Widget &other) void temp_viz::Widget2D::setColor(const Color &color) { - vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getActor(*this)); + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); Color c = vtkcolor(color); actor->GetProperty ()->SetColor (c.val); From 509a93c7ce73cb9697b7c19d9aca6ee02e210ea8 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Tue, 9 Jul 2013 19:35:26 +0400 Subject: [PATCH 066/205] minor naming --- modules/viz/include/opencv2/viz/widget_accessor.hpp | 4 ++-- modules/viz/include/opencv2/viz/widgets.hpp | 1 - modules/viz/src/widget.cpp | 12 ++++++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index ddfd61b1c..a114c3a26 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include namespace temp_viz { @@ -13,6 +13,6 @@ namespace temp_viz struct CV_EXPORTS WidgetAccessor { static vtkSmartPointer getProp(const Widget &widget); - static void setProp(Widget &widget, vtkSmartPointer actor); + static void setProp(Widget &widget, vtkSmartPointer prop); }; } diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 23eb7b71c..2114838c5 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -15,7 +15,6 @@ namespace temp_viz Widget& operator =(const Widget &other); ~Widget(); - private: class Impl; Impl *impl_; diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index b832d15df..450e76633 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -6,10 +6,10 @@ class temp_viz::Widget::Impl { public: - vtkSmartPointer actor; + vtkSmartPointer prop; int ref_counter; - Impl() : actor(0) {} + Impl() : prop(0) {} }; temp_viz::Widget::Widget() : impl_(0) @@ -59,12 +59,12 @@ void temp_viz::Widget::release() vtkSmartPointer temp_viz::WidgetAccessor::getProp(const Widget& widget) { - return widget.impl_->actor; + return widget.impl_->prop; } -void temp_viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer actor) +void temp_viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer prop) { - widget.impl_->actor = actor; + widget.impl_->prop = prop; } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -191,4 +191,4 @@ void temp_viz::Widget2D::setColor(const Color &color) Color c = vtkcolor(color); actor->GetProperty ()->SetColor (c.val); actor->Modified (); -} \ No newline at end of file +} From e4c3416f5885d44ae69e2e022279ffbc96c636ae Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Tue, 9 Jul 2013 20:02:43 +0400 Subject: [PATCH 067/205] experimental widget casting functionality --- modules/viz/include/opencv2/viz/widgets.hpp | 13 +++++++++---- modules/viz/src/simple_widgets.cpp | 14 +++++++------- modules/viz/src/widget.cpp | 10 ++++++++++ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 2114838c5..c61b5a745 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -15,6 +15,8 @@ namespace temp_viz Widget& operator =(const Widget &other); ~Widget(); + + template _W cast(); private: class Impl; Impl *impl_; @@ -56,18 +58,15 @@ namespace temp_viz void setColor(const Color &color); }; - class CV_EXPORTS LineWidget : public Widget3D { public: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); - LineWidget(const Widget &other) : Widget3D(other) {} - LineWidget& operator=(const Widget &other); void setLineWidth(float line_width); float getLineWidth(); }; - + class CV_EXPORTS PlaneWidget : public Widget3D { public: @@ -158,4 +157,10 @@ namespace temp_viz private: struct ApplyCloudNormals; }; + + template<> CV_EXPORTS Widget3D Widget::cast(); + template<> CV_EXPORTS LineWidget Widget::cast(); } + + + diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index d1fab75d2..1d5b0a9e9 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -24,12 +24,6 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C setColor(color); } -temp_viz::LineWidget& temp_viz::LineWidget::operator=(const Widget &other) -{ - Widget3D::operator=(other); - return *this; -} - void temp_viz::LineWidget::setLineWidth(float line_width) { vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); @@ -44,6 +38,12 @@ float temp_viz::LineWidget::getLineWidth() return actor->GetProperty()->GetLineWidth(); } +template<> temp_viz::LineWidget temp_viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// plane widget implementation @@ -690,4 +690,4 @@ temp_viz::CloudNormalsWidget& temp_viz::CloudNormalsWidget::operator=(const Widg { Widget3D::operator=(other); return *this; -} \ No newline at end of file +} diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 450e76633..cb415ce82 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -165,6 +165,16 @@ void temp_viz::Widget3D::setColor(const Color &color) actor->Modified (); } +template<> temp_viz::Widget3D temp_viz::Widget::cast() +{ + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + Widget3D widget; + WidgetAccessor::setProp(widget, actor); + return widget; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// widget2D implementation From d3dee3a2fe541bd0424f08cd2aa62e454ef82333 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 10 Jul 2013 09:55:42 +0200 Subject: [PATCH 068/205] explicit casting among widgets, removed implicit casting --- modules/viz/include/opencv2/viz/widgets.hpp | 35 ++++-------- modules/viz/src/simple_widgets.cpp | 60 ++++++++++----------- modules/viz/src/widget.cpp | 43 ++++----------- 3 files changed, 51 insertions(+), 87 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index c61b5a745..cf265ac48 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -32,8 +32,6 @@ namespace temp_viz { public: Widget3D() {} - Widget3D(const Widget& other); - Widget3D& operator =(const Widget &other); void setPose(const Affine3f &pose); void updatePose(const Affine3f &pose); @@ -52,8 +50,6 @@ namespace temp_viz { public: Widget2D() {} - Widget2D(const Widget &other); - Widget2D& operator=(const Widget &other); void setColor(const Color &color); }; @@ -72,64 +68,48 @@ namespace temp_viz public: PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); - PlaneWidget(const Widget& other) : Widget3D(other) {} - PlaneWidget& operator=(const Widget& other); }; class CV_EXPORTS SphereWidget : public Widget3D { public: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); - SphereWidget(const Widget &other) : Widget3D(other) {} - SphereWidget& operator=(const Widget &other); }; class CV_EXPORTS ArrowWidget : public Widget3D { public: ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color = Color::white()); - ArrowWidget(const Widget &other) : Widget3D(other) {} - ArrowWidget& operator=(const Widget &other); }; class CV_EXPORTS CircleWidget : public Widget3D { public: CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); - CircleWidget(const Widget& other) : Widget3D(other) {} - CircleWidget& operator=(const Widget &other); }; class CV_EXPORTS CylinderWidget : public Widget3D { public: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); - CylinderWidget(const Widget& other) : Widget3D(other) {} - CylinderWidget& operator=(const Widget &other); }; class CV_EXPORTS CubeWidget : public Widget3D { public: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); - CubeWidget(const Widget& other) : Widget3D(other) {} - CubeWidget& operator=(const Widget &other); }; class CV_EXPORTS CoordinateSystemWidget : public Widget3D { public: CoordinateSystemWidget(double scale, const Affine3f& affine); - CoordinateSystemWidget(const Widget &other) : Widget3D(other) {} - CoordinateSystemWidget& operator=(const Widget &other); }; class CV_EXPORTS TextWidget : public Widget2D { public: TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); - TextWidget(const Widget& other) : Widget2D(other) {} - TextWidget& operator=(const Widget &other); void setText(const String &text); String getText() const; @@ -140,8 +120,6 @@ namespace temp_viz public: CloudWidget(InputArray _cloud, InputArray _colors); CloudWidget(InputArray _cloud, const Color &color = Color::white()); - CloudWidget(const Widget &other) : Widget3D(other) {} - CloudWidget& operator=(const Widget &other); private: struct CreateCloudWidget; @@ -151,15 +129,24 @@ namespace temp_viz { public: CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); - CloudNormalsWidget(const Widget &other) : Widget3D(other) {} - CloudNormalsWidget& operator=(const Widget &other); private: struct ApplyCloudNormals; }; + template<> CV_EXPORTS Widget2D Widget::cast(); template<> CV_EXPORTS Widget3D Widget::cast(); template<> CV_EXPORTS LineWidget Widget::cast(); + template<> CV_EXPORTS PlaneWidget Widget::cast(); + template<> CV_EXPORTS SphereWidget Widget::cast(); + template<> CV_EXPORTS CylinderWidget Widget::cast(); + template<> CV_EXPORTS ArrowWidget Widget::cast(); + template<> CV_EXPORTS CircleWidget Widget::cast(); + template<> CV_EXPORTS CubeWidget Widget::cast(); + template<> CV_EXPORTS CoordinateSystemWidget Widget::cast(); + template<> CV_EXPORTS TextWidget Widget::cast(); + template<> CV_EXPORTS CloudWidget Widget::cast(); + template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 1d5b0a9e9..db27884e8 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -87,10 +87,10 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double setColor(color); } -temp_viz::PlaneWidget& temp_viz::PlaneWidget::operator=(const Widget& other) +template<> temp_viz::PlaneWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -116,10 +116,10 @@ temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, in setColor(color); } -temp_viz::SphereWidget& temp_viz::SphereWidget::operator=(const Widget &other) +template<> temp_viz::SphereWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -185,10 +185,10 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const setColor(color); } -temp_viz::ArrowWidget& temp_viz::ArrowWidget::operator=(const Widget &other) +template<> temp_viz::ArrowWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -221,10 +221,10 @@ temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, setColor(color); } -temp_viz::CircleWidget& temp_viz::CircleWidget::operator=(const Widget &other) +template<> temp_viz::CircleWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -252,10 +252,10 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 setColor(color); } -temp_viz::CylinderWidget& temp_viz::CylinderWidget::operator=(const Widget &other) +template<> temp_viz::CylinderWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -279,10 +279,10 @@ temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, b setColor(color); } -temp_viz::CubeWidget& temp_viz::CubeWidget::operator=(const Widget &other) +template<> temp_viz::CubeWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -336,10 +336,10 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff WidgetAccessor::setProp(*this, actor); } -temp_viz::CoordinateSystemWidget& temp_viz::CoordinateSystemWidget::operator=(const Widget &other) +template<> temp_viz::CoordinateSystemWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -363,10 +363,10 @@ temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int fon WidgetAccessor::setProp(*this, actor); } -temp_viz::TextWidget& temp_viz::TextWidget::operator=(const Widget &other) +template<> temp_viz::TextWidget temp_viz::Widget::cast() { - Widget2D::operator=(other); - return *this; + Widget2D widget = this->cast(); + return static_cast(widget); } void temp_viz::TextWidget::setText(const String &text) @@ -548,10 +548,10 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) setColor(color); } -temp_viz::CloudWidget& temp_viz::CloudWidget::operator=(const Widget &other) +template<> temp_viz::CloudWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -686,8 +686,8 @@ temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _ setColor(color); } -temp_viz::CloudNormalsWidget& temp_viz::CloudNormalsWidget::operator=(const Widget &other) +template<> temp_viz::CloudNormalsWidget temp_viz::Widget::cast() { - Widget3D::operator=(other); - return *this; + Widget3D widget = this->cast(); + return static_cast(widget); } diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index cb415ce82..7978d7a5b 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -91,23 +91,6 @@ struct temp_viz::Widget3D::MatrixConverter } }; -temp_viz::Widget3D::Widget3D(const Widget& other) : Widget(other) -{ - // Check if other's actor is castable to vtkProp3D - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(other)); - CV_Assert(actor); -} - -temp_viz::Widget3D& temp_viz::Widget3D::operator =(const Widget &other) -{ - // Check if other's actor is castable to vtkProp3D - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(other)); - CV_Assert(actor); - - Widget::operator=(other); - return *this; -} - void temp_viz::Widget3D::setPose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); @@ -178,22 +161,6 @@ template<> temp_viz::Widget3D temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// widget2D implementation -temp_viz::Widget2D::Widget2D(const Widget &other) : Widget(other) -{ - // Check if other's actor is castable to vtkActor2D - vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(other)); - CV_Assert(actor); -} - -temp_viz::Widget2D& temp_viz::Widget2D::operator=(const Widget &other) -{ - // Check if other's actor is castable to vtkActor2D - vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(other)); - CV_Assert(actor); - Widget::operator=(other); - return *this; -} - void temp_viz::Widget2D::setColor(const Color &color) { vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); @@ -202,3 +169,13 @@ void temp_viz::Widget2D::setColor(const Color &color) actor->GetProperty ()->SetColor (c.val); actor->Modified (); } + +template<> temp_viz::Widget2D temp_viz::Widget::cast() +{ + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + Widget2D widget; + WidgetAccessor::setProp(widget, actor); + return widget; +} From 71c76aecc9bffefce9660008a9ac7d2e50bb7b79 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 10 Jul 2013 12:51:17 +0200 Subject: [PATCH 069/205] PolyLine widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 10 +++ modules/viz/src/simple_widgets.cpp | 82 ++++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 34 ++++++--- 3 files changed, 113 insertions(+), 13 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index cf265ac48..cd1ed9453 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -106,6 +106,15 @@ namespace temp_viz CoordinateSystemWidget(double scale, const Affine3f& affine); }; + class CV_EXPORTS PolyLineWidget : public Widget3D + { + public: + PolyLineWidget(InputArray _points, const Color &color = Color::white()); + + private: + struct CopyImpl; + }; + class CV_EXPORTS TextWidget : public Widget2D { public: @@ -144,6 +153,7 @@ namespace temp_viz template<> CV_EXPORTS CircleWidget Widget::cast(); template<> CV_EXPORTS CubeWidget Widget::cast(); template<> CV_EXPORTS CoordinateSystemWidget Widget::cast(); + template<> CV_EXPORTS PolyLineWidget Widget::cast(); template<> CV_EXPORTS TextWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index db27884e8..a9ed2ef8f 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -26,14 +26,14 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C void temp_viz::LineWidget::setLineWidth(float line_width) { - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); actor->GetProperty()->SetLineWidth(line_width); } float temp_viz::LineWidget::getLineWidth() { - vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); return actor->GetProperty()->GetLineWidth(); } @@ -342,6 +342,82 @@ template<> temp_viz::CoordinateSystemWidget temp_viz::Widget::cast(widget); } +/////////////////////////////////////////////////////////////////////////////////////////////// +/// polyline widget implementation + +struct temp_viz::PolyLineWidget::CopyImpl +{ + template + static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer polyLine) + { + int s_chs = source.channels(); + + for(int y = 0, id = 0; y < source.rows; ++y) + { + const _Tp* srow = source.ptr<_Tp>(y); + + for(int x = 0; x < source.cols; ++x, srow += s_chs, ++id) + { + *output++ = Vec<_Tp, 3>(srow); + polyLine->GetPointIds()->SetId(id,id); + } + } + } +}; + +temp_viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &color) +{ + Mat pointData = _pointData.getMat(); + CV_Assert(pointData.type() == CV_32FC3 || pointData.type() == CV_32FC4 || pointData.type() == CV_64FC3 || pointData.type() == CV_64FC4); + vtkIdType nr_points = pointData.total(); + + vtkSmartPointer points = vtkSmartPointer::New (); + vtkSmartPointer polyData = vtkSmartPointer::New (); + vtkSmartPointer polyLine = vtkSmartPointer::New (); + + if (pointData.depth() == CV_32F) + points->SetDataTypeToFloat(); + else + points->SetDataTypeToDouble(); + + points->SetNumberOfPoints(nr_points); + polyLine->GetPointIds()->SetNumberOfIds(nr_points); + + if (pointData.depth() == CV_32F) + { + // Get a pointer to the beginning of the data array + Vec3f *data_beg = vtkpoints_data(points); + CopyImpl::copy(pointData, data_beg, polyLine); + } + else if (pointData.depth() == CV_64F) + { + // Get a pointer to the beginning of the data array + Vec3d *data_beg = vtkpoints_data(points); + CopyImpl::copy(pointData, data_beg, polyLine); + } + + vtkSmartPointer cells = vtkSmartPointer::New(); + cells->InsertNextCell(polyLine); + + polyData->SetPoints(points); + polyData->SetLines(cells); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(polyData); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> temp_viz::PolyLineWidget temp_viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// text widget implementation @@ -398,8 +474,6 @@ struct temp_viz::CloudWidget::CreateCloudWidget vtkSmartPointer points = polydata->GetPoints(); vtkSmartPointer initcells; nr_points = cloud.total(); - - points = polydata->GetPoints (); if (!points) { diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 76993d160..fb8a9f6da 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -112,16 +112,32 @@ TEST(Viz_viz3d, accuracy) v.showWidget("coordinateSystem", csw); // v.showWidget("text",tw); // v.showWidget("pcw",pcw); - v.showWidget("pcw2",pcw2); +// v.showWidget("pcw2",pcw2); - temp_viz::LineWidget lw2 = lw; +// temp_viz::LineWidget lw2 = lw; // v.showPointCloud("cld",cloud, colors); cv::Mat normals(cloud.size(), cloud.type(), cv::Scalar(0, 10, 0)); // v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); temp_viz::CloudNormalsWidget cnw(cloud, normals); - v.showWidget("n", cnw); +// v.showWidget("n", cnw); + +// lw = v.getWidget("n").cast(); +// pw = v.getWidget("n").cast(); + + cv::Mat points(1, 4, CV_64FC4); + + cv::Vec4d* data = points.ptr(); + data[0] = cv::Vec4d(0.0,0.0,0.0,0.0); + data[1] = cv::Vec4d(1.0,1.0,1.0,1.0); + data[2] = cv::Vec4d(0.0,2.0,0.0,0.0); + data[3] = cv::Vec4d(3.0,4.0,1.0,1.0); + points = points.reshape(0, 2); + + temp_viz::PolyLineWidget plw(points); + v.showWidget("polyline",plw); + lw = v.getWidget("polyline").cast(); while(!v.wasStopped()) { @@ -129,25 +145,25 @@ TEST(Viz_viz3d, accuracy) cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); cv::Affine3f cloudPosition2(angle_x, angle_y, angle_z, cv::Vec3f(pos_x+0.2, pos_y+0.2, pos_z+0.2)); - lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); - lw.setLineWidth(lw.getLineWidth()+pos_x * 10); +// lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); + lw.setLineWidth(pos_x * 10); - pw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + plw.setColor(temp_viz::Color(col_blue, col_green, col_red)); sw.setPose(cloudPosition); // pw.setPose(cloudPosition); aw.setPose(cloudPosition); cw.setPose(cloudPosition); cyw.setPose(cloudPosition); - lw.setPose(cloudPosition); +// lw.setPose(cloudPosition); cuw.setPose(cloudPosition); // cnw.setPose(cloudPosition); // v.showWidget("pcw",pcw, cloudPosition); // v.showWidget("pcw2",pcw2, cloudPosition2); // v.showWidget("plane", pw, cloudPosition); - v.setWidgetPose("n",cloudPosition); - v.setWidgetPose("pcw2", cloudPosition); +// v.setWidgetPose("n",cloudPosition); +// v.setWidgetPose("pcw2", cloudPosition); cnw.setColor(temp_viz::Color(col_blue, col_green, col_red)); pcw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); From e185900270be277c96d2a530344b4ade39d7b5e9 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 10 Jul 2013 15:34:19 +0200 Subject: [PATCH 070/205] grid widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 7 +++++ modules/viz/src/simple_widgets.cpp | 32 +++++++++++++++++++++ modules/viz/test/test_viz3d.cpp | 15 +++++++--- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index cd1ed9453..85ebda020 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -115,6 +115,12 @@ namespace temp_viz struct CopyImpl; }; + class CV_EXPORTS GridWidget : public Widget3D + { + public: + GridWidget(Vec2i dimensions, Vec2d spacing, const Color &color = Color::white()); + }; + class CV_EXPORTS TextWidget : public Widget2D { public: @@ -154,6 +160,7 @@ namespace temp_viz template<> CV_EXPORTS CubeWidget Widget::cast(); template<> CV_EXPORTS CoordinateSystemWidget Widget::cast(); template<> CV_EXPORTS PolyLineWidget Widget::cast(); + template<> CV_EXPORTS GridWidget Widget::cast(); template<> CV_EXPORTS TextWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index a9ed2ef8f..f3ecdb9dc 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -418,6 +418,38 @@ template<> temp_viz::PolyLineWidget temp_viz::Widget::cast(widget); } +/////////////////////////////////////////////////////////////////////////////////////////////// +/// grid widget implementation + +temp_viz::GridWidget::GridWidget(Vec2i dimensions, Vec2d spacing, const Color &color) +{ + // Create the grid using image data + vtkSmartPointer grid = vtkSmartPointer::New(); + + // Add 1 to dimensions because in ImageData dimensions is the number of lines + // - however here it means number of cells + grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1); + grid->SetSpacing(spacing[0], spacing[1], 0.); + + // Set origin of the grid to be the middle of the grid + grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(grid); + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + // Show it as wireframe + actor->GetProperty ()->SetRepresentationToWireframe (); + WidgetAccessor::setProp(*this, actor); +} + +template<> temp_viz::GridWidget temp_viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// text widget implementation diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index fb8a9f6da..7a48bb9a9 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -136,8 +136,13 @@ TEST(Viz_viz3d, accuracy) points = points.reshape(0, 2); temp_viz::PolyLineWidget plw(points); - v.showWidget("polyline",plw); - lw = v.getWidget("polyline").cast(); +// v.showWidget("polyline",plw); +// lw = v.getWidget("polyline").cast(); + + temp_viz::GridWidget gw(temp_viz::Vec2i(10,10), temp_viz::Vec2d(0.1,0.1)); + v.showWidget("grid", gw); + lw = v.getWidget("grid").cast(); +// float grid_x_angle = 0.0; while(!v.wasStopped()) { @@ -145,8 +150,8 @@ TEST(Viz_viz3d, accuracy) cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); cv::Affine3f cloudPosition2(angle_x, angle_y, angle_z, cv::Vec3f(pos_x+0.2, pos_y+0.2, pos_z+0.2)); -// lw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); - lw.setLineWidth(pos_x * 10); + lw.setColor(temp_viz::Color(col_blue, col_green, col_red)); +// lw.setLineWidth(pos_x * 10); plw.setColor(temp_viz::Color(col_blue, col_green, col_red)); @@ -167,6 +172,8 @@ TEST(Viz_viz3d, accuracy) cnw.setColor(temp_viz::Color(col_blue, col_green, col_red)); pcw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); + gw.updatePose(temp_viz::Affine3f(0.0, 0.1, 0.0, cv::Vec3f(0.0,0.0,0.0))); + angle_x += 0.1f; angle_y -= 0.1f; angle_z += 0.1f; From 5813a3a99d7da8cbc060d8ac60486da91c0af2cd Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 10 Jul 2013 16:34:47 +0200 Subject: [PATCH 071/205] text3D widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 10 ++++ modules/viz/src/simple_widgets.cpp | 53 +++++++++++++++++++++ modules/viz/test/test_viz3d.cpp | 3 ++ 3 files changed, 66 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 85ebda020..06750238e 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -121,6 +121,15 @@ namespace temp_viz GridWidget(Vec2i dimensions, Vec2d spacing, const Color &color = Color::white()); }; + class CV_EXPORTS Text3DWidget : public Widget3D + { + public: + Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + class CV_EXPORTS TextWidget : public Widget2D { public: @@ -161,6 +170,7 @@ namespace temp_viz template<> CV_EXPORTS CoordinateSystemWidget Widget::cast(); template<> CV_EXPORTS PolyLineWidget Widget::cast(); template<> CV_EXPORTS GridWidget Widget::cast(); + template<> CV_EXPORTS Text3DWidget Widget::cast(); template<> CV_EXPORTS TextWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index f3ecdb9dc..49e9f6811 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -450,6 +450,59 @@ template<> temp_viz::GridWidget temp_viz::Widget::cast() return static_cast(widget); } +/////////////////////////////////////////////////////////////////////////////////////////////// +/// text3D widget implementation + +temp_viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position, double text_scale, const Color &color) +{ + vtkSmartPointer textSource = vtkSmartPointer::New (); + textSource->SetText (text.c_str()); + textSource->Update (); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInputConnection (textSource->GetOutputPort ()); + + vtkSmartPointer actor = vtkSmartPointer::New (); + actor->SetMapper (mapper); + actor->SetPosition (position.x, position.y, position.z); + actor->SetScale (text_scale); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +void temp_viz::Text3DWidget::setText(const String &text) +{ + vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + // Update text source + vtkPolyDataMapper *mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + vtkVectorText * textSource = vtkVectorText::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); + CV_Assert(textSource); + + textSource->SetText(text.c_str()); + textSource->Update(); +} + +temp_viz::String temp_viz::Text3DWidget::getText() const +{ + vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + vtkPolyDataMapper *mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + vtkVectorText * textSource = vtkVectorText::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); + CV_Assert(textSource); + + return textSource->GetText(); +} + +template<> temp_viz::Text3DWidget temp_viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// text widget implementation diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 7a48bb9a9..090501eb5 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -142,6 +142,9 @@ TEST(Viz_viz3d, accuracy) temp_viz::GridWidget gw(temp_viz::Vec2i(10,10), temp_viz::Vec2d(0.1,0.1)); v.showWidget("grid", gw); lw = v.getWidget("grid").cast(); + + temp_viz::Text3DWidget t3w("OpenCV", cv::Point3f(0.0, 2.0, 0.0), 1.0, temp_viz::Color(255,255,0)); + v.showWidget("txt3d", t3w); // float grid_x_angle = 0.0; while(!v.wasStopped()) From eef8195569869189ed8abd991f81b503145a1381 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 11 Jul 2013 09:30:52 +0200 Subject: [PATCH 072/205] clean unnecessary methods, make text3d face camera --- modules/viz/include/opencv2/viz/viz3d.hpp | 5 - modules/viz/src/q/viz3d_impl.hpp | 21 -- modules/viz/src/viz3d.cpp | 20 -- modules/viz/src/viz3d_impl.cpp | 392 +--------------------- modules/viz/src/viz_main.cpp | 113 ------- 5 files changed, 7 insertions(+), 544 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index a0181cb71..f16d26d42 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -26,16 +26,11 @@ namespace temp_viz void setBackgroundColor(const Color& color = Color::black()); - void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); - void showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose = Affine3f::Identity()); - - bool addPointCloudNormals (const Mat &cloud, const Mat& normals, int level = 100, float scale = 0.02f, const String& id = "cloud"); bool addPolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); bool updatePolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - bool addText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String& id = ""); bool addPolygon(const Mat& cloud, const Color& color, const String& id = "polygon"); void spin (); diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index a49bb4922..b028812fb 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -52,36 +52,15 @@ public: void setBackgroundColor (const Color& color); - bool addText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String& id = ""); - bool updateText (const String &text, int xpos, int ypos, const Color& color, int fontsize = 10, const String& id = ""); - - /** \brief Set the pose of an existing shape. Returns false if the shape doesn't exist, true if the pose was succesfully updated. */ - bool updateShapePose (const String& id, const Affine3f& pose); - - bool addText3D (const String &text, const Point3f &position, const Color& color, double textScale = 1.0, const String& id = ""); - - bool addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level = 100, float scale = 0.02f, const String& id = "cloud"); - - /** \brief If the id exists, updates the point cloud; otherwise, adds a new point cloud to the scene - * \param[in] id a variable to identify the point cloud - * \param[in] cloud cloud input in x,y,z coordinates - * \param[in] colors color input in the same order of the points or single uniform color - * \param[in] pose transform to be applied on the point cloud - */ - void showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose = Affine3f::Identity()); - void showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose = Affine3f::Identity()); - bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - void setPointCloudColor (const Color& color, const String& id = "cloud"); bool setPointCloudRenderingProperties (int property, double value, const String& id = "cloud"); bool getPointCloudRenderingProperties (int property, double &value, const String& id = "cloud"); bool setShapeRenderingProperties (int property, double value, const String& id); - void setShapeColor (const Color& color, const String& id); /** \brief Set whether the point cloud is selected or not * \param[in] selected whether the cloud is selected or not (true = selected) diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 0460630ba..4b9357391 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -17,21 +17,6 @@ void temp_viz::Viz3d::setBackgroundColor(const Color& color) impl_->setBackgroundColor(color); } -void temp_viz::Viz3d::showPointCloud(const String& id, InputArray cloud, InputArray colors, const Affine3f& pose) -{ - impl_->showPointCloud(id, cloud, colors, pose); -} - -void temp_viz::Viz3d::showPointCloud(const String& id, InputArray cloud, const Color& color, const Affine3f& pose) -{ - impl_->showPointCloud(id, cloud, color, pose); -} - -bool temp_viz::Viz3d::addPointCloudNormals (const Mat &cloud, const Mat& normals, int level, float scale, const String& id) -{ - return impl_->addPointCloudNormals(cloud, normals, level, scale, id); -} - bool temp_viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String& id) { return impl_->addPolygonMesh(mesh, Mat(), id); @@ -47,11 +32,6 @@ bool temp_viz::Viz3d::addPolylineFromPolygonMesh (const Mesh3d& mesh, const Stri return impl_->addPolylineFromPolygonMesh(mesh, id); } -bool temp_viz::Viz3d::addText (const String &text, int xpos, int ypos, const Color& color, int fontsize, const String& id) -{ - return impl_->addText(text, xpos, ypos, color, fontsize, id); -} - bool temp_viz::Viz3d::addPolygon(const Mat& cloud, const Color& color, const String& id) { return impl_->addPolygon(cloud, color, id); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index dd94dc343..1a1fca699 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -36,347 +36,6 @@ void temp_viz::Viz3d::VizImpl::setWindowName (const std::string &name) void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } -void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _cloud, InputArray _colors, const Affine3f& pose) -{ - Mat cloud = _cloud.getMat(); - Mat colors = _colors.getMat(); - CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); - CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); - - vtkSmartPointer polydata; - vtkSmartPointer vertices; - vtkSmartPointer points; - vtkSmartPointer initcells; - vtkIdType nr_points = cloud.total(); - - // If the cloud already exists, update otherwise create new one - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - bool exist = am_it == cloud_actor_map_->end(); - if (exist) - { - // Add as new cloud - allocVtkPolyData(polydata); - //polydata = vtkSmartPointer::New (); - vertices = vtkSmartPointer::New (); - polydata->SetVerts (vertices); - - points = polydata->GetPoints (); - - if (!points) - { - points = vtkSmartPointer::New (); - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat(); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble(); - polydata->SetPoints (points); - } - points->SetNumberOfPoints (nr_points); - } - else - { - // Update the cloud - // Get the current poly data - polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); - vertices = polydata->GetVerts (); - points = polydata->GetPoints (); - // Update the point data type based on the cloud - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat (); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble (); - - points->SetNumberOfPoints (nr_points); - } - - if (cloud.depth() == CV_32F) - { - // Get a pointer to the beginning of the data array - Vec3f *data_beg = vtkpoints_data(points); - Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); - std::transform(data_beg, data_end, data_beg, ApplyAffine(pose)); - nr_points = data_end - data_beg; - - } - else if (cloud.depth() == CV_64F) - { - // Get a pointer to the beginning of the data array - Vec3d *data_beg = vtkpoints_data(points); - Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); - std::transform(data_beg, data_end, data_beg, ApplyAffine(pose)); - nr_points = data_end - data_beg; - } - - points->SetNumberOfPoints (nr_points); - - vtkSmartPointer cells = vertices->GetData (); - - if (exist) - updateCells (cells, initcells, nr_points); - else - updateCells (cells, am_it->second.cells, nr_points); - - // Set the cells and the vertices - vertices->SetCells (nr_points, cells); - - // Get a random color - Vec3b* colors_data = new Vec3b[nr_points]; - NanFilter::copy(colors, colors_data, cloud); - - vtkSmartPointer scalars = vtkSmartPointer::New (); - scalars->SetNumberOfComponents (3); - scalars->SetNumberOfTuples (nr_points); - scalars->SetArray (colors_data->val, 3 * nr_points, 0); - - // Assign the colors - Vec2d minmax; - polydata->GetPointData ()->SetScalars (scalars); - scalars->GetRange (minmax.val); - - // If this is the new point cloud, a new actor is created - if (exist) - { - vtkSmartPointer actor; - createActorFromVTKDataSet (polydata, actor); - - actor->GetMapper ()->SetScalarRange (minmax.val); - - // Add it to all renderers - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*cloud_actor_map_)[id].actor = actor; - (*cloud_actor_map_)[id].cells = initcells; - - const Eigen::Vector4f sensor_origin = Eigen::Vector4f::Zero (); - const Eigen::Quaternionf sensor_orientation = Eigen::Quaternionf::Identity (); - - // Save the viewpoint transformation matrix to the global actor map - vtkSmartPointer transformation = vtkSmartPointer::New(); - convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); - - (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; - } - else - { - // Update the mapper - reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); - am_it->second.actor->GetMapper ()->ScalarVisibilityOn(); - am_it->second.actor->Modified (); - } -} - -void temp_viz::Viz3d::VizImpl::showPointCloud(const String& id, InputArray _cloud, const Color& color, const Affine3f& pose) -{ - Mat cloud = _cloud.getMat(); - CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); - - vtkSmartPointer polydata; - vtkSmartPointer vertices; - vtkSmartPointer points; - vtkSmartPointer initcells; - vtkIdType nr_points = cloud.total(); - - // If the cloud already exists, update otherwise create new one - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - bool exist = am_it == cloud_actor_map_->end(); - if (exist) - { - // Add as new cloud - allocVtkPolyData(polydata); - //polydata = vtkSmartPointer::New (); - vertices = vtkSmartPointer::New (); - polydata->SetVerts (vertices); - - points = polydata->GetPoints (); - - if (!points) - { - points = vtkSmartPointer::New (); - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat(); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble(); - polydata->SetPoints (points); - } - points->SetNumberOfPoints (nr_points); - } - else - { - // Update the cloud - // Get the current poly data - polydata = reinterpret_cast(am_it->second.actor->GetMapper ())->GetInput (); - vertices = polydata->GetVerts (); - points = polydata->GetPoints (); - // Update the point data type based on the cloud - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat (); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble (); - - points->SetNumberOfPoints (nr_points); - } - - if (cloud.depth() == CV_32F) - { - // Get a pointer to the beginning of the data array - Vec3f *data_beg = vtkpoints_data(points); - Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); - std::transform(data_beg, data_end, data_beg, ApplyAffine(pose)); - nr_points = data_end - data_beg; - - } - else if (cloud.depth() == CV_64F) - { - // Get a pointer to the beginning of the data array - Vec3d *data_beg = vtkpoints_data(points); - Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); - std::transform(data_beg, data_end, data_beg, ApplyAffine(pose)); - nr_points = data_end - data_beg; - } - - points->SetNumberOfPoints (nr_points); - - vtkSmartPointer cells = vertices->GetData (); - - if (exist) - updateCells (cells, initcells, nr_points); - else - updateCells (cells, am_it->second.cells, nr_points); - - // Set the cells and the vertices - vertices->SetCells (nr_points, cells); - - // Get a random color - Color c = vtkcolor(color); - polydata->GetPointData ()->SetScalars (0); - - // If this is the new point cloud, a new actor is created - if (exist) - { - vtkSmartPointer actor; - createActorFromVTKDataSet (polydata, actor, false); - - actor->GetProperty ()->SetColor(c.val); - - // Add it to all renderers - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*cloud_actor_map_)[id].actor = actor; - (*cloud_actor_map_)[id].cells = initcells; - - const Eigen::Vector4f sensor_origin = Eigen::Vector4f::Zero (); - const Eigen::Quaternionf sensor_orientation = Eigen::Quaternionf::Identity (); - - // Save the viewpoint transformation matrix to the global actor map - vtkSmartPointer transformation = vtkSmartPointer::New(); - convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); - - (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; - } - else - { - // Update the mapper - reinterpret_cast(am_it->second.actor->GetMapper ())->SetInput (polydata); - am_it->second.actor->GetProperty ()->SetColor(c.val); - am_it->second.actor->GetMapper ()->ScalarVisibilityOff(); - am_it->second.actor->Modified (); - } -} - -bool temp_viz::Viz3d::VizImpl::addPointCloudNormals (const cv::Mat &cloud, const cv::Mat& normals, int level, float scale, const std::string &id) -{ - CV_Assert(cloud.size() == normals.size() && cloud.type() == CV_32FC3 && normals.type() == CV_32FC3); - - if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) - return false; - - vtkSmartPointer points = vtkSmartPointer::New(); - vtkSmartPointer lines = vtkSmartPointer::New(); - - points->SetDataTypeToFloat (); - vtkSmartPointer data = vtkSmartPointer::New (); - data->SetNumberOfComponents (3); - - vtkIdType nr_normals = 0; - float* pts = 0; - - // If the cloud is organized, then distribute the normal step in both directions - if (cloud.cols > 1 && cloud.rows > 1) - { - vtkIdType point_step = static_cast (sqrt (double (level))); - nr_normals = (static_cast ((cloud.cols - 1)/ point_step) + 1) * - (static_cast ((cloud.rows - 1) / point_step) + 1); - pts = new float[2 * nr_normals * 3]; - - vtkIdType cell_count = 0; - for (vtkIdType y = 0; y < cloud.rows; y += point_step) - for (vtkIdType x = 0; x < cloud.cols; x += point_step) - { - cv::Point3f p = cloud.at(y, x); - cv::Point3f n = normals.at(y, x) * scale; - - pts[2 * cell_count * 3 + 0] = p.x; - pts[2 * cell_count * 3 + 1] = p.y; - pts[2 * cell_count * 3 + 2] = p.z; - pts[2 * cell_count * 3 + 3] = p.x + n.x; - pts[2 * cell_count * 3 + 4] = p.y + n.y; - pts[2 * cell_count * 3 + 5] = p.z + n.z; - - lines->InsertNextCell (2); - lines->InsertCellPoint (2 * cell_count); - lines->InsertCellPoint (2 * cell_count + 1); - cell_count++; - } - } - else - { - nr_normals = (cloud.size().area() - 1) / level + 1 ; - pts = new float[2 * nr_normals * 3]; - - for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level) - { - cv::Point3f p = cloud.ptr()[i]; - cv::Point3f n = normals.ptr()[i] * scale; - - pts[2 * j * 3 + 0] = p.x; - pts[2 * j * 3 + 1] = p.y; - pts[2 * j * 3 + 2] = p.z; - pts[2 * j * 3 + 3] = p.x + n.x; - pts[2 * j * 3 + 4] = p.y + n.y; - pts[2 * j * 3 + 5] = p.z + n.z; - - lines->InsertNextCell (2); - lines->InsertCellPoint (2 * j); - lines->InsertCellPoint (2 * j + 1); - } - } - - data->SetArray (&pts[0], 2 * nr_normals * 3, 0); - points->SetData (data); - - vtkSmartPointer polyData = vtkSmartPointer::New(); - polyData->SetPoints (points); - polyData->SetLines (lines); - - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (polyData); - mapper->SetColorModeToMapScalars(); - mapper->SetScalarModeToUsePointData(); - - // create actor - vtkSmartPointer actor = vtkSmartPointer::New (); - actor->SetMapper (mapper); - - // Add it to all renderers - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*cloud_actor_map_)[id].actor = actor; - return (true); -} - bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); @@ -742,50 +401,6 @@ bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3 return (true); } -////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addText3D (const std::string &text, const cv::Point3f& position, const Color& color, double textScale, const std::string &id) -{ - std::string tid; - if (id.empty ()) - tid = text; - else - tid = id; - - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (tid); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addText3d] A text with id <" << tid << "> already exists! Please choose a different id and retry." << std::endl, false; - - vtkSmartPointer textSource = vtkSmartPointer::New (); - textSource->SetText (text.c_str()); - textSource->Update (); - - vtkSmartPointer textMapper = vtkSmartPointer::New (); - textMapper->SetInputConnection (textSource->GetOutputPort ()); - - // Since each follower may follow a different camera, we need different followers - vtkRenderer* renderer = renderer_; - - vtkSmartPointer textActor = vtkSmartPointer::New (); - textActor->SetMapper (textMapper); - textActor->SetPosition (position.x, position.y, position.z); - textActor->SetScale (textScale); - - Color c = vtkcolor(color); - textActor->GetProperty ()->SetColor (c.val); - textActor->SetCamera (renderer->GetActiveCamera ()); - - renderer->AddActor (textActor); - renderer->Render (); - - // Save the pointer/ID pair to the global actor map. If we are saving multiple vtkFollowers - // for multiple viewport - (*shape_actor_map_)[tid] = textActor; - - - return (true); -} - bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) { CV_Assert(cloud.type() == CV_32FC3 && cloud.rows == 1); @@ -882,6 +497,13 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget actor->SetUserMatrix (matrix); actor->Modified(); } + // If the actor is a vtkFollower, then it should always face the camera + vtkFollower *follower = vtkFollower::SafeDownCast(actor); + if (follower) + { + follower->SetCamera(renderer_->GetActiveCamera()); + } + renderer_->AddActor(WidgetAccessor::getProp(widget)); (*widget_actor_map_)[id].actor = WidgetAccessor::getProp(widget); } diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 0d56fe0a5..442a5ff8e 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -350,21 +350,6 @@ void temp_viz::Viz3d::VizImpl::setBackgroundColor (const Color& color) renderer_->SetBackground (c.val); } -///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setPointCloudColor (const Color& color, const std::string &id) -{ - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - if (am_it != cloud_actor_map_->end ()) - { - vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); - - Color c = vtkcolor(color); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->Modified (); - } -} - ///////////////////////////////////////////////////////////////////////////////////////////// bool temp_viz::Viz3d::VizImpl::getPointCloudRenderingProperties (int property, double &value, const std::string &id) { @@ -470,26 +455,6 @@ bool temp_viz::Viz3d::VizImpl::setPointCloudSelected (const bool selected, const return true; } -///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setShapeColor (const Color& color, const std::string &id) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - vtkActor* actor = vtkActor::SafeDownCast (am_it->second); - - Color c = vtkcolor(color); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetProperty ()->SetColor (c.val); - actor->GetProperty ()->SetEdgeColor (c.val); - actor->GetProperty ()->SetAmbient (0.8); - actor->GetProperty ()->SetDiffuse (0.8); - actor->GetProperty ()->SetSpecular (0.8); - actor->GetProperty ()->SetLighting (0); - actor->Modified (); - } -} - ///////////////////////////////////////////////////////////////////////////////////////////// bool temp_viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double value, const std::string &id) { @@ -618,28 +583,6 @@ void temp_viz::Viz3d::VizImpl::updateCamera () renderer_->Render (); } -///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::updateShapePose (const std::string &id, const cv::Affine3f& pose) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - - vtkLODActor* actor; - - if (am_it == shape_actor_map_->end ()) - return (false); - else - actor = vtkLODActor::SafeDownCast (am_it->second); - - vtkSmartPointer matrix = vtkSmartPointer::New (); - - convertToVtkMatrix (pose.matrix, matrix); - - actor->SetUserMatrix (matrix); - actor->Modified (); - - return (true); -} - ///////////////////////////////////////////////////////////////////////////////////////////// void temp_viz::Viz3d::VizImpl::getCameras (temp_viz::Camera& camera) { @@ -916,62 +859,6 @@ bool temp_viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, return (true); } -///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize, const std::string &id) -{ - std::string tid = id.empty() ? text : id; - - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (tid); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addText] A text with id <"< already exists! Please choose a different id and retry.\n" << std::endl, false; - - // Create an Actor - vtkSmartPointer actor = vtkSmartPointer::New (); - actor->SetPosition (xpos, ypos); - actor->SetInput (text.c_str ()); - - vtkSmartPointer tprop = actor->GetTextProperty (); - tprop->SetFontSize (fontsize); - tprop->SetFontFamilyToArial (); - tprop->SetJustificationToLeft (); - tprop->BoldOn (); - - Color c = vtkcolor(color); - tprop->SetColor (c.val); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[tid] = actor; - return (true); -} - -////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::updateText (const std::string &text, int xpos, int ypos, const Color& color, int fontsize, const std::string &id) -{ - std::string tid = id.empty() ? text : id; - - ShapeActorMap::iterator am_it = shape_actor_map_->find (tid); - if (am_it == shape_actor_map_->end ()) - return false; - - // Retrieve the Actor - vtkTextActor *actor = vtkTextActor::SafeDownCast (am_it->second); - - actor->SetPosition (xpos, ypos); - actor->SetInput (text.c_str ()); - - vtkTextProperty* tprop = actor->GetTextProperty (); - tprop->SetFontSize (fontsize); - - Color c = vtkcolor(color); - tprop->SetColor (c.val); - - actor->Modified (); - - return (true); -} - bool temp_viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& mesh, const std::string &id) { CV_Assert(mesh.cloud.rows == 1 && mesh.cloud.type() == CV_32FC3); From acd63c1497b151e29f9f1d86b2e67c2479c1bbbb Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 11 Jul 2013 11:52:59 +0200 Subject: [PATCH 073/205] fix grid widget unused color --- modules/viz/src/simple_widgets.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 49e9f6811..91a9cadda 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -442,6 +442,7 @@ temp_viz::GridWidget::GridWidget(Vec2i dimensions, Vec2d spacing, const Color &c // Show it as wireframe actor->GetProperty ()->SetRepresentationToWireframe (); WidgetAccessor::setProp(*this, actor); + setColor(color); } template<> temp_viz::GridWidget temp_viz::Widget::cast() From c6a8bd65a8cd22db4907f57fad5ec65c1c9a9405 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Thu, 11 Jul 2013 13:54:36 +0400 Subject: [PATCH 074/205] fixed some warnings for windows minor buitification --- modules/viz/include/opencv2/viz/widgets.hpp | 6 +++--- modules/viz/src/interactor_style.cpp | 2 +- modules/viz/src/precomp.hpp | 21 +++++++++++++++++++ modules/viz/src/q/interactor_style.h | 2 +- modules/viz/src/q/viz3d_impl.hpp | 6 +++++- modules/viz/src/simple_widgets.cpp | 5 ----- modules/viz/src/viz3d_impl.cpp | 23 +-------------------- 7 files changed, 32 insertions(+), 33 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 06750238e..0471ff986 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -142,8 +142,8 @@ namespace temp_viz class CV_EXPORTS CloudWidget : public Widget3D { public: - CloudWidget(InputArray _cloud, InputArray _colors); - CloudWidget(InputArray _cloud, const Color &color = Color::white()); + CloudWidget(InputArray cloud, InputArray colors); + CloudWidget(InputArray cloud, const Color &color = Color::white()); private: struct CreateCloudWidget; @@ -152,7 +152,7 @@ namespace temp_viz class CV_EXPORTS CloudNormalsWidget : public Widget3D { public: - CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); + CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); private: struct ApplyCloudNormals; diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 62d2d2084..6e7bc7490 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -78,7 +78,7 @@ void temp_viz::InteractorStyle::OnChar () else if (key.find ("XF86ZoomOut") != std::string::npos) zoomOut (); - bool keymod = false; + int keymod = false; switch (modifier_) { case KB_MOD_ALT: diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 7f3588e6b..4a53d7a4a 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -157,3 +157,24 @@ #include "opencv2/viz/widget_accessor.hpp" #include #include + +namespace temp_viz +{ + template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); + + template<> static inline Vec3f* vtkpoints_data(vtkSmartPointer& points) + { + CV_Assert(points->GetDataType() == VTK_FLOAT); + vtkDataArray *data = points->GetData(); + float *pointer = static_cast(data)->GetPointer(0); + return reinterpret_cast(pointer); + } + + template<> static inline Vec3d* vtkpoints_data(vtkSmartPointer& points) + { + CV_Assert(points->GetDataType() == VTK_DOUBLE); + vtkDataArray *data = points->GetData(); + double *pointer = static_cast(data)->GetPointer(0); + return reinterpret_cast(pointer); + } +} diff --git a/modules/viz/src/q/interactor_style.h b/modules/viz/src/q/interactor_style.h index e6c8c3b86..267b2b619 100644 --- a/modules/viz/src/q/interactor_style.h +++ b/modules/viz/src/q/interactor_style.h @@ -28,7 +28,7 @@ namespace temp_viz * \author Radu B. Rusu * \ingroup visualization */ - class CV_EXPORTS InteractorStyle : public vtkInteractorStyleTrackballCamera + class InteractorStyle : public vtkInteractorStyleTrackballCamera { public: diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/q/viz3d_impl.hpp index b028812fb..c2b79b429 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/q/viz3d_impl.hpp @@ -12,7 +12,7 @@ namespace temp_viz { -class CV_EXPORTS Viz3d::VizImpl +struct Viz3d::VizImpl { public: typedef cv::Ptr Ptr; @@ -366,6 +366,10 @@ struct ApplyAffine result[2] = (_Tp)(m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11]); return result; } + +private: + ApplyAffine(const ApplyAffine&); + ApplyAffine& operator=(const ApplyAffine&); }; } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 49e9f6811..fb863de4d 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -1,10 +1,5 @@ #include "precomp.hpp" -namespace temp_viz -{ - template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); -} - /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 1a1fca699..d04348e3e 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1,26 +1,5 @@ #include "precomp.hpp" -namespace temp_viz -{ - template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); - - template<> Vec3f* vtkpoints_data(vtkSmartPointer& points) - { - CV_Assert(points->GetDataType() == VTK_FLOAT); - vtkDataArray *data = points->GetData(); - float *pointer = static_cast(data)->GetPointer(0); - return reinterpret_cast(pointer); - } - - template<> Vec3d* vtkpoints_data(vtkSmartPointer& points) - { - CV_Assert(points->GetDataType() == VTK_DOUBLE); - vtkDataArray *data = points->GetData(); - double *pointer = static_cast(data)->GetPointer(0); - return reinterpret_cast(pointer); - } -} - void temp_viz::Viz3d::VizImpl::setFullScreen (bool mode) { if (window_) @@ -577,4 +556,4 @@ temp_viz::Affine3f temp_viz::Viz3d::VizImpl::getWidgetPose(const String &id) con vtkSmartPointer matrix = actor->GetUserMatrix(); Matx44f matrix_cv = convertToMatx(matrix); return Affine3f(matrix_cv); -} \ No newline at end of file +} From ae2e3a1a93dd1c62df388df798e961f3be134dd0 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 12 Jul 2013 16:53:25 +0400 Subject: [PATCH 075/205] viz license header template --- modules/viz/include/opencv2/viz.hpp | 53 ++++++++++++++++++++++++++++- modules/viz/src/simple_widgets.cpp | 8 +++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 2ec8fbb86..fda105adc 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -1,6 +1,57 @@ -#pragma once +/*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) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., 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. +// +// * Point Cloud Library (PCL) - www.pointclouds.org +// During implementation if OpenCV Viz module, similar module +// from PCL was used as reference implementation. +// +//M*/ + +#ifndef __OPENCV_VIZ_HPP +#define __OPENCV_VIZ_HPP + #include #include #include + +#endif __OPENCV_VIZ_HPP + diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index fb863de4d..9386c8563 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -636,7 +636,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); - vtkSmartPointer actor = vtkSmartPointer::New(); + vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); @@ -666,6 +666,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) mapper->ImmediateModeRenderingOff (); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); actor->GetProperty ()->SetInterpolationToFlat (); actor->GetProperty ()->BackfaceCullingOn (); @@ -679,7 +680,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) Mat cloud = _cloud.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); - vtkSmartPointer actor = vtkSmartPointer::New(); + vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); @@ -693,6 +694,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) mapper->ImmediateModeRenderingOff (); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); actor->GetProperty ()->SetInterpolationToFlat (); actor->GetProperty ()->BackfaceCullingOn (); @@ -845,3 +847,5 @@ template<> temp_viz::CloudNormalsWidget temp_viz::Widget::castcast(); return static_cast(widget); } + + From 6045ae856b19fbd71583278cc33370875a274b96 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 12 Jul 2013 23:59:19 +0400 Subject: [PATCH 076/205] reshape continuous clouds for better performance. --- modules/viz/src/simple_widgets.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 9386c8563..d9184d365 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -635,7 +635,12 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) Mat colors = _colors.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); - + + if (cloud.isContinuous() && colors.isContinuous()) + { + cloud.reshape(cloud.channels(), 1); + colors.reshape(colors.channels(), 1); + } vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); From 328f0e32d8002d9942948f52855d9543caeae165 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 13 Jul 2013 00:00:57 +0400 Subject: [PATCH 077/205] added makeTransformToGlobal() function --- modules/viz/include/opencv2/viz.hpp | 15 ++++++++++++--- modules/viz/src/precomp.hpp | 2 +- modules/viz/src/viz.cpp | 21 ++++++++++++++++++++- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index fda105adc..137183476 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -44,8 +44,8 @@ // //M*/ -#ifndef __OPENCV_VIZ_HPP -#define __OPENCV_VIZ_HPP +#ifndef __OPENCV_VIZ_HPP__ +#define __OPENCV_VIZ_HPP__ #include @@ -53,5 +53,14 @@ #include -#endif __OPENCV_VIZ_HPP +namespace temp_viz +{ + //! takes coordiante frame data and builds transfrom to global coordinate frame + CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); + + CV_EXPORTS Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& up_vector); +} + + +#endif /* __OPENCV_VIZ_HPP__ */ diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 4a53d7a4a..67c9ccd9c 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -154,8 +154,8 @@ #include #include +#include #include "opencv2/viz/widget_accessor.hpp" -#include #include namespace temp_viz diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 89d145003..07c600809 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -1 +1,20 @@ -#include "precomp.hpp" \ No newline at end of file +#include "precomp.hpp" + + +cv::Affine3f temp_viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin) +{ + Affine3f::Mat3 R; + R.val[0] = axis_x.val[0]; + R.val[3] = axis_x.val[1]; + R.val[6] = axis_x.val[2]; + + R.val[1] = axis_y.val[0]; + R.val[4] = axis_y.val[1]; + R.val[7] = axis_y.val[2]; + + R.val[2] = axis_z.val[0]; + R.val[5] = axis_z.val[1]; + R.val[8] = axis_z.val[2]; + + return Affine3f(R, origin); +} From f480eca6685b8ef1cf1cd8772a55397b58a2c60a Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 13 Jul 2013 01:49:59 +0400 Subject: [PATCH 078/205] removed Affine3f from coordinate frame constructor --- modules/viz/include/opencv2/viz/widgets.hpp | 4 ++-- modules/viz/src/simple_widgets.cpp | 16 +--------------- modules/viz/src/viz_main.cpp | 2 +- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 0471ff986..d44e22f04 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -103,13 +103,13 @@ namespace temp_viz class CV_EXPORTS CoordinateSystemWidget : public Widget3D { public: - CoordinateSystemWidget(double scale, const Affine3f& affine); + CoordinateSystemWidget(double scale = 1.0); }; class CV_EXPORTS PolyLineWidget : public Widget3D { public: - PolyLineWidget(InputArray _points, const Color &color = Color::white()); + PolyLineWidget(InputArray points, const Color &color = Color::white()); private: struct CopyImpl; diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index d9184d365..35c972fc0 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -283,7 +283,7 @@ template<> temp_viz::CubeWidget temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// coordinate system widget implementation -temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Affine3f& affine) +temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale) { vtkSmartPointer axes = vtkSmartPointer::New (); axes->SetOrigin (0, 0, 0); @@ -313,20 +313,6 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale, const Aff vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - - cv::Vec3d t = affine.translation(); - actor->SetPosition (t[0], t[1], t[2]); - - cv::Matx33f m = affine.rotation(); - - cv::Vec3f rvec; - cv::Rodrigues(m, rvec); - - float r_angle = cv::norm(rvec); - rvec *= 1.f/r_angle; - - actor->SetOrientation(0,0,0); - actor->RotateWXYZ(r_angle*180/CV_PI,rvec[0], rvec[1], rvec[2]); WidgetAccessor::setProp(*this, actor); } diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 442a5ff8e..5dcc7c41c 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -7,7 +7,7 @@ #ifndef __APPLE__ vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew () { - return (vtkRenderWindowInteractor::New ()); + return vtkRenderWindowInteractor::New(); } #endif From 3e41f0647e2a8ab0d077906132efd0d4cbf306ab Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 13 Jul 2013 17:45:46 +0400 Subject: [PATCH 079/205] removed q subfolder --- modules/viz/include/opencv2/viz/mesh_load.hpp | 10 - modules/viz/include/opencv2/viz/types.hpp | 5 +- modules/viz/src/common.cpp | 2 +- modules/viz/src/{q => }/common.h | 0 modules/viz/src/interactor_style.cpp | 2 +- modules/viz/src/{q => }/interactor_style.h | 2 +- modules/viz/src/mesh_load.cpp | 4 +- modules/viz/src/precomp.hpp | 2 +- modules/viz/src/viz3d.cpp | 2 +- modules/viz/src/viz3d_impl.cpp | 559 ----------------- modules/viz/src/{q => }/viz3d_impl.hpp | 24 +- modules/viz/src/viz_main.cpp | 561 +++++++++++++++++- modules/viz/src/{q => }/viz_types.h | 0 modules/viz/test/test_viz3d.cpp | 60 +- 14 files changed, 612 insertions(+), 621 deletions(-) delete mode 100644 modules/viz/include/opencv2/viz/mesh_load.hpp rename modules/viz/src/{q => }/common.h (100%) rename modules/viz/src/{q => }/interactor_style.h (99%) delete mode 100644 modules/viz/src/viz3d_impl.cpp rename modules/viz/src/{q => }/viz3d_impl.hpp (96%) rename modules/viz/src/{q => }/viz_types.h (100%) diff --git a/modules/viz/include/opencv2/viz/mesh_load.hpp b/modules/viz/include/opencv2/viz/mesh_load.hpp deleted file mode 100644 index 737679c14..000000000 --- a/modules/viz/include/opencv2/viz/mesh_load.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace temp_viz -{ - CV_EXPORTS Mesh3d::Ptr mesh_load(const String& file); -} diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index d64debc81..dc67219f9 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -67,10 +67,13 @@ namespace temp_viz class CV_EXPORTS Mesh3d { public: - typedef cv::Ptr Ptr; + typedef Ptr Ptr; Mat cloud, colors; std::vector polygons; + + static Mesh3d::Ptr mesh_load(const String& file); + }; ///////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/common.cpp b/modules/viz/src/common.cpp index 78678a069..5cb57c86f 100644 --- a/modules/viz/src/common.cpp +++ b/modules/viz/src/common.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/modules/viz/src/q/common.h b/modules/viz/src/common.h similarity index 100% rename from modules/viz/src/q/common.h rename to modules/viz/src/common.h diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 6e7bc7490..16b2e43ba 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -1,6 +1,6 @@ #include "precomp.hpp" -#include +#include "interactor_style.h" //#include diff --git a/modules/viz/src/q/interactor_style.h b/modules/viz/src/interactor_style.h similarity index 99% rename from modules/viz/src/q/interactor_style.h rename to modules/viz/src/interactor_style.h index 267b2b619..87095d593 100644 --- a/modules/viz/src/q/interactor_style.h +++ b/modules/viz/src/interactor_style.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "viz_types.h" #include namespace temp_viz diff --git a/modules/viz/src/mesh_load.cpp b/modules/viz/src/mesh_load.cpp index 8b0a678b7..c729f2a6a 100644 --- a/modules/viz/src/mesh_load.cpp +++ b/modules/viz/src/mesh_load.cpp @@ -1,5 +1,3 @@ -#include - #include "precomp.hpp" #include @@ -8,7 +6,7 @@ #include #include -temp_viz::Mesh3d::Ptr temp_viz::mesh_load(const String& file) +temp_viz::Mesh3d::Ptr temp_viz::Mesh3d::mesh_load(const String& file) { Mesh3d::Ptr mesh = new Mesh3d(); diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 67c9ccd9c..11e0cdcdd 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -152,7 +152,7 @@ #endif -#include +#include "viz3d_impl.hpp" #include #include #include "opencv2/viz/widget_accessor.hpp" diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 4b9357391..80ce52aff 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -1,5 +1,5 @@ #include -#include +#include "viz3d_impl.hpp" temp_viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_name)) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp deleted file mode 100644 index d04348e3e..000000000 --- a/modules/viz/src/viz3d_impl.cpp +++ /dev/null @@ -1,559 +0,0 @@ -#include "precomp.hpp" - -void temp_viz::Viz3d::VizImpl::setFullScreen (bool mode) -{ - if (window_) - window_->SetFullScreen (mode); -} - -void temp_viz::Viz3d::VizImpl::setWindowName (const std::string &name) -{ - if (window_) - window_->SetWindowName (name.c_str ()); -} - -void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } -void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } - -bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) -{ - CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); - CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); - CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); - - if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) - return std::cout << "[addPolygonMesh] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; - - // int rgb_idx = -1; - // std::vector fields; - - - // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgb", fields); - // if (rgb_idx == -1) - // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgba", fields); - - vtkSmartPointer colors_array; -#if 1 - if (!mesh.colors.empty()) - { - colors_array = vtkSmartPointer::New (); - colors_array->SetNumberOfComponents (3); - colors_array->SetName ("Colors"); - - const unsigned char* data = mesh.colors.ptr(); - - //TODO check mask - CV_Assert(mask.empty()); //because not implemented; - - for(int i = 0; i < mesh.colors.cols; ++i) - colors_array->InsertNextTupleValue(&data[i*3]); - - // temp_viz::RGB rgb_data; - // for (size_t i = 0; i < cloud->size (); ++i) - // { - // if (!isFinite (cloud->points[i])) - // continue; - // memcpy (&rgb_data, reinterpret_cast (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (temp_viz::RGB)); - // unsigned char color[3]; - // color[0] = rgb_data.r; - // color[1] = rgb_data.g; - // color[2] = rgb_data.b; - // colors->InsertNextTupleValue (color); - // } - } -#endif - - // Create points from polyMesh.cloud - vtkSmartPointer points = vtkSmartPointer::New (); - vtkIdType nr_points = mesh.cloud.size().area(); - - points->SetNumberOfPoints (nr_points); - - - // Get a pointer to the beginning of the data array - float *data = static_cast (points->GetData ())->GetPointer (0); - - - std::vector lookup; - // If the dataset is dense (no NaNs) - if (mask.empty()) - { - cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); - mesh.cloud.copyTo(hdr); - } - else - { - lookup.resize (nr_points); - - const unsigned char *mdata = mask.ptr(); - const cv::Point3f *cdata = mesh.cloud.ptr(); - cv::Point3f* out = reinterpret_cast(data); - - int j = 0; // true point index - for (int i = 0; i < nr_points; ++i) - if(mdata[i]) - { - lookup[i] = j; - out[j++] = cdata[i]; - } - nr_points = j; - points->SetNumberOfPoints (nr_points); - } - - // Get the maximum size of a polygon - int max_size_of_polygon = -1; - for (size_t i = 0; i < mesh.polygons.size (); ++i) - if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) - max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); - - vtkSmartPointer actor; - - if (mesh.polygons.size () > 1) - { - // Create polys from polyMesh.polygons - vtkSmartPointer cell_array = vtkSmartPointer::New (); - vtkIdType *cell = cell_array->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); - int idx = 0; - if (lookup.size () > 0) - { - for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) - { - size_t n_points = mesh.polygons[i].vertices.size (); - *cell++ = n_points; - //cell_array->InsertNextCell (n_points); - for (size_t j = 0; j < n_points; j++, ++idx) - *cell++ = lookup[mesh.polygons[i].vertices[j]]; - //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]); - } - } - else - { - for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) - { - size_t n_points = mesh.polygons[i].vertices.size (); - *cell++ = n_points; - //cell_array->InsertNextCell (n_points); - for (size_t j = 0; j < n_points; j++, ++idx) - *cell++ = mesh.polygons[i].vertices[j]; - //cell_array->InsertCellPoint (vertices[i].vertices[j]); - } - } - vtkSmartPointer polydata; - allocVtkPolyData (polydata); - cell_array->GetData ()->SetNumberOfValues (idx); - cell_array->Squeeze (); - polydata->SetStrips (cell_array); - polydata->SetPoints (points); - - if (colors_array) - polydata->GetPointData ()->SetScalars (colors_array); - - createActorFromVTKDataSet (polydata, actor, false); - } - else - { - vtkSmartPointer polygon = vtkSmartPointer::New (); - size_t n_points = mesh.polygons[0].vertices.size (); - polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); - - if (lookup.size () > 0) - { - for (size_t j = 0; j < n_points - 1; ++j) - polygon->GetPointIds ()->SetId (j, lookup[mesh.polygons[0].vertices[j]]); - } - else - { - for (size_t j = 0; j < n_points - 1; ++j) - polygon->GetPointIds ()->SetId (j, mesh.polygons[0].vertices[j]); - } - vtkSmartPointer poly_grid; - allocVtkUnstructuredGrid (poly_grid); - poly_grid->Allocate (1, 1); - poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); - poly_grid->SetPoints (points); - poly_grid->Update (); - if (colors_array) - poly_grid->GetPointData ()->SetScalars (colors_array); - - createActorFromVTKDataSet (poly_grid, actor, false); - } - renderer_->AddActor (actor); - actor->GetProperty ()->SetRepresentationToSurface (); - // Backface culling renders the visualization slower, but guarantees that we see all triangles - actor->GetProperty ()->BackfaceCullingOff (); - actor->GetProperty ()->SetInterpolationToFlat (); - actor->GetProperty ()->EdgeVisibilityOff (); - actor->GetProperty ()->ShadingOff (); - - // Save the pointer/ID pair to the global actor map - (*cloud_actor_map_)[id].actor = actor; - //if (vertices.size () > 1) - // (*cloud_actor_map_)[id].cells = static_cast(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData (); - - const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); - const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); - - // Save the viewpoint transformation matrix to the global actor map - vtkSmartPointer transformation = vtkSmartPointer::New(); - convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); - (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; - - return (true); -} - - -bool temp_viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) -{ - CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); - CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); - CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); - - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - if (am_it == cloud_actor_map_->end ()) - return (false); - - // Get the current poly data - vtkSmartPointer polydata = static_cast(am_it->second.actor->GetMapper ())->GetInput (); - if (!polydata) - return (false); - vtkSmartPointer cells = polydata->GetStrips (); - if (!cells) - return (false); - vtkSmartPointer points = polydata->GetPoints (); - // Copy the new point array in - vtkIdType nr_points = mesh.cloud.size().area(); - points->SetNumberOfPoints (nr_points); - - // Get a pointer to the beginning of the data array - float *data = (static_cast (points->GetData ()))->GetPointer (0); - - int ptr = 0; - std::vector lookup; - // If the dataset is dense (no NaNs) - if (mask.empty()) - { - cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); - mesh.cloud.copyTo(hdr); - - } - else - { - lookup.resize (nr_points); - - const unsigned char *mdata = mask.ptr(); - const cv::Point3f *cdata = mesh.cloud.ptr(); - cv::Point3f* out = reinterpret_cast(data); - - int j = 0; // true point index - for (int i = 0; i < nr_points; ++i) - if(mdata[i]) - { - lookup[i] = j; - out[j++] = cdata[i]; - } - nr_points = j; - points->SetNumberOfPoints (nr_points);; - } - - // Update colors - vtkUnsignedCharArray* colors_array = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ()); - - if (!mesh.colors.empty() && colors_array) - { - if (mask.empty()) - { - const unsigned char* data = mesh.colors.ptr(); - for(int i = 0; i < mesh.colors.cols; ++i) - colors_array->InsertNextTupleValue(&data[i*3]); - } - else - { - const unsigned char* color = mesh.colors.ptr(); - const unsigned char* mdata = mask.ptr(); - - int j = 0; - for(int i = 0; i < mesh.colors.cols; ++i) - if (mdata[i]) - colors_array->SetTupleValue (j++, &color[i*3]); - - } - } - - // Get the maximum size of a polygon - int max_size_of_polygon = -1; - for (size_t i = 0; i < mesh.polygons.size (); ++i) - if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) - max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); - - // Update the cells - cells = vtkSmartPointer::New (); - vtkIdType *cell = cells->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); - int idx = 0; - if (lookup.size () > 0) - { - for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) - { - size_t n_points = mesh.polygons[i].vertices.size (); - *cell++ = n_points; - for (size_t j = 0; j < n_points; j++, cell++, ++idx) - *cell = lookup[mesh.polygons[i].vertices[j]]; - } - } - else - { - for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) - { - size_t n_points = mesh.polygons[i].vertices.size (); - *cell++ = n_points; - for (size_t j = 0; j < n_points; j++, cell++, ++idx) - *cell = mesh.polygons[i].vertices[j]; - } - } - cells->GetData ()->SetNumberOfValues (idx); - cells->Squeeze (); - // Set the the vertices - polydata->SetStrips (cells); - polydata->Update (); - return (true); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color, bool display_length, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addArrow] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; - - // Create an Actor - vtkSmartPointer leader = vtkSmartPointer::New (); - leader->GetPositionCoordinate()->SetCoordinateSystemToWorld (); - leader->GetPositionCoordinate()->SetValue (p1.x, p1.y, p1.z); - leader->GetPosition2Coordinate()->SetCoordinateSystemToWorld (); - leader->GetPosition2Coordinate()->SetValue (p2.x, p2.y, p2.z); - leader->SetArrowStyleToFilled(); - leader->SetArrowPlacementToPoint2 (); - - if (display_length) - leader->AutoLabelOn (); - else - leader->AutoLabelOff (); - - Color c = vtkcolor(color); - leader->GetProperty ()->SetColor (c.val); - renderer_->AddActor (leader); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = leader; - return (true); -} -//////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color_line, const Color& color_text, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addArrow] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; - return (false); - } - - // Create an Actor - vtkSmartPointer leader = vtkSmartPointer::New (); - leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld (); - leader->GetPositionCoordinate ()->SetValue (p1.x, p1.y, p1.z); - leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld (); - leader->GetPosition2Coordinate ()->SetValue (p2.x, p2.y, p2.z); - leader->SetArrowStyleToFilled (); - leader->AutoLabelOn (); - - Color ct = vtkcolor(color_text); - leader->GetLabelTextProperty()->SetColor(ct.val); - - Color cl = vtkcolor(color_line); - leader->GetProperty ()->SetColor (cl.val); - renderer_->AddActor (leader); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = leader; - return (true); -} - -bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) -{ - CV_Assert(cloud.type() == CV_32FC3 && cloud.rows == 1); - - vtkSmartPointer points = vtkSmartPointer::New (); - vtkSmartPointer polygon = vtkSmartPointer::New (); - - int total = cloud.size().area(); - points->SetNumberOfPoints (total); - polygon->GetPointIds ()->SetNumberOfIds (total); - - for (int i = 0; i < total; ++i) - { - cv::Point3f p = cloud.ptr()[i]; - points->SetPoint (i, p.x, p.y, p.z); - polygon->GetPointIds ()->SetId (i, i); - } - - vtkSmartPointer poly_grid; - allocVtkUnstructuredGrid (poly_grid); - poly_grid->Allocate (1, 1); - poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); - poly_grid->SetPoints (points); - poly_grid->Update (); - - - ////////////////////////////////////////////////////// - vtkSmartPointer data = poly_grid; - - Color c = vtkcolor(color); - - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - vtkSmartPointer all_data = vtkSmartPointer::New (); - - // Add old data - all_data->AddInput (reinterpret_cast ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ()); - - // Add new data - vtkSmartPointer surface_filter = vtkSmartPointer::New (); - surface_filter->SetInput (vtkUnstructuredGrid::SafeDownCast (data)); - vtkSmartPointer poly_data = surface_filter->GetOutput (); - all_data->AddInput (poly_data); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (all_data->GetOutput (), actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetProperty ()->BackfaceCullingOff (); - - removeActorFromRenderer (am_it->second); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } - else - { - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetProperty ()->BackfaceCullingOff (); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } - - return (true); -} - -void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose) -{ - WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - if (exists) - { - // Remove it if it exists and add it again - removeActorFromRenderer(wam_itr->second.actor); - } - // Get the actor and set the user matrix - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget)); - if (actor) - { - // If the actor is 3D, apply pose - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified(); - } - // If the actor is a vtkFollower, then it should always face the camera - vtkFollower *follower = vtkFollower::SafeDownCast(actor); - if (follower) - { - follower->SetCamera(renderer_->GetActiveCamera()); - } - - renderer_->AddActor(WidgetAccessor::getProp(widget)); - (*widget_actor_map_)[id].actor = WidgetAccessor::getProp(widget); -} - -void temp_viz::Viz3d::VizImpl::removeWidget(const String &id) -{ - WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - CV_Assert(removeActorFromRenderer (wam_itr->second.actor)); - widget_actor_map_->erase(wam_itr); -} - -temp_viz::Widget temp_viz::Viz3d::VizImpl::getWidget(const String &id) const -{ - WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - - Widget widget; - WidgetAccessor::setProp(widget, wam_itr->second.actor); - return widget; -} - -void temp_viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) -{ - WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); - CV_Assert(actor); - - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); -} - -void temp_viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) -{ - WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); - CV_Assert(actor); - - vtkSmartPointer matrix = actor->GetUserMatrix(); - if (!matrix) - { - setWidgetPose(id, pose); - return ; - } - Matx44f matrix_cv = convertToMatx(matrix); - Affine3f updated_pose = pose * Affine3f(matrix_cv); - matrix = convertToVtkMatrix(updated_pose.matrix); - - actor->SetUserMatrix (matrix); - actor->Modified (); -} - -temp_viz::Affine3f temp_viz::Viz3d::VizImpl::getWidgetPose(const String &id) const -{ - WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); - CV_Assert(actor); - - vtkSmartPointer matrix = actor->GetUserMatrix(); - Matx44f matrix_cv = convertToMatx(matrix); - return Affine3f(matrix_cv); -} diff --git a/modules/viz/src/q/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp similarity index 96% rename from modules/viz/src/q/viz3d_impl.hpp rename to modules/viz/src/viz3d_impl.hpp index c2b79b429..88593c24d 100644 --- a/modules/viz/src/q/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -2,17 +2,15 @@ #include #include -#include -#include -#include +#include "interactor_style.h" +#include "viz_types.h" +#include "common.h" #include #include #include -namespace temp_viz -{ -struct Viz3d::VizImpl +struct temp_viz::Viz3d::VizImpl { public: typedef cv::Ptr Ptr; @@ -23,16 +21,7 @@ public: void setFullScreen (bool mode); void setWindowName (const String &name); - /** \brief Register a callback function for keyboard input - * \param[in] callback function that will be registered as a callback for a keyboard event - * \param[in] cookie for passing user data to callback - */ void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie = 0); - - /** \brief Register a callback function for mouse events - * \param[in] ccallback function that will be registered as a callback for a mouse event - * \param[in] cookie for passing user data to callback - */ void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); void spin (); @@ -289,6 +278,11 @@ private: void allocVtkUnstructuredGrid (vtkSmartPointer &polydata); }; + + +namespace temp_viz +{ + //void getTransformationMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternionf& orientation, Eigen::Matrix4f &transformation); //void convertToVtkMatrix (const Eigen::Matrix4f &m, vtkSmartPointer &vtk_matrix); diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index 5dcc7c41c..b3b502203 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -1,7 +1,7 @@ #include "precomp.hpp" #include -#include +#include "viz3d_impl.hpp" #include #ifndef __APPLE__ @@ -1058,3 +1058,562 @@ void temp_viz::convertToEigenMatrix (const vtkSmartPointer &vtk_ma for (int k = 0; k < 4; k++) m (i,k) = static_cast (vtk_matrix->GetElement (i, k)); } + + +void temp_viz::Viz3d::VizImpl::setFullScreen (bool mode) +{ + if (window_) + window_->SetFullScreen (mode); +} + +void temp_viz::Viz3d::VizImpl::setWindowName (const std::string &name) +{ + if (window_) + window_->SetWindowName (name.c_str ()); +} + +void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } +void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } + +bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) +{ + CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); + CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); + CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); + + if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) + return std::cout << "[addPolygonMesh] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; + + // int rgb_idx = -1; + // std::vector fields; + + + // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgb", fields); + // if (rgb_idx == -1) + // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgba", fields); + + vtkSmartPointer colors_array; +#if 1 + if (!mesh.colors.empty()) + { + colors_array = vtkSmartPointer::New (); + colors_array->SetNumberOfComponents (3); + colors_array->SetName ("Colors"); + + const unsigned char* data = mesh.colors.ptr(); + + //TODO check mask + CV_Assert(mask.empty()); //because not implemented; + + for(int i = 0; i < mesh.colors.cols; ++i) + colors_array->InsertNextTupleValue(&data[i*3]); + + // temp_viz::RGB rgb_data; + // for (size_t i = 0; i < cloud->size (); ++i) + // { + // if (!isFinite (cloud->points[i])) + // continue; + // memcpy (&rgb_data, reinterpret_cast (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (temp_viz::RGB)); + // unsigned char color[3]; + // color[0] = rgb_data.r; + // color[1] = rgb_data.g; + // color[2] = rgb_data.b; + // colors->InsertNextTupleValue (color); + // } + } +#endif + + // Create points from polyMesh.cloud + vtkSmartPointer points = vtkSmartPointer::New (); + vtkIdType nr_points = mesh.cloud.size().area(); + + points->SetNumberOfPoints (nr_points); + + + // Get a pointer to the beginning of the data array + float *data = static_cast (points->GetData ())->GetPointer (0); + + + std::vector lookup; + // If the dataset is dense (no NaNs) + if (mask.empty()) + { + cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); + mesh.cloud.copyTo(hdr); + } + else + { + lookup.resize (nr_points); + + const unsigned char *mdata = mask.ptr(); + const cv::Point3f *cdata = mesh.cloud.ptr(); + cv::Point3f* out = reinterpret_cast(data); + + int j = 0; // true point index + for (int i = 0; i < nr_points; ++i) + if(mdata[i]) + { + lookup[i] = j; + out[j++] = cdata[i]; + } + nr_points = j; + points->SetNumberOfPoints (nr_points); + } + + // Get the maximum size of a polygon + int max_size_of_polygon = -1; + for (size_t i = 0; i < mesh.polygons.size (); ++i) + if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) + max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); + + vtkSmartPointer actor; + + if (mesh.polygons.size () > 1) + { + // Create polys from polyMesh.polygons + vtkSmartPointer cell_array = vtkSmartPointer::New (); + vtkIdType *cell = cell_array->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); + int idx = 0; + if (lookup.size () > 0) + { + for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) + { + size_t n_points = mesh.polygons[i].vertices.size (); + *cell++ = n_points; + //cell_array->InsertNextCell (n_points); + for (size_t j = 0; j < n_points; j++, ++idx) + *cell++ = lookup[mesh.polygons[i].vertices[j]]; + //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]); + } + } + else + { + for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) + { + size_t n_points = mesh.polygons[i].vertices.size (); + *cell++ = n_points; + //cell_array->InsertNextCell (n_points); + for (size_t j = 0; j < n_points; j++, ++idx) + *cell++ = mesh.polygons[i].vertices[j]; + //cell_array->InsertCellPoint (vertices[i].vertices[j]); + } + } + vtkSmartPointer polydata; + allocVtkPolyData (polydata); + cell_array->GetData ()->SetNumberOfValues (idx); + cell_array->Squeeze (); + polydata->SetStrips (cell_array); + polydata->SetPoints (points); + + if (colors_array) + polydata->GetPointData ()->SetScalars (colors_array); + + createActorFromVTKDataSet (polydata, actor, false); + } + else + { + vtkSmartPointer polygon = vtkSmartPointer::New (); + size_t n_points = mesh.polygons[0].vertices.size (); + polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); + + if (lookup.size () > 0) + { + for (size_t j = 0; j < n_points - 1; ++j) + polygon->GetPointIds ()->SetId (j, lookup[mesh.polygons[0].vertices[j]]); + } + else + { + for (size_t j = 0; j < n_points - 1; ++j) + polygon->GetPointIds ()->SetId (j, mesh.polygons[0].vertices[j]); + } + vtkSmartPointer poly_grid; + allocVtkUnstructuredGrid (poly_grid); + poly_grid->Allocate (1, 1); + poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); + poly_grid->SetPoints (points); + poly_grid->Update (); + if (colors_array) + poly_grid->GetPointData ()->SetScalars (colors_array); + + createActorFromVTKDataSet (poly_grid, actor, false); + } + renderer_->AddActor (actor); + actor->GetProperty ()->SetRepresentationToSurface (); + // Backface culling renders the visualization slower, but guarantees that we see all triangles + actor->GetProperty ()->BackfaceCullingOff (); + actor->GetProperty ()->SetInterpolationToFlat (); + actor->GetProperty ()->EdgeVisibilityOff (); + actor->GetProperty ()->ShadingOff (); + + // Save the pointer/ID pair to the global actor map + (*cloud_actor_map_)[id].actor = actor; + //if (vertices.size () > 1) + // (*cloud_actor_map_)[id].cells = static_cast(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData (); + + const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); + const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); + + // Save the viewpoint transformation matrix to the global actor map + vtkSmartPointer transformation = vtkSmartPointer::New(); + convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); + (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; + + return (true); +} + + +bool temp_viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) +{ + CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); + CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); + CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); + + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + CloudActorMap::iterator am_it = cloud_actor_map_->find (id); + if (am_it == cloud_actor_map_->end ()) + return (false); + + // Get the current poly data + vtkSmartPointer polydata = static_cast(am_it->second.actor->GetMapper ())->GetInput (); + if (!polydata) + return (false); + vtkSmartPointer cells = polydata->GetStrips (); + if (!cells) + return (false); + vtkSmartPointer points = polydata->GetPoints (); + // Copy the new point array in + vtkIdType nr_points = mesh.cloud.size().area(); + points->SetNumberOfPoints (nr_points); + + // Get a pointer to the beginning of the data array + float *data = (static_cast (points->GetData ()))->GetPointer (0); + + int ptr = 0; + std::vector lookup; + // If the dataset is dense (no NaNs) + if (mask.empty()) + { + cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); + mesh.cloud.copyTo(hdr); + + } + else + { + lookup.resize (nr_points); + + const unsigned char *mdata = mask.ptr(); + const cv::Point3f *cdata = mesh.cloud.ptr(); + cv::Point3f* out = reinterpret_cast(data); + + int j = 0; // true point index + for (int i = 0; i < nr_points; ++i) + if(mdata[i]) + { + lookup[i] = j; + out[j++] = cdata[i]; + } + nr_points = j; + points->SetNumberOfPoints (nr_points);; + } + + // Update colors + vtkUnsignedCharArray* colors_array = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ()); + + if (!mesh.colors.empty() && colors_array) + { + if (mask.empty()) + { + const unsigned char* data = mesh.colors.ptr(); + for(int i = 0; i < mesh.colors.cols; ++i) + colors_array->InsertNextTupleValue(&data[i*3]); + } + else + { + const unsigned char* color = mesh.colors.ptr(); + const unsigned char* mdata = mask.ptr(); + + int j = 0; + for(int i = 0; i < mesh.colors.cols; ++i) + if (mdata[i]) + colors_array->SetTupleValue (j++, &color[i*3]); + + } + } + + // Get the maximum size of a polygon + int max_size_of_polygon = -1; + for (size_t i = 0; i < mesh.polygons.size (); ++i) + if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) + max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); + + // Update the cells + cells = vtkSmartPointer::New (); + vtkIdType *cell = cells->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); + int idx = 0; + if (lookup.size () > 0) + { + for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) + { + size_t n_points = mesh.polygons[i].vertices.size (); + *cell++ = n_points; + for (size_t j = 0; j < n_points; j++, cell++, ++idx) + *cell = lookup[mesh.polygons[i].vertices[j]]; + } + } + else + { + for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) + { + size_t n_points = mesh.polygons[i].vertices.size (); + *cell++ = n_points; + for (size_t j = 0; j < n_points; j++, cell++, ++idx) + *cell = mesh.polygons[i].vertices[j]; + } + } + cells->GetData ()->SetNumberOfValues (idx); + cells->Squeeze (); + // Set the the vertices + polydata->SetStrips (cells); + polydata->Update (); + return (true); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color, bool display_length, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + return std::cout << "[addArrow] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; + + // Create an Actor + vtkSmartPointer leader = vtkSmartPointer::New (); + leader->GetPositionCoordinate()->SetCoordinateSystemToWorld (); + leader->GetPositionCoordinate()->SetValue (p1.x, p1.y, p1.z); + leader->GetPosition2Coordinate()->SetCoordinateSystemToWorld (); + leader->GetPosition2Coordinate()->SetValue (p2.x, p2.y, p2.z); + leader->SetArrowStyleToFilled(); + leader->SetArrowPlacementToPoint2 (); + + if (display_length) + leader->AutoLabelOn (); + else + leader->AutoLabelOff (); + + Color c = vtkcolor(color); + leader->GetProperty ()->SetColor (c.val); + renderer_->AddActor (leader); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = leader; + return (true); +} +//////////////////////////////////////////////////////////////////////////////////////////// +bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color_line, const Color& color_text, const std::string &id) +{ + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + std::cout << "[addArrow] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; + return (false); + } + + // Create an Actor + vtkSmartPointer leader = vtkSmartPointer::New (); + leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld (); + leader->GetPositionCoordinate ()->SetValue (p1.x, p1.y, p1.z); + leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld (); + leader->GetPosition2Coordinate ()->SetValue (p2.x, p2.y, p2.z); + leader->SetArrowStyleToFilled (); + leader->AutoLabelOn (); + + Color ct = vtkcolor(color_text); + leader->GetLabelTextProperty()->SetColor(ct.val); + + Color cl = vtkcolor(color_line); + leader->GetProperty ()->SetColor (cl.val); + renderer_->AddActor (leader); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = leader; + return (true); +} + +bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) +{ + CV_Assert(cloud.type() == CV_32FC3 && cloud.rows == 1); + + vtkSmartPointer points = vtkSmartPointer::New (); + vtkSmartPointer polygon = vtkSmartPointer::New (); + + int total = cloud.size().area(); + points->SetNumberOfPoints (total); + polygon->GetPointIds ()->SetNumberOfIds (total); + + for (int i = 0; i < total; ++i) + { + cv::Point3f p = cloud.ptr()[i]; + points->SetPoint (i, p.x, p.y, p.z); + polygon->GetPointIds ()->SetId (i, i); + } + + vtkSmartPointer poly_grid; + allocVtkUnstructuredGrid (poly_grid); + poly_grid->Allocate (1, 1); + poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); + poly_grid->SetPoints (points); + poly_grid->Update (); + + + ////////////////////////////////////////////////////// + vtkSmartPointer data = poly_grid; + + Color c = vtkcolor(color); + + // Check to see if this ID entry already exists (has it been already added to the visualizer?) + ShapeActorMap::iterator am_it = shape_actor_map_->find (id); + if (am_it != shape_actor_map_->end ()) + { + vtkSmartPointer all_data = vtkSmartPointer::New (); + + // Add old data + all_data->AddInput (reinterpret_cast ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ()); + + // Add new data + vtkSmartPointer surface_filter = vtkSmartPointer::New (); + surface_filter->SetInput (vtkUnstructuredGrid::SafeDownCast (data)); + vtkSmartPointer poly_data = surface_filter->GetOutput (); + all_data->AddInput (poly_data); + + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (all_data->GetOutput (), actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetProperty ()->BackfaceCullingOff (); + + removeActorFromRenderer (am_it->second); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } + else + { + // Create an Actor + vtkSmartPointer actor; + createActorFromVTKDataSet (data, actor); + actor->GetProperty ()->SetRepresentationToWireframe (); + actor->GetProperty ()->SetColor (c.val); + actor->GetMapper ()->ScalarVisibilityOff (); + actor->GetProperty ()->BackfaceCullingOff (); + renderer_->AddActor (actor); + + // Save the pointer/ID pair to the global actor map + (*shape_actor_map_)[id] = actor; + } + + return (true); +} + +void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + if (exists) + { + // Remove it if it exists and add it again + removeActorFromRenderer(wam_itr->second.actor); + } + // Get the actor and set the user matrix + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget)); + if (actor) + { + // If the actor is 3D, apply pose + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified(); + } + // If the actor is a vtkFollower, then it should always face the camera + vtkFollower *follower = vtkFollower::SafeDownCast(actor); + if (follower) + { + follower->SetCamera(renderer_->GetActiveCamera()); + } + + renderer_->AddActor(WidgetAccessor::getProp(widget)); + (*widget_actor_map_)[id].actor = WidgetAccessor::getProp(widget); +} + +void temp_viz::Viz3d::VizImpl::removeWidget(const String &id) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + CV_Assert(removeActorFromRenderer (wam_itr->second.actor)); + widget_actor_map_->erase(wam_itr); +} + +temp_viz::Widget temp_viz::Viz3d::VizImpl::getWidget(const String &id) const +{ + WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + Widget widget; + WidgetAccessor::setProp(widget, wam_itr->second.actor); + return widget; +} + +void temp_viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + CV_Assert(actor); + + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified (); +} + +void temp_viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + CV_Assert(actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + if (!matrix) + { + setWidgetPose(id, pose); + return ; + } + Matx44f matrix_cv = convertToMatx(matrix); + Affine3f updated_pose = pose * Affine3f(matrix_cv); + matrix = convertToVtkMatrix(updated_pose.matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); +} + +temp_viz::Affine3f temp_viz::Viz3d::VizImpl::getWidgetPose(const String &id) const +{ + WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + CV_Assert(actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv = convertToMatx(matrix); + return Affine3f(matrix_cv); +} diff --git a/modules/viz/src/q/viz_types.h b/modules/viz/src/viz_types.h similarity index 100% rename from modules/viz/src/q/viz_types.h rename to modules/viz/src/viz_types.h diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 090501eb5..884b0b576 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -48,7 +48,6 @@ #include #include -#include cv::Mat cvcloud_load() { @@ -83,45 +82,50 @@ TEST(Viz_viz3d, accuracy) float pos_x = 0.0f; float pos_y = 0.0f; float pos_z = 0.0f; -// temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("d:/horse.ply"); -// v.addPolygonMesh(*mesh, "pq"); + temp_viz::Mesh3d::Ptr mesh = temp_viz::Mesh3d::mesh_load("d:/horse.ply"); + v.addPolygonMesh(*mesh, "pq"); int col_blue = 0; int col_green = 0; int col_red = 0; temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(4.0,4.0,4.0), temp_viz::Color(0,255,0)); - temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0), 5.0); + temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0), 50.0); temp_viz::SphereWidget sw(cv::Point3f(0,0,0), 0.5); temp_viz::ArrowWidget aw(cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 0.5, 0.01, temp_viz::Color(0,255,0)); temp_viz::CylinderWidget cyw(cv::Point3f(0,0,0), cv::Point3f(-1,-1,-1), 0.5, 30, temp_viz::Color(0,255,0)); temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1)); - temp_viz::CoordinateSystemWidget csw(1.0f, cv::Affine3f::Identity()); + temp_viz::CoordinateSystemWidget csw; temp_viz::TextWidget tw("TEST", cv::Point2i(100,100), 20); temp_viz::CloudWidget pcw(cloud, colors); temp_viz::CloudWidget pcw2(cloud, temp_viz::Color(0,255,255)); // v.showWidget("line", lw); // v.showWidget("plane", pw); -// v.showWidget("sphere", sw); -// v.showWidget("arrow", aw); -// v.showWidget("circle", cw); -// v.showWidget("cylinder", cyw); -// v.showWidget("cube", cuw); - v.showWidget("coordinateSystem", csw); -// v.showWidget("text",tw); -// v.showWidget("pcw",pcw); -// v.showWidget("pcw2",pcw2); + v.showWidget("sphere", sw); + v.spin(); + //v.showWidget("arrow", aw); + //v.showWidget("circle", cw); + //v.showWidget("cylinder", cyw); + //v.showWidget("cube", cuw); + //v.showWidget("coordinateSystem", csw); + //v.showWidget("coordinateSystem2", temp_viz::CoordinateSystemWidget(2.0), cv::Affine3f(0, 0, 0, cv::Vec3f(2, 0, 0))); + //v.showWidget("text",tw); + //v.showWidget("pcw",pcw); + //v.showWidget("pcw2",pcw2); // temp_viz::LineWidget lw2 = lw; // v.showPointCloud("cld",cloud, colors); - + cv::Mat normals(cloud.size(), cloud.type(), cv::Scalar(0, 10, 0)); // v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); - temp_viz::CloudNormalsWidget cnw(cloud, normals); -// v.showWidget("n", cnw); + //temp_viz::CloudNormalsWidget cnw(cloud, normals); + //v.showWidget("n", cnw); + + + // lw = v.getWidget("n").cast(); // pw = v.getWidget("n").cast(); @@ -135,16 +139,18 @@ TEST(Viz_viz3d, accuracy) data[3] = cv::Vec4d(3.0,4.0,1.0,1.0); points = points.reshape(0, 2); - temp_viz::PolyLineWidget plw(points); -// v.showWidget("polyline",plw); + temp_viz::PolyLineWidget plw(points, temp_viz::Color::green()); + v.showWidget("polyline",plw); // lw = v.getWidget("polyline").cast(); - temp_viz::GridWidget gw(temp_viz::Vec2i(10,10), temp_viz::Vec2d(0.1,0.1)); - v.showWidget("grid", gw); + v.spin(); + + //temp_viz::GridWidget gw(temp_viz::Vec2i(100,100), temp_viz::Vec2d(1,1)); + //v.showWidget("grid", gw); lw = v.getWidget("grid").cast(); - temp_viz::Text3DWidget t3w("OpenCV", cv::Point3f(0.0, 2.0, 0.0), 1.0, temp_viz::Color(255,255,0)); - v.showWidget("txt3d", t3w); + //temp_viz::Text3DWidget t3w("OpenCV", cv::Point3f(0.0, 2.0, 0.0), 1.0, temp_viz::Color(255,255,0)); + //v.showWidget("txt3d", t3w); // float grid_x_angle = 0.0; while(!v.wasStopped()) @@ -156,7 +162,7 @@ TEST(Viz_viz3d, accuracy) lw.setColor(temp_viz::Color(col_blue, col_green, col_red)); // lw.setLineWidth(pos_x * 10); - plw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + //plw.setColor(temp_viz::Color(col_blue, col_green, col_red)); sw.setPose(cloudPosition); // pw.setPose(cloudPosition); @@ -172,10 +178,10 @@ TEST(Viz_viz3d, accuracy) // v.setWidgetPose("n",cloudPosition); // v.setWidgetPose("pcw2", cloudPosition); - cnw.setColor(temp_viz::Color(col_blue, col_green, col_red)); - pcw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); + //cnw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + //pcw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); - gw.updatePose(temp_viz::Affine3f(0.0, 0.1, 0.0, cv::Vec3f(0.0,0.0,0.0))); + //gw.updatePose(temp_viz::Affine3f(0.0, 0.1, 0.0, cv::Vec3f(0.0,0.0,0.0))); angle_x += 0.1f; angle_y -= 0.1f; From 83cb28f1690d53facb1d069a9dbf3ad45600b1c7 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 13 Jul 2013 18:01:56 +0400 Subject: [PATCH 080/205] temp_viz removed --- modules/viz/include/opencv2/viz.hpp | 11 +- modules/viz/include/opencv2/viz/events.hpp | 139 ++++---- modules/viz/include/opencv2/viz/types.hpp | 172 ++++----- modules/viz/include/opencv2/viz/viz3d.hpp | 63 ++-- .../include/opencv2/viz/widget_accessor.hpp | 21 +- modules/viz/include/opencv2/viz/widgets.hpp | 334 +++++++++--------- modules/viz/src/common.cpp | 18 +- modules/viz/src/common.h | 215 +++++------ modules/viz/src/interactor_style.cpp | 57 +-- modules/viz/src/interactor_style.h | 7 +- modules/viz/src/mesh_load.cpp | 2 +- modules/viz/src/precomp.hpp | 33 +- modules/viz/src/simple_widgets.cpp | 103 +++--- modules/viz/src/types.cpp | 26 +- modules/viz/src/viz.cpp | 2 +- modules/viz/src/viz3d.cpp | 36 +- modules/viz/src/viz3d_impl.hpp | 152 ++++---- modules/viz/src/viz_main.cpp | 150 ++++---- modules/viz/src/viz_types.h | 43 +-- modules/viz/src/widget.cpp | 40 +-- 20 files changed, 830 insertions(+), 794 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 137183476..f956d0ef8 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -53,12 +53,15 @@ #include -namespace temp_viz +namespace cv { - //! takes coordiante frame data and builds transfrom to global coordinate frame - CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); + namespace viz + { + //! takes coordiante frame data and builds transfrom to global coordinate frame + CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); - CV_EXPORTS Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& up_vector); + CV_EXPORTS Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& up_vector); + } } diff --git a/modules/viz/include/opencv2/viz/events.hpp b/modules/viz/include/opencv2/viz/events.hpp index 410364e9c..aa1d950da 100644 --- a/modules/viz/include/opencv2/viz/events.hpp +++ b/modules/viz/include/opencv2/viz/events.hpp @@ -3,79 +3,82 @@ #include #include -namespace temp_viz +namespace cv { - class KeyboardEvent + namespace viz { - public: - static const unsigned int Alt = 1; - static const unsigned int Ctrl = 2; - static const unsigned int Shift = 4; - - /** \brief Constructor - * \param[in] action true for key was pressed, false for released - * \param[in] key_sym the key-name that caused the action - * \param[in] key the key code that caused the action - * \param[in] alt whether the alt key was pressed at the time where this event was triggered - * \param[in] ctrl whether the ctrl was pressed at the time where this event was triggered - * \param[in] shift whether the shift was pressed at the time where this event was triggered - */ - KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); - - bool isAltPressed () const; - bool isCtrlPressed () const; - bool isShiftPressed () const; - - unsigned char getKeyCode () const; - - const String& getKeySym () const; - bool keyDown () const; - bool keyUp () const; - - protected: - - bool action_; - unsigned int modifiers_; - unsigned char key_code_; - String key_sym_; - }; - - class MouseEvent - { - public: - enum Type + class KeyboardEvent { - MouseMove = 1, - MouseButtonPress, - MouseButtonRelease, - MouseScrollDown, - MouseScrollUp, - MouseDblClick - } ; + public: + static const unsigned int Alt = 1; + static const unsigned int Ctrl = 2; + static const unsigned int Shift = 4; - enum MouseButton + /** \brief Constructor + * \param[in] action true for key was pressed, false for released + * \param[in] key_sym the key-name that caused the action + * \param[in] key the key code that caused the action + * \param[in] alt whether the alt key was pressed at the time where this event was triggered + * \param[in] ctrl whether the ctrl was pressed at the time where this event was triggered + * \param[in] shift whether the shift was pressed at the time where this event was triggered + */ + KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); + + bool isAltPressed () const; + bool isCtrlPressed () const; + bool isShiftPressed () const; + + unsigned char getKeyCode () const; + + const String& getKeySym () const; + bool keyDown () const; + bool keyUp () const; + + protected: + + bool action_; + unsigned int modifiers_; + unsigned char key_code_; + String key_sym_; + }; + + class MouseEvent { - NoButton = 0, - LeftButton, - MiddleButton, - RightButton, - VScroll /*other buttons, scroll wheels etc. may follow*/ - } ; + public: + enum Type + { + MouseMove = 1, + MouseButtonPress, + MouseButtonRelease, + MouseScrollDown, + MouseScrollUp, + MouseDblClick + } ; - MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); + enum MouseButton + { + NoButton = 0, + LeftButton, + MiddleButton, + RightButton, + VScroll /*other buttons, scroll wheels etc. may follow*/ + } ; + + MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); - Type type; - MouseButton button; - Point pointer; - unsigned int key_state; - }; + Type type; + MouseButton button; + Point pointer; + unsigned int key_state; + }; + } } //////////////////////////////////////////////////////////////////// /// Implementation -inline temp_viz::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) +inline cv::viz::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) : action_ (_action), modifiers_ (0), key_code_(key), key_sym_ (_key_sym) { if (alt) @@ -88,15 +91,15 @@ inline temp_viz::KeyboardEvent::KeyboardEvent (bool _action, const std::string& modifiers_ |= Shift; } -inline bool temp_viz::KeyboardEvent::isAltPressed () const { return (modifiers_ & Alt) != 0; } -inline bool temp_viz::KeyboardEvent::isCtrlPressed () const { return (modifiers_ & Ctrl) != 0; } -inline bool temp_viz::KeyboardEvent::isShiftPressed () const { return (modifiers_ & Shift) != 0; } -inline unsigned char temp_viz::KeyboardEvent::getKeyCode () const { return key_code_; } -inline const temp_viz::String& temp_viz::KeyboardEvent::getKeySym () const { return key_sym_; } -inline bool temp_viz::KeyboardEvent::keyDown () const { return action_; } -inline bool temp_viz::KeyboardEvent::keyUp () const { return !action_; } +inline bool cv::viz::KeyboardEvent::isAltPressed () const { return (modifiers_ & Alt) != 0; } +inline bool cv::viz::KeyboardEvent::isCtrlPressed () const { return (modifiers_ & Ctrl) != 0; } +inline bool cv::viz::KeyboardEvent::isShiftPressed () const { return (modifiers_ & Shift) != 0; } +inline unsigned char cv::viz::KeyboardEvent::getKeyCode () const { return key_code_; } +inline const cv::String& cv::viz::KeyboardEvent::getKeySym () const { return key_sym_; } +inline bool cv::viz::KeyboardEvent::keyDown () const { return action_; } +inline bool cv::viz::KeyboardEvent::keyUp () const { return !action_; } -inline temp_viz::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) +inline cv::viz::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) : type(_type), button(_button), pointer(_p), key_state(0) { if (alt) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index dc67219f9..fd00a7a0a 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -5,105 +5,109 @@ #include #include -namespace temp_viz +namespace cv { - //qt creator hack - typedef cv::Scalar Scalar; - typedef cv::Mat Mat; typedef std::string String; +// //qt creator hack +// typedef cv::Scalar Scalar; +// typedef cv::Mat Mat; +// typedef std::string String; - typedef cv::Vec3d Vec3d; - typedef cv::Vec3f Vec3f; - typedef cv::Vec4d Vec4d; - typedef cv::Vec4f Vec4f; - typedef cv::Vec2d Vec2d; - typedef cv::Vec2i Vec2i; - typedef cv::Vec3b Vec3b; - typedef cv::Matx33d Matx33d; - typedef cv::Affine3f Affine3f; - typedef cv::Affine3d Affine3d; - typedef cv::Point2i Point2i; - typedef cv::Point3f Point3f; - typedef cv::Point3d Point3d; - typedef cv::Matx44d Matx44d; - typedef cv::Matx44f Matx44f; - typedef cv::Size Size; - typedef cv::Point Point; - typedef cv::InputArray InputArray; - using cv::Point3_; - using cv::Vec; - using cv::Mat_; - using cv::DataDepth; - using cv::DataType; - - class CV_EXPORTS Color : public Scalar +// typedef cv::Vec3d Vec3d; +// typedef cv::Vec3f Vec3f; +// typedef cv::Vec4d Vec4d; +// typedef cv::Vec4f Vec4f; +// typedef cv::Vec2d Vec2d; +// typedef cv::Vec2i Vec2i; +// typedef cv::Vec3b Vec3b; +// typedef cv::Matx33d Matx33d; +// typedef cv::Affine3f Affine3f; +// typedef cv::Affine3d Affine3d; +// typedef cv::Point2i Point2i; +// typedef cv::Point3f Point3f; +// typedef cv::Point3d Point3d; +// typedef cv::Matx44d Matx44d; +// typedef cv::Matx44f Matx44f; +// typedef cv::Size Size; +// typedef cv::Point Point; +// typedef cv::InputArray InputArray; +// using cv::Point3_; +// using cv::Vec; +// using cv::Mat_; +// using cv::DataDepth; +// using cv::DataType; +// using cv::Ptr; + namespace viz { - public: - Color(); - Color(double gray); - Color(double blue, double green, double red); + class CV_EXPORTS Color : public Scalar + { + public: + Color(); + Color(double gray); + Color(double blue, double green, double red); - Color(const Scalar& color); + Color(const Scalar& color); - static Color black(); - static Color blue(); - static Color green(); - static Color cyan(); + static Color black(); + static Color blue(); + static Color green(); + static Color cyan(); - static Color red(); - static Color magenta(); - static Color yellow(); - static Color white(); + static Color red(); + static Color magenta(); + static Color yellow(); + static Color white(); - static Color gray(); - }; + static Color gray(); + }; - struct CV_EXPORTS Vertices - { - std::vector vertices; - }; + struct CV_EXPORTS Vertices + { + std::vector vertices; + }; - class CV_EXPORTS Mesh3d - { - public: - typedef Ptr Ptr; + class CV_EXPORTS Mesh3d + { + public: + typedef Ptr Ptr; - Mat cloud, colors; - std::vector polygons; + Mat cloud, colors; + std::vector polygons; - static Mesh3d::Ptr mesh_load(const String& file); + static Mesh3d::Ptr mesh_load(const String& file); - }; + }; - ///////////////////////////////////////////////////////////////////////////// - /// Utility functions + ///////////////////////////////////////////////////////////////////////////// + /// Utility functions - inline Color vtkcolor(const Color& color) - { - Color scaled_color = color * (1.0/255.0); - std::swap(scaled_color[0], scaled_color[2]); - return scaled_color; + inline Color vtkcolor(const Color& color) + { + Color scaled_color = color * (1.0/255.0); + std::swap(scaled_color[0], scaled_color[2]); + return scaled_color; + } + + inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } + template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } + + inline bool isNan(float x) + { + unsigned int *u = reinterpret_cast(&x); + return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff); + } + + inline bool isNan(double x) + { + unsigned int *u = reinterpret_cast(&x); + return (u[1] & 0x7ff00000) == 0x7ff00000 && (u[0] != 0 || (u[1] & 0x000fffff) != 0); + } + + template inline bool isNan(const Vec<_Tp, cn>& v) + { return isNan(v.val[0]) || isNan(v.val[1]) || isNan(v.val[2]); } + + template inline bool isNan(const Point3_<_Tp>& p) + { return isNan(p.x) || isNan(p.y) || isNan(p.z); } } - - inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } - template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } - - inline bool isNan(float x) - { - unsigned int *u = reinterpret_cast(&x); - return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff); - } - - inline bool isNan(double x) - { - unsigned int *u = reinterpret_cast(&x); - return (u[1] & 0x7ff00000) == 0x7ff00000 && (u[0] != 0 || (u[1] & 0x000fffff) != 0); - } - - template inline bool isNan(const Vec<_Tp, cn>& v) - { return isNan(v.val[0]) || isNan(v.val[1]) || isNan(v.val[2]); } - - template inline bool isNan(const Point3_<_Tp>& p) - { return isNan(p.x) || isNan(p.y) || isNan(p.z); } } diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index f16d26d42..a603c879a 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -13,48 +13,51 @@ #include #include -namespace temp_viz +namespace cv { - class CV_EXPORTS Viz3d + namespace viz { - public: + class CV_EXPORTS Viz3d + { + public: - typedef cv::Ptr Ptr; + typedef cv::Ptr Ptr; - Viz3d(const String& window_name = String()); - ~Viz3d(); + Viz3d(const String& window_name = String()); + ~Viz3d(); - void setBackgroundColor(const Color& color = Color::black()); + void setBackgroundColor(const Color& color = Color::black()); - bool addPolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); - bool updatePolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); + bool addPolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); + bool updatePolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); - bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); + bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - bool addPolygon(const Mat& cloud, const Color& color, const String& id = "polygon"); + bool addPolygon(const Mat& cloud, const Color& color, const String& id = "polygon"); - void spin (); - void spinOnce (int time = 1, bool force_redraw = false); + void spin (); + void spinOnce (int time = 1, bool force_redraw = false); - void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, 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 registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); - bool wasStopped() const; - - void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); - void removeWidget(const String &id); - Widget getWidget(const String &id) const; - - void setWidgetPose(const String &id, const Affine3f &pose); - void updateWidgetPose(const String &id, const Affine3f &pose); - Affine3f getWidgetPose(const String &id) const; - private: - Viz3d(const Viz3d&); - Viz3d& operator=(const Viz3d&); + bool wasStopped() const; - struct VizImpl; - VizImpl* impl_; - }; + void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; + + void setWidgetPose(const String &id, const Affine3f &pose); + void updateWidgetPose(const String &id, const Affine3f &pose); + Affine3f getWidgetPose(const String &id) const; + private: + Viz3d(const Viz3d&); + Viz3d& operator=(const Viz3d&); + + struct VizImpl; + VizImpl* impl_; + }; + } } diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index a114c3a26..d6c935dd8 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -4,15 +4,18 @@ #include #include -namespace temp_viz +namespace cv { - class Widget; - - //The class is only that depends on VTK in its interface. - //It is indended for those users who want to develop own widgets system using VTK library API. - struct CV_EXPORTS WidgetAccessor + namespace viz { - static vtkSmartPointer getProp(const Widget &widget); - static void setProp(Widget &widget, vtkSmartPointer prop); - }; + class Widget; + + //The class is only that depends on VTK in its interface. + //It is indended for those users who want to develop own widgets system using VTK library API. + struct CV_EXPORTS WidgetAccessor + { + static vtkSmartPointer getProp(const Widget &widget); + static void setProp(Widget &widget, vtkSmartPointer prop); + }; + } } diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index d44e22f04..ad523738e 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -3,178 +3,182 @@ #include -namespace temp_viz +namespace cv { - ///////////////////////////////////////////////////////////////////////////// - /// The base class for all widgets - class CV_EXPORTS Widget + namespace viz { - public: - Widget(); - Widget(const Widget &other); - Widget& operator =(const Widget &other); - - ~Widget(); + ///////////////////////////////////////////////////////////////////////////// + /// The base class for all widgets + class CV_EXPORTS Widget + { + public: + Widget(); + Widget(const Widget &other); + Widget& operator =(const Widget &other); - template _W cast(); - private: - class Impl; - Impl *impl_; - friend struct WidgetAccessor; - - void create(); - void release(); - }; - - ///////////////////////////////////////////////////////////////////////////// - /// The base class for all 3D widgets - class CV_EXPORTS Widget3D : public Widget - { - public: - Widget3D() {} - - void setPose(const Affine3f &pose); - void updatePose(const Affine3f &pose); - Affine3f getPose() const; - - void setColor(const Color &color); - - private: - struct MatrixConverter; - - }; - - ///////////////////////////////////////////////////////////////////////////// - /// The base class for all 2D widgets - class CV_EXPORTS Widget2D : public Widget - { - public: - Widget2D() {} - - void setColor(const Color &color); - }; - - class CV_EXPORTS LineWidget : public Widget3D - { - public: - LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); - - void setLineWidth(float line_width); - float getLineWidth(); - }; + ~Widget(); - class CV_EXPORTS PlaneWidget : public Widget3D - { - public: - PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); - PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); - }; - - class CV_EXPORTS SphereWidget : public Widget3D - { - public: - SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); - }; - - class CV_EXPORTS ArrowWidget : public Widget3D - { - public: - ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color = Color::white()); - }; + template _W cast(); + private: + class Impl; + Impl *impl_; + friend struct WidgetAccessor; - class CV_EXPORTS CircleWidget : public Widget3D - { - public: - CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); - }; - - class CV_EXPORTS CylinderWidget : public Widget3D - { - public: - CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); - }; - - class CV_EXPORTS CubeWidget : public Widget3D - { - public: - CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); - }; - - class CV_EXPORTS CoordinateSystemWidget : public Widget3D - { - public: - CoordinateSystemWidget(double scale = 1.0); - }; - - class CV_EXPORTS PolyLineWidget : public Widget3D - { - public: - PolyLineWidget(InputArray points, const Color &color = Color::white()); - - private: - struct CopyImpl; - }; - - class CV_EXPORTS GridWidget : public Widget3D - { - public: - GridWidget(Vec2i dimensions, Vec2d spacing, const Color &color = Color::white()); - }; - - class CV_EXPORTS Text3DWidget : public Widget3D - { - public: - Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()); - - void setText(const String &text); - String getText() const; - }; - - class CV_EXPORTS TextWidget : public Widget2D - { - public: - TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); - - void setText(const String &text); - String getText() const; - }; - - class CV_EXPORTS CloudWidget : public Widget3D - { - public: - CloudWidget(InputArray cloud, InputArray colors); - CloudWidget(InputArray cloud, const Color &color = Color::white()); - - private: - struct CreateCloudWidget; - }; - - class CV_EXPORTS CloudNormalsWidget : public Widget3D - { - public: - CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); + void create(); + void release(); + }; - private: - struct ApplyCloudNormals; - }; + ///////////////////////////////////////////////////////////////////////////// + /// The base class for all 3D widgets + class CV_EXPORTS Widget3D : public Widget + { + public: + Widget3D() {} - template<> CV_EXPORTS Widget2D Widget::cast(); - template<> CV_EXPORTS Widget3D Widget::cast(); - template<> CV_EXPORTS LineWidget Widget::cast(); - template<> CV_EXPORTS PlaneWidget Widget::cast(); - template<> CV_EXPORTS SphereWidget Widget::cast(); - template<> CV_EXPORTS CylinderWidget Widget::cast(); - template<> CV_EXPORTS ArrowWidget Widget::cast(); - template<> CV_EXPORTS CircleWidget Widget::cast(); - template<> CV_EXPORTS CubeWidget Widget::cast(); - template<> CV_EXPORTS CoordinateSystemWidget Widget::cast(); - template<> CV_EXPORTS PolyLineWidget Widget::cast(); - template<> CV_EXPORTS GridWidget Widget::cast(); - template<> CV_EXPORTS Text3DWidget Widget::cast(); - template<> CV_EXPORTS TextWidget Widget::cast(); - template<> CV_EXPORTS CloudWidget Widget::cast(); - template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); -} + void setPose(const Affine3f &pose); + void updatePose(const Affine3f &pose); + Affine3f getPose() const; + + void setColor(const Color &color); + + private: + struct MatrixConverter; + + }; + + ///////////////////////////////////////////////////////////////////////////// + /// The base class for all 2D widgets + class CV_EXPORTS Widget2D : public Widget + { + public: + Widget2D() {} + + void setColor(const Color &color); + }; + + class CV_EXPORTS LineWidget : public Widget3D + { + public: + LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + + void setLineWidth(float line_width); + float getLineWidth(); + }; + + class CV_EXPORTS PlaneWidget : public Widget3D + { + public: + PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); + PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); + }; + + class CV_EXPORTS SphereWidget : public Widget3D + { + public: + SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); + }; + + class CV_EXPORTS ArrowWidget : public Widget3D + { + public: + ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color = Color::white()); + }; + + class CV_EXPORTS CircleWidget : public Widget3D + { + public: + CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); + }; + + class CV_EXPORTS CylinderWidget : public Widget3D + { + public: + CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); + }; + + class CV_EXPORTS CubeWidget : public Widget3D + { + public: + CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); + }; + + class CV_EXPORTS CoordinateSystemWidget : public Widget3D + { + public: + CoordinateSystemWidget(double scale = 1.0); + }; + + class CV_EXPORTS PolyLineWidget : public Widget3D + { + public: + PolyLineWidget(InputArray points, const Color &color = Color::white()); + + private: + struct CopyImpl; + }; + + class CV_EXPORTS GridWidget : public Widget3D + { + public: + GridWidget(Vec2i dimensions, Vec2d spacing, const Color &color = Color::white()); + }; + + class CV_EXPORTS Text3DWidget : public Widget3D + { + public: + Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + + class CV_EXPORTS TextWidget : public Widget2D + { + public: + TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + + class CV_EXPORTS CloudWidget : public Widget3D + { + public: + CloudWidget(InputArray cloud, InputArray colors); + CloudWidget(InputArray cloud, const Color &color = Color::white()); + + private: + struct CreateCloudWidget; + }; + + class CV_EXPORTS CloudNormalsWidget : public Widget3D + { + public: + CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); + + private: + struct ApplyCloudNormals; + }; + + template<> CV_EXPORTS Widget2D Widget::cast(); + template<> CV_EXPORTS Widget3D Widget::cast(); + template<> CV_EXPORTS LineWidget Widget::cast(); + template<> CV_EXPORTS PlaneWidget Widget::cast(); + template<> CV_EXPORTS SphereWidget Widget::cast(); + template<> CV_EXPORTS CylinderWidget Widget::cast(); + template<> CV_EXPORTS ArrowWidget Widget::cast(); + template<> CV_EXPORTS CircleWidget Widget::cast(); + template<> CV_EXPORTS CubeWidget Widget::cast(); + template<> CV_EXPORTS CoordinateSystemWidget Widget::cast(); + template<> CV_EXPORTS PolyLineWidget Widget::cast(); + template<> CV_EXPORTS GridWidget Widget::cast(); + template<> CV_EXPORTS Text3DWidget Widget::cast(); + template<> CV_EXPORTS TextWidget Widget::cast(); + template<> CV_EXPORTS CloudWidget Widget::cast(); + template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); + + } /* namespace viz */ +} /* namespace cv */ diff --git a/modules/viz/src/common.cpp b/modules/viz/src/common.cpp index 5cb57c86f..dc4e53e42 100644 --- a/modules/viz/src/common.cpp +++ b/modules/viz/src/common.cpp @@ -5,7 +5,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////// -//Eigen::Matrix4d temp_viz::vtkToEigen (vtkMatrix4x4* vtk_matrix) +//Eigen::Matrix4d cv::viz::vtkToEigen (vtkMatrix4x4* vtk_matrix) //{ // Eigen::Matrix4d eigen_matrix = Eigen::Matrix4d::Identity (); // for (int i=0; i < 4; i++) @@ -16,7 +16,7 @@ //} /////////////////////////////////////////////////////////////////////////////////////////////// -//Eigen::Vector2i temp_viz::worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height) +//Eigen::Vector2i cv::viz::worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height) //{ // // Transform world to clipping coordinates // Eigen::Vector4d world (view_projection_matrix * world_pt); @@ -34,7 +34,7 @@ //} ///////////////////////////////////////////////////////////////////////////////////////////// -//void temp_viz::getViewFrustum (const Eigen::Matrix4d &view_projection_matrix, double planes[24]) +//void cv::viz::getViewFrustum (const Eigen::Matrix4d &view_projection_matrix, double planes[24]) //{ // // Set up the normals // Eigen::Vector4d normals[6]; @@ -65,7 +65,7 @@ // } //} -//int temp_viz::cullFrustum (double frustum[24], const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb) +//int cv::viz::cullFrustum (double frustum[24], const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb) //{ // int result = PCL_INSIDE_FRUSTUM; @@ -104,7 +104,7 @@ //} //void -//temp_viz::getModelViewPosition (Eigen::Matrix4d model_view_matrix, Eigen::Vector3d &position) +//cv::viz::getModelViewPosition (Eigen::Matrix4d model_view_matrix, Eigen::Vector3d &position) //{ // //Compute eye or position from model view matrix // Eigen::Matrix4d inverse_model_view_matrix = model_view_matrix.inverse(); @@ -174,7 +174,7 @@ int hull_vertex_table[43][7] = { ///////////////////////////////////////////////////////////////////////////////////////////// //float -//temp_viz::viewScreenArea ( +//cv::viz::viewScreenArea ( // const Eigen::Vector3d &eye, // const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, // const Eigen::Matrix4d &view_projection_matrix, int width, int height) @@ -261,7 +261,7 @@ int hull_vertex_table[43][7] = { // for (int i = 0; i < num; i++) // { // Eigen::Vector4d world_pt = bounding_box[hull_vertex_table[pos][i]]; -// Eigen::Vector2i screen_pt = temp_viz::worldToView(world_pt, view_projection_matrix, width, height); +// Eigen::Vector2i screen_pt = cv::viz::worldToView(world_pt, view_projection_matrix, width, height); // // cout << "point[" << i << "]: " << screen_pt.x() << " " << screen_pt.y() << endl; // dst[i] = Eigen::Vector2d(screen_pt.x (), screen_pt.y ()); // } @@ -276,7 +276,7 @@ int hull_vertex_table[43][7] = { //} ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Camera::computeViewMatrix (Affine3d& view_mat) const +void cv::viz::Camera::computeViewMatrix (Affine3d& view_mat) const { //constructs view matrix from camera pos, view up, and the point it is looking at //this code is based off of gluLookAt http://www.opengl.org/wiki/GluLookAt_code @@ -297,7 +297,7 @@ void temp_viz::Camera::computeViewMatrix (Affine3d& view_mat) const } /////////////////////////////////////////////////////////////////////// -void temp_viz::Camera::computeProjectionMatrix (Matx44d& proj) const +void cv::viz::Camera::computeProjectionMatrix (Matx44d& proj) const { double top = clip[0] * tan (0.5 * fovy); double left = -(top * window_size[0]) / window_size[1]; diff --git a/modules/viz/src/common.h b/modules/viz/src/common.h index e9cb64bda..c19dd8979 100644 --- a/modules/viz/src/common.h +++ b/modules/viz/src/common.h @@ -3,121 +3,124 @@ #include #include #include -//#include -namespace temp_viz +namespace cv { - //CV_EXPORTS Eigen::Matrix4d vtkToEigen (vtkMatrix4x4* vtk_matrix); - //CV_EXPORTS Eigen::Vector2i worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height); - //CV_EXPORTS void getViewFrustum (const Eigen::Matrix4d &view_projection_matrix, double planes[24]); - -// enum FrustumCull -// { -// PCL_INSIDE_FRUSTUM, -// PCL_INTERSECT_FRUSTUM, -// PCL_OUTSIDE_FRUSTUM -// }; - - //CV_EXPORTS int cullFrustum (double planes[24], const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb); - //CV_EXPORTS float viewScreenArea (const Eigen::Vector3d &eye, const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const Eigen::Matrix4d &view_projection_matrix, int width, int height); - - enum RenderingProperties + namespace viz { - VIZ_POINT_SIZE, - VIZ_OPACITY, - VIZ_LINE_WIDTH, - VIZ_FONT_SIZE, - VIZ_COLOR, - VIZ_REPRESENTATION, - VIZ_IMMEDIATE_RENDERING, - VIZ_SHADING - }; + //CV_EXPORTS Eigen::Matrix4d vtkToEigen (vtkMatrix4x4* vtk_matrix); + //CV_EXPORTS Eigen::Vector2i worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height); + //CV_EXPORTS void getViewFrustum (const Eigen::Matrix4d &view_projection_matrix, double planes[24]); - enum RenderingRepresentationProperties - { - REPRESENTATION_POINTS, - REPRESENTATION_WIREFRAME, - REPRESENTATION_SURFACE - }; + // enum FrustumCull + // { + // PCL_INSIDE_FRUSTUM, + // PCL_INTERSECT_FRUSTUM, + // PCL_OUTSIDE_FRUSTUM + // }; - enum ShadingRepresentationProperties - { - SHADING_FLAT, - SHADING_GOURAUD, - SHADING_PHONG - }; + //CV_EXPORTS int cullFrustum (double planes[24], const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb); + //CV_EXPORTS float viewScreenArea (const Eigen::Vector3d &eye, const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const Eigen::Matrix4d &view_projection_matrix, int width, int height); - class CV_EXPORTS Camera - { - public: - /** Focal point or lookAt. The view direction can be obtained by (focal-pos).normalized () */ - Vec3d focal; - - /** \brief Position of the camera. */ - Vec3d pos; - - /** \brief Up vector of the camera. */ - Vec3d view_up; - - /** \brief Near/far clipping planes depths */ - Vec2d clip; - - /** \brief Field of view angle in y direction (radians). */ - double fovy; - - // the following variables are the actual position and size of the window on the screen and NOT the viewport! - // except for the size, which is the same the viewport is assumed to be centered and same size as the window. - Vec2i window_size; - Vec2i window_pos; - - /** \brief Computes View matrix for Camera (Based on gluLookAt) - * \param[out] view_mat the resultant matrix - */ - void computeViewMatrix(Affine3d& view_mat) const; - - /** \brief Computes Projection Matrix for Camera - * \param[out] proj the resultant matrix - */ - void computeProjectionMatrix(Matx44d& proj) const; - - /** \brief converts point to window coordiantes - * \param[in] pt xyz point to be converted - * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 - * - * This function computes the projection and view matrix every time. - * It is very inefficient to use this for every point in the point cloud! - */ - void cvtWindowCoordinates (const cv::Point3f& pt, Vec4d& window_cord) const + enum RenderingProperties { - Affine3d view; - computeViewMatrix (view); + VIZ_POINT_SIZE, + VIZ_OPACITY, + VIZ_LINE_WIDTH, + VIZ_FONT_SIZE, + VIZ_COLOR, + VIZ_REPRESENTATION, + VIZ_IMMEDIATE_RENDERING, + VIZ_SHADING + }; - Matx44d proj; - computeProjectionMatrix (proj); - cvtWindowCoordinates (pt, proj * view.matrix, window_cord); - return; - } - - /** \brief converts point to window coordiantes - * \param[in] pt xyz point to be converted - * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 - * \param[in] composite_mat composite transformation matrix (proj*view) - * - * Use this function to compute window coordinates with a precomputed - * transformation function. The typical composite matrix will be - * the projection matrix * the view matrix. However, additional - * matrices like a camera disortion matrix can also be added. - */ - void cvtWindowCoordinates (const Point3f& pt, const Matx44d& composite_mat, Vec4d& window_cord) const + enum RenderingRepresentationProperties { - Vec4d pte (pt.x, pt.y, pt.z, 1); - window_cord = composite_mat * pte; - window_cord = window_cord/window_cord[3]; + REPRESENTATION_POINTS, + REPRESENTATION_WIREFRAME, + REPRESENTATION_SURFACE + }; - window_cord[0] = (window_cord[0]+1.0) / 2.0*window_size[0]; - window_cord[1] = (window_cord[1]+1.0) / 2.0*window_size[1]; - window_cord[2] = (window_cord[2]+1.0) / 2.0; - } - }; + enum ShadingRepresentationProperties + { + SHADING_FLAT, + SHADING_GOURAUD, + SHADING_PHONG + }; + + class CV_EXPORTS Camera + { + public: + /** Focal point or lookAt. The view direction can be obtained by (focal-pos).normalized () */ + Vec3d focal; + + /** \brief Position of the camera. */ + Vec3d pos; + + /** \brief Up vector of the camera. */ + Vec3d view_up; + + /** \brief Near/far clipping planes depths */ + Vec2d clip; + + /** \brief Field of view angle in y direction (radians). */ + double fovy; + + // the following variables are the actual position and size of the window on the screen and NOT the viewport! + // except for the size, which is the same the viewport is assumed to be centered and same size as the window. + Vec2i window_size; + Vec2i window_pos; + + /** \brief Computes View matrix for Camera (Based on gluLookAt) + * \param[out] view_mat the resultant matrix + */ + void computeViewMatrix(Affine3d& view_mat) const; + + /** \brief Computes Projection Matrix for Camera + * \param[out] proj the resultant matrix + */ + void computeProjectionMatrix(Matx44d& proj) const; + + /** \brief converts point to window coordiantes + * \param[in] pt xyz point to be converted + * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 + * + * This function computes the projection and view matrix every time. + * It is very inefficient to use this for every point in the point cloud! + */ + void cvtWindowCoordinates (const cv::Point3f& pt, Vec4d& window_cord) const + { + Affine3d view; + computeViewMatrix (view); + + Matx44d proj; + computeProjectionMatrix (proj); + cvtWindowCoordinates (pt, proj * view.matrix, window_cord); + return; + } + + /** \brief converts point to window coordiantes + * \param[in] pt xyz point to be converted + * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 + * \param[in] composite_mat composite transformation matrix (proj*view) + * + * Use this function to compute window coordinates with a precomputed + * transformation function. The typical composite matrix will be + * the projection matrix * the view matrix. However, additional + * matrices like a camera disortion matrix can also be added. + */ + void cvtWindowCoordinates (const Point3f& pt, const Matx44d& composite_mat, Vec4d& window_cord) const + { + Vec4d pte (pt.x, pt.y, pt.z, 1); + window_cord = composite_mat * pte; + window_cord = window_cord/window_cord[3]; + + window_cord[0] = (window_cord[0]+1.0) / 2.0*window_size[0]; + window_cord[1] = (window_cord[1]+1.0) / 2.0*window_size[1]; + window_cord[2] = (window_cord[2]+1.0) / 2.0; + } + }; + + } } diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 16b2e43ba..6c2942c04 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -7,9 +7,9 @@ using namespace cv; ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::Initialize () +void cv::viz::InteractorStyle::Initialize () { - modifier_ = temp_viz::InteractorStyle::KB_MOD_ALT; + modifier_ = cv::viz::InteractorStyle::KB_MOD_ALT; // Set windows size (width, height) to unknown (-1) win_size_ = Vec2i(-1, -1); win_pos_ = Vec2i(0, 0); @@ -33,7 +33,7 @@ void temp_viz::InteractorStyle::Initialize () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::saveScreenshot (const std::string &file) +void cv::viz::InteractorStyle::saveScreenshot (const std::string &file) { FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); wif_->SetInput (Interactor->GetRenderWindow ()); @@ -44,29 +44,29 @@ void temp_viz::InteractorStyle::saveScreenshot (const std::string &file) } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::zoomIn () +void cv::viz::InteractorStyle::zoomIn () { FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); // Zoom in StartDolly (); double factor = 10.0 * 0.2 * .5; - Dolly (pow (1.1, factor)); + Dolly (std::pow (1.1, factor)); EndDolly (); } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::zoomOut () +void cv::viz::InteractorStyle::zoomOut () { FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); // Zoom out StartDolly (); double factor = 10.0 * -0.2 * .5; - Dolly (pow (1.1, factor)); + Dolly (std::pow (1.1, factor)); EndDolly (); } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnChar () +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]); @@ -133,7 +133,7 @@ void temp_viz::InteractorStyle::OnChar () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) +void cv::viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) { // Register the callback function and store the user data mouseCallback_ = callback; @@ -141,7 +141,7 @@ void temp_viz::InteractorStyle::registerMouseCallback(void (*callback)(const Mou } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie) +void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie) { // Register the callback function and store the user data keyboardCallback_ = callback; @@ -150,7 +150,7 @@ void temp_viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const ////////////////////////////////////////////////////////////////////////////////////////////// void -temp_viz::InteractorStyle::OnKeyDown () +cv::viz::InteractorStyle::OnKeyDown () { if (!init_) { @@ -507,7 +507,7 @@ temp_viz::InteractorStyle::OnKeyDown () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnKeyUp () +void cv::viz::InteractorStyle::OnKeyUp () { KeyboardEvent event (false, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); // Check if there is a keyboard callback registered @@ -518,7 +518,7 @@ void temp_viz::InteractorStyle::OnKeyUp () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnMouseMove () +void cv::viz::InteractorStyle::OnMouseMove () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseMove, MouseEvent::NoButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); @@ -528,7 +528,7 @@ void temp_viz::InteractorStyle::OnMouseMove () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnLeftButtonDown () +void cv::viz::InteractorStyle::OnLeftButtonDown () { Vec2i p(Interactor->GetEventPosition()); MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; @@ -539,7 +539,7 @@ void temp_viz::InteractorStyle::OnLeftButtonDown () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnLeftButtonUp () +void cv::viz::InteractorStyle::OnLeftButtonUp () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); @@ -549,7 +549,7 @@ void temp_viz::InteractorStyle::OnLeftButtonUp () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnMiddleButtonDown () +void cv::viz::InteractorStyle::OnMiddleButtonDown () { Vec2i p(Interactor->GetEventPosition()); @@ -561,7 +561,7 @@ void temp_viz::InteractorStyle::OnMiddleButtonDown () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnMiddleButtonUp () +void cv::viz::InteractorStyle::OnMiddleButtonUp () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); @@ -571,7 +571,7 @@ void temp_viz::InteractorStyle::OnMiddleButtonUp () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnRightButtonDown () +void cv::viz::InteractorStyle::OnRightButtonDown () { Vec2i p(Interactor->GetEventPosition()); @@ -583,7 +583,7 @@ void temp_viz::InteractorStyle::OnRightButtonDown () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnRightButtonUp () +void cv::viz::InteractorStyle::OnRightButtonUp () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); @@ -593,7 +593,7 @@ void temp_viz::InteractorStyle::OnRightButtonUp () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnMouseWheelForward () +void cv::viz::InteractorStyle::OnMouseWheelForward () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); @@ -625,7 +625,7 @@ void temp_viz::InteractorStyle::OnMouseWheelForward () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnMouseWheelBackward () +void cv::viz::InteractorStyle::OnMouseWheelBackward () { Vec2i p(Interactor->GetEventPosition()); MouseEvent event (MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); @@ -658,7 +658,7 @@ void temp_viz::InteractorStyle::OnMouseWheelBackward () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::InteractorStyle::OnTimer () +void cv::viz::InteractorStyle::OnTimer () { if (!init_) { @@ -676,10 +676,15 @@ void temp_viz::InteractorStyle::OnTimer () } -namespace temp_viz -{ - // Standard VTK macro for *New () - vtkStandardNewMacro (InteractorStyle); + + +namespace cv +{ + namespace viz + { + //Standard VTK macro for *New() + vtkStandardNewMacro(InteractorStyle) + } } diff --git a/modules/viz/src/interactor_style.h b/modules/viz/src/interactor_style.h index 87095d593..04ccb68fb 100644 --- a/modules/viz/src/interactor_style.h +++ b/modules/viz/src/interactor_style.h @@ -3,8 +3,10 @@ #include "viz_types.h" #include -namespace temp_viz +namespace cv { + namespace viz + { /** \brief PCLVisualizerInteractorStyle defines an unique, custom VTK * based interactory style for PCL Visualizer applications. Besides * defining the rendering style, we also create a list of custom actions @@ -54,7 +56,7 @@ namespace temp_viz /** \brief Pass a pointer to the actor map * \param[in] actors the actor map that will be used with this style */ - inline void setCloudActorMap (const cv::Ptr& actors) { actors_ = actors; } + inline void setCloudActorMap (const Ptr& actors) { actors_ = actors; } /** \brief Pass a set of renderers to the interactor style. * \param[in] rens the vtkRendererCollection to use @@ -152,4 +154,5 @@ namespace temp_viz /** \brief MouseEvent callback user data */ void *mouse_callback_cookie_; }; + } } diff --git a/modules/viz/src/mesh_load.cpp b/modules/viz/src/mesh_load.cpp index c729f2a6a..cf302d6ec 100644 --- a/modules/viz/src/mesh_load.cpp +++ b/modules/viz/src/mesh_load.cpp @@ -6,7 +6,7 @@ #include #include -temp_viz::Mesh3d::Ptr temp_viz::Mesh3d::mesh_load(const String& file) +cv::viz::Mesh3d::Ptr cv::viz::Mesh3d::mesh_load(const String& file) { Mesh3d::Ptr mesh = new Mesh3d(); diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 11e0cdcdd..d6976f779 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -158,23 +158,26 @@ #include "opencv2/viz/widget_accessor.hpp" #include -namespace temp_viz +namespace cv { - template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); - - template<> static inline Vec3f* vtkpoints_data(vtkSmartPointer& points) + namespace viz { - CV_Assert(points->GetDataType() == VTK_FLOAT); - vtkDataArray *data = points->GetData(); - float *pointer = static_cast(data)->GetPointer(0); - return reinterpret_cast(pointer); - } + template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); - template<> static inline Vec3d* vtkpoints_data(vtkSmartPointer& points) - { - CV_Assert(points->GetDataType() == VTK_DOUBLE); - vtkDataArray *data = points->GetData(); - double *pointer = static_cast(data)->GetPointer(0); - return reinterpret_cast(pointer); + template<> static inline Vec3f* vtkpoints_data(vtkSmartPointer& points) + { + CV_Assert(points->GetDataType() == VTK_FLOAT); + vtkDataArray *data = points->GetData(); + float *pointer = static_cast(data)->GetPointer(0); + return reinterpret_cast(pointer); + } + + template<> static inline Vec3d* vtkpoints_data(vtkSmartPointer& points) + { + CV_Assert(points->GetDataType() == VTK_DOUBLE); + vtkDataArray *data = points->GetData(); + double *pointer = static_cast(data)->GetPointer(0); + return reinterpret_cast(pointer); + } } } diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/simple_widgets.cpp index 35c972fc0..28d4a9edc 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/simple_widgets.cpp @@ -2,7 +2,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation -temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) +cv::viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) { vtkSmartPointer line = vtkSmartPointer::New(); line->SetPoint1 (pt1.x, pt1.y, pt1.z); @@ -19,21 +19,21 @@ temp_viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const C setColor(color); } -void temp_viz::LineWidget::setLineWidth(float line_width) +void cv::viz::LineWidget::setLineWidth(float line_width) { vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); actor->GetProperty()->SetLineWidth(line_width); } -float temp_viz::LineWidget::getLineWidth() +float cv::viz::LineWidget::getLineWidth() { vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); return actor->GetProperty()->GetLineWidth(); } -template<> temp_viz::LineWidget temp_viz::Widget::cast() +template<> cv::viz::LineWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -42,11 +42,11 @@ template<> temp_viz::LineWidget temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// plane widget implementation -temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color &color) +cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color &color) { vtkSmartPointer plane = vtkSmartPointer::New (); plane->SetNormal (coefs[0], coefs[1], coefs[2]); - double norm = cv::norm(cv::Vec3f(coefs.val)); + double norm = cv::norm(Vec3f(coefs.val)); plane->Push (-coefs[3] / norm); vtkSmartPointer mapper = vtkSmartPointer::New (); @@ -60,15 +60,15 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color setColor(color); } -temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size, const Color &color) +cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size, const Color &color) { vtkSmartPointer plane = vtkSmartPointer::New (); - cv::Point3f coefs3(coefs[0], coefs[1], coefs[2]); + Point3f coefs3(coefs[0], coefs[1], coefs[2]); double norm_sqr = 1.0 / coefs3.dot (coefs3); plane->SetNormal(coefs[0], coefs[1], coefs[2]); double t = coefs3.dot(pt) + coefs[3]; - cv::Vec3f p_center = pt - coefs3 * t * norm_sqr; + Vec3f p_center = pt - coefs3 * t * norm_sqr; plane->SetCenter (p_center[0], p_center[1], p_center[2]); vtkSmartPointer mapper = vtkSmartPointer::New (); @@ -82,7 +82,7 @@ temp_viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double setColor(color); } -template<> temp_viz::PlaneWidget temp_viz::Widget::cast() +template<> cv::viz::PlaneWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -91,7 +91,7 @@ template<> temp_viz::PlaneWidget temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// sphere widget implementation -temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution, const Color &color) +cv::viz::SphereWidget::SphereWidget(const Point3f ¢er, float radius, int sphere_resolution, const Color &color) { vtkSmartPointer sphere = vtkSmartPointer::New (); sphere->SetRadius (radius); @@ -111,7 +111,7 @@ temp_viz::SphereWidget::SphereWidget(const cv::Point3f ¢er, float radius, in setColor(color); } -template<> temp_viz::SphereWidget temp_viz::Widget::cast() +template<> cv::viz::SphereWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -120,7 +120,7 @@ template<> temp_viz::SphereWidget temp_viz::Widget::cast /////////////////////////////////////////////////////////////////////////////////////////////// /// arrow widget implementation -temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color) +cv::viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color) { vtkSmartPointer arrowSource = vtkSmartPointer::New (); @@ -180,7 +180,7 @@ temp_viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const setColor(color); } -template<> temp_viz::ArrowWidget temp_viz::Widget::cast() +template<> cv::viz::ArrowWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -189,7 +189,7 @@ template<> temp_viz::ArrowWidget temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// circle widget implementation -temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, double thickness, const temp_viz::Color& color) +cv::viz::CircleWidget::CircleWidget(const Point3f& pt, double radius, double thickness, const Color& color) { vtkSmartPointer disk = vtkSmartPointer::New (); // Maybe the resolution should be lower e.g. 50 or 25 @@ -216,7 +216,7 @@ temp_viz::CircleWidget::CircleWidget(const temp_viz::Point3f& pt, double radius, setColor(color); } -template<> temp_viz::CircleWidget temp_viz::Widget::cast() +template<> cv::viz::CircleWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -225,9 +225,9 @@ template<> temp_viz::CircleWidget temp_viz::Widget::cast /////////////////////////////////////////////////////////////////////////////////////////////// /// cylinder widget implementation -temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides, const Color &color) +cv::viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides, const Color &color) { - const cv::Point3f pt2 = pt_on_axis + axis_direction; + const Point3f pt2 = pt_on_axis + axis_direction; vtkSmartPointer line = vtkSmartPointer::New (); line->SetPoint1 (pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); line->SetPoint2 (pt2.x, pt2.y, pt2.z); @@ -247,7 +247,7 @@ temp_viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3 setColor(color); } -template<> temp_viz::CylinderWidget temp_viz::Widget::cast() +template<> cv::viz::CylinderWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -256,7 +256,7 @@ template<> temp_viz::CylinderWidget temp_viz::Widget::cast cube = vtkSmartPointer::New (); cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); @@ -274,7 +274,7 @@ temp_viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, b setColor(color); } -template<> temp_viz::CubeWidget temp_viz::Widget::cast() +template<> cv::viz::CubeWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -283,7 +283,7 @@ template<> temp_viz::CubeWidget temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// coordinate system widget implementation -temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale) +cv::viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale) { vtkSmartPointer axes = vtkSmartPointer::New (); axes->SetOrigin (0, 0, 0); @@ -317,7 +317,7 @@ temp_viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale) WidgetAccessor::setProp(*this, actor); } -template<> temp_viz::CoordinateSystemWidget temp_viz::Widget::cast() +template<> cv::viz::CoordinateSystemWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -326,7 +326,7 @@ template<> temp_viz::CoordinateSystemWidget temp_viz::Widget::cast static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer polyLine) @@ -346,7 +346,7 @@ struct temp_viz::PolyLineWidget::CopyImpl } }; -temp_viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &color) +cv::viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &color) { Mat pointData = _pointData.getMat(); CV_Assert(pointData.type() == CV_32FC3 || pointData.type() == CV_32FC4 || pointData.type() == CV_64FC3 || pointData.type() == CV_64FC4); @@ -393,7 +393,7 @@ temp_viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &col setColor(color); } -template<> temp_viz::PolyLineWidget temp_viz::Widget::cast() +template<> cv::viz::PolyLineWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -402,7 +402,7 @@ template<> temp_viz::PolyLineWidget temp_viz::Widget::cast grid = vtkSmartPointer::New(); @@ -425,7 +425,7 @@ temp_viz::GridWidget::GridWidget(Vec2i dimensions, Vec2d spacing, const Color &c WidgetAccessor::setProp(*this, actor); } -template<> temp_viz::GridWidget temp_viz::Widget::cast() +template<> cv::viz::GridWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -434,7 +434,7 @@ template<> temp_viz::GridWidget temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// text3D widget implementation -temp_viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position, double text_scale, const Color &color) +cv::viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position, double text_scale, const Color &color) { vtkSmartPointer textSource = vtkSmartPointer::New (); textSource->SetText (text.c_str()); @@ -452,7 +452,7 @@ temp_viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position setColor(color); } -void temp_viz::Text3DWidget::setText(const String &text) +void cv::viz::Text3DWidget::setText(const String &text) { vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); @@ -466,7 +466,7 @@ void temp_viz::Text3DWidget::setText(const String &text) textSource->Update(); } -temp_viz::String temp_viz::Text3DWidget::getText() const +cv::String cv::viz::Text3DWidget::getText() const { vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); @@ -478,7 +478,7 @@ temp_viz::String temp_viz::Text3DWidget::getText() const return textSource->GetText(); } -template<> temp_viz::Text3DWidget temp_viz::Widget::cast() +template<> cv::viz::Text3DWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -487,7 +487,7 @@ template<> temp_viz::Text3DWidget temp_viz::Widget::cast /////////////////////////////////////////////////////////////////////////////////////////////// /// text widget implementation -temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) +cv::viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) { vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetPosition (pos.x, pos.y); @@ -505,20 +505,20 @@ temp_viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int fon WidgetAccessor::setProp(*this, actor); } -template<> temp_viz::TextWidget temp_viz::Widget::cast() +template<> cv::viz::TextWidget cv::viz::Widget::cast() { Widget2D widget = this->cast(); return static_cast(widget); } -void temp_viz::TextWidget::setText(const String &text) +void cv::viz::TextWidget::setText(const String &text) { vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); actor->SetInput(text.c_str()); } -temp_viz::String temp_viz::TextWidget::getText() const +cv::String cv::viz::TextWidget::getText() const { vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); @@ -528,7 +528,7 @@ temp_viz::String temp_viz::TextWidget::getText() const /////////////////////////////////////////////////////////////////////////////////////////////// /// point cloud widget implementation -struct temp_viz::CloudWidget::CreateCloudWidget +struct cv::viz::CloudWidget::CreateCloudWidget { static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) { @@ -615,7 +615,7 @@ struct temp_viz::CloudWidget::CreateCloudWidget } }; -temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) +cv::viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) { Mat cloud = _cloud.getMat(); Mat colors = _colors.getMat(); @@ -646,7 +646,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) vtkSmartPointer mapper = vtkSmartPointer::New (); mapper->SetInput (polydata); - cv::Vec3d minmax(scalars->GetRange()); + Vec3d minmax(scalars->GetRange()); mapper->SetScalarRange(minmax.val); mapper->SetScalarModeToUsePointData (); @@ -666,7 +666,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) WidgetAccessor::setProp(*this, actor); } -temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) +cv::viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) { Mat cloud = _cloud.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); @@ -695,7 +695,7 @@ temp_viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) setColor(color); } -template<> temp_viz::CloudWidget temp_viz::Widget::cast() +template<> cv::viz::CloudWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); @@ -704,17 +704,16 @@ template<> temp_viz::CloudWidget temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// cloud normals widget implementation -struct temp_viz::CloudNormalsWidget::ApplyCloudNormals +struct cv::viz::CloudNormalsWidget::ApplyCloudNormals { template struct Impl { - static vtkSmartPointer applyOrganized(const cv::Mat &cloud, const cv::Mat& normals, - int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + static vtkSmartPointer applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals) { - vtkIdType point_step = static_cast (sqrt (double (level))); - nr_normals = (static_cast ((cloud.cols - 1)/ point_step) + 1) * - (static_cast ((cloud.rows - 1) / point_step) + 1); + vtkIdType point_step = static_cast(std::sqrt(level)); + nr_normals = (static_cast ((cloud.cols - 1) / point_step) + 1) * + (static_cast ((cloud.rows - 1) / point_step) + 1); vtkSmartPointer lines = vtkSmartPointer::New(); pts = new _Tp[2 * nr_normals * 3]; @@ -743,8 +742,7 @@ struct temp_viz::CloudNormalsWidget::ApplyCloudNormals return lines; } - static vtkSmartPointer applyUnorganized(const cv::Mat &cloud, const cv::Mat& normals, - int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + static vtkSmartPointer applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) { vtkSmartPointer lines = vtkSmartPointer::New(); nr_normals = (cloud.size().area() - 1) / level + 1 ; @@ -772,8 +770,7 @@ struct temp_viz::CloudNormalsWidget::ApplyCloudNormals }; template - static inline vtkSmartPointer apply(const cv::Mat &cloud, const cv::Mat& normals, - int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + static inline vtkSmartPointer apply(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) { if (cloud.cols > 1 && cloud.rows > 1) return ApplyCloudNormals::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals); @@ -782,7 +779,7 @@ struct temp_viz::CloudNormalsWidget::ApplyCloudNormals } }; -temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color) +cv::viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color) { Mat cloud = _cloud.getMat(); Mat normals = _normals.getMat(); @@ -833,7 +830,7 @@ temp_viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _ setColor(color); } -template<> temp_viz::CloudNormalsWidget temp_viz::Widget::cast() +template<> cv::viz::CloudNormalsWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); return static_cast(widget); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 765913614..38a284cb0 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -3,20 +3,20 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////// /// cv::viz::Color -temp_viz::Color::Color() : Scalar(0, 0, 0) {} -temp_viz::Color::Color(double gray) : Scalar(gray, gray, gray) {} -temp_viz::Color::Color(double blue, double green, double red) : Scalar(blue, green, red) {} -temp_viz::Color::Color(const Scalar& color) : Scalar(color) {} +cv::viz::Color::Color() : Scalar(0, 0, 0) {} +cv::viz::Color::Color(double gray) : Scalar(gray, gray, gray) {} +cv::viz::Color::Color(double blue, double green, double red) : Scalar(blue, green, red) {} +cv::viz::Color::Color(const Scalar& color) : Scalar(color) {} -temp_viz::Color temp_viz::Color::black() { return Color( 0, 0, 0); } -temp_viz::Color temp_viz::Color::green() { return Color( 0, 255, 0); } -temp_viz::Color temp_viz::Color::blue() { return Color(255, 0, 0); } -temp_viz::Color temp_viz::Color::cyan() { return Color(255, 255, 0); } +cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); } +cv::viz::Color cv::viz::Color::green() { return Color( 0, 255, 0); } +cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); } +cv::viz::Color cv::viz::Color::cyan() { return Color(255, 255, 0); } -temp_viz::Color temp_viz::Color::red() { return Color( 0, 0, 255); } -temp_viz::Color temp_viz::Color::magenta() { return Color( 0, 255, 255); } -temp_viz::Color temp_viz::Color::yellow() { return Color(255, 0, 255); } -temp_viz::Color temp_viz::Color::white() { return Color(255, 255, 255); } +cv::viz::Color cv::viz::Color::red() { return Color( 0, 0, 255); } +cv::viz::Color cv::viz::Color::magenta() { return Color( 0, 255, 255); } +cv::viz::Color cv::viz::Color::yellow() { return Color(255, 0, 255); } +cv::viz::Color cv::viz::Color::white() { return Color(255, 255, 255); } -temp_viz::Color temp_viz::Color::gray() { return Color(128, 128, 128); } +cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); } diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 07c600809..c2461d0b5 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -1,7 +1,7 @@ #include "precomp.hpp" -cv::Affine3f temp_viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin) +cv::Affine3f cv::viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin) { Affine3f::Mat3 R; R.val[0] = axis_x.val[0]; diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 80ce52aff..530762187 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -2,89 +2,89 @@ #include "viz3d_impl.hpp" -temp_viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_name)) +cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_name)) { } -temp_viz::Viz3d::~Viz3d() +cv::viz::Viz3d::~Viz3d() { delete impl_; } -void temp_viz::Viz3d::setBackgroundColor(const Color& color) +void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } -bool temp_viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String& id) +bool cv::viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String& id) { return impl_->addPolygonMesh(mesh, Mat(), id); } -bool temp_viz::Viz3d::updatePolygonMesh (const Mesh3d& mesh, const String& id) +bool cv::viz::Viz3d::updatePolygonMesh (const Mesh3d& mesh, const String& id) { return impl_->updatePolygonMesh(mesh, Mat(), id); } -bool temp_viz::Viz3d::addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id) +bool cv::viz::Viz3d::addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id) { return impl_->addPolylineFromPolygonMesh(mesh, id); } -bool temp_viz::Viz3d::addPolygon(const Mat& cloud, const Color& color, const String& id) +bool cv::viz::Viz3d::addPolygon(const Mat& cloud, const Color& color, const String& id) { return impl_->addPolygon(cloud, color, id); } -void temp_viz::Viz3d::spin() +void cv::viz::Viz3d::spin() { impl_->spin(); } -void temp_viz::Viz3d::spinOnce (int time, bool force_redraw) +void cv::viz::Viz3d::spinOnce (int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); } -void temp_viz::Viz3d::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) +void cv::viz::Viz3d::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) { impl_->registerKeyboardCallback(callback, cookie); } -void temp_viz::Viz3d::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) +void cv::viz::Viz3d::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) { impl_->registerMouseCallback(callback, cookie); } -bool temp_viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } +bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } -void temp_viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) +void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { impl_->showWidget(id, widget, pose); } -void temp_viz::Viz3d::removeWidget(const String &id) +void cv::viz::Viz3d::removeWidget(const String &id) { impl_->removeWidget(id); } -temp_viz::Widget temp_viz::Viz3d::getWidget(const String &id) const +cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_->getWidget(id); } -void temp_viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) +void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { impl_->setWidgetPose(id, pose); } -void temp_viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) +void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } -temp_viz::Affine3f temp_viz::Viz3d::getWidgetPose(const String &id) const +cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 88593c24d..4578a65d4 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -10,7 +10,7 @@ #include -struct temp_viz::Viz3d::VizImpl +struct cv::viz::Viz3d::VizImpl { public: typedef cv::Ptr Ptr; @@ -280,91 +280,93 @@ private: -namespace temp_viz +namespace cv { - -//void getTransformationMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternionf& orientation, Eigen::Matrix4f &transformation); - -//void convertToVtkMatrix (const Eigen::Matrix4f &m, vtkSmartPointer &vtk_matrix); - -void convertToVtkMatrix (const cv::Matx44f& m, vtkSmartPointer &vtk_matrix); -void convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m); - -vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m); -cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix); - -/** \brief Convert origin and orientation to vtkMatrix4x4 - * \param[in] origin the point cloud origin - * \param[in] orientation the point cloud orientation - * \param[out] vtk_matrix the resultant VTK 4x4 matrix - */ -void convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix); -void convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m); - - -struct NanFilter -{ - template - struct Impl + namespace viz { - typedef Vec<_Tp, 3> _Out; + //void getTransformationMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternionf& orientation, Eigen::Matrix4f &transformation); - static _Out* copy(const Mat& source, _Out* output, const Mat& nan_mask) + //void convertToVtkMatrix (const Eigen::Matrix4f &m, vtkSmartPointer &vtk_matrix); + + void convertToVtkMatrix (const cv::Matx44f& m, vtkSmartPointer &vtk_matrix); + void convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m); + + vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m); + cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix); + + /** \brief Convert origin and orientation to vtkMatrix4x4 + * \param[in] origin the point cloud origin + * \param[in] orientation the point cloud orientation + * \param[out] vtk_matrix the resultant VTK 4x4 matrix + */ + void convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix); + void convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m); + + + struct NanFilter { - CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size()); - CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4); - CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth()); - - int s_chs = source.channels(); - int m_chs = nan_mask.channels(); - - for(int y = 0; y < source.rows; ++y) + template + struct Impl { - const _Tp* srow = source.ptr<_Tp>(y); - const _Msk* mrow = nan_mask.ptr<_Msk>(y); + typedef Vec<_Tp, 3> _Out; - for(int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) - if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) - *output++ = _Out(srow); + static _Out* copy(const Mat& source, _Out* output, const Mat& nan_mask) + { + CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size()); + CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4); + CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth()); + + int s_chs = source.channels(); + int m_chs = nan_mask.channels(); + + for(int y = 0; y < source.rows; ++y) + { + const _Tp* srow = source.ptr<_Tp>(y); + const _Msk* mrow = nan_mask.ptr<_Msk>(y); + + for(int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) + if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) + *output++ = _Out(srow); + } + return output; + } + }; + + template + static inline Vec<_Tp, 3>* copy(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask) + { + CV_Assert(nan_mask.depth() == CV_32F || nan_mask.depth() == CV_64F); + + typedef Vec<_Tp, 3>* (*copy_func)(const Mat&, Vec<_Tp, 3>*, const Mat&); + const static copy_func table[2] = { &NanFilter::Impl<_Tp, float>::copy, &NanFilter::Impl<_Tp, double>::copy }; + + return table[nan_mask.depth() - 5](source, output, nan_mask); } - return output; - } - }; + }; - template - static inline Vec<_Tp, 3>* copy(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask) - { - CV_Assert(nan_mask.depth() == CV_32F || nan_mask.depth() == CV_64F); + struct ApplyAffine + { + const Affine3f& affine_; + ApplyAffine(const Affine3f& affine) : affine_(affine) {} - typedef Vec<_Tp, 3>* (*copy_func)(const Mat&, Vec<_Tp, 3>*, const Mat&); - const static copy_func table[2] = { &NanFilter::Impl<_Tp, float>::copy, &NanFilter::Impl<_Tp, double>::copy }; + template Point3_<_Tp> operator()(const Point3_<_Tp>& p) const { return affine_ * p; } - return table[nan_mask.depth() - 5](source, output, nan_mask); + template Vec<_Tp, 3> operator()(const Vec<_Tp, 3>& v) const + { + const float* m = affine_.matrix.val; + + Vec<_Tp, 3> result; + result[0] = (_Tp)(m[0] * v[0] + m[1] * v[1] + m[ 2] * v[2] + m[ 3]); + result[1] = (_Tp)(m[4] * v[0] + m[5] * v[1] + m[ 6] * v[2] + m[ 7]); + result[2] = (_Tp)(m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11]); + return result; + } + + private: + ApplyAffine(const ApplyAffine&); + ApplyAffine& operator=(const ApplyAffine&); + }; } -}; - -struct ApplyAffine -{ - const Affine3f& affine_; - ApplyAffine(const Affine3f& affine) : affine_(affine) {} - - template Point3_<_Tp> operator()(const Point3_<_Tp>& p) const { return affine_ * p; } - - template Vec<_Tp, 3> operator()(const Vec<_Tp, 3>& v) const - { - const float* m = affine_.matrix.val; - - Vec<_Tp, 3> result; - result[0] = (_Tp)(m[0] * v[0] + m[1] * v[1] + m[ 2] * v[2] + m[ 3]); - result[1] = (_Tp)(m[4] * v[0] + m[5] * v[1] + m[ 6] * v[2] + m[ 7]); - result[2] = (_Tp)(m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11]); - return result; - } - -private: - ApplyAffine(const ApplyAffine&); - ApplyAffine& operator=(const ApplyAffine&); -}; } diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz_main.cpp index b3b502203..1a8be1dd9 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz_main.cpp @@ -12,8 +12,8 @@ vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew () #endif ///////////////////////////////////////////////////////////////////////////////////////////// -temp_viz::Viz3d::VizImpl::VizImpl (const std::string &name) - : style_ (vtkSmartPointer::New ()) +cv::viz::Viz3d::VizImpl::VizImpl (const std::string &name) + : style_ (vtkSmartPointer::New ()) , cloud_actor_map_ (new CloudActorMap) , shape_actor_map_ (new ShapeActorMap) , widget_actor_map_ (new WidgetActorMap) @@ -83,7 +83,7 @@ temp_viz::Viz3d::VizImpl::VizImpl (const std::string &name) } ///////////////////////////////////////////////////////////////////////////////////////////// -temp_viz::Viz3d::VizImpl::~VizImpl () +cv::viz::Viz3d::VizImpl::~VizImpl () { if (interactor_ != NULL) interactor_->DestroyTimer (timer_id_); @@ -92,22 +92,22 @@ temp_viz::Viz3d::VizImpl::~VizImpl () } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } +void cv::viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) +void cv::viz::Viz3d::VizImpl::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) { style_->registerMouseCallback(callback, cookie); } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) +void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) { style_->registerKeyboardCallback(callback, cookie); } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::spin () +void cv::viz::Viz3d::VizImpl::spin () { resetStoppedFlag (); window_->Render (); @@ -115,7 +115,7 @@ void temp_viz::Viz3d::VizImpl::spin () } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::spinOnce (int time, bool force_redraw) +void cv::viz::Viz3d::VizImpl::spinOnce (int time, bool force_redraw) { resetStoppedFlag (); @@ -139,7 +139,7 @@ void temp_viz::Viz3d::VizImpl::spinOnce (int time, bool force_redraw) } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::removePointCloud (const std::string &id) +bool cv::viz::Viz3d::VizImpl::removePointCloud (const std::string &id) { CloudActorMap::iterator am_it = cloud_actor_map_->find (id); if (am_it == cloud_actor_map_->end ()) @@ -152,7 +152,7 @@ bool temp_viz::Viz3d::VizImpl::removePointCloud (const std::string &id) } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::removeShape (const std::string &id) +bool cv::viz::Viz3d::VizImpl::removeShape (const std::string &id) { // Check to see if the given ID entry exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); @@ -191,7 +191,7 @@ bool temp_viz::Viz3d::VizImpl::removeShape (const std::string &id) } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::removeText3D (const std::string &id) +bool cv::viz::Viz3d::VizImpl::removeText3D (const std::string &id) { // Check to see if the given ID entry exists ShapeActorMap::iterator am_it = shape_actor_map_->find (id); @@ -206,7 +206,7 @@ bool temp_viz::Viz3d::VizImpl::removeText3D (const std::string &id) } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::removeAllPointClouds () +bool cv::viz::Viz3d::VizImpl::removeAllPointClouds () { // Check to see if the given ID entry exists CloudActorMap::iterator am_it = cloud_actor_map_->begin (); @@ -221,7 +221,7 @@ bool temp_viz::Viz3d::VizImpl::removeAllPointClouds () } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::removeAllShapes () +bool cv::viz::Viz3d::VizImpl::removeAllShapes () { // Check to see if the given ID entry exists ShapeActorMap::iterator am_it = shape_actor_map_->begin (); @@ -237,7 +237,7 @@ bool temp_viz::Viz3d::VizImpl::removeAllShapes () ////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) +bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) { vtkLODActor* actor_to_remove = vtkLODActor::SafeDownCast (actor); @@ -262,7 +262,7 @@ bool temp_viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) +bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) { vtkActor* actor_to_remove = vtkActor::SafeDownCast (actor); @@ -287,7 +287,7 @@ bool temp_viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) +bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) { vtkProp* actor_to_remove = vtkProp::SafeDownCast(actor); @@ -305,7 +305,7 @@ bool temp_viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &data, vtkSmartPointer &actor, bool use_scalars) +void cv::viz::Viz3d::VizImpl::createActorFromVTKDataSet (const vtkSmartPointer &data, vtkSmartPointer &actor, bool use_scalars) { if (!actor) actor = vtkSmartPointer::New (); @@ -344,14 +344,14 @@ void temp_viz::Viz3d::VizImpl::createActorFromVTKDataSet (const vtkSmartPointer< } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setBackgroundColor (const Color& color) +void cv::viz::Viz3d::VizImpl::setBackgroundColor (const Color& color) { Color c = vtkcolor(color); renderer_->SetBackground (c.val); } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::getPointCloudRenderingProperties (int property, double &value, const std::string &id) +bool cv::viz::Viz3d::VizImpl::getPointCloudRenderingProperties (int property, double &value, const std::string &id) { CloudActorMap::iterator am_it = cloud_actor_map_->find (id); if (am_it == cloud_actor_map_->end ()) @@ -387,7 +387,7 @@ bool temp_viz::Viz3d::VizImpl::getPointCloudRenderingProperties (int property, d } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::setPointCloudRenderingProperties (int property, double value, const std::string &id) +bool cv::viz::Viz3d::VizImpl::setPointCloudRenderingProperties (int property, double value, const std::string &id) { CloudActorMap::iterator am_it = cloud_actor_map_->find (id); if (am_it == cloud_actor_map_->end ()) @@ -433,7 +433,7 @@ bool temp_viz::Viz3d::VizImpl::setPointCloudRenderingProperties (int property, d } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::setPointCloudSelected (const bool selected, const std::string &id) +bool cv::viz::Viz3d::VizImpl::setPointCloudSelected (const bool selected, const std::string &id) { CloudActorMap::iterator am_it = cloud_actor_map_->find (id); if (am_it == cloud_actor_map_->end ()) @@ -456,7 +456,7 @@ bool temp_viz::Viz3d::VizImpl::setPointCloudSelected (const bool selected, const } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double value, const std::string &id) +bool cv::viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double value, const std::string &id) { ShapeActorMap::iterator am_it = shape_actor_map_->find (id); if (am_it == shape_actor_map_->end ()) @@ -512,7 +512,7 @@ bool temp_viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double { if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) { - std::cout << "[temp_viz::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Gouraud shading was requested. Estimating normals...\n" << std::endl; + std::cout << "[cv::viz::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Gouraud shading was requested. Estimating normals...\n" << std::endl; vtkSmartPointer normals = vtkSmartPointer::New (); normals->SetInput (actor->GetMapper ()->GetInput ()); @@ -526,7 +526,7 @@ bool temp_viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double { if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) { - std::cout << "[temp_viz::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Phong shading was requested. Estimating normals...\n" << std::endl; + std::cout << "[cv::viz::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Phong shading was requested. Estimating normals...\n" << std::endl; vtkSmartPointer normals = vtkSmartPointer::New (); normals->SetInput (actor->GetMapper ()->GetInput ()); normals->Update (); @@ -547,7 +547,7 @@ bool temp_viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::initCameraParameters () +void cv::viz::Viz3d::VizImpl::initCameraParameters () { Camera camera_temp; // Set default camera parameters to something meaningful @@ -571,12 +571,12 @@ void temp_viz::Viz3d::VizImpl::initCameraParameters () } ///////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::cameraParamsSet () const { return (camera_set_); } +bool cv::viz::Viz3d::VizImpl::cameraParamsSet () const { return (camera_set_); } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::updateCamera () +void cv::viz::Viz3d::VizImpl::updateCamera () { - std::cout << "[temp_viz::PCLVisualizer::updateCamera()] This method was deprecated, just re-rendering all scenes now." << std::endl; + std::cout << "[cv::viz::PCLVisualizer::updateCamera()] This method was deprecated, just re-rendering all scenes now." << std::endl; //rens_->InitTraversal (); // Update the camera parameters @@ -584,7 +584,7 @@ void temp_viz::Viz3d::VizImpl::updateCamera () } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::getCameras (temp_viz::Camera& camera) +void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) { vtkCamera* active_camera = renderer_->GetActiveCamera (); @@ -599,7 +599,7 @@ void temp_viz::Viz3d::VizImpl::getCameras (temp_viz::Camera& camera) } ///////////////////////////////////////////////////////////////////////////////////////////// -cv::Affine3f temp_viz::Viz3d::VizImpl::getViewerPose () +cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose () { vtkCamera& camera = *renderer_->GetActiveCamera (); @@ -628,14 +628,14 @@ cv::Affine3f temp_viz::Viz3d::VizImpl::getViewerPose () } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::resetCamera () +void cv::viz::Viz3d::VizImpl::resetCamera () { renderer_->ResetCamera (); } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up) +void cv::viz::Viz3d::VizImpl::setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up) { vtkSmartPointer cam = renderer_->GetActiveCamera (); @@ -646,7 +646,7 @@ void temp_viz::Viz3d::VizImpl::setCameraPosition (const cv::Vec3d& pos, const cv } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z) +void cv::viz::Viz3d::VizImpl::setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z) { //rens_->InitTraversal (); @@ -659,7 +659,7 @@ void temp_viz::Viz3d::VizImpl::setCameraPosition (double pos_x, double pos_y, do } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setCameraParameters (const cv::Matx33f& intrinsics, const cv::Affine3f& extrinsics) +void cv::viz::Viz3d::VizImpl::setCameraParameters (const cv::Matx33f& intrinsics, const cv::Affine3f& extrinsics) { // Position = extrinsic translation cv::Vec3f pos_vec = extrinsics.translation(); @@ -698,7 +698,7 @@ void temp_viz::Viz3d::VizImpl::setCameraParameters (const cv::Matx33f& intrinsic } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setCameraParameters (const temp_viz::Camera &camera) +void cv::viz::Viz3d::VizImpl::setCameraParameters (const cv::viz::Camera &camera) { //rens_->InitTraversal (); @@ -715,7 +715,7 @@ void temp_viz::Viz3d::VizImpl::setCameraParameters (const temp_viz::Camera &came } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setCameraClipDistances (double near, double far) +void cv::viz::Viz3d::VizImpl::setCameraClipDistances (double near, double far) { //rens_->InitTraversal (); @@ -724,7 +724,7 @@ void temp_viz::Viz3d::VizImpl::setCameraClipDistances (double near, double far) } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setCameraFieldOfView (double fovy) +void cv::viz::Viz3d::VizImpl::setCameraFieldOfView (double fovy) { //rens_->InitTraversal (); @@ -735,7 +735,7 @@ void temp_viz::Viz3d::VizImpl::setCameraFieldOfView (double fovy) } ///////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) +void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) { vtkSmartPointer camera_pose; static CloudActorMap::iterator it = cloud_actor_map_->find (id); @@ -771,7 +771,7 @@ void temp_viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) } //////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, const std::string & id) +bool cv::viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, const std::string & id) { ShapeActorMap::iterator am_it = shape_actor_map_->find (id); if (am_it != shape_actor_map_->end ()) @@ -791,7 +791,7 @@ bool temp_viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const std::string & id) +bool cv::viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const std::string & id) { ShapeActorMap::iterator am_it = shape_actor_map_->find (id); if (am_it != shape_actor_map_->end ()) @@ -818,7 +818,7 @@ bool temp_viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointerfind (id); if (am_it != shape_actor_map_->end ()) @@ -837,7 +837,7 @@ bool temp_viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, } //////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, vtkSmartPointer transform, const std::string &id) +bool cv::viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, vtkSmartPointer transform, const std::string &id) { ShapeActorMap::iterator am_it = shape_actor_map_->find (id); if (am_it != shape_actor_map_->end ()) @@ -859,7 +859,7 @@ bool temp_viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, return (true); } -bool temp_viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& mesh, const std::string &id) +bool cv::viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& mesh, const std::string &id) { CV_Assert(mesh.cloud.rows == 1 && mesh.cloud.type() == CV_32FC3); @@ -913,7 +913,7 @@ bool temp_viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& mesh, c /////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setRepresentationToSurfaceForAllActors () +void cv::viz::Viz3d::VizImpl::setRepresentationToSurfaceForAllActors () { vtkActorCollection * actors = renderer_->GetActors (); actors->InitTraversal (); @@ -923,7 +923,7 @@ void temp_viz::Viz3d::VizImpl::setRepresentationToSurfaceForAllActors () } /////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setRepresentationToPointsForAllActors () +void cv::viz::Viz3d::VizImpl::setRepresentationToPointsForAllActors () { vtkActorCollection * actors = renderer_->GetActors (); actors->InitTraversal (); @@ -933,7 +933,7 @@ void temp_viz::Viz3d::VizImpl::setRepresentationToPointsForAllActors () } /////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::setRepresentationToWireframeForAllActors () +void cv::viz::Viz3d::VizImpl::setRepresentationToWireframeForAllActors () { vtkActorCollection * actors = renderer_->GetActors (); actors->InitTraversal (); @@ -943,7 +943,7 @@ void temp_viz::Viz3d::VizImpl::setRepresentationToWireframeForAllActors () } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::updateCells (vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points) +void cv::viz::Viz3d::VizImpl::updateCells (vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points) { // If no init cells and cells has not been initialized... if (!cells) @@ -986,24 +986,24 @@ void temp_viz::Viz3d::VizImpl::updateCells (vtkSmartPointer &cel } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) +void cv::viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) { polydata = vtkSmartPointer::New (); } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) +void cv::viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) { polydata = vtkSmartPointer::New (); } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::Viz3d::VizImpl::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) +void cv::viz::Viz3d::VizImpl::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) { polydata = vtkSmartPointer::New (); } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix) +void cv::viz::convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix) { // set rotation Eigen::Matrix3f rot = orientation.toRotationMatrix (); @@ -1018,14 +1018,14 @@ void temp_viz::convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Q vtk_matrix->SetElement (3, 3, 1.0f); } -void temp_viz::convertToVtkMatrix (const cv::Matx44f &m, vtkSmartPointer &vtk_matrix) +void cv::viz::convertToVtkMatrix (const Matx44f &m, vtkSmartPointer &vtk_matrix) { for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) vtk_matrix->SetElement (i, k, m (i, k)); } -vtkSmartPointer temp_viz::convertToVtkMatrix (const cv::Matx44f &m) +vtkSmartPointer cv::viz::convertToVtkMatrix (const cv::Matx44f &m) { vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); for (int i = 0; i < 4; i++) @@ -1034,7 +1034,7 @@ vtkSmartPointer temp_viz::convertToVtkMatrix (const cv::Matx44f &m return vtk_matrix; } -void temp_viz::convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m) +void cv::viz::convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m) { for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) @@ -1042,7 +1042,7 @@ void temp_viz::convertToCvMatrix (const vtkSmartPointer &vtk_matri } -cv::Matx44f temp_viz::convertToMatx(const vtkSmartPointer& vtk_matrix) +cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer& vtk_matrix) { cv::Matx44f m; for (int i = 0; i < 4; i++) @@ -1052,7 +1052,7 @@ cv::Matx44f temp_viz::convertToMatx(const vtkSmartPointer& vtk_mat } ////////////////////////////////////////////////////////////////////////////////////////////// -void temp_viz::convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m) +void cv::viz::convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m) { for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) @@ -1060,22 +1060,22 @@ void temp_viz::convertToEigenMatrix (const vtkSmartPointer &vtk_ma } -void temp_viz::Viz3d::VizImpl::setFullScreen (bool mode) +void cv::viz::Viz3d::VizImpl::setFullScreen (bool mode) { if (window_) window_->SetFullScreen (mode); } -void temp_viz::Viz3d::VizImpl::setWindowName (const std::string &name) +void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) { if (window_) window_->SetWindowName (name.c_str ()); } -void temp_viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } -void temp_viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } +void cv::viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } +void cv::viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } -bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) +bool cv::viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); @@ -1088,9 +1088,9 @@ bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& ma // std::vector fields; - // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgb", fields); + // rgb_idx = cv::viz::getFieldIndex (*cloud, "rgb", fields); // if (rgb_idx == -1) - // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgba", fields); + // rgb_idx = cv::viz::getFieldIndex (*cloud, "rgba", fields); vtkSmartPointer colors_array; #if 1 @@ -1108,12 +1108,12 @@ bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& ma for(int i = 0; i < mesh.colors.cols; ++i) colors_array->InsertNextTupleValue(&data[i*3]); - // temp_viz::RGB rgb_data; + // cv::viz::RGB rgb_data; // for (size_t i = 0; i < cloud->size (); ++i) // { // if (!isFinite (cloud->points[i])) // continue; - // memcpy (&rgb_data, reinterpret_cast (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (temp_viz::RGB)); + // memcpy (&rgb_data, reinterpret_cast (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (cv::viz::RGB)); // unsigned char color[3]; // color[0] = rgb_data.r; // color[1] = rgb_data.g; @@ -1262,7 +1262,7 @@ bool temp_viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& ma } -bool temp_viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) +bool cv::viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) { CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); @@ -1379,7 +1379,7 @@ bool temp_viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv:: } //////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color, bool display_length, const std::string &id) +bool cv::viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color, bool display_length, const std::string &id) { // Check to see if this ID entry already exists (has it been already added to the visualizer?) ShapeActorMap::iterator am_it = shape_actor_map_->find (id); @@ -1409,7 +1409,7 @@ bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3 return (true); } //////////////////////////////////////////////////////////////////////////////////////////// -bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color_line, const Color& color_text, const std::string &id) +bool cv::viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color_line, const Color& color_text, const std::string &id) { // Check to see if this ID entry already exists (has it been already added to the visualizer?) ShapeActorMap::iterator am_it = shape_actor_map_->find (id); @@ -1440,7 +1440,7 @@ bool temp_viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3 return (true); } -bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) +bool cv::viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) { CV_Assert(cloud.type() == CV_32FC3 && cloud.rows == 1); @@ -1518,7 +1518,7 @@ bool temp_viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& co return (true); } -void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose) +void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); @@ -1547,7 +1547,7 @@ void temp_viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget (*widget_actor_map_)[id].actor = WidgetAccessor::getProp(widget); } -void temp_viz::Viz3d::VizImpl::removeWidget(const String &id) +void cv::viz::Viz3d::VizImpl::removeWidget(const String &id) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); @@ -1556,7 +1556,7 @@ void temp_viz::Viz3d::VizImpl::removeWidget(const String &id) widget_actor_map_->erase(wam_itr); } -temp_viz::Widget temp_viz::Viz3d::VizImpl::getWidget(const String &id) const +cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const { WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); @@ -1567,7 +1567,7 @@ temp_viz::Widget temp_viz::Viz3d::VizImpl::getWidget(const String &id) const return widget; } -void temp_viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) +void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); @@ -1581,7 +1581,7 @@ void temp_viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &p actor->Modified (); } -void temp_viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) +void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); @@ -1604,7 +1604,7 @@ void temp_viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f actor->Modified (); } -temp_viz::Affine3f temp_viz::Viz3d::VizImpl::getWidgetPose(const String &id) const +cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const { WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); diff --git a/modules/viz/src/viz_types.h b/modules/viz/src/viz_types.h index 3dbb44f18..9d47a0c8b 100644 --- a/modules/viz/src/viz_types.h +++ b/modules/viz/src/viz_types.h @@ -2,30 +2,33 @@ #include "precomp.hpp" -namespace temp_viz +namespace cv { - struct CV_EXPORTS CloudActor + namespace viz { - /** \brief The actor holding the data to render. */ - vtkSmartPointer actor; + struct CV_EXPORTS CloudActor + { + /** \brief The actor holding the data to render. */ + vtkSmartPointer actor; - /** \brief The viewpoint transformation matrix. */ - vtkSmartPointer viewpoint_transformation_; + /** \brief The viewpoint transformation matrix. */ + vtkSmartPointer viewpoint_transformation_; - /** \brief Internal cell array. Used for optimizing updatePointCloud. */ - vtkSmartPointer cells; - }; - - // TODO This will be used to contain both cloud and shape actors - struct CV_EXPORTS WidgetActor - { - vtkSmartPointer actor; - vtkSmartPointer viewpoint_transformation_; - vtkSmartPointer cells; - }; + /** \brief Internal cell array. Used for optimizing updatePointCloud. */ + vtkSmartPointer cells; + }; - typedef std::map CloudActorMap; - typedef std::map > ShapeActorMap; - typedef std::map WidgetActorMap; + // TODO This will be used to contain both cloud and shape actors + struct CV_EXPORTS WidgetActor + { + vtkSmartPointer actor; + vtkSmartPointer viewpoint_transformation_; + vtkSmartPointer cells; + }; + + typedef std::map CloudActorMap; + typedef std::map > ShapeActorMap; + typedef std::map WidgetActorMap; + } } diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 7978d7a5b..bb257fe7d 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -3,7 +3,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////// /// widget implementation -class temp_viz::Widget::Impl +class cv::viz::Widget::Impl { public: vtkSmartPointer prop; @@ -12,17 +12,17 @@ public: Impl() : prop(0) {} }; -temp_viz::Widget::Widget() : impl_(0) +cv::viz::Widget::Widget() : impl_(0) { create(); } -temp_viz::Widget::Widget(const Widget &other) : impl_(other.impl_) +cv::viz::Widget::Widget(const Widget &other) : impl_(other.impl_) { if (impl_) CV_XADD(&impl_->ref_counter, 1); } -temp_viz::Widget& temp_viz::Widget::operator=(const Widget &other) +cv::viz::Widget& cv::viz::Widget::operator=(const Widget &other) { if (this != &other) { @@ -33,19 +33,19 @@ temp_viz::Widget& temp_viz::Widget::operator=(const Widget &other) return *this; } -temp_viz::Widget::~Widget() +cv::viz::Widget::~Widget() { release(); } -void temp_viz::Widget::create() +void cv::viz::Widget::create() { if (impl_) release(); impl_ = new Impl(); impl_->ref_counter = 1; } -void temp_viz::Widget::release() +void cv::viz::Widget::release() { if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) { @@ -57,12 +57,12 @@ void temp_viz::Widget::release() /////////////////////////////////////////////////////////////////////////////////////////////// /// widget accessor implementaion -vtkSmartPointer temp_viz::WidgetAccessor::getProp(const Widget& widget) +vtkSmartPointer cv::viz::WidgetAccessor::getProp(const Widget& widget) { return widget.impl_->prop; } -void temp_viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer prop) +void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer prop) { widget.impl_->prop = prop; } @@ -70,18 +70,18 @@ void temp_viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer /////////////////////////////////////////////////////////////////////////////////////////////// /// widget3D implementation -struct temp_viz::Widget3D::MatrixConverter +struct cv::viz::Widget3D::MatrixConverter { - static cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix) + static Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix) { - cv::Matx44f m; + Matx44f m; for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) m(i, k) = vtk_matrix->GetElement (i, k); return m; } - static vtkSmartPointer convertToVtkMatrix (const cv::Matx44f& m) + static vtkSmartPointer convertToVtkMatrix (const Matx44f& m) { vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); for (int i = 0; i < 4; i++) @@ -91,7 +91,7 @@ struct temp_viz::Widget3D::MatrixConverter } }; -void temp_viz::Widget3D::setPose(const Affine3f &pose) +void cv::viz::Widget3D::setPose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); @@ -101,7 +101,7 @@ void temp_viz::Widget3D::setPose(const Affine3f &pose) actor->Modified (); } -void temp_viz::Widget3D::updatePose(const Affine3f &pose) +void cv::viz::Widget3D::updatePose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); @@ -121,7 +121,7 @@ void temp_viz::Widget3D::updatePose(const Affine3f &pose) actor->Modified (); } -temp_viz::Affine3f temp_viz::Widget3D::getPose() const +cv::Affine3f cv::viz::Widget3D::getPose() const { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); @@ -131,7 +131,7 @@ temp_viz::Affine3f temp_viz::Widget3D::getPose() const return Affine3f(matrix_cv); } -void temp_viz::Widget3D::setColor(const Color &color) +void cv::viz::Widget3D::setColor(const Color &color) { // Cast to actor instead of prop3d since prop3d doesn't provide getproperty vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); @@ -148,7 +148,7 @@ void temp_viz::Widget3D::setColor(const Color &color) actor->Modified (); } -template<> temp_viz::Widget3D temp_viz::Widget::cast() +template<> cv::viz::Widget3D cv::viz::Widget::cast() { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); @@ -161,7 +161,7 @@ template<> temp_viz::Widget3D temp_viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// widget2D implementation -void temp_viz::Widget2D::setColor(const Color &color) +void cv::viz::Widget2D::setColor(const Color &color) { vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); @@ -170,7 +170,7 @@ void temp_viz::Widget2D::setColor(const Color &color) actor->Modified (); } -template<> temp_viz::Widget2D temp_viz::Widget::cast() +template<> cv::viz::Widget2D cv::viz::Widget::cast() { vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); From 512afe2a90607e90976adc143504bb3003d9002e Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 13 Jul 2013 18:23:46 +0400 Subject: [PATCH 081/205] beatification of test_viz --- modules/viz/test/test_viz3d.cpp | 168 +++++++++++++++----------------- 1 file changed, 77 insertions(+), 91 deletions(-) diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 884b0b576..a1b99fae5 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -48,6 +48,7 @@ #include #include +using namespace cv; cv::Mat cvcloud_load() { @@ -67,102 +68,86 @@ cv::Mat cvcloud_load() TEST(Viz_viz3d, accuracy) { - temp_viz::Viz3d v("abc"); - //v.spin(); - - v.setBackgroundColor(); - cv::Mat cloud = cvcloud_load(); - cv::Mat colors(cloud.size(), CV_8UC3, cv::Scalar(0, 255, 0)); - - float angle_x = 0.0f; - float angle_y = 0.0f; - float angle_z = 0.0f; - float pos_x = 0.0f; - float pos_y = 0.0f; - float pos_z = 0.0f; - temp_viz::Mesh3d::Ptr mesh = temp_viz::Mesh3d::mesh_load("d:/horse.ply"); - v.addPolygonMesh(*mesh, "pq"); + cv::Mat normals(cloud.size(), cloud.type(), cv::Scalar(0, 10, 0)); + //cv::viz::Mesh3d::Ptr mesh = cv::viz::Mesh3d::mesh_load("d:/horse.ply"); - int col_blue = 0; - int col_green = 0; - int col_red = 0; + const Vec4d data[] = { Vec4d(0.0, 0.0, 0.0, 0.0), Vec4d(1.0, 1.0, 1.0, 1.0), cv::Vec4d(0.0, 2.0, 0.0, 0.0), cv::Vec4d(3.0, 4.0, 1.0, 1.0) }; + cv::Mat points(1, sizeof(data)/sizeof(data[0]), CV_64FC4, (void*)data); + points = points.reshape(4, 2); - temp_viz::LineWidget lw(cv::Point3f(0.0,0.0,0.0), cv::Point3f(4.0,4.0,4.0), temp_viz::Color(0,255,0)); - temp_viz::PlaneWidget pw(cv::Vec4f(0.0,1.0,2.0,3.0), 50.0); - temp_viz::SphereWidget sw(cv::Point3f(0,0,0), 0.5); - temp_viz::ArrowWidget aw(cv::Point3f(0,0,0), cv::Point3f(1,1,1), temp_viz::Color(255,0,0)); - temp_viz::CircleWidget cw(cv::Point3f(0,0,0), 0.5, 0.01, temp_viz::Color(0,255,0)); - temp_viz::CylinderWidget cyw(cv::Point3f(0,0,0), cv::Point3f(-1,-1,-1), 0.5, 30, temp_viz::Color(0,255,0)); - temp_viz::CubeWidget cuw(cv::Point3f(-2,-2,-2), cv::Point3f(-1,-1,-1)); - temp_viz::CoordinateSystemWidget csw; - temp_viz::TextWidget tw("TEST", cv::Point2i(100,100), 20); - temp_viz::CloudWidget pcw(cloud, colors); - temp_viz::CloudWidget pcw2(cloud, temp_viz::Color(0,255,255)); + cv::viz::Viz3d viz("abc"); + viz.setBackgroundColor(); -// v.showWidget("line", lw); -// v.showWidget("plane", pw); - v.showWidget("sphere", sw); - v.spin(); - //v.showWidget("arrow", aw); - //v.showWidget("circle", cw); - //v.showWidget("cylinder", cyw); - //v.showWidget("cube", cuw); - //v.showWidget("coordinateSystem", csw); - //v.showWidget("coordinateSystem2", temp_viz::CoordinateSystemWidget(2.0), cv::Affine3f(0, 0, 0, cv::Vec3f(2, 0, 0))); - //v.showWidget("text",tw); - //v.showWidget("pcw",pcw); - //v.showWidget("pcw2",pcw2); + Vec3f angle = Vec3f::all(0); + Vec3f pos = Vec3f::all(0); + + //viz.addPolygonMesh(*mesh, "pq"); + + viz::Color color = viz::Color::black(); + + viz::LineWidget lw(Point3f(0, 0, 0), Point3f(4.f, 4.f,4.f), viz::Color::green()); + viz::PlaneWidget pw(Vec4f(0.0,1.0,2.0,3.0), 5.0); + viz::SphereWidget sw(Point3f(0, 0, 0), 0.5); + viz::ArrowWidget aw(Point3f(0, 0, 0), Point3f(1, 1, 1), viz::Color::red()); + viz::CircleWidget cw(Point3f(0, 0, 0), 0.5, 0.01, viz::Color::green()); + viz::CylinderWidget cyw(Point3f(0, 0, 0), Point3f(-1, -1, -1), 0.5, 30, viz::Color::green()); + viz::CubeWidget cuw(Point3f(-2, -2, -2), Point3f(-1, -1, -1)); + viz::CoordinateSystemWidget csw; + viz::TextWidget tw("TEST", Point(100, 100), 20); + viz::CloudWidget pcw(cloud, colors); + viz::CloudWidget pcw2(cloud, viz::Color::magenta()); -// temp_viz::LineWidget lw2 = lw; + viz.showWidget("line", lw); + viz.showWidget("plane", pw); + viz.showWidget("sphere", sw); + viz.showWidget("arrow", aw); + viz.showWidget("circle", cw); + viz.showWidget("cylinder", cyw); + viz.showWidget("cube", cuw); + viz.showWidget("coordinateSystem", csw); + viz.showWidget("coordinateSystem2", viz::CoordinateSystemWidget(2.0), Affine3f().translate(Vec3f(2, 0, 0))); + viz.showWidget("text",tw); + viz.showWidget("pcw",pcw); + viz.showWidget("pcw2",pcw2); + +// viz::LineWidget lw2 = lw; // v.showPointCloud("cld",cloud, colors); - cv::Mat normals(cloud.size(), cloud.type(), cv::Scalar(0, 10, 0)); - // v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); - //temp_viz::CloudNormalsWidget cnw(cloud, normals); + //viz::CloudNormalsWidget cnw(cloud, normals); //v.showWidget("n", cnw); + +// lw = v.getWidget("n").cast(); +// pw = v.getWidget("n").cast(); + + + viz::PolyLineWidget plw(points, viz::Color::green()); + viz.showWidget("polyline", plw); +// lw = v.getWidget("polyline").cast(); + + viz.spin(); - - -// lw = v.getWidget("n").cast(); -// pw = v.getWidget("n").cast(); - - cv::Mat points(1, 4, CV_64FC4); - - cv::Vec4d* data = points.ptr(); - data[0] = cv::Vec4d(0.0,0.0,0.0,0.0); - data[1] = cv::Vec4d(1.0,1.0,1.0,1.0); - data[2] = cv::Vec4d(0.0,2.0,0.0,0.0); - data[3] = cv::Vec4d(3.0,4.0,1.0,1.0); - points = points.reshape(0, 2); - - temp_viz::PolyLineWidget plw(points, temp_viz::Color::green()); - v.showWidget("polyline",plw); -// lw = v.getWidget("polyline").cast(); - - v.spin(); - - //temp_viz::GridWidget gw(temp_viz::Vec2i(100,100), temp_viz::Vec2d(1,1)); + //viz::GridWidget gw(viz::Vec2i(100,100), viz::Vec2d(1,1)); //v.showWidget("grid", gw); - lw = v.getWidget("grid").cast(); + lw = viz.getWidget("grid").cast(); - //temp_viz::Text3DWidget t3w("OpenCV", cv::Point3f(0.0, 2.0, 0.0), 1.0, temp_viz::Color(255,255,0)); + //viz::Text3DWidget t3w("OpenCV", cv::Point3f(0.0, 2.0, 0.0), 1.0, viz::Color(255,255,0)); //v.showWidget("txt3d", t3w); // float grid_x_angle = 0.0; - while(!v.wasStopped()) + while(!viz.wasStopped()) { // Creating new point cloud with id cloud1 - cv::Affine3f cloudPosition(angle_x, angle_y, angle_z, cv::Vec3f(pos_x, pos_y, pos_z)); - cv::Affine3f cloudPosition2(angle_x, angle_y, angle_z, cv::Vec3f(pos_x+0.2, pos_y+0.2, pos_z+0.2)); + cv::Affine3f cloudPosition(angle, pos); + cv::Affine3f cloudPosition2(angle, pos + Vec3f(0.2f, 0.2f, 0.2f)); - lw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + lw.setColor(color); // lw.setLineWidth(pos_x * 10); - //plw.setColor(temp_viz::Color(col_blue, col_green, col_red)); + //plw.setColor(viz::Color(col_blue, col_green, col_red)); sw.setPose(cloudPosition); // pw.setPose(cloudPosition); @@ -178,34 +163,35 @@ TEST(Viz_viz3d, accuracy) // v.setWidgetPose("n",cloudPosition); // v.setWidgetPose("pcw2", cloudPosition); - //cnw.setColor(temp_viz::Color(col_blue, col_green, col_red)); - //pcw2.setColor(temp_viz::Color(col_blue, col_green, col_red)); + //cnw.setColor(viz::Color(col_blue, col_green, col_red)); + //pcw2.setColor(viz::Color(col_blue, col_green, col_red)); - //gw.updatePose(temp_viz::Affine3f(0.0, 0.1, 0.0, cv::Vec3f(0.0,0.0,0.0))); + //gw.updatePose(viz::Affine3f(0.0, 0.1, 0.0, cv::Vec3f(0.0,0.0,0.0))); - angle_x += 0.1f; - angle_y -= 0.1f; - angle_z += 0.1f; - pos_x = std::sin(angle_x); - pos_y = std::sin(angle_y); - pos_z = std::sin(angle_z); - col_blue = int(angle_x * 10) % 256; - col_green = int(angle_x * 20) % 256; - col_red = int(angle_x * 30) % 256; + angle[0] += 0.1f; + angle[1] -= 0.1f; + angle[2] += 0.1f; + pos[0] = std::sin(angle[0]); + pos[1] = std::sin(angle[1]); + pos[2] = std::sin(angle[2]); - v.spinOnce(1, true); + color[0] = int(angle[0] * 10) % 256; + color[1] = int(angle[0] * 20) % 256; + color[2] = int(angle[0] * 30) % 256; + + viz.spinOnce(1, true); } // // -// temp_viz::ModelCoefficients mc; +// viz::ModelCoefficients mc; // mc.values.resize(4); // mc.values[0] = mc.values[1] = mc.values[2] = mc.values[3] = 1; // v.addPlane(mc); // // -// temp_viz::Mesh3d::Ptr mesh = temp_viz::mesh_load("horse.ply"); +// viz::Mesh3d::Ptr mesh = viz::mesh_load("horse.ply"); // v.addPolygonMesh(*mesh, "pq"); // // v.spinOnce(1000, true); @@ -229,7 +215,7 @@ TEST(Viz_viz3d, accuracy) // // colors.setTo(cv::Scalar(255, 0, 0)); // -// v.addSphere(cv::Point3f(0, 0, 0), 0.3, temp_viz::Color::blue()); +// v.addSphere(cv::Point3f(0, 0, 0), 0.3, viz::Color::blue()); // // cv::Mat cvpoly(1, 5, CV_32FC3); // cv::Point3f* pdata = cvpoly.ptr(); @@ -238,7 +224,7 @@ TEST(Viz_viz3d, accuracy) // pdata[2] = cv::Point3f(3, 1, 2); // pdata[3] = cv::Point3f(0, 2, 4); // pdata[4] = cv::Point3f(7, 2, 3); -// v.addPolygon(cvpoly, temp_viz::Color::white()); +// v.addPolygon(cvpoly, viz::Color::white()); // // // Updating cloud1 // v.showPointCloud("cloud1", cloud, colors); From d6e2b657f92a207dbf4809f9c24d12eb34cc0dbc Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 13 Jul 2013 19:08:25 +0400 Subject: [PATCH 082/205] more refactoring --- modules/viz/include/opencv2/viz.hpp | 23 ++ modules/viz/include/opencv2/viz/events.hpp | 113 ------- modules/viz/include/opencv2/viz/types.hpp | 103 +++--- modules/viz/include/opencv2/viz/viz3d.hpp | 34 +- modules/viz/src/cloud_widgets.cpp | 313 +++++++++++++++++ modules/viz/src/common.cpp | 13 +- modules/viz/src/interactor_style.cpp | 5 - modules/viz/src/interactor_style.h | 38 +-- modules/viz/src/precomp.hpp | 1 - .../{simple_widgets.cpp => shape_widgets.cpp} | 314 +----------------- modules/viz/src/types.cpp | 39 +++ modules/viz/src/viz3d.cpp | 73 +--- .../viz/src/{viz_main.cpp => viz3d_impl.cpp} | 37 +-- modules/viz/src/viz3d_impl.hpp | 38 +-- 14 files changed, 482 insertions(+), 662 deletions(-) delete mode 100644 modules/viz/include/opencv2/viz/events.hpp create mode 100644 modules/viz/src/cloud_widgets.cpp rename modules/viz/src/{simple_widgets.cpp => shape_widgets.cpp} (60%) rename modules/viz/src/{viz_main.cpp => viz3d_impl.cpp} (98%) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index f956d0ef8..b20ccaebc 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -60,7 +60,30 @@ namespace cv //! takes coordiante frame data and builds transfrom to global coordinate frame CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); + //! constructs camera pose from posiont, focal_point and up_vector (see gluLookAt() for more infromation CV_EXPORTS Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& up_vector); + + //! checks float value for Nan + inline bool isNan(float x) + { + unsigned int *u = reinterpret_cast(&x); + return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff); + } + + //! checks double value for Nan + inline bool isNan(double x) + { + unsigned int *u = reinterpret_cast(&x); + return (u[1] & 0x7ff00000) == 0x7ff00000 && (u[0] != 0 || (u[1] & 0x000fffff) != 0); + } + + //! checks vectors for Nans + template inline bool isNan(const Vec<_Tp, cn>& v) + { return isNan(v.val[0]) || isNan(v.val[1]) || isNan(v.val[2]); } + + //! checks point for Nans + template inline bool isNan(const Point3_<_Tp>& p) + { return isNan(p.x) || isNan(p.y) || isNan(p.z); } } } diff --git a/modules/viz/include/opencv2/viz/events.hpp b/modules/viz/include/opencv2/viz/events.hpp deleted file mode 100644 index aa1d950da..000000000 --- a/modules/viz/include/opencv2/viz/events.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include -#include - -namespace cv -{ - namespace viz - { - class KeyboardEvent - { - public: - static const unsigned int Alt = 1; - static const unsigned int Ctrl = 2; - static const unsigned int Shift = 4; - - /** \brief Constructor - * \param[in] action true for key was pressed, false for released - * \param[in] key_sym the key-name that caused the action - * \param[in] key the key code that caused the action - * \param[in] alt whether the alt key was pressed at the time where this event was triggered - * \param[in] ctrl whether the ctrl was pressed at the time where this event was triggered - * \param[in] shift whether the shift was pressed at the time where this event was triggered - */ - KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); - - bool isAltPressed () const; - bool isCtrlPressed () const; - bool isShiftPressed () const; - - unsigned char getKeyCode () const; - - const String& getKeySym () const; - bool keyDown () const; - bool keyUp () const; - - protected: - - bool action_; - unsigned int modifiers_; - unsigned char key_code_; - String key_sym_; - }; - - class MouseEvent - { - public: - enum Type - { - MouseMove = 1, - MouseButtonPress, - MouseButtonRelease, - MouseScrollDown, - MouseScrollUp, - MouseDblClick - } ; - - enum MouseButton - { - NoButton = 0, - LeftButton, - MiddleButton, - RightButton, - VScroll /*other buttons, scroll wheels etc. may follow*/ - } ; - - MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); - - - Type type; - MouseButton button; - Point pointer; - unsigned int key_state; - }; - } -} - -//////////////////////////////////////////////////////////////////// -/// Implementation - -inline cv::viz::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) - : action_ (_action), modifiers_ (0), key_code_(key), key_sym_ (_key_sym) -{ - if (alt) - modifiers_ = Alt; - - if (ctrl) - modifiers_ |= Ctrl; - - if (shift) - modifiers_ |= Shift; -} - -inline bool cv::viz::KeyboardEvent::isAltPressed () const { return (modifiers_ & Alt) != 0; } -inline bool cv::viz::KeyboardEvent::isCtrlPressed () const { return (modifiers_ & Ctrl) != 0; } -inline bool cv::viz::KeyboardEvent::isShiftPressed () const { return (modifiers_ & Shift) != 0; } -inline unsigned char cv::viz::KeyboardEvent::getKeyCode () const { return key_code_; } -inline const cv::String& cv::viz::KeyboardEvent::getKeySym () const { return key_sym_; } -inline bool cv::viz::KeyboardEvent::keyDown () const { return action_; } -inline bool cv::viz::KeyboardEvent::keyUp () const { return !action_; } - -inline cv::viz::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) - : type(_type), button(_button), pointer(_p), key_state(0) -{ - if (alt) - key_state = KeyboardEvent::Alt; - - if (ctrl) - key_state |= KeyboardEvent::Ctrl; - - if (shift) - key_state |= KeyboardEvent::Shift; -} diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index fd00a7a0a..357b46f25 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include @@ -8,35 +8,7 @@ namespace cv { typedef std::string String; -// //qt creator hack -// typedef cv::Scalar Scalar; -// typedef cv::Mat Mat; -// typedef std::string String; -// typedef cv::Vec3d Vec3d; -// typedef cv::Vec3f Vec3f; -// typedef cv::Vec4d Vec4d; -// typedef cv::Vec4f Vec4f; -// typedef cv::Vec2d Vec2d; -// typedef cv::Vec2i Vec2i; -// typedef cv::Vec3b Vec3b; -// typedef cv::Matx33d Matx33d; -// typedef cv::Affine3f Affine3f; -// typedef cv::Affine3d Affine3d; -// typedef cv::Point2i Point2i; -// typedef cv::Point3f Point3f; -// typedef cv::Point3d Point3d; -// typedef cv::Matx44d Matx44d; -// typedef cv::Matx44f Matx44f; -// typedef cv::Size Size; -// typedef cv::Point Point; -// typedef cv::InputArray InputArray; -// using cv::Point3_; -// using cv::Vec; -// using cv::Mat_; -// using cv::DataDepth; -// using cv::DataType; -// using cv::Ptr; namespace viz { class CV_EXPORTS Color : public Scalar @@ -79,35 +51,58 @@ namespace cv }; - ///////////////////////////////////////////////////////////////////////////// - /// Utility functions - - inline Color vtkcolor(const Color& color) + class CV_EXPORTS KeyboardEvent { - Color scaled_color = color * (1.0/255.0); - std::swap(scaled_color[0], scaled_color[2]); - return scaled_color; - } + public: + static const unsigned int Alt = 1; + static const unsigned int Ctrl = 2; + static const unsigned int Shift = 4; - inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } - template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } + /** \brief Constructor + * \param[in] action true for key was pressed, false for released + * \param[in] key_sym the key-name that caused the action + * \param[in] key the key code that caused the action + * \param[in] alt whether the alt key was pressed at the time where this event was triggered + * \param[in] ctrl whether the ctrl was pressed at the time where this event was triggered + * \param[in] shift whether the shift was pressed at the time where this event was triggered + */ + KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); - inline bool isNan(float x) + bool isAltPressed () const; + bool isCtrlPressed () const; + bool isShiftPressed () const; + + unsigned char getKeyCode () const; + + const String& getKeySym () const; + bool keyDown () const; + bool keyUp () const; + + protected: + + bool action_; + unsigned int modifiers_; + unsigned char key_code_; + String key_sym_; + }; + + class CV_EXPORTS MouseEvent { - unsigned int *u = reinterpret_cast(&x); - return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff); - } + public: + enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ; + enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ; + + MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); + + Type type; + MouseButton button; + Point pointer; + unsigned int key_state; + }; + + } /* namespace viz */ +} /* namespace cv */ + - inline bool isNan(double x) - { - unsigned int *u = reinterpret_cast(&x); - return (u[1] & 0x7ff00000) == 0x7ff00000 && (u[0] != 0 || (u[1] & 0x000fffff) != 0); - } - template inline bool isNan(const Vec<_Tp, cn>& v) - { return isNan(v.val[0]) || isNan(v.val[1]) || isNan(v.val[2]); } - template inline bool isNan(const Point3_<_Tp>& p) - { return isNan(p.x) || isNan(p.y) || isNan(p.z); } - } -} diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index a603c879a..db8819afd 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -4,14 +4,9 @@ //#error "Viz is in beta state now. Please define macro above to use it" #endif -#include #include - - -#include #include #include -#include namespace cv { @@ -20,28 +15,21 @@ namespace cv class CV_EXPORTS Viz3d { public: - typedef cv::Ptr Ptr; + typedef void (*KeyboardCallback)(const KeyboardEvent&, void*); + typedef void (*MouseCallback)(const MouseEvent&, void*); Viz3d(const String& window_name = String()); ~Viz3d(); void setBackgroundColor(const Color& color = Color::black()); - bool addPolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); - bool updatePolygonMesh (const Mesh3d& mesh, const String& id = "polygon"); - + //to refactor + bool addPolygonMesh(const Mesh3d& mesh, const String& id = "polygon"); + bool updatePolygonMesh(const Mesh3d& mesh, const String& id = "polygon"); bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - bool addPolygon(const Mat& cloud, const Color& color, const String& id = "polygon"); - void spin (); - void spinOnce (int time = 1, bool force_redraw = false); - - void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie = 0); - void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); - - bool wasStopped() const; void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); void removeWidget(const String &id); @@ -50,6 +38,13 @@ namespace cv void setWidgetPose(const String &id, const Affine3f &pose); void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; + + void spin(); + void spinOnce(int time = 1, bool force_redraw = false); + bool wasStopped() const; + + void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); + void registerMouseCallback(MouseCallback callback, void* cookie = 0); private: Viz3d(const Viz3d&); Viz3d& operator=(const Viz3d&); @@ -57,8 +52,9 @@ namespace cv struct VizImpl; VizImpl* impl_; }; - } -} + + } /* namespace viz */ +} /* namespace cv */ diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp new file mode 100644 index 000000000..6999813e8 --- /dev/null +++ b/modules/viz/src/cloud_widgets.cpp @@ -0,0 +1,313 @@ +#include "precomp.hpp" + + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Point Cloud Widget implementation + +struct cv::viz::CloudWidget::CreateCloudWidget +{ + static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) + { + vtkSmartPointer polydata = vtkSmartPointer::New (); + vtkSmartPointer vertices = vtkSmartPointer::New (); + + polydata->SetVerts (vertices); + + vtkSmartPointer points = polydata->GetPoints(); + vtkSmartPointer initcells; + nr_points = cloud.total(); + + if (!points) + { + points = vtkSmartPointer::New (); + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat(); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble(); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); + + if (cloud.depth() == CV_32F) + { + // Get a pointer to the beginning of the data array + Vec3f *data_beg = vtkpoints_data(points); + Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + else if (cloud.depth() == CV_64F) + { + // Get a pointer to the beginning of the data array + Vec3d *data_beg = vtkpoints_data(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + points->SetNumberOfPoints (nr_points); + + // Update cells + vtkSmartPointer cells = vertices->GetData (); + // If no init cells and cells has not been initialized... + if (!cells) + cells = vtkSmartPointer::New (); + + // If we have less values then we need to recreate the array + if (cells->GetNumberOfTuples () < nr_points) + { + cells = vtkSmartPointer::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::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); + } + + // Set the cells and the vertices + vertices->SetCells (nr_points, cells); + return polydata; + } +}; + +cv::viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) +{ + Mat cloud = _cloud.getMat(); + Mat colors = _colors.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); + + if (cloud.isContinuous() && colors.isContinuous()) + { + cloud.reshape(cloud.channels(), 1); + colors.reshape(colors.channels(), 1); + } + + vtkIdType nr_points; + vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + + // Filter colors + Vec3b* colors_data = new Vec3b[nr_points]; + NanFilter::copy(colors, colors_data, cloud); + + vtkSmartPointer scalars = vtkSmartPointer::New (); + scalars->SetNumberOfComponents (3); + scalars->SetNumberOfTuples (nr_points); + scalars->SetArray (colors_data->val, 3 * nr_points, 0); + + // Assign the colors + polydata->GetPointData ()->SetScalars (scalars); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (polydata); + + Vec3d minmax(scalars->GetRange()); + mapper->SetScalarRange(minmax.val); + mapper->SetScalarModeToUsePointData (); + + bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); + + mapper->SetInterpolateScalarsBeforeMapping (interpolation); + mapper->ScalarVisibilityOn (); + + mapper->ImmediateModeRenderingOff (); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); + actor->GetProperty ()->SetInterpolationToFlat (); + actor->GetProperty ()->BackfaceCullingOn (); + actor->SetMapper (mapper); + + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) +{ + Mat cloud = _cloud.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + + + vtkIdType nr_points; + vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (polydata); + + bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); + + mapper->SetInterpolateScalarsBeforeMapping (interpolation); + mapper->ScalarVisibilityOff (); + + mapper->ImmediateModeRenderingOff (); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); + actor->GetProperty ()->SetInterpolationToFlat (); + actor->GetProperty ()->BackfaceCullingOn (); + actor->SetMapper (mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::CloudWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Cloud Normals Widget implementation + +struct cv::viz::CloudNormalsWidget::ApplyCloudNormals +{ + template + struct Impl + { + static vtkSmartPointer applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals) + { + vtkIdType point_step = static_cast(std::sqrt(level)); + nr_normals = (static_cast ((cloud.cols - 1) / point_step) + 1) * + (static_cast ((cloud.rows - 1) / point_step) + 1); + vtkSmartPointer lines = vtkSmartPointer::New(); + + pts = new _Tp[2 * nr_normals * 3]; + + int cch = cloud.channels(); + vtkIdType cell_count = 0; + for (vtkIdType y = 0; y < cloud.rows; y += point_step) + { + const _Tp *prow = cloud.ptr<_Tp>(y); + const _Tp *nrow = normals.ptr<_Tp>(y); + for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch) + { + pts[2 * cell_count * 3 + 0] = prow[x]; + pts[2 * cell_count * 3 + 1] = prow[x+1]; + pts[2 * cell_count * 3 + 2] = prow[x+2]; + pts[2 * cell_count * 3 + 3] = prow[x] + nrow[x] * scale; + pts[2 * cell_count * 3 + 4] = prow[x+1] + nrow[x+1] * scale; + pts[2 * cell_count * 3 + 5] = prow[x+2] + nrow[x+2] * scale; + + lines->InsertNextCell (2); + lines->InsertCellPoint (2 * cell_count); + lines->InsertCellPoint (2 * cell_count + 1); + cell_count++; + } + } + return lines; + } + + static vtkSmartPointer applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + { + vtkSmartPointer lines = vtkSmartPointer::New(); + nr_normals = (cloud.size().area() - 1) / level + 1 ; + pts = new _Tp[2 * nr_normals * 3]; + + int cch = cloud.channels(); + const _Tp *p = cloud.ptr<_Tp>(); + const _Tp *n = normals.ptr<_Tp>(); + for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level * cch) + { + + pts[2 * j * 3 + 0] = p[i]; + pts[2 * j * 3 + 1] = p[i+1]; + pts[2 * j * 3 + 2] = p[i+2]; + pts[2 * j * 3 + 3] = p[i] + n[i] * scale; + pts[2 * j * 3 + 4] = p[i+1] + n[i+1] * scale; + pts[2 * j * 3 + 5] = p[i+2] + n[i+2] * scale; + + lines->InsertNextCell (2); + lines->InsertCellPoint (2 * j); + lines->InsertCellPoint (2 * j + 1); + } + return lines; + } + }; + + template + static inline vtkSmartPointer apply(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) + { + if (cloud.cols > 1 && cloud.rows > 1) + return ApplyCloudNormals::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals); + else + return ApplyCloudNormals::Impl<_Tp>::applyUnorganized(cloud, normals, level, scale, pts, nr_normals); + } +}; + +cv::viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color) +{ + Mat cloud = _cloud.getMat(); + Mat normals = _normals.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type()); + + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer lines = vtkSmartPointer::New(); + vtkIdType nr_normals = 0; + + if (cloud.depth() == CV_32F) + { + points->SetDataTypeToFloat(); + + vtkSmartPointer data = vtkSmartPointer::New (); + data->SetNumberOfComponents (3); + + float* pts = 0; + lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals); + data->SetArray (&pts[0], 2 * nr_normals * 3, 0); + points->SetData (data); + } + else + { + points->SetDataTypeToDouble(); + + vtkSmartPointer data = vtkSmartPointer::New (); + data->SetNumberOfComponents (3); + + double* pts = 0; + lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals); + data->SetArray (&pts[0], 2 * nr_normals * 3, 0); + points->SetData (data); + } + + vtkSmartPointer polyData = vtkSmartPointer::New(); + polyData->SetPoints (points); + polyData->SetLines (lines); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (polyData); + mapper->SetColorModeToMapScalars(); + mapper->SetScalarModeToUsePointData(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::CloudNormalsWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} diff --git a/modules/viz/src/common.cpp b/modules/viz/src/common.cpp index dc4e53e42..08da19b5d 100644 --- a/modules/viz/src/common.cpp +++ b/modules/viz/src/common.cpp @@ -1,20 +1,9 @@ #include #include #include +#include "viz3d_impl.hpp" -///////////////////////////////////////////////////////////////////////////////////////////// - -//Eigen::Matrix4d cv::viz::vtkToEigen (vtkMatrix4x4* vtk_matrix) -//{ -// Eigen::Matrix4d eigen_matrix = Eigen::Matrix4d::Identity (); -// for (int i=0; i < 4; i++) -// for (int j=0; j < 4; j++) -// eigen_matrix (i, j) = vtk_matrix->GetElement (i, j); - -// return eigen_matrix; -//} - /////////////////////////////////////////////////////////////////////////////////////////////// //Eigen::Vector2i cv::viz::worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height) //{ diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 6c2942c04..2daec8126 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -222,7 +222,6 @@ cv::viz::InteractorStyle::OnKeyDown () " ALT + s, S : turn stereo mode on/off\n" " ALT + f, F : switch between maximized window mode and original size\n" "\n" - " SHIFT + left click : select a point\n" << std::endl; break; } @@ -676,9 +675,6 @@ void cv::viz::InteractorStyle::OnTimer () } - - - namespace cv { namespace viz @@ -687,4 +683,3 @@ namespace cv vtkStandardNewMacro(InteractorStyle) } } - diff --git a/modules/viz/src/interactor_style.h b/modules/viz/src/interactor_style.h index 04ccb68fb..db20a1ad9 100644 --- a/modules/viz/src/interactor_style.h +++ b/modules/viz/src/interactor_style.h @@ -1,15 +1,14 @@ #pragma once #include "viz_types.h" -#include +#include namespace cv { namespace viz { - /** \brief PCLVisualizerInteractorStyle defines an unique, custom VTK - * based interactory style for PCL Visualizer applications. Besides - * defining the rendering style, we also create a list of custom actions + /** \brief InteractorStyle defines an unique, custom VTK based interactory style Viz applications. + * Besides defining the rendering style, we also create a list of custom actions * that are triggered on different keys being pressed: * * - p, P : switch to a point-based representation @@ -28,7 +27,6 @@ namespace cv * - SHIFT + left click : select a point * * \author Radu B. Rusu - * \ingroup visualization */ class InteractorStyle : public vtkInteractorStyleTrackballCamera { @@ -43,41 +41,19 @@ namespace cv static InteractorStyle *New (); - InteractorStyle () {} virtual ~InteractorStyle () {} // this macro defines Superclass, the isA functionality and the safe downcast method - vtkTypeMacro (InteractorStyle, vtkInteractorStyleTrackballCamera); + vtkTypeMacro (InteractorStyle, vtkInteractorStyleTrackballCamera) /** \brief Initialization routine. Must be called before anything else. */ virtual void Initialize (); - /** \brief Pass a pointer to the actor map - * \param[in] actors the actor map that will be used with this style - */ inline void setCloudActorMap (const Ptr& actors) { actors_ = actors; } - - /** \brief Pass a set of renderers to the interactor style. - * \param[in] rens the vtkRendererCollection to use - */ void setRenderer (vtkSmartPointer& ren) { renderer_ = ren; } - - /** \brief Register a callback function for mouse events - * \param[in] ccallback function that will be registered as a callback for a mouse event - * \param[in] cookie for passing user data to callback - */ void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); - - /** \brief Register a callback function for keyboard events - * \param[in] callback a function that will be registered as a callback for a keyboard event - * \param[in] cookie user data passed to the callback function - */ void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0); - - /** \brief Save the current rendered image to disk, as a PNG screenshot. - * \param[in] file the name of the PNG file - */ void saveScreenshot (const std::string &file); /** \brief Change the default keyboard modified from ALT to a different special key. @@ -134,24 +110,18 @@ namespace cv /** \brief Interactor style internal method. Gets called periodically if a timer is set. */ virtual void OnTimer (); - void zoomIn (); void zoomOut (); /** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */ bool stereo_anaglyph_mask_default_; - /** \brief The keyboard modifier to use. Default: Alt. */ KeyboardModifier modifier_; - /** \brief KeyboardEvent callback function pointer*/ void (*keyboardCallback_)(const KeyboardEvent&, void*); - /** \brief KeyboardEvent callback user data*/ void *keyboard_callback_cookie_; - /** \brief MouseEvent callback function pointer */ void (*mouseCallback_)(const MouseEvent&, void*); - /** \brief MouseEvent callback user data */ void *mouse_callback_cookie_; }; } diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index d6976f779..bff8cedc8 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -156,7 +156,6 @@ #include #include #include "opencv2/viz/widget_accessor.hpp" -#include namespace cv { diff --git a/modules/viz/src/simple_widgets.cpp b/modules/viz/src/shape_widgets.cpp similarity index 60% rename from modules/viz/src/simple_widgets.cpp rename to modules/viz/src/shape_widgets.cpp index 28d4a9edc..d0e1d7c3a 100644 --- a/modules/viz/src/simple_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -423,6 +423,7 @@ cv::viz::GridWidget::GridWidget(Vec2i dimensions, Vec2d spacing, const Color &co // Show it as wireframe actor->GetProperty ()->SetRepresentationToWireframe (); WidgetAccessor::setProp(*this, actor); + setColor(color); } template<> cv::viz::GridWidget cv::viz::Widget::cast() @@ -524,316 +525,3 @@ cv::String cv::viz::TextWidget::getText() const CV_Assert(actor); return actor->GetInput(); } - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// point cloud widget implementation - -struct cv::viz::CloudWidget::CreateCloudWidget -{ - static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) - { - vtkSmartPointer polydata = vtkSmartPointer::New (); - vtkSmartPointer vertices = vtkSmartPointer::New (); - - polydata->SetVerts (vertices); - - vtkSmartPointer points = polydata->GetPoints(); - vtkSmartPointer initcells; - nr_points = cloud.total(); - - if (!points) - { - points = vtkSmartPointer::New (); - if (cloud.depth() == CV_32F) - points->SetDataTypeToFloat(); - else if (cloud.depth() == CV_64F) - points->SetDataTypeToDouble(); - polydata->SetPoints (points); - } - points->SetNumberOfPoints (nr_points); - - if (cloud.depth() == CV_32F) - { - // Get a pointer to the beginning of the data array - Vec3f *data_beg = vtkpoints_data(points); - Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); - nr_points = data_end - data_beg; - } - else if (cloud.depth() == CV_64F) - { - // Get a pointer to the beginning of the data array - Vec3d *data_beg = vtkpoints_data(points); - Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); - nr_points = data_end - data_beg; - } - points->SetNumberOfPoints (nr_points); - - // Update cells - vtkSmartPointer cells = vertices->GetData (); - // If no init cells and cells has not been initialized... - if (!cells) - cells = vtkSmartPointer::New (); - - // If we have less values then we need to recreate the array - if (cells->GetNumberOfTuples () < nr_points) - { - cells = vtkSmartPointer::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::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); - } - - // Set the cells and the vertices - vertices->SetCells (nr_points, cells); - return polydata; - } -}; - -cv::viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) -{ - Mat cloud = _cloud.getMat(); - Mat colors = _colors.getMat(); - CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); - CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); - - if (cloud.isContinuous() && colors.isContinuous()) - { - cloud.reshape(cloud.channels(), 1); - colors.reshape(colors.channels(), 1); - } - - vtkIdType nr_points; - vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); - - // Filter colors - Vec3b* colors_data = new Vec3b[nr_points]; - NanFilter::copy(colors, colors_data, cloud); - - vtkSmartPointer scalars = vtkSmartPointer::New (); - scalars->SetNumberOfComponents (3); - scalars->SetNumberOfTuples (nr_points); - scalars->SetArray (colors_data->val, 3 * nr_points, 0); - - // Assign the colors - polydata->GetPointData ()->SetScalars (scalars); - - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (polydata); - - Vec3d minmax(scalars->GetRange()); - mapper->SetScalarRange(minmax.val); - mapper->SetScalarModeToUsePointData (); - - bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); - - mapper->SetInterpolateScalarsBeforeMapping (interpolation); - mapper->ScalarVisibilityOn (); - - mapper->ImmediateModeRenderingOff (); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); - actor->GetProperty ()->SetInterpolationToFlat (); - actor->GetProperty ()->BackfaceCullingOn (); - actor->SetMapper (mapper); - - WidgetAccessor::setProp(*this, actor); -} - -cv::viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) -{ - Mat cloud = _cloud.getMat(); - CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); - - - vtkIdType nr_points; - vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); - - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (polydata); - - bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); - - mapper->SetInterpolateScalarsBeforeMapping (interpolation); - mapper->ScalarVisibilityOff (); - - mapper->ImmediateModeRenderingOff (); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); - actor->GetProperty ()->SetInterpolationToFlat (); - actor->GetProperty ()->BackfaceCullingOn (); - actor->SetMapper (mapper); - - WidgetAccessor::setProp(*this, actor); - setColor(color); -} - -template<> cv::viz::CloudWidget cv::viz::Widget::cast() -{ - Widget3D widget = this->cast(); - return static_cast(widget); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// cloud normals widget implementation - -struct cv::viz::CloudNormalsWidget::ApplyCloudNormals -{ - template - struct Impl - { - static vtkSmartPointer applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals) - { - vtkIdType point_step = static_cast(std::sqrt(level)); - nr_normals = (static_cast ((cloud.cols - 1) / point_step) + 1) * - (static_cast ((cloud.rows - 1) / point_step) + 1); - vtkSmartPointer lines = vtkSmartPointer::New(); - - pts = new _Tp[2 * nr_normals * 3]; - - int cch = cloud.channels(); - vtkIdType cell_count = 0; - for (vtkIdType y = 0; y < cloud.rows; y += point_step) - { - const _Tp *prow = cloud.ptr<_Tp>(y); - const _Tp *nrow = normals.ptr<_Tp>(y); - for (vtkIdType x = 0; x < cloud.cols; x += point_step * cch) - { - pts[2 * cell_count * 3 + 0] = prow[x]; - pts[2 * cell_count * 3 + 1] = prow[x+1]; - pts[2 * cell_count * 3 + 2] = prow[x+2]; - pts[2 * cell_count * 3 + 3] = prow[x] + nrow[x] * scale; - pts[2 * cell_count * 3 + 4] = prow[x+1] + nrow[x+1] * scale; - pts[2 * cell_count * 3 + 5] = prow[x+2] + nrow[x+2] * scale; - - lines->InsertNextCell (2); - lines->InsertCellPoint (2 * cell_count); - lines->InsertCellPoint (2 * cell_count + 1); - cell_count++; - } - } - return lines; - } - - static vtkSmartPointer applyUnorganized(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) - { - vtkSmartPointer lines = vtkSmartPointer::New(); - nr_normals = (cloud.size().area() - 1) / level + 1 ; - pts = new _Tp[2 * nr_normals * 3]; - - int cch = cloud.channels(); - const _Tp *p = cloud.ptr<_Tp>(); - const _Tp *n = normals.ptr<_Tp>(); - for (vtkIdType i = 0, j = 0; j < nr_normals; j++, i = j * level * cch) - { - - pts[2 * j * 3 + 0] = p[i]; - pts[2 * j * 3 + 1] = p[i+1]; - pts[2 * j * 3 + 2] = p[i+2]; - pts[2 * j * 3 + 3] = p[i] + n[i] * scale; - pts[2 * j * 3 + 4] = p[i+1] + n[i+1] * scale; - pts[2 * j * 3 + 5] = p[i+2] + n[i+2] * scale; - - lines->InsertNextCell (2); - lines->InsertCellPoint (2 * j); - lines->InsertCellPoint (2 * j + 1); - } - return lines; - } - }; - - template - static inline vtkSmartPointer apply(const Mat &cloud, const Mat& normals, int level, float scale, _Tp *&pts, vtkIdType &nr_normals) - { - if (cloud.cols > 1 && cloud.rows > 1) - return ApplyCloudNormals::Impl<_Tp>::applyOrganized(cloud, normals, level, scale, pts, nr_normals); - else - return ApplyCloudNormals::Impl<_Tp>::applyUnorganized(cloud, normals, level, scale, pts, nr_normals); - } -}; - -cv::viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color) -{ - Mat cloud = _cloud.getMat(); - Mat normals = _normals.getMat(); - CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); - CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type()); - - vtkSmartPointer points = vtkSmartPointer::New(); - vtkSmartPointer lines = vtkSmartPointer::New(); - vtkIdType nr_normals = 0; - - if (cloud.depth() == CV_32F) - { - points->SetDataTypeToFloat(); - - vtkSmartPointer data = vtkSmartPointer::New (); - data->SetNumberOfComponents (3); - - float* pts = 0; - lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals); - data->SetArray (&pts[0], 2 * nr_normals * 3, 0); - points->SetData (data); - } - else - { - points->SetDataTypeToDouble(); - - vtkSmartPointer data = vtkSmartPointer::New (); - data->SetNumberOfComponents (3); - - double* pts = 0; - lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals); - data->SetArray (&pts[0], 2 * nr_normals * 3, 0); - points->SetData (data); - } - - vtkSmartPointer polyData = vtkSmartPointer::New(); - polyData->SetPoints (points); - polyData->SetLines (lines); - - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (polyData); - mapper->SetColorModeToMapScalars(); - mapper->SetScalarModeToUsePointData(); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(mapper); - WidgetAccessor::setProp(*this, actor); - setColor(color); -} - -template<> cv::viz::CloudNormalsWidget cv::viz::Widget::cast() -{ - Widget3D widget = this->cast(); - return static_cast(widget); -} - - diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 38a284cb0..fb277963a 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -20,3 +20,42 @@ cv::viz::Color cv::viz::Color::white() { return Color(255, 255, 255); } cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); } +//////////////////////////////////////////////////////////////////// +/// cv::viz::KeyboardEvent + +cv::viz::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) + : action_ (_action), modifiers_ (0), key_code_(key), key_sym_ (_key_sym) +{ + if (alt) + modifiers_ = Alt; + + if (ctrl) + modifiers_ |= Ctrl; + + if (shift) + modifiers_ |= Shift; +} + +bool cv::viz::KeyboardEvent::isAltPressed () const { return (modifiers_ & Alt) != 0; } +bool cv::viz::KeyboardEvent::isCtrlPressed () const { return (modifiers_ & Ctrl) != 0; } +bool cv::viz::KeyboardEvent::isShiftPressed () const { return (modifiers_ & Shift) != 0; } +unsigned char cv::viz::KeyboardEvent::getKeyCode () const { return key_code_; } +const cv::String& cv::viz::KeyboardEvent::getKeySym () const { return key_sym_; } +bool cv::viz::KeyboardEvent::keyDown () const { return action_; } +bool cv::viz::KeyboardEvent::keyUp () const { return !action_; } + +//////////////////////////////////////////////////////////////////// +/// cv::viz::MouseEvent + +cv::viz::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) + : type(_type), button(_button), pointer(_p), key_state(0) +{ + if (alt) + key_state = KeyboardEvent::Alt; + + if (ctrl) + key_state |= KeyboardEvent::Ctrl; + + if (shift) + key_state |= KeyboardEvent::Shift; +} diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 530762187..f4a300b21 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -2,20 +2,10 @@ #include "viz3d_impl.hpp" -cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_name)) -{ +cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_name)) {} +cv::viz::Viz3d::~Viz3d() { delete impl_; } -} - -cv::viz::Viz3d::~Viz3d() -{ - delete impl_; -} - -void cv::viz::Viz3d::setBackgroundColor(const Color& color) -{ - impl_->setBackgroundColor(color); -} +void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } bool cv::viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String& id) { @@ -37,54 +27,21 @@ bool cv::viz::Viz3d::addPolygon(const Mat& cloud, const Color& color, const Stri return impl_->addPolygon(cloud, color, id); } -void cv::viz::Viz3d::spin() -{ - impl_->spin(); -} - -void cv::viz::Viz3d::spinOnce (int time, bool force_redraw) -{ - impl_->spinOnce(time, force_redraw); -} - -void cv::viz::Viz3d::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) -{ - impl_->registerKeyboardCallback(callback, cookie); -} - -void cv::viz::Viz3d::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) -{ - impl_->registerMouseCallback(callback, cookie); -} - +void cv::viz::Viz3d::spin() { impl_->spin(); } +void cv::viz::Viz3d::spinOnce (int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); } bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } -void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) -{ - impl_->showWidget(id, widget, pose); -} +void cv::viz::Viz3d::registerKeyboardCallback(KeyboardCallback callback, void* cookie) +{ impl_->registerKeyboardCallback(callback, cookie); } -void cv::viz::Viz3d::removeWidget(const String &id) -{ - impl_->removeWidget(id); -} +void cv::viz::Viz3d::registerMouseCallback(MouseCallback callback, void* cookie) +{ impl_->registerMouseCallback(callback, cookie); } -cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const -{ - return impl_->getWidget(id); -} -void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) -{ - impl_->setWidgetPose(id, pose); -} -void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) -{ - impl_->updateWidgetPose(id, pose); -} - -cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const -{ - return impl_->getWidgetPose(id); -} +void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { impl_->showWidget(id, widget, pose); } +void cv::viz::Viz3d::removeWidget(const String &id) { impl_->removeWidget(id); } +cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_->getWidget(id); } +void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { impl_->setWidgetPose(id, pose); } +void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } +cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } diff --git a/modules/viz/src/viz_main.cpp b/modules/viz/src/viz3d_impl.cpp similarity index 98% rename from modules/viz/src/viz_main.cpp rename to modules/viz/src/viz3d_impl.cpp index 1a8be1dd9..eab528224 100644 --- a/modules/viz/src/viz_main.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1,6 +1,4 @@ #include "precomp.hpp" - -#include #include "viz3d_impl.hpp" #include @@ -95,16 +93,11 @@ cv::viz::Viz3d::VizImpl::~VizImpl () void cv::viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) -{ - style_->registerMouseCallback(callback, cookie); -} +void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void* cookie) +{ style_->registerMouseCallback(callback, cookie); } -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie) -{ - style_->registerKeyboardCallback(callback, cookie); -} +void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(KeyboardCallback callback, void* cookie) +{ style_->registerKeyboardCallback(callback, cookie); } ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::spin () @@ -1018,13 +1011,6 @@ void cv::viz::convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Qu vtk_matrix->SetElement (3, 3, 1.0f); } -void cv::viz::convertToVtkMatrix (const Matx44f &m, vtkSmartPointer &vtk_matrix) -{ - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - vtk_matrix->SetElement (i, k, m (i, k)); -} - vtkSmartPointer cv::viz::convertToVtkMatrix (const cv::Matx44f &m) { vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); @@ -1034,14 +1020,6 @@ vtkSmartPointer cv::viz::convertToVtkMatrix (const cv::Matx44f &m) return vtk_matrix; } -void cv::viz::convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m) -{ - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - m(i,k) = vtk_matrix->GetElement (i, k); -} - - cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer& vtk_matrix) { cv::Matx44f m; @@ -1052,13 +1030,6 @@ cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer& vtk_matr } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m) -{ - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - m (i,k) = static_cast (vtk_matrix->GetElement (i, k)); -} - void cv::viz::Viz3d::VizImpl::setFullScreen (bool mode) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 4578a65d4..3f86a8643 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -1,28 +1,25 @@ #pragma once -#include -#include +#include #include "interactor_style.h" #include "viz_types.h" #include "common.h" -#include -#include -#include - struct cv::viz::Viz3d::VizImpl { public: typedef cv::Ptr Ptr; + typedef Viz3d::KeyboardCallback KeyboardCallback; + typedef Viz3d::MouseCallback MouseCallback; - VizImpl (const String &name = String()); + VizImpl (const String &name); virtual ~VizImpl (); void setFullScreen (bool mode); void setWindowName (const String &name); - void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void* cookie = 0); - void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); + void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); + void registerMouseCallback(MouseCallback callback, void* cookie = 0); void spin (); void spinOnce (int time = 1, bool force_redraw = false); @@ -173,9 +170,7 @@ public: void setWidgetPose(const String &id, const Affine3f &pose); void updateWidgetPose(const String &id, const Affine3f &pose); - Affine3f getWidgetPose(const String &id) const; - - void all_data(); + Affine3f getWidgetPose(const String &id) const; private: vtkSmartPointer interactor_; @@ -285,12 +280,6 @@ namespace cv namespace viz { //void getTransformationMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternionf& orientation, Eigen::Matrix4f &transformation); - - //void convertToVtkMatrix (const Eigen::Matrix4f &m, vtkSmartPointer &vtk_matrix); - - void convertToVtkMatrix (const cv::Matx44f& m, vtkSmartPointer &vtk_matrix); - void convertToCvMatrix (const vtkSmartPointer &vtk_matrix, cv::Matx44f &m); - vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m); cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix); @@ -300,8 +289,6 @@ namespace cv * \param[out] vtk_matrix the resultant VTK 4x4 matrix */ void convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix); - void convertToEigenMatrix (const vtkSmartPointer &vtk_matrix, Eigen::Matrix4f &m); - struct NanFilter { @@ -366,6 +353,17 @@ namespace cv ApplyAffine(const ApplyAffine&); ApplyAffine& operator=(const ApplyAffine&); }; + + + inline Color vtkcolor(const Color& color) + { + Color scaled_color = color * (1.0/255.0); + std::swap(scaled_color[0], scaled_color[2]); + return scaled_color; + } + + inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } + template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } } } From 6ca1822f36910e95b184ff94b32af581b7bf812b Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 13 Jul 2013 20:02:31 +0400 Subject: [PATCH 083/205] added comments with future work for VizImpl added authors to license header --- modules/viz/CMakeLists.txt | 39 ++--- modules/viz/include/opencv2/viz.hpp | 12 +- modules/viz/include/opencv2/viz/types.hpp | 1 - modules/viz/src/viz.cpp | 19 +++ modules/viz/src/viz3d_impl.cpp | 45 +----- modules/viz/src/viz3d_impl.hpp | 172 ++++++++++++---------- 6 files changed, 148 insertions(+), 140 deletions(-) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index b45060371..9310b2443 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -1,3 +1,6 @@ +set(BUILD_opencv_viz_INIT OFF) + + ############################################################################### # Find qvtk # This sets the following variables: @@ -36,20 +39,23 @@ macro(find_vtk) endif() endmacro() + + + +#find_package(OpenGL) +#if (OPENGL_FOUND) +# if(OPENGL_INCLUDE_DIR) +# include_directories("${OPENGL_INCLUDE_DIR}") +# endif() +# if(OPENGL_DEFINITIONS) +# add_definitions("${OPENGL_DEFINITIONS}") +# endif() +#endif() + + find_vtk() -find_package(OpenGL) -if (OPENGL_FOUND) - if(OPENGL_INCLUDE_DIR) - include_directories("${OPENGL_INCLUDE_DIR}") - endif() - if(OPENGL_DEFINITIONS) - add_definitions("${OPENGL_DEFINITIONS}") - endif() -endif() - - if(NOT HAVE_VTK) set(DEFAULT FALSE) set(REASON "VTK was not found.") @@ -65,14 +71,13 @@ endif() add_definitions(-DHAVE_VTK) -set(BUILD_opencv_viz_INIT OFF) - -include_directories(src) set(the_description "Viz") -ocv_define_module(viz opencv_core opencv_calib3d) -#${PCL_LIBRARIES} +set(BUILD_opencv_viz_INIT OFF) +include_directories(src) +ocv_define_module(viz opencv_core) -target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkHybrid vtkCharts vtkFiltering vtkRendering ${OPENGL_LIBRARIES}) +target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkFiltering vtkRendering) +#${OPENGL_LIBRARIES}) if(APPLE) target_link_libraries(opencv_viz "-framework Cocoa") diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index b20ccaebc..5f1b7766f 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -38,9 +38,12 @@ // 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. // -// * Point Cloud Library (PCL) - www.pointclouds.org -// During implementation if OpenCV Viz module, similar module -// from PCL was used as reference implementation. +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// * Ozan Tonkal +// +// During implementation of OpenCV Viz module, similar module +// from PCL (www.pointclouds.org) was used as reference implementation. // //M*/ @@ -60,9 +63,10 @@ namespace cv //! takes coordiante frame data and builds transfrom to global coordinate frame CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); - //! constructs camera pose from posiont, focal_point and up_vector (see gluLookAt() for more infromation + //! 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& up_vector); + //! checks float value for Nan inline bool isNan(float x) { diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 357b46f25..50f1f1b0e 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index c2461d0b5..923aa51ef 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -18,3 +18,22 @@ cv::Affine3f cv::viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& ax return Affine3f(R, origin); } + + +vtkSmartPointer cv::viz::convertToVtkMatrix (const cv::Matx44f &m) +{ + vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + vtk_matrix->SetElement(i, k, m(i, k)); + return vtk_matrix; +} + +cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer& vtk_matrix) +{ + cv::Matx44f m; + for (int i = 0; i < 4; i++) + for (int k = 0; k < 4; k++) + m(i, k) = vtk_matrix->GetElement (i, k); + return m; +} diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index eab528224..d7b9fcd40 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -626,11 +626,9 @@ void cv::viz::Viz3d::VizImpl::resetCamera () renderer_->ResetCamera (); } - ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up) { - vtkSmartPointer cam = renderer_->GetActiveCamera (); cam->SetPosition (pos[0], pos[1], pos[2]); cam->SetFocalPoint (view[0], view[1], view[2]); @@ -642,13 +640,10 @@ void cv::viz::Viz3d::VizImpl::setCameraPosition (const cv::Vec3d& pos, const cv: void cv::viz::Viz3d::VizImpl::setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z) { //rens_->InitTraversal (); - - vtkSmartPointer cam = renderer_->GetActiveCamera (); cam->SetPosition (pos_x, pos_y, pos_z); cam->SetViewUp (up_x, up_y, up_z); renderer_->Render (); - } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -980,20 +975,13 @@ void cv::viz::Viz3d::VizImpl::updateCells (vtkSmartPointer &cell ////////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) -{ - polydata = vtkSmartPointer::New (); -} -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) -{ - polydata = vtkSmartPointer::New (); -} -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) -{ - polydata = vtkSmartPointer::New (); -} +{polydata = vtkSmartPointer::New (); } +void cv::viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) +{ polydata = vtkSmartPointer::New (); } + +void cv::viz::Viz3d::VizImpl::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) +{ polydata = vtkSmartPointer::New (); } ////////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix) @@ -1011,23 +999,6 @@ void cv::viz::convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Qu vtk_matrix->SetElement (3, 3, 1.0f); } -vtkSmartPointer cv::viz::convertToVtkMatrix (const cv::Matx44f &m) -{ - vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - vtk_matrix->SetElement(i, k, m(i, k)); - return vtk_matrix; -} - -cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer& vtk_matrix) -{ - cv::Matx44f m; - for (int i = 0; i < 4; i++) - for (int k = 0; k < 4; k++) - m(i, k) = vtk_matrix->GetElement (i, k); - return m; -} ////////////////////////////////////////////////////////////////////////////////////////////// @@ -1043,8 +1014,8 @@ void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) window_->SetWindowName (name.c_str ()); } -void cv::viz::Viz3d::VizImpl::setPosition (int x, int y) { window_->SetPosition (x, y); } -void cv::viz::Viz3d::VizImpl::setSize (int xw, int yw) { window_->SetSize (xw, yw); } +void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPosition (x, y); } +void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } bool cv::viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 3f86a8643..f3f245c93 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -13,47 +13,50 @@ public: typedef Viz3d::MouseCallback MouseCallback; VizImpl (const String &name); - virtual ~VizImpl (); - void setFullScreen (bool mode); - void setWindowName (const String &name); - - void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); - void registerMouseCallback(MouseCallback callback, void* cookie = 0); - void spin (); - void spinOnce (int time = 1, bool force_redraw = false); + + + + + + + + //to refactor bool removePointCloud (const String& id = "cloud"); - inline bool removePolygonMesh (const String& id = "polygon") - { - // Polygon Meshes are represented internally as point clouds with special cell array structures since 1.4 - return removePointCloud (id); - } + inline bool removePolygonMesh (const String& id = "polygon") { return removePointCloud (id); } bool removeShape (const String& id = "cloud"); - bool removeText3D (const String& id = "cloud"); bool removeAllPointClouds (); + + //create Viz3d::removeAllWidgets() bool removeAllShapes (); - void setBackgroundColor (const Color& color); - + //to refactor bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); - bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); + // to refactor: Widget3D:: & Viz3d:: bool setPointCloudRenderingProperties (int property, double value, const String& id = "cloud"); bool getPointCloudRenderingProperties (int property, double &value, const String& id = "cloud"); - bool setShapeRenderingProperties (int property, double value, const String& id); /** \brief Set whether the point cloud is selected or not * \param[in] selected whether the cloud is selected or not (true = selected) * \param[in] id the point cloud object id (default: cloud) */ + // probably should just remove bool setPointCloudSelected (const bool selected, const String& id = "cloud" ); + + + + + + + /** \brief Returns true when the user tried to close the window */ bool wasStopped () const { if (interactor_ != NULL) return (stopped_); else return true; } @@ -64,106 +67,113 @@ public: void close () { stopped_ = true; - // This tends to close the window... - interactor_->TerminateApp (); + interactor_->TerminateApp (); // This tends to close the window... } + + + + + + + + + + + // to refactor bool addPolygon(const cv::Mat& cloud, const Color& color, const String& id = "polygon"); bool addArrow (const Point3f& pt1, const Point3f& pt2, const Color& color, bool display_length, const String& id = "arrow"); bool addArrow (const Point3f& pt1, const Point3f& pt2, const Color& color_line, const Color& color_text, const String& id = "arrow"); - // Add a vtkPolydata as a mesh + // Probably remove this bool addModelFromPolyData (vtkSmartPointer polydata, const String& id = "PolyData"); bool addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const String& id = "PolyData"); + + // I think this should be moved to 'static Widget Widget::fromPlyFile(const String&)'; bool addModelFromPLYFile (const String &filename, const String& id = "PLYModel"); bool addModelFromPLYFile (const String &filename, vtkSmartPointer transform, const String& id = "PLYModel"); - /** \brief Changes the visual representation for all actors to surface representation. */ - void setRepresentationToSurfaceForAllActors (); - /** \brief Changes the visual representation for all actors to points representation. */ - void setRepresentationToPointsForAllActors (); + // to implement in Viz3d with shorter name + void setRepresentationToSurfaceForAllActors(); + void setRepresentationToPointsForAllActors(); + void setRepresentationToWireframeForAllActors(); - /** \brief Changes the visual representation for all actors to wireframe representation. */ - void setRepresentationToWireframeForAllActors (); - /** \brief Initialize camera parameters with some default values. */ - void initCameraParameters (); - /** \brief Search for camera parameters at the command line and set them internally. - bool getCameraParameters (int argc, char **argv); - /** \brief Checks whether the camera parameters were manually loaded from file.*/ - bool cameraParamsSet () const; - /** \brief Update camera parameters and render. */ - void updateCamera (); - /** \brief Reset camera parameters and render. */ - void resetCamera (); + + + // //////////////////////////////////////////////////////////////////////////////////// + // All camera methods to refactor into set/getViewwerPose, setCamera() + // and 'Camera' class itself with various constructors/fields + + void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ + bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ + void updateCamera (); /** \brief Update camera parameters and render. */ + void resetCamera (); /** \brief Reset camera parameters and render. */ /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset. - * \param[in] id the point cloud object id (default: cloud) - */ + * \param[in] id the point cloud object id (default: cloud) */ void resetCameraViewpoint (const String& id = "cloud"); - /** \brief Set the camera pose given by position, viewpoint and up vector - * \param[in] pos_x the x coordinate of the camera location - * \param[in] pos_y the y coordinate of the camera location - * \param[in] pos_z the z coordinate of the camera location - * \param[in] view_x the x component of the view point of the camera - * \param[in] view_y the y component of the view point of the camera - * \param[in] view_z the z component of the view point of the camera - * \param[in] up_x the x component of the view up direction of the camera - * \param[in] up_y the y component of the view up direction of the camera - * \param[in] up_z the y component of the view up direction of the camera - */ + * \param[in] pos camera location + * \param[in] view the view point of the camera + * \param[in] up the view up direction of the camera */ void setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up); /** \brief Set the camera location and viewup according to the given arguments - * \param[in] pos_x the x coordinate of the camera location - * \param[in] pos_y the y coordinate of the camera location - * \param[in] pos_z the z coordinate of the camera location - * \param[in] up_x the x component of the view up direction of the camera - * \param[in] up_y the y component of the view up direction of the camera - * \param[in] up_z the z component of the view up direction of the camera - */ + * \param[in] pos_x,y,z the x,y,z coordinate of the camera location + * \param[in] up_x,y,z the x,y,z component of the view up direction of the camera */ void setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z); /** \brief Set the camera parameters via an intrinsics and and extrinsics matrix - * \note This assumes that the pixels are square and that the center of the image is at the center of the sensor. - * \param[in] intrinsics the intrinsics that will be used to compute the VTK camera parameters - * \param[in] extrinsics the extrinsics that will be used to compute the VTK camera parameters - */ + * \note This assumes that the pixels are square and that the center of the image is at the center of the sensor. + * \param[in] intrinsics the intrinsics that will be used to compute the VTK camera parameters + * \param[in] extrinsics the extrinsics that will be used to compute the VTK camera parameters */ void setCameraParameters (const cv::Matx33f& intrinsics, const Affine3f& extrinsics); - - /** \brief Set the camera parameters by given a full camera data structure. - * \param[in] camera camera structure containing all the camera parameters. - */ void setCameraParameters (const Camera &camera); - - /** \brief Set the camera clipping distances. - * \param[in] near the near clipping distance (no objects closer than this to the camera will be drawn) - * \param[in] far the far clipping distance (no objects further away than this to the camera will be drawn) - */ void setCameraClipDistances (double near, double far); - - /** \brief Set the camera vertical field of view in radians */ void setCameraFieldOfView (double fovy); - - /** \brief Get the current camera parameters. */ void getCameras (Camera& camera); - /** \brief Get the current viewing pose. */ - Affine3f getViewerPose (); + //to implement Viz3d set/getViewerPose() + Affine3f getViewerPose(); + + + + + + + + + + + + //to implemnt in Viz3d void saveScreenshot (const String &file); + void setWindowPosition (int x, int y); + void setWindowSize (int xw, int yw); + void setFullScreen (bool mode); + void setWindowName (const String &name); + void setBackgroundColor (const Color& color); - /** \brief Return a pointer to the underlying VTK Render Window used. */ - //vtkSmartPointer getRenderWindow () { return (window_); } + void spin (); + void spinOnce (int time = 1, bool force_redraw = false); - void setPosition (int x, int y); - void setSize (int xw, int yw); - + void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); + void registerMouseCallback(MouseCallback callback, void* cookie = 0); + + + + + + + + + //declare above (to move to up) void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); void removeWidget(const String &id); Widget getWidget(const String &id) const; From 757e61d94cec4f8c3535786759c64ffb03dd9079 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 15 Jul 2013 13:11:34 +0400 Subject: [PATCH 084/205] restored OpenCVModule.cmake --- cmake/OpenCVModule.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index bd5720b30..48aa7139a 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -432,8 +432,6 @@ macro(ocv_glob_module_sources) file(GLOB lib_hdrs "include/opencv2/*.hpp" "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h") - file(GLOB_RECURSE qq "src/q/*.h*") - file(GLOB lib_device_srcs "src/cuda/*.cu") set(device_objs "") set(lib_device_hdrs "") @@ -447,7 +445,7 @@ macro(ocv_glob_module_sources) endif() ocv_set_module_sources(${ARGN} HEADERS ${lib_hdrs} ${lib_hdrs_detail} - SOURCES ${lib_srcs} ${lib_int_hdrs} ${device_objs} ${lib_device_srcs} ${lib_device_hdrs} ${qq}) + SOURCES ${lib_srcs} ${lib_int_hdrs} ${device_objs} ${lib_device_srcs} ${lib_device_hdrs}) source_group("Src" FILES ${lib_srcs} ${lib_int_hdrs}) source_group("Include" FILES ${lib_hdrs}) From b066d1982f1668fcb62d381c52c1a5815c5c17ce Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 15 Jul 2013 12:02:20 +0200 Subject: [PATCH 085/205] mesh widget implementation --- modules/viz/include/opencv2/viz/types.hpp | 25 +- modules/viz/include/opencv2/viz/widgets.hpp | 14 +- modules/viz/src/cloud_widgets.cpp | 153 +++++ modules/viz/src/mesh_load.cpp | 79 --- modules/viz/src/precomp.hpp | 24 - modules/viz/src/shape_widgets.cpp | 10 +- modules/viz/src/types.cpp | 84 +++ modules/viz/src/viz.cpp | 24 + modules/viz/src/viz3d_impl.cpp | 681 ++++++++++---------- modules/viz/src/widget.cpp | 1 + modules/viz/test/test_viz3d.cpp | 33 +- 11 files changed, 649 insertions(+), 479 deletions(-) delete mode 100644 modules/viz/src/mesh_load.cpp diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 50f1f1b0e..8bd38e429 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -32,22 +32,15 @@ namespace cv static Color gray(); }; - - struct CV_EXPORTS Vertices - { - std::vector vertices; - }; - class CV_EXPORTS Mesh3d { public: - typedef Ptr Ptr; - - Mat cloud, colors; - std::vector polygons; - - static Mesh3d::Ptr mesh_load(const String& file); - + typedef cv::Ptr Ptr; + Mat cloud, colors, polygons; + static cv::viz::Mesh3d::Ptr loadMesh(const String& file); + + private: + struct loadMeshImpl; }; class CV_EXPORTS KeyboardEvent @@ -100,8 +93,4 @@ namespace cv }; } /* namespace viz */ -} /* namespace cv */ - - - - +} /* namespace cv */ \ No newline at end of file diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index ad523738e..415c318dc 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -159,6 +159,15 @@ namespace cv private: struct ApplyCloudNormals; }; + + class CV_EXPORTS MeshWidget : public Widget3D + { + public: + MeshWidget(const Mesh3d &mesh); + + private: + struct CopyImpl; + }; template<> CV_EXPORTS Widget2D Widget::cast(); template<> CV_EXPORTS Widget3D Widget::cast(); @@ -178,7 +187,4 @@ namespace cv template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); } /* namespace viz */ -} /* namespace cv */ - - - +} /* namespace cv */ \ No newline at end of file diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index 6999813e8..e52193141 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -1,5 +1,12 @@ #include "precomp.hpp" +namespace cv +{ + namespace viz + { + template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); + } +} /////////////////////////////////////////////////////////////////////////////////////////////// /// Point Cloud Widget implementation @@ -311,3 +318,149 @@ template<> cv::viz::CloudNormalsWidget cv::viz::Widget::castcast(); return static_cast(widget); } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Mesh Widget implementation + +struct cv::viz::MeshWidget::CopyImpl +{ + template + static Vec<_Tp, 3> * copy(const Mat &source, Vec<_Tp, 3> *output, int *look_up, const Mat &nan_mask) + { + CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size()); + CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4); + CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth()); + + int s_chs = source.channels(); + int m_chs = nan_mask.channels(); + + int index = 0; + const _Tp* srow = source.ptr<_Tp>(0); + const _Tp* mrow = nan_mask.ptr<_Tp>(0); + + for(int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) + { + if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) + { + look_up[x] = index; + *output++ = Vec<_Tp, 3>(srow); + ++index; + } + } + return output; + } +}; + +cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) +{ + CV_Assert(mesh.cloud.rows == 1 && (mesh.cloud.type() == CV_32FC3 || mesh.cloud.type() == CV_64FC3 || mesh.cloud.type() == CV_32FC4 || mesh.cloud.type() == CV_64FC4)); + CV_Assert(mesh.colors.empty() || (mesh.colors.type() == CV_8UC3 && mesh.cloud.size() == mesh.colors.size())); + CV_Assert(!mesh.polygons.empty() && mesh.polygons.type() == CV_32SC1); + + vtkSmartPointer points = vtkSmartPointer::New (); + vtkIdType nr_points = mesh.cloud.total(); + int * look_up = new int[nr_points]; + points->SetNumberOfPoints (nr_points); + + // Copy data from cloud to vtkPoints + if (mesh.cloud.depth() == CV_32F) + { + points->SetDataTypeToFloat(); + Vec3f *data_beg = vtkpoints_data(points); + Vec3f *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud); + nr_points = data_end - data_beg; + } + else + { + points->SetDataTypeToDouble(); + Vec3d *data_beg = vtkpoints_data(points); + Vec3d *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud); + nr_points = data_end - data_beg; + } + + vtkSmartPointer scalars; + + if (!mesh.colors.empty()) + { + Vec3b * colors_data = 0; + colors_data = new Vec3b[nr_points]; + NanFilter::copy(mesh.colors, colors_data, mesh.cloud); + + scalars = vtkSmartPointer::New (); + scalars->SetNumberOfComponents (3); + scalars->SetNumberOfTuples (nr_points); + scalars->SetArray (colors_data->val, 3 * nr_points, 0); + } + + points->SetNumberOfPoints(nr_points); + + vtkSmartPointer data; + + if (mesh.polygons.size().area() > 1) + { + vtkSmartPointer cell_array = vtkSmartPointer::New(); + const int * polygons = mesh.polygons.ptr(); + + int idx = 0; + int poly_size = mesh.polygons.total(); + for (int i = 0; i < poly_size; ++idx) + { + int n_points = polygons[i++]; + + cell_array->InsertNextCell(n_points); + for (int j = 0; j < n_points; ++j, ++idx) + cell_array->InsertCellPoint(look_up[polygons[i++]]); + } + vtkSmartPointer polydata = vtkSmartPointer::New(); + cell_array->GetData ()->SetNumberOfValues (idx); + cell_array->Squeeze (); + polydata->SetStrips (cell_array); + polydata->SetPoints (points); + + if (scalars) + polydata->GetPointData ()->SetScalars (scalars); + + data = polydata; + } + else + { + // Only one polygon + vtkSmartPointer polygon = vtkSmartPointer::New (); + const int * polygons = mesh.polygons.ptr(); + int n_points = polygons[0]; + + polygon->GetPointIds()->SetNumberOfIds(n_points); + + for (int j = 1; j < n_points+1; ++j) + polygon->GetPointIds ()->SetId (j, look_up[polygons[j]]); + + vtkSmartPointer poly_grid = vtkSmartPointer::New(); + poly_grid->Allocate (1, 1); + poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); + poly_grid->SetPoints (points); + poly_grid->Update (); + + if (scalars) + poly_grid->GetPointData ()->SetScalars (scalars); + + data = poly_grid; + } + + vtkSmartPointer actor = vtkSmartPointer::New(); + + actor->GetProperty()->SetRepresentationToSurface(); + actor->GetProperty()->BackfaceCullingOff(); // Backface culling is off for higher efficiency + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->EdgeVisibilityOff(); + actor->GetProperty()->ShadingOff(); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (data); + mapper->ImmediateModeRenderingOff (); + + vtkIdType numberOfCloudPoints = nr_points * 0.1; + actor->SetNumberOfCloudPoints (int (numberOfCloudPoints > 1 ? numberOfCloudPoints : 1)); + actor->SetMapper (mapper); + + WidgetAccessor::setProp(*this, actor); +} diff --git a/modules/viz/src/mesh_load.cpp b/modules/viz/src/mesh_load.cpp deleted file mode 100644 index cf302d6ec..000000000 --- a/modules/viz/src/mesh_load.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "precomp.hpp" - -#include -#include -#include -#include -#include - -cv::viz::Mesh3d::Ptr cv::viz::Mesh3d::mesh_load(const String& file) -{ - Mesh3d::Ptr mesh = new Mesh3d(); - - vtkSmartPointer reader = vtkSmartPointer::New(); - reader->SetFileName(file.c_str()); - reader->Update(); - vtkSmartPointer poly_data = reader->GetOutput (); - - typedef unsigned int uint32_t; - mesh->polygons.clear(); - - vtkSmartPointer mesh_points = poly_data->GetPoints (); - vtkIdType nr_points = mesh_points->GetNumberOfPoints (); - vtkIdType nr_polygons = poly_data->GetNumberOfPolys (); - - mesh->cloud.create(1, nr_points, CV_32FC3); - - double point_xyz[3]; - for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) - { - mesh_points->GetPoint (i, &point_xyz[0]); - mesh->cloud.ptr()[i] = cv::Point3d(point_xyz[0], point_xyz[1], point_xyz[2]);; - } - - // Then the color information, if any - vtkUnsignedCharArray* poly_colors = NULL; - if (poly_data->GetPointData() != NULL) - poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("Colors")); - - // some applications do not save the name of scalars (including PCL's native vtk_io) - if (!poly_colors && poly_data->GetPointData () != NULL) - poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("scalars")); - - if (!poly_colors && poly_data->GetPointData () != NULL) - poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("RGB")); - - // TODO: currently only handles rgb values with 3 components - if (poly_colors && (poly_colors->GetNumberOfComponents () == 3)) - { - mesh->colors.create(1, nr_points, CV_8UC3); - unsigned char point_color[3]; - - for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) - { - poly_colors->GetTupleValue (i, &point_color[0]); - - //RGB or BGR????? - mesh->colors.ptr()[i] = cv::Vec3b(point_color[0], point_color[1], point_color[2]); - } - } - else - mesh->colors.release(); - - // Now handle the polygons - mesh->polygons.resize (nr_polygons); - vtkIdType* cell_points; - vtkIdType nr_cell_points; - vtkCellArray * mesh_polygons = poly_data->GetPolys (); - mesh_polygons->InitTraversal (); - int id_poly = 0; - while (mesh_polygons->GetNextCell (nr_cell_points, cell_points)) - { - mesh->polygons[id_poly].vertices.resize (nr_cell_points); - for (int i = 0; i < nr_cell_points; ++i) - mesh->polygons[id_poly].vertices[i] = static_cast (cell_points[i]); - ++id_poly; - } - - return mesh; -} diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index bff8cedc8..3e98182a6 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -156,27 +156,3 @@ #include #include #include "opencv2/viz/widget_accessor.hpp" - -namespace cv -{ - namespace viz - { - template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); - - template<> static inline Vec3f* vtkpoints_data(vtkSmartPointer& points) - { - CV_Assert(points->GetDataType() == VTK_FLOAT); - vtkDataArray *data = points->GetData(); - float *pointer = static_cast(data)->GetPointer(0); - return reinterpret_cast(pointer); - } - - template<> static inline Vec3d* vtkpoints_data(vtkSmartPointer& points) - { - CV_Assert(points->GetDataType() == VTK_DOUBLE); - vtkDataArray *data = points->GetData(); - double *pointer = static_cast(data)->GetPointer(0); - return reinterpret_cast(pointer); - } - } -} diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index d0e1d7c3a..6e210ec85 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1,5 +1,13 @@ #include "precomp.hpp" +namespace cv +{ + namespace viz + { + template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); + } +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation cv::viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) @@ -524,4 +532,4 @@ cv::String cv::viz::TextWidget::getText() const vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); return actor->GetInput(); -} +} \ No newline at end of file diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index fb277963a..e13355c38 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -59,3 +59,87 @@ cv::viz::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, if (shift) key_state |= KeyboardEvent::Shift; } + +//////////////////////////////////////////////////////////////////// +/// cv::viz::Mesh3d + +struct cv::viz::Mesh3d::loadMeshImpl +{ + static cv::viz::Mesh3d::Ptr loadMesh(const String &file) + { + Mesh3d::Ptr mesh = new Mesh3d(); + + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(file.c_str()); + reader->Update(); + vtkSmartPointer poly_data = reader->GetOutput (); + + typedef unsigned int uint32_t; + + vtkSmartPointer mesh_points = poly_data->GetPoints (); + vtkIdType nr_points = mesh_points->GetNumberOfPoints (); + vtkIdType nr_polygons = poly_data->GetNumberOfPolys (); + + mesh->cloud.create(1, nr_points, CV_32FC3); + + double point_xyz[3]; + for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) + { + mesh_points->GetPoint (i, &point_xyz[0]); + mesh->cloud.ptr()[i] = cv::Point3d(point_xyz[0], point_xyz[1], point_xyz[2]);; + } + + // Then the color information, if any + vtkUnsignedCharArray* poly_colors = NULL; + if (poly_data->GetPointData() != NULL) + poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("Colors")); + + // some applications do not save the name of scalars (including PCL's native vtk_io) + if (!poly_colors && poly_data->GetPointData () != NULL) + poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("scalars")); + + if (!poly_colors && poly_data->GetPointData () != NULL) + poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("RGB")); + + // TODO: currently only handles rgb values with 3 components + if (poly_colors && (poly_colors->GetNumberOfComponents () == 3)) + { + mesh->colors.create(1, nr_points, CV_8UC3); + unsigned char point_color[3]; + + for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) + { + poly_colors->GetTupleValue (i, &point_color[0]); + + //RGB or BGR????? + mesh->colors.ptr()[i] = cv::Vec3b(point_color[0], point_color[1], point_color[2]); + } + } + else + mesh->colors.release(); + + // Now handle the polygons + vtkIdType* cell_points; + vtkIdType nr_cell_points; + vtkCellArray * mesh_polygons = poly_data->GetPolys (); + mesh_polygons->InitTraversal (); + int id_poly = 0; + + mesh->polygons.create(1, mesh_polygons->GetSize(), CV_32SC1); + + int * polygons = mesh->polygons.ptr(); + while (mesh_polygons->GetNextCell (nr_cell_points, cell_points)) + { + *polygons++ = nr_cell_points; + for (int i = 0; i < nr_cell_points; ++i) + *polygons++ = static_cast (cell_points[i]); + } + + return mesh; + } +}; + +cv::viz::Mesh3d::Ptr cv::viz::Mesh3d::loadMesh(const String& file) +{ + return loadMeshImpl::loadMesh(file); +} diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 923aa51ef..1d53b5d25 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -37,3 +37,27 @@ cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer& vtk_matr m(i, k) = vtk_matrix->GetElement (i, k); return m; } + +namespace cv +{ + namespace viz + { + template Vec<_Tp, 3>* vtkpoints_data(vtkSmartPointer& points); + + template<> Vec3f* vtkpoints_data(vtkSmartPointer& points) + { + CV_Assert(points->GetDataType() == VTK_FLOAT); + vtkDataArray *data = points->GetData(); + float *pointer = static_cast(data)->GetPointer(0); + return reinterpret_cast(pointer); + } + + template<> Vec3d* vtkpoints_data(vtkSmartPointer& points) + { + CV_Assert(points->GetDataType() == VTK_DOUBLE); + vtkDataArray *data = points->GetData(); + double *pointer = static_cast(data)->GetPointer(0); + return reinterpret_cast(pointer); + } + } +} \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index d7b9fcd40..0220d9c65 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -849,53 +849,53 @@ bool cv::viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, bool cv::viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& mesh, const std::string &id) { - CV_Assert(mesh.cloud.rows == 1 && mesh.cloud.type() == CV_32FC3); - - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addPolylineFromPolygonMesh] A shape with id <"<< id << "> already exists! Please choose a different id and retry.\n" << std::endl, false; - - vtkSmartPointer poly_points = vtkSmartPointer::New (); - poly_points->SetNumberOfPoints (mesh.cloud.size().area()); - - const cv::Point3f *cdata = mesh.cloud.ptr(); - for (int i = 0; i < mesh.cloud.cols; ++i) - poly_points->InsertPoint (i, cdata[i].x, cdata[i].y,cdata[i].z); - - - // Create a cell array to store the lines in and add the lines to it - vtkSmartPointer cells = vtkSmartPointer::New (); - vtkSmartPointer polyData; - allocVtkPolyData (polyData); - - for (size_t i = 0; i < mesh.polygons.size (); i++) - { - vtkSmartPointer polyLine = vtkSmartPointer::New(); - polyLine->GetPointIds()->SetNumberOfIds(mesh.polygons[i].vertices.size()); - for(unsigned int k = 0; k < mesh.polygons[i].vertices.size(); k++) - { - polyLine->GetPointIds()->SetId(k,mesh. polygons[i].vertices[k]); - } - - cells->InsertNextCell (polyLine); - } - - // Add the points to the dataset - polyData->SetPoints (poly_points); - - // Add the lines to the dataset - polyData->SetLines (cells); - - // Setup actor and mapper - vtkSmartPointer < vtkPolyDataMapper > mapper = vtkSmartPointer::New (); - mapper->SetInput (polyData); - - vtkSmartPointer actor = vtkSmartPointer::New (); - actor->SetMapper (mapper); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; +// CV_Assert(mesh.cloud.rows == 1 && mesh.cloud.type() == CV_32FC3); +// +// ShapeActorMap::iterator am_it = shape_actor_map_->find (id); +// if (am_it != shape_actor_map_->end ()) +// return std::cout << "[addPolylineFromPolygonMesh] A shape with id <"<< id << "> already exists! Please choose a different id and retry.\n" << std::endl, false; +// +// vtkSmartPointer poly_points = vtkSmartPointer::New (); +// poly_points->SetNumberOfPoints (mesh.cloud.size().area()); +// +// const cv::Point3f *cdata = mesh.cloud.ptr(); +// for (int i = 0; i < mesh.cloud.cols; ++i) +// poly_points->InsertPoint (i, cdata[i].x, cdata[i].y,cdata[i].z); +// +// +// // Create a cell array to store the lines in and add the lines to it +// vtkSmartPointer cells = vtkSmartPointer::New (); +// vtkSmartPointer polyData; +// allocVtkPolyData (polyData); +// +// for (size_t i = 0; i < mesh.polygons.size (); i++) +// { +// vtkSmartPointer polyLine = vtkSmartPointer::New(); +// polyLine->GetPointIds()->SetNumberOfIds(mesh.polygons[i].vertices.size()); +// for(unsigned int k = 0; k < mesh.polygons[i].vertices.size(); k++) +// { +// polyLine->GetPointIds()->SetId(k,mesh. polygons[i].vertices[k]); +// } +// +// cells->InsertNextCell (polyLine); +// } +// +// // Add the points to the dataset +// polyData->SetPoints (poly_points); +// +// // Add the lines to the dataset +// polyData->SetLines (cells); +// +// // Setup actor and mapper +// vtkSmartPointer < vtkPolyDataMapper > mapper = vtkSmartPointer::New (); +// mapper->SetInput (polyData); +// +// vtkSmartPointer actor = vtkSmartPointer::New (); +// actor->SetMapper (mapper); +// renderer_->AddActor(actor); +// +// // Save the pointer/ID pair to the global actor map +// (*shape_actor_map_)[id] = actor; return (true); } @@ -1019,304 +1019,305 @@ void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize bool cv::viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) { - CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); - CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); - CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); - - if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) - return std::cout << "[addPolygonMesh] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; - - // int rgb_idx = -1; - // std::vector fields; - - - // rgb_idx = cv::viz::getFieldIndex (*cloud, "rgb", fields); - // if (rgb_idx == -1) - // rgb_idx = cv::viz::getFieldIndex (*cloud, "rgba", fields); - - vtkSmartPointer colors_array; -#if 1 - if (!mesh.colors.empty()) - { - colors_array = vtkSmartPointer::New (); - colors_array->SetNumberOfComponents (3); - colors_array->SetName ("Colors"); - - const unsigned char* data = mesh.colors.ptr(); - - //TODO check mask - CV_Assert(mask.empty()); //because not implemented; - - for(int i = 0; i < mesh.colors.cols; ++i) - colors_array->InsertNextTupleValue(&data[i*3]); - - // cv::viz::RGB rgb_data; - // for (size_t i = 0; i < cloud->size (); ++i) - // { - // if (!isFinite (cloud->points[i])) - // continue; - // memcpy (&rgb_data, reinterpret_cast (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (cv::viz::RGB)); - // unsigned char color[3]; - // color[0] = rgb_data.r; - // color[1] = rgb_data.g; - // color[2] = rgb_data.b; - // colors->InsertNextTupleValue (color); - // } - } -#endif - - // Create points from polyMesh.cloud - vtkSmartPointer points = vtkSmartPointer::New (); - vtkIdType nr_points = mesh.cloud.size().area(); - - points->SetNumberOfPoints (nr_points); - - - // Get a pointer to the beginning of the data array - float *data = static_cast (points->GetData ())->GetPointer (0); - - - std::vector lookup; - // If the dataset is dense (no NaNs) - if (mask.empty()) - { - cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); - mesh.cloud.copyTo(hdr); - } - else - { - lookup.resize (nr_points); - - const unsigned char *mdata = mask.ptr(); - const cv::Point3f *cdata = mesh.cloud.ptr(); - cv::Point3f* out = reinterpret_cast(data); - - int j = 0; // true point index - for (int i = 0; i < nr_points; ++i) - if(mdata[i]) - { - lookup[i] = j; - out[j++] = cdata[i]; - } - nr_points = j; - points->SetNumberOfPoints (nr_points); - } - - // Get the maximum size of a polygon - int max_size_of_polygon = -1; - for (size_t i = 0; i < mesh.polygons.size (); ++i) - if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) - max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); - - vtkSmartPointer actor; - - if (mesh.polygons.size () > 1) - { - // Create polys from polyMesh.polygons - vtkSmartPointer cell_array = vtkSmartPointer::New (); - vtkIdType *cell = cell_array->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); - int idx = 0; - if (lookup.size () > 0) - { - for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) - { - size_t n_points = mesh.polygons[i].vertices.size (); - *cell++ = n_points; - //cell_array->InsertNextCell (n_points); - for (size_t j = 0; j < n_points; j++, ++idx) - *cell++ = lookup[mesh.polygons[i].vertices[j]]; - //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]); - } - } - else - { - for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) - { - size_t n_points = mesh.polygons[i].vertices.size (); - *cell++ = n_points; - //cell_array->InsertNextCell (n_points); - for (size_t j = 0; j < n_points; j++, ++idx) - *cell++ = mesh.polygons[i].vertices[j]; - //cell_array->InsertCellPoint (vertices[i].vertices[j]); - } - } - vtkSmartPointer polydata; - allocVtkPolyData (polydata); - cell_array->GetData ()->SetNumberOfValues (idx); - cell_array->Squeeze (); - polydata->SetStrips (cell_array); - polydata->SetPoints (points); - - if (colors_array) - polydata->GetPointData ()->SetScalars (colors_array); - - createActorFromVTKDataSet (polydata, actor, false); - } - else - { - vtkSmartPointer polygon = vtkSmartPointer::New (); - size_t n_points = mesh.polygons[0].vertices.size (); - polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); - - if (lookup.size () > 0) - { - for (size_t j = 0; j < n_points - 1; ++j) - polygon->GetPointIds ()->SetId (j, lookup[mesh.polygons[0].vertices[j]]); - } - else - { - for (size_t j = 0; j < n_points - 1; ++j) - polygon->GetPointIds ()->SetId (j, mesh.polygons[0].vertices[j]); - } - vtkSmartPointer poly_grid; - allocVtkUnstructuredGrid (poly_grid); - poly_grid->Allocate (1, 1); - poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); - poly_grid->SetPoints (points); - poly_grid->Update (); - if (colors_array) - poly_grid->GetPointData ()->SetScalars (colors_array); - - createActorFromVTKDataSet (poly_grid, actor, false); - } - renderer_->AddActor (actor); - actor->GetProperty ()->SetRepresentationToSurface (); - // Backface culling renders the visualization slower, but guarantees that we see all triangles - actor->GetProperty ()->BackfaceCullingOff (); - actor->GetProperty ()->SetInterpolationToFlat (); - actor->GetProperty ()->EdgeVisibilityOff (); - actor->GetProperty ()->ShadingOff (); - - // Save the pointer/ID pair to the global actor map - (*cloud_actor_map_)[id].actor = actor; - //if (vertices.size () > 1) - // (*cloud_actor_map_)[id].cells = static_cast(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData (); - - const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); - const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); - - // Save the viewpoint transformation matrix to the global actor map - vtkSmartPointer transformation = vtkSmartPointer::New(); - convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); - (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; - - return (true); +// CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); +// CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); +// CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); +// +// if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) +// return std::cout << "[addPolygonMesh] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; +// +// // int rgb_idx = -1; +// // std::vector fields; +// +// +// // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgb", fields); +// // if (rgb_idx == -1) +// // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgba", fields); +// +// vtkSmartPointer colors_array; +// #if 1 +// if (!mesh.colors.empty()) +// { +// colors_array = vtkSmartPointer::New (); +// colors_array->SetNumberOfComponents (3); +// colors_array->SetName ("Colors"); +// +// const unsigned char* data = mesh.colors.ptr(); +// +// //TODO check mask +// CV_Assert(mask.empty()); //because not implemented; +// +// for(int i = 0; i < mesh.colors.cols; ++i) +// colors_array->InsertNextTupleValue(&data[i*3]); +// +// // temp_viz::RGB rgb_data; +// // for (size_t i = 0; i < cloud->size (); ++i) +// // { +// // if (!isFinite (cloud->points[i])) +// // continue; +// // memcpy (&rgb_data, reinterpret_cast (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (temp_viz::RGB)); +// // unsigned char color[3]; +// // color[0] = rgb_data.r; +// // color[1] = rgb_data.g; +// // color[2] = rgb_data.b; +// // colors->InsertNextTupleValue (color); +// // } +// } +// #endif +// +// // Create points from polyMesh.cloud +// vtkSmartPointer points = vtkSmartPointer::New (); +// vtkIdType nr_points = mesh.cloud.size().area(); +// +// points->SetNumberOfPoints (nr_points); +// +// +// // Get a pointer to the beginning of the data array +// float *data = static_cast (points->GetData ())->GetPointer (0); +// +// +// std::vector lookup; +// // If the dataset is dense (no NaNs) +// if (mask.empty()) +// { +// cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); +// mesh.cloud.copyTo(hdr); +// } +// else +// { +// lookup.resize (nr_points); +// +// const unsigned char *mdata = mask.ptr(); +// const cv::Point3f *cdata = mesh.cloud.ptr(); +// cv::Point3f* out = reinterpret_cast(data); +// +// int j = 0; // true point index +// for (int i = 0; i < nr_points; ++i) +// if(mdata[i]) +// { +// lookup[i] = j; +// out[j++] = cdata[i]; +// } +// nr_points = j; +// points->SetNumberOfPoints (nr_points); +// } +// +// // Get the maximum size of a polygon +// int max_size_of_polygon = -1; +// for (size_t i = 0; i < mesh.polygons.size (); ++i) +// if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) +// max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); +// +// vtkSmartPointer actor; +// +// if (mesh.polygons.size () > 1) +// { +// // Create polys from polyMesh.polygons +// vtkSmartPointer cell_array = vtkSmartPointer::New (); +// vtkIdType *cell = cell_array->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); +// int idx = 0; +// if (lookup.size () > 0) +// { +// for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) +// { +// size_t n_points = mesh.polygons[i].vertices.size (); +// *cell++ = n_points; +// //cell_array->InsertNextCell (n_points); +// for (size_t j = 0; j < n_points; j++, ++idx) +// *cell++ = lookup[mesh.polygons[i].vertices[j]]; +// //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]); +// } +// } +// else +// { +// for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) +// { +// size_t n_points = mesh.polygons[i].vertices.size (); +// *cell++ = n_points; +// //cell_array->InsertNextCell (n_points); +// for (size_t j = 0; j < n_points; j++, ++idx) +// *cell++ = mesh.polygons[i].vertices[j]; +// //cell_array->InsertCellPoint (vertices[i].vertices[j]); +// } +// } +// vtkSmartPointer polydata; +// allocVtkPolyData (polydata); +// cell_array->GetData ()->SetNumberOfValues (idx); +// cell_array->Squeeze (); +// polydata->SetStrips (cell_array); +// polydata->SetPoints (points); +// +// if (colors_array) +// polydata->GetPointData ()->SetScalars (colors_array); +// +// createActorFromVTKDataSet (polydata, actor, false); +// } +// else +// { +// vtkSmartPointer polygon = vtkSmartPointer::New (); +// size_t n_points = mesh.polygons[0].vertices.size (); +// polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); +// +// if (lookup.size () > 0) +// { +// for (size_t j = 0; j < n_points - 1; ++j) +// polygon->GetPointIds ()->SetId (j, lookup[mesh.polygons[0].vertices[j]]); +// } +// else +// { +// for (size_t j = 0; j < n_points - 1; ++j) +// polygon->GetPointIds ()->SetId (j, mesh.polygons[0].vertices[j]); +// } +// vtkSmartPointer poly_grid; +// allocVtkUnstructuredGrid (poly_grid); +// poly_grid->Allocate (1, 1); +// poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); +// poly_grid->SetPoints (points); +// poly_grid->Update (); +// if (colors_array) +// poly_grid->GetPointData ()->SetScalars (colors_array); +// +// createActorFromVTKDataSet (poly_grid, actor, false); +// } +// renderer_->AddActor (actor); +// actor->GetProperty ()->SetRepresentationToSurface (); +// // Backface culling renders the visualization slower, but guarantees that we see all triangles +// actor->GetProperty ()->BackfaceCullingOff (); +// actor->GetProperty ()->SetInterpolationToFlat (); +// actor->GetProperty ()->EdgeVisibilityOff (); +// actor->GetProperty ()->ShadingOff (); +// +// // Save the pointer/ID pair to the global actor map +// (*cloud_actor_map_)[id].actor = actor; +// //if (vertices.size () > 1) +// // (*cloud_actor_map_)[id].cells = static_cast(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData (); +// +// const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); +// const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); +// +// // Save the viewpoint transformation matrix to the global actor map +// vtkSmartPointer transformation = vtkSmartPointer::New(); +// convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); +// (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; +// +// return (true); +return true; } bool cv::viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) { - CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); - CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); - CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); - - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - if (am_it == cloud_actor_map_->end ()) - return (false); - - // Get the current poly data - vtkSmartPointer polydata = static_cast(am_it->second.actor->GetMapper ())->GetInput (); - if (!polydata) - return (false); - vtkSmartPointer cells = polydata->GetStrips (); - if (!cells) - return (false); - vtkSmartPointer points = polydata->GetPoints (); - // Copy the new point array in - vtkIdType nr_points = mesh.cloud.size().area(); - points->SetNumberOfPoints (nr_points); - - // Get a pointer to the beginning of the data array - float *data = (static_cast (points->GetData ()))->GetPointer (0); - - int ptr = 0; - std::vector lookup; - // If the dataset is dense (no NaNs) - if (mask.empty()) - { - cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); - mesh.cloud.copyTo(hdr); - - } - else - { - lookup.resize (nr_points); - - const unsigned char *mdata = mask.ptr(); - const cv::Point3f *cdata = mesh.cloud.ptr(); - cv::Point3f* out = reinterpret_cast(data); - - int j = 0; // true point index - for (int i = 0; i < nr_points; ++i) - if(mdata[i]) - { - lookup[i] = j; - out[j++] = cdata[i]; - } - nr_points = j; - points->SetNumberOfPoints (nr_points);; - } - - // Update colors - vtkUnsignedCharArray* colors_array = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ()); - - if (!mesh.colors.empty() && colors_array) - { - if (mask.empty()) - { - const unsigned char* data = mesh.colors.ptr(); - for(int i = 0; i < mesh.colors.cols; ++i) - colors_array->InsertNextTupleValue(&data[i*3]); - } - else - { - const unsigned char* color = mesh.colors.ptr(); - const unsigned char* mdata = mask.ptr(); - - int j = 0; - for(int i = 0; i < mesh.colors.cols; ++i) - if (mdata[i]) - colors_array->SetTupleValue (j++, &color[i*3]); - - } - } - - // Get the maximum size of a polygon - int max_size_of_polygon = -1; - for (size_t i = 0; i < mesh.polygons.size (); ++i) - if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) - max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); - - // Update the cells - cells = vtkSmartPointer::New (); - vtkIdType *cell = cells->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); - int idx = 0; - if (lookup.size () > 0) - { - for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) - { - size_t n_points = mesh.polygons[i].vertices.size (); - *cell++ = n_points; - for (size_t j = 0; j < n_points; j++, cell++, ++idx) - *cell = lookup[mesh.polygons[i].vertices[j]]; - } - } - else - { - for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) - { - size_t n_points = mesh.polygons[i].vertices.size (); - *cell++ = n_points; - for (size_t j = 0; j < n_points; j++, cell++, ++idx) - *cell = mesh.polygons[i].vertices[j]; - } - } - cells->GetData ()->SetNumberOfValues (idx); - cells->Squeeze (); - // Set the the vertices - polydata->SetStrips (cells); - polydata->Update (); +// CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); +// CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); +// CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); +// +// // Check to see if this ID entry already exists (has it been already added to the visualizer?) +// CloudActorMap::iterator am_it = cloud_actor_map_->find (id); +// if (am_it == cloud_actor_map_->end ()) +// return (false); +// +// // Get the current poly data +// vtkSmartPointer polydata = static_cast(am_it->second.actor->GetMapper ())->GetInput (); +// if (!polydata) +// return (false); +// vtkSmartPointer cells = polydata->GetStrips (); +// if (!cells) +// return (false); +// vtkSmartPointer points = polydata->GetPoints (); +// // Copy the new point array in +// vtkIdType nr_points = mesh.cloud.size().area(); +// points->SetNumberOfPoints (nr_points); +// +// // Get a pointer to the beginning of the data array +// float *data = (static_cast (points->GetData ()))->GetPointer (0); +// +// int ptr = 0; +// std::vector lookup; +// // If the dataset is dense (no NaNs) +// if (mask.empty()) +// { +// cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); +// mesh.cloud.copyTo(hdr); +// +// } +// else +// { +// lookup.resize (nr_points); +// +// const unsigned char *mdata = mask.ptr(); +// const cv::Point3f *cdata = mesh.cloud.ptr(); +// cv::Point3f* out = reinterpret_cast(data); +// +// int j = 0; // true point index +// for (int i = 0; i < nr_points; ++i) +// if(mdata[i]) +// { +// lookup[i] = j; +// out[j++] = cdata[i]; +// } +// nr_points = j; +// points->SetNumberOfPoints (nr_points);; +// } +// +// // Update colors +// vtkUnsignedCharArray* colors_array = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ()); +// +// if (!mesh.colors.empty() && colors_array) +// { +// if (mask.empty()) +// { +// const unsigned char* data = mesh.colors.ptr(); +// for(int i = 0; i < mesh.colors.cols; ++i) +// colors_array->InsertNextTupleValue(&data[i*3]); +// } +// else +// { +// const unsigned char* color = mesh.colors.ptr(); +// const unsigned char* mdata = mask.ptr(); +// +// int j = 0; +// for(int i = 0; i < mesh.colors.cols; ++i) +// if (mdata[i]) +// colors_array->SetTupleValue (j++, &color[i*3]); +// +// } +// } +// +// // Get the maximum size of a polygon +// int max_size_of_polygon = -1; +// for (size_t i = 0; i < mesh.polygons.size (); ++i) +// if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) +// max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); +// +// // Update the cells +// cells = vtkSmartPointer::New (); +// vtkIdType *cell = cells->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); +// int idx = 0; +// if (lookup.size () > 0) +// { +// for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) +// { +// size_t n_points = mesh.polygons[i].vertices.size (); +// *cell++ = n_points; +// for (size_t j = 0; j < n_points; j++, cell++, ++idx) +// *cell = lookup[mesh.polygons[i].vertices[j]]; +// } +// } +// else +// { +// for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) +// { +// size_t n_points = mesh.polygons[i].vertices.size (); +// *cell++ = n_points; +// for (size_t j = 0; j < n_points; j++, cell++, ++idx) +// *cell = mesh.polygons[i].vertices[j]; +// } +// } +// cells->GetData ()->SetNumberOfValues (idx); +// cells->Squeeze (); +// // Set the the vertices +// polydata->SetStrips (cells); +// polydata->Update (); return (true); } diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index bb257fe7d..8f9e90404 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -1,3 +1,4 @@ + #include "precomp.hpp" /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index a1b99fae5..f2ba913d0 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -99,18 +99,18 @@ TEST(Viz_viz3d, accuracy) viz::CloudWidget pcw(cloud, colors); viz::CloudWidget pcw2(cloud, viz::Color::magenta()); - viz.showWidget("line", lw); - viz.showWidget("plane", pw); - viz.showWidget("sphere", sw); - viz.showWidget("arrow", aw); - viz.showWidget("circle", cw); - viz.showWidget("cylinder", cyw); - viz.showWidget("cube", cuw); - viz.showWidget("coordinateSystem", csw); - viz.showWidget("coordinateSystem2", viz::CoordinateSystemWidget(2.0), Affine3f().translate(Vec3f(2, 0, 0))); - viz.showWidget("text",tw); - viz.showWidget("pcw",pcw); - viz.showWidget("pcw2",pcw2); + viz.showWidget("line", lw); + viz.showWidget("plane", pw); + viz.showWidget("sphere", sw); + viz.showWidget("arrow", aw); + viz.showWidget("circle", cw); + viz.showWidget("cylinder", cyw); + viz.showWidget("cube", cuw); + viz.showWidget("coordinateSystem", csw); + viz.showWidget("coordinateSystem2", viz::CoordinateSystemWidget(2.0), Affine3f().translate(Vec3f(2, 0, 0))); + viz.showWidget("text",tw); + viz.showWidget("pcw",pcw); + viz.showWidget("pcw2",pcw2); // viz::LineWidget lw2 = lw; // v.showPointCloud("cld",cloud, colors); @@ -128,16 +128,23 @@ TEST(Viz_viz3d, accuracy) viz.showWidget("polyline", plw); // lw = v.getWidget("polyline").cast(); + viz::Mesh3d::Ptr mesh = cv::viz::Mesh3d::loadMesh("horse.ply"); + + viz::MeshWidget mw(*mesh); + viz.showWidget("mesh", mw); + viz.spin(); //viz::GridWidget gw(viz::Vec2i(100,100), viz::Vec2d(1,1)); //v.showWidget("grid", gw); - lw = viz.getWidget("grid").cast(); +// lw = viz.getWidget("grid").cast(); //viz::Text3DWidget t3w("OpenCV", cv::Point3f(0.0, 2.0, 0.0), 1.0, viz::Color(255,255,0)); //v.showWidget("txt3d", t3w); + // float grid_x_angle = 0.0; + while(!viz.wasStopped()) { // Creating new point cloud with id cloud1 From 25f98bc0222cc327594cfdf0a6affce97bf310b6 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 15 Jul 2013 12:02:53 +0200 Subject: [PATCH 086/205] mesh widget casting --- modules/viz/include/opencv2/viz/widgets.hpp | 1 + modules/viz/src/cloud_widgets.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 415c318dc..474c1bb81 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -185,6 +185,7 @@ namespace cv template<> CV_EXPORTS TextWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); + template<> CV_EXPORTS MeshWidget Widget::cast(); } /* namespace viz */ } /* namespace cv */ \ No newline at end of file diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index e52193141..fdbaf2731 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -464,3 +464,9 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) WidgetAccessor::setProp(*this, actor); } + +template<> CV_EXPORTS cv::viz::MeshWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} \ No newline at end of file From 4c228c07f1be74e8833504f4a480699c784221aa Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 15 Jul 2013 16:30:04 +0400 Subject: [PATCH 087/205] fixed copilation --- modules/viz/src/cloud_widgets.cpp | 4 ++-- modules/viz/src/precomp.hpp | 1 + modules/viz/src/types.cpp | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index fdbaf2731..18be02321 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -329,7 +329,7 @@ struct cv::viz::MeshWidget::CopyImpl { CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size()); CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4); - CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth()); + CV_DbgAssert(DataDepth<_Tp>::value == nan_mask.depth()); int s_chs = source.channels(); int m_chs = nan_mask.channels(); @@ -469,4 +469,4 @@ template<> CV_EXPORTS cv::viz::MeshWidget cv::viz::Widget::castcast(); return static_cast(widget); -} \ No newline at end of file +} diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 3e98182a6..df3a97040 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -155,4 +155,5 @@ #include "viz3d_impl.hpp" #include #include +#include #include "opencv2/viz/widget_accessor.hpp" diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index e13355c38..311ad9df2 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -1,4 +1,4 @@ -#include +#include "precomp.hpp" ////////////////////////////////////////////////////////////////////////////////////////////////////// /// cv::viz::Color @@ -78,7 +78,7 @@ struct cv::viz::Mesh3d::loadMeshImpl vtkSmartPointer mesh_points = poly_data->GetPoints (); vtkIdType nr_points = mesh_points->GetNumberOfPoints (); - vtkIdType nr_polygons = poly_data->GetNumberOfPolys (); + //vtkIdType nr_polygons = poly_data->GetNumberOfPolys (); mesh->cloud.create(1, nr_points, CV_32FC3); @@ -123,7 +123,6 @@ struct cv::viz::Mesh3d::loadMeshImpl vtkIdType nr_cell_points; vtkCellArray * mesh_polygons = poly_data->GetPolys (); mesh_polygons->InitTraversal (); - int id_poly = 0; mesh->polygons.create(1, mesh_polygons->GetSize(), CV_32SC1); From 0e20473c97f66f611ce329da98635e7d39ab9e84 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 15 Jul 2013 16:46:39 +0400 Subject: [PATCH 088/205] minor mesh load fixes --- modules/viz/src/types.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 311ad9df2..d3ba6c4a4 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -73,8 +73,6 @@ struct cv::viz::Mesh3d::loadMeshImpl reader->SetFileName(file.c_str()); reader->Update(); vtkSmartPointer poly_data = reader->GetOutput (); - - typedef unsigned int uint32_t; vtkSmartPointer mesh_points = poly_data->GetPoints (); vtkIdType nr_points = mesh_points->GetNumberOfPoints (); @@ -82,11 +80,12 @@ struct cv::viz::Mesh3d::loadMeshImpl mesh->cloud.create(1, nr_points, CV_32FC3); - double point_xyz[3]; + Vec3f *mesh_cloud = mesh->cloud.ptr(); for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) { - mesh_points->GetPoint (i, &point_xyz[0]); - mesh->cloud.ptr()[i] = cv::Point3d(point_xyz[0], point_xyz[1], point_xyz[2]);; + Vec3d point; + mesh_points->GetPoint (i, point.val); + mesh_cloud[i] = point; } // Then the color information, if any @@ -105,14 +104,15 @@ struct cv::viz::Mesh3d::loadMeshImpl if (poly_colors && (poly_colors->GetNumberOfComponents () == 3)) { mesh->colors.create(1, nr_points, CV_8UC3); - unsigned char point_color[3]; + Vec3b *mesh_colors = mesh->colors.ptr(); for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) { - poly_colors->GetTupleValue (i, &point_color[0]); + Vec3b point_color; + poly_colors->GetTupleValue (i, point_color.val); - //RGB or BGR????? - mesh->colors.ptr()[i] = cv::Vec3b(point_color[0], point_color[1], point_color[2]); + //RGB or BGR? should we swap channels???? + mesh_colors[i] = point_color; } } else From dc348ff93db223c5124ac1a1c2e4ba3a5cb1f9b7 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 15 Jul 2013 19:18:37 +0400 Subject: [PATCH 089/205] removed Mesh::Ptr since mesh itself consists of shared points (cv::Mat) --- modules/viz/include/opencv2/viz/types.hpp | 10 ++++++---- modules/viz/src/types.cpp | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 8bd38e429..b0e3efda3 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -35,9 +35,11 @@ namespace cv class CV_EXPORTS Mesh3d { public: - typedef cv::Ptr Ptr; - Mat cloud, colors, polygons; - static cv::viz::Mesh3d::Ptr loadMesh(const String& file); + + Mat cloud, colors; + Mat polygons; + + static cv::viz::Mesh3d loadMesh(const String& file); private: struct loadMeshImpl; @@ -93,4 +95,4 @@ namespace cv }; } /* namespace viz */ -} /* namespace cv */ \ No newline at end of file +} /* namespace cv */ diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index d3ba6c4a4..7cb25a036 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -65,9 +65,9 @@ cv::viz::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, struct cv::viz::Mesh3d::loadMeshImpl { - static cv::viz::Mesh3d::Ptr loadMesh(const String &file) + static cv::viz::Mesh3d loadMesh(const String &file) { - Mesh3d::Ptr mesh = new Mesh3d(); + Mesh3d mesh; vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(file.c_str()); @@ -78,9 +78,9 @@ struct cv::viz::Mesh3d::loadMeshImpl vtkIdType nr_points = mesh_points->GetNumberOfPoints (); //vtkIdType nr_polygons = poly_data->GetNumberOfPolys (); - mesh->cloud.create(1, nr_points, CV_32FC3); + mesh.cloud.create(1, nr_points, CV_32FC3); - Vec3f *mesh_cloud = mesh->cloud.ptr(); + Vec3f *mesh_cloud = mesh.cloud.ptr(); for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) { Vec3d point; @@ -103,8 +103,8 @@ struct cv::viz::Mesh3d::loadMeshImpl // TODO: currently only handles rgb values with 3 components if (poly_colors && (poly_colors->GetNumberOfComponents () == 3)) { - mesh->colors.create(1, nr_points, CV_8UC3); - Vec3b *mesh_colors = mesh->colors.ptr(); + mesh.colors.create(1, nr_points, CV_8UC3); + Vec3b *mesh_colors = mesh.colors.ptr(); for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) { @@ -116,7 +116,7 @@ struct cv::viz::Mesh3d::loadMeshImpl } } else - mesh->colors.release(); + mesh.colors.release(); // Now handle the polygons vtkIdType* cell_points; @@ -124,9 +124,9 @@ struct cv::viz::Mesh3d::loadMeshImpl vtkCellArray * mesh_polygons = poly_data->GetPolys (); mesh_polygons->InitTraversal (); - mesh->polygons.create(1, mesh_polygons->GetSize(), CV_32SC1); + mesh.polygons.create(1, mesh_polygons->GetSize(), CV_32SC1); - int * polygons = mesh->polygons.ptr(); + int* polygons = mesh.polygons.ptr(); while (mesh_polygons->GetNextCell (nr_cell_points, cell_points)) { *polygons++ = nr_cell_points; @@ -138,7 +138,7 @@ struct cv::viz::Mesh3d::loadMeshImpl } }; -cv::viz::Mesh3d::Ptr cv::viz::Mesh3d::loadMesh(const String& file) +cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file) { return loadMeshImpl::loadMesh(file); } From 1bfd7ad17efcefb2141660417c448582d7a062a5 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 15 Jul 2013 15:14:13 +0200 Subject: [PATCH 090/205] arrow widget thickness parameter --- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/shape_widgets.cpp | 6 +++++- modules/viz/test/test_viz3d.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 474c1bb81..56ecde784 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -81,7 +81,7 @@ namespace cv class CV_EXPORTS ArrowWidget : public Widget3D { public: - ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color = Color::white()); + ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); }; class CV_EXPORTS CircleWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index e2cb9a560..2272e17f8 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -128,9 +128,13 @@ template<> cv::viz::SphereWidget cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// arrow widget implementation -cv::viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, const Color &color) +cv::viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness, const Color &color) { vtkSmartPointer arrowSource = vtkSmartPointer::New (); + arrowSource->SetShaftRadius(thickness); + // The thickness and radius of the tip are adjusted based on the thickness of the arrow + arrowSource->SetTipRadius(thickness * 3.0); + arrowSource->SetTipLength(thickness * 10.0); float startPoint[3], endPoint[3]; startPoint[0] = pt1.x; diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index f2ba913d0..687d9f19d 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -90,7 +90,7 @@ TEST(Viz_viz3d, accuracy) viz::LineWidget lw(Point3f(0, 0, 0), Point3f(4.f, 4.f,4.f), viz::Color::green()); viz::PlaneWidget pw(Vec4f(0.0,1.0,2.0,3.0), 5.0); viz::SphereWidget sw(Point3f(0, 0, 0), 0.5); - viz::ArrowWidget aw(Point3f(0, 0, 0), Point3f(1, 1, 1), viz::Color::red()); + viz::ArrowWidget aw(Point3f(0, 0, 0), Point3f(1, 1, 1), 0.01, viz::Color::red()); viz::CircleWidget cw(Point3f(0, 0, 0), 0.5, 0.01, viz::Color::green()); viz::CylinderWidget cyw(Point3f(0, 0, 0), Point3f(-1, -1, -1), 0.5, 30, viz::Color::green()); viz::CubeWidget cuw(Point3f(-2, -2, -2), Point3f(-1, -1, -1)); From 4b85c849cabf7edeef69590e840b8f987786cb2a Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 15 Jul 2013 16:13:33 +0200 Subject: [PATCH 091/205] fix rgb and bgr incompatibility --- modules/viz/src/cloud_widgets.cpp | 4 ++-- modules/viz/src/types.cpp | 2 +- modules/viz/src/viz3d_impl.cpp | 6 +++--- modules/viz/src/viz3d_impl.hpp | 36 +++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index 18be02321..dbf93f49d 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -116,7 +116,7 @@ cv::viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) // Filter colors Vec3b* colors_data = new Vec3b[nr_points]; - NanFilter::copy(colors, colors_data, cloud); + NanFilter::copyColor(colors, colors_data, cloud); vtkSmartPointer scalars = vtkSmartPointer::New (); scalars->SetNumberOfComponents (3); @@ -384,7 +384,7 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) { Vec3b * colors_data = 0; colors_data = new Vec3b[nr_points]; - NanFilter::copy(mesh.colors, colors_data, mesh.cloud); + NanFilter::copyColor(mesh.colors, colors_data, mesh.cloud); scalars = vtkSmartPointer::New (); scalars->SetNumberOfComponents (3); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 7cb25a036..871c2dbcb 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -111,7 +111,7 @@ struct cv::viz::Mesh3d::loadMeshImpl Vec3b point_color; poly_colors->GetTupleValue (i, point_color.val); - //RGB or BGR? should we swap channels???? + std::swap(point_color[0], point_color[2]); // RGB -> BGR mesh_colors[i] = point_color; } } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 0220d9c65..ca4b75bbf 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -847,7 +847,7 @@ bool cv::viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, return (true); } -bool cv::viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& mesh, const std::string &id) +bool cv::viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& /*mesh*/, const std::string &/*id*/) { // CV_Assert(mesh.cloud.rows == 1 && mesh.cloud.type() == CV_32FC3); // @@ -1017,7 +1017,7 @@ void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPosition (x, y); } void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } -bool cv::viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& mesh, const Mat& mask, const std::string &id) +bool cv::viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& /*mesh*/, const Mat& /*mask*/, const std::string &/*id*/) { // CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); // CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); @@ -1205,7 +1205,7 @@ return true; } -bool cv::viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const std::string &id) +bool cv::viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& /*mesh*/, const cv::Mat& /*mask*/, const std::string &/*id*/) { // CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); // CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index f3f245c93..04b816d48 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -327,6 +327,31 @@ namespace cv } return output; } + + static _Out* copyColor(const Mat& source, _Out* output, const Mat& nan_mask) + { + CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size()); + CV_Assert(nan_mask.channels() == 3 || nan_mask.channels() == 4); + CV_DbgAssert(DataDepth<_Msk>::value == nan_mask.depth()); + + int s_chs = source.channels(); + int m_chs = nan_mask.channels(); + + for(int y = 0; y < source.rows; ++y) + { + const _Tp* srow = source.ptr<_Tp>(y); + const _Msk* mrow = nan_mask.ptr<_Msk>(y); + + for(int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) + if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) + { + *output = _Out(srow); + std::swap((*output)[0], (*output)[2]); // BGR -> RGB + ++output; + } + } + return output; + } }; template @@ -339,6 +364,17 @@ namespace cv return table[nan_mask.depth() - 5](source, output, nan_mask); } + + template + static inline Vec<_Tp, 3>* copyColor(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask) + { + CV_Assert(nan_mask.depth() == CV_32F || nan_mask.depth() == CV_64F); + + typedef Vec<_Tp, 3>* (*copy_func)(const Mat&, Vec<_Tp, 3>*, const Mat&); + const static copy_func table[2] = { &NanFilter::Impl<_Tp, float>::copyColor, &NanFilter::Impl<_Tp, double>::copyColor }; + + return table[nan_mask.depth() - 5](source, output, nan_mask); + } }; struct ApplyAffine From 769eba7535d35b384ba5f45fbb006894a3036895 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 15 Jul 2013 16:47:19 +0200 Subject: [PATCH 092/205] cube wire_frame fix using vtkOutlineSource --- modules/viz/src/precomp.hpp | 1 + modules/viz/src/shape_widgets.cpp | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index df3a97040..73a1a85f5 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 2272e17f8..89818062e 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -269,19 +269,24 @@ template<> cv::viz::CylinderWidget cv::viz::Widget::cast cube = vtkSmartPointer::New (); - cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); +{ + vtkSmartPointer mapper = vtkSmartPointer::New (); + if (wire_frame) + { + vtkSmartPointer cube = vtkSmartPointer::New(); + cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); + mapper->SetInput(cube->GetOutput ()); + } + else + { + vtkSmartPointer cube = vtkSmartPointer::New (); + cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); + mapper->SetInput(cube->GetOutput ()); + } - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(cube->GetOutput ()); - vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - if (wire_frame) - actor->GetProperty ()->SetRepresentationToWireframe (); - WidgetAccessor::setProp(*this, actor); setColor(color); } From 40e47e6f3f2f272fd8eda12ce4cabf1644c64f39 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 17 Jul 2013 11:35:14 +0200 Subject: [PATCH 093/205] Image widgets implementation, GridWidget: vtkExtractEdges instead of Wireframe --- modules/viz/include/opencv2/viz/widgets.hpp | 24 ++ modules/viz/src/precomp.hpp | 3 +- modules/viz/src/shape_widgets.cpp | 239 +++++++++++++++++++- 3 files changed, 262 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 56ecde784..4ed47e116 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -140,6 +140,28 @@ namespace cv void setText(const String &text); String getText() const; }; + + class CV_EXPORTS ImageOverlayWidget : public Widget2D + { + public: + ImageOverlayWidget(const Mat &image, const Point2i &pos); + + void setImage(const Mat &image); + + private: + struct CopyImpl; + }; + + class CV_EXPORTS Image3DWidget : public Widget3D + { + public: + Image3DWidget(const Mat &image); + + void setImage(const Mat &image); + + private: + struct CopyImpl; + }; class CV_EXPORTS CloudWidget : public Widget3D { @@ -183,6 +205,8 @@ namespace cv template<> CV_EXPORTS GridWidget Widget::cast(); template<> CV_EXPORTS Text3DWidget Widget::cast(); template<> CV_EXPORTS TextWidget Widget::cast(); + template<> CV_EXPORTS ImageOverlayWidget Widget::cast(); + template<> CV_EXPORTS Image3DWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); template<> CV_EXPORTS MeshWidget Widget::cast(); diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 73a1a85f5..0974dc5da 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -108,6 +108,7 @@ #include #include #include +#include #include #include @@ -132,7 +133,7 @@ #include #include #include - +#include #include #include diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 89818062e..cca8b3383 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -432,13 +432,17 @@ cv::viz::GridWidget::GridWidget(Vec2i dimensions, Vec2d spacing, const Color &co // Set origin of the grid to be the middle of the grid grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0); + // Extract the edges so we have the grid + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInputConnection(grid->GetProducerPort()); + filter->Update(); + vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(grid); + mapper->SetInput(filter->GetOutput()); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - // Show it as wireframe - actor->GetProperty ()->SetRepresentationToWireframe (); WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -542,3 +546,232 @@ cv::String cv::viz::TextWidget::getText() const CV_Assert(actor); return actor->GetInput(); } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// image overlay widget implementation + +struct cv::viz::ImageOverlayWidget::CopyImpl +{ + struct Impl + { + static void copyImageMultiChannel(const Mat &image, vtkSmartPointer output) + { + int i_chs = image.channels(); + + for (int i = 0; i < image.rows; ++i) + { + const unsigned char * irows = image.ptr(i); + for (int j = 0; j < image.cols; ++j, irows += i_chs) + { + unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); + memcpy(vrows, irows, i_chs); + std::swap(vrows[0], vrows[2]); // BGR -> RGB + } + } + output->Modified(); + } + + static void copyImageSingleChannel(const Mat &image, vtkSmartPointer output) + { + for (int i = 0; i < image.rows; ++i) + { + const unsigned char * irows = image.ptr(i); + for (int j = 0; j < image.cols; ++j, ++irows) + { + unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); + *vrows = *irows; + } + } + output->Modified(); + } + }; + + static void copyImage(const Mat &image, vtkSmartPointer output) + { + int i_chs = image.channels(); + if (i_chs > 1) + { + // Multi channel images are handled differently because of BGR <-> RGB + Impl::copyImageMultiChannel(image, output); + } + else + { + Impl::copyImageSingleChannel(image, output); + } + } +}; + +cv::viz::ImageOverlayWidget::ImageOverlayWidget(const Mat &image, const Point2i &pos) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + // Create the vtk image and set its parameters based on input image + vtkSmartPointer vtk_image = vtkSmartPointer::New(); + vtk_image->SetDimensions(image.cols, image.rows, 1); + vtk_image->SetNumberOfScalarComponents(image.channels()); + vtk_image->SetScalarTypeToUnsignedChar(); + vtk_image->AllocateScalars(); + + CopyImpl::copyImage(image, vtk_image); + + // Need to flip the image as the coordinates are different in OpenCV and VTK + vtkSmartPointer flipFilter = vtkSmartPointer::New(); + flipFilter->SetFilteredAxis(1); // Vertical flip + flipFilter->SetInputConnection(vtk_image->GetProducerPort()); + flipFilter->Update(); + + vtkSmartPointer imageMapper = vtkSmartPointer::New(); + imageMapper->SetInputConnection(flipFilter->GetOutputPort()); + imageMapper->SetColorWindow(255); // OpenCV color + imageMapper->SetColorLevel(127.5); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(imageMapper); + actor->SetPosition(pos.x, pos.y); + + WidgetAccessor::setProp(*this, actor); +} + +void cv::viz::ImageOverlayWidget::setImage(const Mat &image) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + vtkImageMapper *mapper = vtkImageMapper::SafeDownCast(actor->GetMapper()); + CV_Assert(mapper); + + // Create the vtk image and set its parameters based on input image + vtkSmartPointer vtk_image = vtkSmartPointer::New(); + vtk_image->SetDimensions(image.cols, image.rows, 1); + vtk_image->SetNumberOfScalarComponents(image.channels()); + vtk_image->SetScalarTypeToUnsignedChar(); + vtk_image->AllocateScalars(); + + CopyImpl::copyImage(image, vtk_image); + + // Need to flip the image as the coordinates are different in OpenCV and VTK + vtkSmartPointer flipFilter = vtkSmartPointer::New(); + flipFilter->SetFilteredAxis(1); // Vertical flip + flipFilter->SetInputConnection(vtk_image->GetProducerPort()); + flipFilter->Update(); + + mapper->SetInputConnection(flipFilter->GetOutputPort()); +} + +template<> cv::viz::ImageOverlayWidget cv::viz::Widget::cast() +{ + Widget2D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// image 3D widget implementation + +struct cv::viz::Image3DWidget::CopyImpl +{ + struct Impl + { + static void copyImageMultiChannel(const Mat &image, vtkSmartPointer output) + { + int i_chs = image.channels(); + + for (int i = 0; i < image.rows; ++i) + { + const unsigned char * irows = image.ptr(i); + for (int j = 0; j < image.cols; ++j, irows += i_chs) + { + unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); + memcpy(vrows, irows, i_chs); + std::swap(vrows[0], vrows[2]); // BGR -> RGB + } + } + output->Modified(); + } + + static void copyImageSingleChannel(const Mat &image, vtkSmartPointer output) + { + for (int i = 0; i < image.rows; ++i) + { + const unsigned char * irows = image.ptr(i); + for (int j = 0; j < image.cols; ++j, ++irows) + { + unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); + *vrows = *irows; + } + } + output->Modified(); + } + }; + + static void copyImage(const Mat &image, vtkSmartPointer output) + { + int i_chs = image.channels(); + if (i_chs > 1) + { + // Multi channel images are handled differently because of BGR <-> RGB + Impl::copyImageMultiChannel(image, output); + } + else + { + Impl::copyImageSingleChannel(image, output); + } + } +}; + +cv::viz::Image3DWidget::Image3DWidget(const Mat &image) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + // Create the vtk image and set its parameters based on input image + vtkSmartPointer vtk_image = vtkSmartPointer::New(); + vtk_image->SetDimensions(image.cols, image.rows, 1); + vtk_image->SetNumberOfScalarComponents(image.channels()); + vtk_image->SetScalarTypeToUnsignedChar(); + vtk_image->AllocateScalars(); + + CopyImpl::copyImage(image, vtk_image); + + // Need to flip the image as the coordinates are different in OpenCV and VTK + vtkSmartPointer flipFilter = vtkSmartPointer::New(); + flipFilter->SetFilteredAxis(1); // Vertical flip + flipFilter->SetInputConnection(vtk_image->GetProducerPort()); + flipFilter->Update(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetInput(flipFilter->GetOutput()); + + WidgetAccessor::setProp(*this, actor); +} + +void cv::viz::Image3DWidget::setImage(const Mat &image) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + vtkImageActor *actor = vtkImageActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + // Create the vtk image and set its parameters based on input image + vtkSmartPointer vtk_image = vtkSmartPointer::New(); + vtk_image->SetDimensions(image.cols, image.rows, 1); + vtk_image->SetNumberOfScalarComponents(image.channels()); + vtk_image->SetScalarTypeToUnsignedChar(); + vtk_image->AllocateScalars(); + + CopyImpl::copyImage(image, vtk_image); + + // Need to flip the image as the coordinates are different in OpenCV and VTK + vtkSmartPointer flipFilter = vtkSmartPointer::New(); + flipFilter->SetFilteredAxis(1); // Vertical flip + flipFilter->SetInputConnection(vtk_image->GetProducerPort()); + flipFilter->Update(); + + actor->SetInput(flipFilter->GetOutput()); +} + +template<> cv::viz::Image3DWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} \ No newline at end of file From 3260404fdf939d9b41d76a5ae427b5f37b9ab8ba Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 18 Jul 2013 10:39:34 +0200 Subject: [PATCH 094/205] initial CameraPositionWidget implementation using eye, look_at, up_vector --- modules/viz/include/opencv2/viz/widgets.hpp | 8 +++ modules/viz/src/shape_widgets.cpp | 70 +++++++++++++++++++++ modules/viz/test/test_viz3d.cpp | 49 ++++++++++----- 3 files changed, 110 insertions(+), 17 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 4ed47e116..1e46ada34 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace cv @@ -162,6 +163,13 @@ namespace cv private: struct CopyImpl; }; + + class CV_EXPORTS CameraPositionWidget : public Widget3D + { + public: + CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale = 1.0); + + }; class CV_EXPORTS CloudWidget : public Widget3D { diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index cca8b3383..05715b4ae 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -774,4 +774,74 @@ template<> cv::viz::Image3DWidget cv::viz::Widget::cast( { Widget3D widget = this->cast(); return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// camera position widget implementation +cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale) +{ + vtkSmartPointer axes = vtkSmartPointer::New (); + axes->SetOrigin (0, 0, 0); + axes->SetScaleFactor (scale); + + // Compute the transformation matrix for drawing the camera frame in a scene + Vec3f u,v,n; + n = normalize(look_at - position); + u = normalize(up_vector.cross(n)); + v = n.cross(u); + + vtkSmartPointer mat_trans = vtkSmartPointer::New(); + mat_trans->SetElement(0,0,u[0]); + mat_trans->SetElement(0,1,u[1]); + mat_trans->SetElement(0,2,u[2]); + mat_trans->SetElement(1,0,v[0]); + mat_trans->SetElement(1,1,v[1]); + mat_trans->SetElement(1,2,v[2]); + mat_trans->SetElement(2,0,n[0]); + mat_trans->SetElement(2,1,n[1]); + mat_trans->SetElement(2,2,n[2]); + // Inverse rotation (orthogonal, so just take transpose) + mat_trans->Transpose(); + // Then translate the coordinate frame to camera position + mat_trans->SetElement(0,3,position[0]); + mat_trans->SetElement(1,3,position[1]); + mat_trans->SetElement(2,3,position[2]); + mat_trans->SetElement(3,3,1); + + vtkSmartPointer axes_colors = vtkSmartPointer::New (); + axes_colors->Allocate (6); + axes_colors->InsertNextValue (0.0); + axes_colors->InsertNextValue (0.0); + axes_colors->InsertNextValue (0.5); + axes_colors->InsertNextValue (0.5); + axes_colors->InsertNextValue (1.0); + axes_colors->InsertNextValue (1.0); + + vtkSmartPointer axes_data = axes->GetOutput (); + axes_data->Update (); + axes_data->GetPointData ()->SetScalars (axes_colors); + + // Transform the default coordinate frame + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->SetMatrix(mat_trans); + + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(axes_data); + filter->SetTransform(transform); + filter->Update(); + + vtkSmartPointer axes_tubes = vtkSmartPointer::New (); + axes_tubes->SetInput (filter->GetOutput()); + axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); + axes_tubes->SetNumberOfSides (6); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetScalarModeToUsePointData (); + mapper->SetInput(axes_tubes->GetOutput ()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); } \ No newline at end of file diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 687d9f19d..067be215b 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -89,7 +90,7 @@ TEST(Viz_viz3d, accuracy) viz::LineWidget lw(Point3f(0, 0, 0), Point3f(4.f, 4.f,4.f), viz::Color::green()); viz::PlaneWidget pw(Vec4f(0.0,1.0,2.0,3.0), 5.0); - viz::SphereWidget sw(Point3f(0, 0, 0), 0.5); + viz::SphereWidget sw(Point3f(0, 0, 0), 0.2); viz::ArrowWidget aw(Point3f(0, 0, 0), Point3f(1, 1, 1), 0.01, viz::Color::red()); viz::CircleWidget cw(Point3f(0, 0, 0), 0.5, 0.01, viz::Color::green()); viz::CylinderWidget cyw(Point3f(0, 0, 0), Point3f(-1, -1, -1), 0.5, 30, viz::Color::green()); @@ -99,18 +100,18 @@ TEST(Viz_viz3d, accuracy) viz::CloudWidget pcw(cloud, colors); viz::CloudWidget pcw2(cloud, viz::Color::magenta()); - viz.showWidget("line", lw); - viz.showWidget("plane", pw); +// viz.showWidget("line", lw); +// viz.showWidget("plane", pw); viz.showWidget("sphere", sw); - viz.showWidget("arrow", aw); - viz.showWidget("circle", cw); - viz.showWidget("cylinder", cyw); - viz.showWidget("cube", cuw); +// viz.showWidget("arrow", aw); +// viz.showWidget("circle", cw); +// viz.showWidget("cylinder", cyw); +// viz.showWidget("cube", cuw); viz.showWidget("coordinateSystem", csw); - viz.showWidget("coordinateSystem2", viz::CoordinateSystemWidget(2.0), Affine3f().translate(Vec3f(2, 0, 0))); - viz.showWidget("text",tw); - viz.showWidget("pcw",pcw); - viz.showWidget("pcw2",pcw2); +// viz.showWidget("coordinateSystem2", viz::CoordinateSystemWidget(2.0), Affine3f().translate(Vec3f(2, 0, 0))); +// viz.showWidget("text",tw); +// viz.showWidget("pcw",pcw); +// viz.showWidget("pcw2",pcw2); // viz::LineWidget lw2 = lw; // v.showPointCloud("cld",cloud, colors); @@ -125,13 +126,26 @@ TEST(Viz_viz3d, accuracy) viz::PolyLineWidget plw(points, viz::Color::green()); - viz.showWidget("polyline", plw); +// viz.showWidget("polyline", plw); // lw = v.getWidget("polyline").cast(); - viz::Mesh3d::Ptr mesh = cv::viz::Mesh3d::loadMesh("horse.ply"); + viz::Mesh3d mesh = cv::viz::Mesh3d::loadMesh("horse.ply"); - viz::MeshWidget mw(*mesh); - viz.showWidget("mesh", mw); + viz::MeshWidget mw(mesh); +// viz.showWidget("mesh", mw); + + Mat img = imread("opencv.png"); +// resize(img, img, Size(50,50)); +// viz.showWidget("img", viz::ImageOverlayWidget(img, Point2i(50,50))); + + viz::CameraPositionWidget cpw(Vec3f(0.5, 0.5, 3.0), Vec3f(0.0,0.0,0.0), Vec3f(0.0,-1.0,0.0), 0.5); + viz::Text3DWidget t3w1("Camera1", Point3f(0.4, 0.6, 3.0), 0.1); + + + viz.showWidget("CameraPositionWidget", cpw); + viz.showWidget("camera_label", t3w1); +// viz.showWidget("CameraPositionWidget2", cpw2); +// viz.showWidget("CameraPositionWidget3", cpw3); viz.spin(); @@ -156,13 +170,14 @@ TEST(Viz_viz3d, accuracy) //plw.setColor(viz::Color(col_blue, col_green, col_red)); - sw.setPose(cloudPosition); +// sw.setPose(cloudPosition); // pw.setPose(cloudPosition); aw.setPose(cloudPosition); cw.setPose(cloudPosition); cyw.setPose(cloudPosition); // lw.setPose(cloudPosition); - cuw.setPose(cloudPosition); +// cpw.updatePose(Affine3f(0.1,0.0,0.0, cv::Vec3f(0.0,0.0,0.0))); +// cpw.setPose(cloudPosition); // cnw.setPose(cloudPosition); // v.showWidget("pcw",pcw, cloudPosition); // v.showWidget("pcw2",pcw2, cloudPosition2); From 9d3f3c66da9f78437ace62958d3e84a20b447628 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 18 Jul 2013 17:08:58 +0200 Subject: [PATCH 095/205] camera position widget: constructor with no parameter, constructor with intrinsic matrix for visualizing frustum --- modules/viz/include/opencv2/viz/widgets.hpp | 3 +- modules/viz/src/precomp.hpp | 1 + modules/viz/src/shape_widgets.cpp | 80 ++++++++++++++++++++- modules/viz/test/test_viz3d.cpp | 16 ++++- 4 files changed, 96 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 1e46ada34..aa2bc49b9 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -167,8 +167,9 @@ namespace cv class CV_EXPORTS CameraPositionWidget : public Widget3D { public: + CameraPositionWidget(double scale = 1.0); CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale = 1.0); - + CameraPositionWidget(const Matx33f &K, const Color &color = Color::white()); }; class CV_EXPORTS CloudWidget : public Widget3D diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 0974dc5da..148fbb54d 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -134,6 +134,7 @@ #include #include #include +#include #include #include diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 05715b4ae..5ab15b8ce 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -778,6 +778,41 @@ template<> cv::viz::Image3DWidget cv::viz::Widget::cast( /////////////////////////////////////////////////////////////////////////////////////////////// /// camera position widget implementation + +cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) +{ + vtkSmartPointer axes = vtkSmartPointer::New (); + axes->SetOrigin (0, 0, 0); + axes->SetScaleFactor (scale); + + vtkSmartPointer axes_colors = vtkSmartPointer::New (); + axes_colors->Allocate (6); + axes_colors->InsertNextValue (0.0); + axes_colors->InsertNextValue (0.0); + axes_colors->InsertNextValue (0.5); + axes_colors->InsertNextValue (0.5); + axes_colors->InsertNextValue (1.0); + axes_colors->InsertNextValue (1.0); + + vtkSmartPointer axes_data = axes->GetOutput (); + axes_data->Update (); + axes_data->GetPointData ()->SetScalars (axes_colors); + + vtkSmartPointer axes_tubes = vtkSmartPointer::New (); + axes_tubes->SetInput (axes_data); + axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); + axes_tubes->SetNumberOfSides (6); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetScalarModeToUsePointData (); + mapper->SetInput(axes_tubes->GetOutput ()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale) { vtkSmartPointer axes = vtkSmartPointer::New (); @@ -844,4 +879,47 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec3f &position, const actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); -} \ No newline at end of file +} + +cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Color &color) +{ + vtkSmartPointer camera = vtkSmartPointer::New(); + float focal_length = K(0,0); + float c_x = K(0,2); + float c_y = K(1,2); + float aspect_ratio = c_x / c_y; + float img_width = c_x * 2; + float img_height = c_y * 2; + // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) + float fovy = 2.0f * atan2(c_y,focal_length) * 180 / CV_PI; + + camera->SetViewAngle(fovy); + camera->SetPosition(0.0,0.0,0.0); + camera->SetViewUp(0.0,1.0,0.0); + camera->SetFocalPoint(0.0,0.0,1.0); + + double planesArray[24]; + camera->GetFrustumPlanes(aspect_ratio, planesArray); + + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planesArray); + + vtkSmartPointer frustumSource = + vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + frustumSource->Update(); + + // Extract the edges so we have the grid + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(frustumSource->GetOutput()); + filter->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(filter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 067be215b..b234c99d5 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -138,12 +138,22 @@ TEST(Viz_viz3d, accuracy) // resize(img, img, Size(50,50)); // viz.showWidget("img", viz::ImageOverlayWidget(img, Point2i(50,50))); - viz::CameraPositionWidget cpw(Vec3f(0.5, 0.5, 3.0), Vec3f(0.0,0.0,0.0), Vec3f(0.0,-1.0,0.0), 0.5); - viz::Text3DWidget t3w1("Camera1", Point3f(0.4, 0.6, 3.0), 0.1); + Matx33f K(657, 0, 320, + 0, 657, 240, + 0, 0, 1); + viz::CameraPositionWidget cpw(Vec3f(0.5, 0.5, 3.0), Vec3f(0.0,0.0,0.0), Vec3f(0.0,-1.0,0.0), 0.5); + viz::CameraPositionWidget cpw2(0.5); + viz::CameraPositionWidget frustum(K, viz::Color::green()); + viz::Text3DWidget t3w1("Camera1", Point3f(0.4, 0.6, 3.0), 0.1); + viz::Text3DWidget t3w2("Camera2", Point3f(0,0,0), 0.1); viz.showWidget("CameraPositionWidget", cpw); + viz.showWidget("CameraPositionWidget2", cpw2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); viz.showWidget("camera_label", t3w1); + viz.showWidget("camera_label2", t3w2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); + viz.showWidget("frustrum", frustum, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); + // viz.showWidget("CameraPositionWidget2", cpw2); // viz.showWidget("CameraPositionWidget3", cpw3); @@ -175,6 +185,8 @@ TEST(Viz_viz3d, accuracy) aw.setPose(cloudPosition); cw.setPose(cloudPosition); cyw.setPose(cloudPosition); + + frustum.setPose(cloudPosition); // lw.setPose(cloudPosition); // cpw.updatePose(Affine3f(0.1,0.0,0.0, cv::Vec3f(0.0,0.0,0.0))); // cpw.setPose(cloudPosition); From 2294eb82c9d63f2eaae01a1d9d2998afd9fe388e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 18 Jul 2013 17:46:08 +0200 Subject: [PATCH 096/205] fix aspect_ratio in camera position widget, add scale parameter (tentative implementation of scale) --- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/shape_widgets.cpp | 13 ++++++------- modules/viz/test/test_viz3d.cpp | 4 +++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index aa2bc49b9..23ce27fea 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -169,7 +169,7 @@ namespace cv public: CameraPositionWidget(double scale = 1.0); CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale = 1.0); - CameraPositionWidget(const Matx33f &K, const Color &color = Color::white()); + CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); }; class CV_EXPORTS CloudWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 5ab15b8ce..a55ecafb9 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -881,22 +881,21 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec3f &position, const WidgetAccessor::setProp(*this, actor); } -cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Color &color) +cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); - float focal_length = K(0,0); - float c_x = K(0,2); + float f_x = K(0,0); + float f_y = K(1,1); float c_y = K(1,2); - float aspect_ratio = c_x / c_y; - float img_width = c_x * 2; - float img_height = c_y * 2; + float aspect_ratio = f_y / f_x; // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) - float fovy = 2.0f * atan2(c_y,focal_length) * 180 / CV_PI; + float fovy = 2.0f * atan2(c_y,f_y) * 180 / CV_PI; camera->SetViewAngle(fovy); camera->SetPosition(0.0,0.0,0.0); camera->SetViewUp(0.0,1.0,0.0); camera->SetFocalPoint(0.0,0.0,1.0); + camera->SetClippingRange(0.01, scale * f_y * 0.001); double planesArray[24]; camera->GetFrustumPlanes(aspect_ratio, planesArray); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index b234c99d5..2fe9ca1c1 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -144,7 +144,8 @@ TEST(Viz_viz3d, accuracy) viz::CameraPositionWidget cpw(Vec3f(0.5, 0.5, 3.0), Vec3f(0.0,0.0,0.0), Vec3f(0.0,-1.0,0.0), 0.5); viz::CameraPositionWidget cpw2(0.5); - viz::CameraPositionWidget frustum(K, viz::Color::green()); + viz::CameraPositionWidget frustum(K, 2.0, viz::Color::green()); + viz::CameraPositionWidget frustum2(K, 4.0, viz::Color::red()); viz::Text3DWidget t3w1("Camera1", Point3f(0.4, 0.6, 3.0), 0.1); viz::Text3DWidget t3w2("Camera2", Point3f(0,0,0), 0.1); @@ -153,6 +154,7 @@ TEST(Viz_viz3d, accuracy) viz.showWidget("camera_label", t3w1); viz.showWidget("camera_label2", t3w2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); viz.showWidget("frustrum", frustum, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); + viz.showWidget("frustrum2", frustum2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); // viz.showWidget("CameraPositionWidget2", cpw2); // viz.showWidget("CameraPositionWidget3", cpw3); From 0a3691d6acb76c8a557237bc964aa97ada6400a9 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 19 Jul 2013 18:30:12 +0200 Subject: [PATCH 097/205] CameraPositionWidget: constructor with Vec2f fov (tentative) --- modules/viz/include/opencv2/viz/widgets.hpp | 1 + modules/viz/src/shape_widgets.cpp | 40 ++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 23ce27fea..7eeaa5d77 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -170,6 +170,7 @@ namespace cv CameraPositionWidget(double scale = 1.0); CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale = 1.0); CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); }; class CV_EXPORTS CloudWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index a55ecafb9..6c75b24c7 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -895,7 +895,7 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, double sca camera->SetPosition(0.0,0.0,0.0); camera->SetViewUp(0.0,1.0,0.0); camera->SetFocalPoint(0.0,0.0,1.0); - camera->SetClippingRange(0.01, scale * f_y * 0.001); + camera->SetClippingRange(0.01, scale); double planesArray[24]; camera->GetFrustumPlanes(aspect_ratio, planesArray); @@ -922,3 +922,41 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, double sca WidgetAccessor::setProp(*this, actor); setColor(color); } + + +cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double scale, const Color &color) +{ + vtkSmartPointer camera = vtkSmartPointer::New(); + + camera->SetViewAngle(fov[1] * 180 / CV_PI); // Vertical field of view + camera->SetPosition(0.0,0.0,0.0); + camera->SetViewUp(0.0,1.0,0.0); + camera->SetFocalPoint(0.0,0.0,1.0); + camera->SetClippingRange(0.01, scale); + + double planesArray[24]; + // Default aspect ratio = 1.0? fovx/fovy? + camera->GetFrustumPlanes(1.0, planesArray); + + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planesArray); + + vtkSmartPointer frustumSource = + vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + frustumSource->Update(); + + // Extract the edges so we have the grid + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(frustumSource->GetOutput()); + filter->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(filter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} From 13a2516a6a3709caca2a95b3d9f6879ca5d3896b Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 09:11:16 +0200 Subject: [PATCH 098/205] avoid memory leak in mesh widget --- modules/viz/src/cloud_widgets.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index dbf93f49d..9eec79074 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -359,7 +359,8 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) vtkSmartPointer points = vtkSmartPointer::New (); vtkIdType nr_points = mesh.cloud.total(); - int * look_up = new int[nr_points]; + Mat look_up_mat(1, nr_points, CV_32SC1); + int * look_up = look_up_mat.ptr(); points->SetNumberOfPoints (nr_points); // Copy data from cloud to vtkPoints From f3b228c91f95b3231254738df7d2e76003fbcc9a Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 12:53:19 +0200 Subject: [PATCH 099/205] initial implementation of trajectory widget --- modules/viz/include/opencv2/viz/widgets.hpp | 8 ++ modules/viz/src/shape_widgets.cpp | 101 ++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 7eeaa5d77..2a7b67834 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -172,6 +172,14 @@ namespace cv CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); }; + + class CV_EXPORTS TrajectoryWidget : public Widget3D + { + public: + TrajectoryWidget(const std::vector &path, const Color &color = Color::white(), bool show_frames = false, double scale = 1.0); +// TrajectoryWidget(const std::vector &path, double scale = 1.0); + TrajectoryWidget(const std::vector &path, const Matx33f &K); // Camera frustums + }; class CV_EXPORTS CloudWidget : public Widget3D { diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 6c75b24c7..90a0cf7b2 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -960,3 +960,104 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double sca WidgetAccessor::setProp(*this, actor); setColor(color); } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// trajectory widget implementation + +cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Color &color, bool show_frames, double scale) +{ + vtkIdType nr_points = path.size(); + + vtkSmartPointer points = vtkSmartPointer::New (); + vtkSmartPointer polyData = vtkSmartPointer::New (); + vtkSmartPointer polyLine = vtkSmartPointer::New (); + + points->SetDataTypeToFloat(); + points->SetNumberOfPoints(nr_points); + polyLine->GetPointIds()->SetNumberOfIds(nr_points); + + Vec3f last_pos(0.0f,0.0f,0.0f); + Vec3f *data_beg = vtkpoints_data(points); + *data_beg = path[0] * last_pos; + + for (vtkIdType i = 0; i < nr_points; ++i) + { + last_pos = path[i] * last_pos; + *data_beg++ = last_pos; + polyLine->GetPointIds()->SetId(i,i); + } + + vtkSmartPointer cells = vtkSmartPointer::New(); + cells->InsertNextCell(polyLine); + + polyData->SetPoints(points); + polyData->SetLines(cells); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + if (show_frames) + { + vtkSmartPointer mat_trans = vtkSmartPointer::New(); + mat_trans->Identity(); + + for (vtkIdType i = 0; i < nr_points; ++i) + { + vtkSmartPointer axes = vtkSmartPointer::New(); + axes->SetOrigin (0, 0, 0); + axes->SetScaleFactor (scale); + + vtkSmartPointer axes_colors = vtkSmartPointer::New (); + axes_colors->SetNumberOfComponents(3); + axes_colors->InsertNextTuple3(255,0,0); + axes_colors->InsertNextTuple3(255,0,0); + axes_colors->InsertNextTuple3(0,255,0); + axes_colors->InsertNextTuple3(0,255,0); + axes_colors->InsertNextTuple3(0,0,255); + axes_colors->InsertNextTuple3(0,0,255); + + vtkSmartPointer axes_data = axes->GetOutput (); + axes_data->Update (); + axes_data->GetPointData ()->SetScalars (axes_colors); + + // Transform the default coordinate frame + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + vtkMatrix4x4::Multiply4x4(convertToVtkMatrix(path[i].matrix), mat_trans, mat_trans); + transform->SetMatrix(mat_trans); + + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(axes_data); + filter->SetTransform(transform); + filter->Update(); + + vtkSmartPointer axes_tubes = vtkSmartPointer::New (); + axes_tubes->SetInput (filter->GetOutput()); + axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); + axes_tubes->SetNumberOfSides (6); + + appendFilter->AddInputConnection(axes_tubes->GetOutputPort()); + } + } + + // Set the color only for polyData + vtkSmartPointer colors = vtkSmartPointer::New(); + colors->SetNumberOfComponents(3); + + // TODO Make this more efficient + for (int i = 0; i < nr_points; ++i) + colors->InsertNextTuple3(color[2], color[1], color[0]); + + polyData->GetPointData()->SetScalars(colors); + + appendFilter->AddInputConnection(polyData->GetProducerPort()); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUsePointData (); + mapper->SetInput(appendFilter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + + From 16c8c98895d3a29ba1b20904c40ed4363972568b Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 14:11:06 +0200 Subject: [PATCH 100/205] trajectory widget with frustums --- modules/viz/include/opencv2/viz/widgets.hpp | 3 +- modules/viz/src/shape_widgets.cpp | 63 ++++++++++++++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 2a7b67834..465517b7d 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -177,8 +177,7 @@ namespace cv { public: TrajectoryWidget(const std::vector &path, const Color &color = Color::white(), bool show_frames = false, double scale = 1.0); -// TrajectoryWidget(const std::vector &path, double scale = 1.0); - TrajectoryWidget(const std::vector &path, const Matx33f &K); // Camera frustums + TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); // Camera frustums }; class CV_EXPORTS CloudWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 90a0cf7b2..13241073e 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -908,7 +908,6 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, double sca frustumSource->SetPlanes(planes); frustumSource->Update(); - // Extract the edges so we have the grid vtkSmartPointer filter = vtkSmartPointer::New(); filter->SetInput(frustumSource->GetOutput()); filter->Update(); @@ -1060,4 +1059,66 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c WidgetAccessor::setProp(*this, actor); } +cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale, const Color &color) +{ + vtkIdType nr_points = path.size(); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + + vtkSmartPointer camera = vtkSmartPointer::New(); + float f_x = K(0,0); + float f_y = K(1,1); + float c_y = K(1,2); + float aspect_ratio = f_y / f_x; + // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) + float fovy = 2.0f * atan2(c_y,f_y) * 180 / CV_PI; + + camera->SetViewAngle(fovy); + camera->SetPosition(0.0,0.0,0.0); + camera->SetViewUp(0.0,1.0,0.0); + camera->SetFocalPoint(0.0,0.0,1.0); + camera->SetClippingRange(0.01, scale); + + double planesArray[24]; + camera->GetFrustumPlanes(aspect_ratio, planesArray); + + vtkSmartPointer mat_trans = vtkSmartPointer::New(); + mat_trans->Identity(); + + for (vtkIdType i = 0; i < nr_points; ++i) + { + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planesArray); + + vtkSmartPointer frustumSource = vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + frustumSource->Update(); + // Extract the edges + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(frustumSource->GetOutput()); + filter->Update(); + + // Transform the default coordinate frame + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + vtkMatrix4x4::Multiply4x4(convertToVtkMatrix(path[i].matrix), mat_trans, mat_trans); + transform->SetMatrix(mat_trans); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetInput(filter->GetOutput()); + transform_filter->SetTransform(transform); + transform_filter->Update(); + + appendFilter->AddInputConnection(transform_filter->GetOutputPort()); + } + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(appendFilter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} From 5af739dfc1f598dd8547e8eb000c64e1363601bc Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 14:34:44 +0200 Subject: [PATCH 101/205] plane widget size fix --- modules/viz/include/opencv2/viz/widgets.hpp | 2 ++ modules/viz/src/shape_widgets.cpp | 29 ++++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 465517b7d..48616ca3f 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -71,6 +71,8 @@ namespace cv public: PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); + private: + struct SetSizeImpl; }; class CV_EXPORTS SphereWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 13241073e..4067ef5e9 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -50,6 +50,26 @@ template<> cv::viz::LineWidget cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// plane widget implementation +struct cv::viz::PlaneWidget::SetSizeImpl +{ + template + static vtkSmartPointer setSize(const Vec<_Tp, 3> ¢er, vtkSmartPointer poly_data, double size) + { + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->Translate(center[0], center[1], center[2]); + transform->Scale(size, size, size); + transform->Translate(-center[0], -center[1], -center[2]); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetInput(poly_data); + transform_filter->SetTransform(transform); + transform_filter->Update(); + + return transform_filter->GetOutput(); + } +}; + cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color &color) { vtkSmartPointer plane = vtkSmartPointer::New (); @@ -57,12 +77,14 @@ cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color & double norm = cv::norm(Vec3f(coefs.val)); plane->Push (-coefs[3] / norm); + Vec3d p_center; + plane->GetOrigin(p_center.val); + vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(plane->GetOutput ()); + mapper->SetInput(SetSizeImpl::setSize(p_center, plane->GetOutput(), size)); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - actor->SetScale(size); WidgetAccessor::setProp(*this, actor); setColor(color); @@ -80,11 +102,10 @@ cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double plane->SetCenter (p_center[0], p_center[1], p_center[2]); vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(plane->GetOutput ()); + mapper->SetInput(SetSizeImpl::setSize(p_center, plane->GetOutput(), size)); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - actor->SetScale(size); WidgetAccessor::setProp(*this, actor); setColor(color); From c0f44ca42117881df9c3d0213b5fb6586f5be5ac Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 15:03:28 +0200 Subject: [PATCH 102/205] shorten Trajectory widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 3 + modules/viz/src/shape_widgets.cpp | 133 ++++++++++---------- modules/viz/test/test_viz3d.cpp | 39 ++++-- 3 files changed, 98 insertions(+), 77 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 48616ca3f..101d8568d 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -180,6 +180,9 @@ namespace cv public: TrajectoryWidget(const std::vector &path, const Color &color = Color::white(), bool show_frames = false, double scale = 1.0); TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); // Camera frustums + + private: + struct ApplyPath; }; class CV_EXPORTS CloudWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 4067ef5e9..ed07691bb 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -984,6 +984,36 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double sca /////////////////////////////////////////////////////////////////////////////////////////////// /// trajectory widget implementation +struct cv::viz::TrajectoryWidget::ApplyPath +{ + static void applyPath(vtkSmartPointer poly_data, vtkSmartPointer append_filter, const std::vector &path) + { + vtkSmartPointer mat_trans = vtkSmartPointer::New(); + mat_trans->Identity(); + + vtkIdType nr_points = path.size(); + + for (vtkIdType i = 0; i < nr_points; ++i) + { + vtkSmartPointer new_data = vtkSmartPointer::New(); + new_data->DeepCopy(poly_data); + + // Transform the default coordinate frame + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + vtkMatrix4x4::Multiply4x4(convertToVtkMatrix(path[i].matrix), mat_trans, mat_trans); + transform->SetMatrix(mat_trans); + + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(new_data); + filter->SetTransform(transform); + filter->Update(); + + append_filter->AddInputConnection(filter->GetOutputPort()); + } + } +}; + cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Color &color, bool show_frames, double scale) { vtkIdType nr_points = path.size(); @@ -1016,49 +1046,33 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c vtkSmartPointer appendFilter = vtkSmartPointer::New(); if (show_frames) { - vtkSmartPointer mat_trans = vtkSmartPointer::New(); - mat_trans->Identity(); + vtkSmartPointer axes = vtkSmartPointer::New(); + axes->SetOrigin (0, 0, 0); + axes->SetScaleFactor (scale); - for (vtkIdType i = 0; i < nr_points; ++i) - { - vtkSmartPointer axes = vtkSmartPointer::New(); - axes->SetOrigin (0, 0, 0); - axes->SetScaleFactor (scale); - - vtkSmartPointer axes_colors = vtkSmartPointer::New (); - axes_colors->SetNumberOfComponents(3); - axes_colors->InsertNextTuple3(255,0,0); - axes_colors->InsertNextTuple3(255,0,0); - axes_colors->InsertNextTuple3(0,255,0); - axes_colors->InsertNextTuple3(0,255,0); - axes_colors->InsertNextTuple3(0,0,255); - axes_colors->InsertNextTuple3(0,0,255); - - vtkSmartPointer axes_data = axes->GetOutput (); - axes_data->Update (); - axes_data->GetPointData ()->SetScalars (axes_colors); - - // Transform the default coordinate frame - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->PreMultiply(); - vtkMatrix4x4::Multiply4x4(convertToVtkMatrix(path[i].matrix), mat_trans, mat_trans); - transform->SetMatrix(mat_trans); - - vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(axes_data); - filter->SetTransform(transform); - filter->Update(); - - vtkSmartPointer axes_tubes = vtkSmartPointer::New (); - axes_tubes->SetInput (filter->GetOutput()); - axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); - axes_tubes->SetNumberOfSides (6); - - appendFilter->AddInputConnection(axes_tubes->GetOutputPort()); - } + vtkSmartPointer axes_colors = vtkSmartPointer::New (); + axes_colors->SetNumberOfComponents(3); + axes_colors->InsertNextTuple3(255,0,0); + axes_colors->InsertNextTuple3(255,0,0); + axes_colors->InsertNextTuple3(0,255,0); + axes_colors->InsertNextTuple3(0,255,0); + axes_colors->InsertNextTuple3(0,0,255); + axes_colors->InsertNextTuple3(0,0,255); + + vtkSmartPointer axes_data = axes->GetOutput (); + axes_data->Update (); + axes_data->GetPointData ()->SetScalars (axes_colors); + + vtkSmartPointer axes_tubes = vtkSmartPointer::New (); + axes_tubes->SetInput (axes_data); + axes_tubes->SetRadius (axes->GetScaleFactor() / 50.0); + axes_tubes->SetNumberOfSides (6); + axes_tubes->Update(); + + ApplyPath::applyPath(axes_tubes->GetOutput(), appendFilter, path); } - // Set the color only for polyData + // Set the color for polyData vtkSmartPointer colors = vtkSmartPointer::New(); colors->SetNumberOfComponents(3); @@ -1103,36 +1117,19 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c double planesArray[24]; camera->GetFrustumPlanes(aspect_ratio, planesArray); - vtkSmartPointer mat_trans = vtkSmartPointer::New(); - mat_trans->Identity(); + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planesArray); - for (vtkIdType i = 0; i < nr_points; ++i) - { - vtkSmartPointer planes = vtkSmartPointer::New(); - planes->SetFrustumPlanes(planesArray); - - vtkSmartPointer frustumSource = vtkSmartPointer::New(); - frustumSource->SetPlanes(planes); - frustumSource->Update(); + vtkSmartPointer frustumSource = vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + frustumSource->Update(); - // Extract the edges - vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(frustumSource->GetOutput()); - filter->Update(); - - // Transform the default coordinate frame - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->PreMultiply(); - vtkMatrix4x4::Multiply4x4(convertToVtkMatrix(path[i].matrix), mat_trans, mat_trans); - transform->SetMatrix(mat_trans); - - vtkSmartPointer transform_filter = vtkSmartPointer::New(); - transform_filter->SetInput(filter->GetOutput()); - transform_filter->SetTransform(transform); - transform_filter->Update(); - - appendFilter->AddInputConnection(transform_filter->GetOutputPort()); - } + // Extract the edges + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(frustumSource->GetOutput()); + filter->Update(); + + ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput(appendFilter->GetOutput()); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 2fe9ca1c1..66f811884 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -89,7 +89,9 @@ TEST(Viz_viz3d, accuracy) viz::Color color = viz::Color::black(); viz::LineWidget lw(Point3f(0, 0, 0), Point3f(4.f, 4.f,4.f), viz::Color::green()); - viz::PlaneWidget pw(Vec4f(0.0,1.0,2.0,3.0), 5.0); + viz::PlaneWidget pw(Vec4f(0.0,1.0,2.0,3.0)); + viz::PlaneWidget pw2(Vec4f(0.0,1.0,2.0,3.0), 2.0, viz::Color::red()); + viz::PlaneWidget pw3(Vec4f(0.0,1.0,2.0,3.0), 3.0, viz::Color::blue()); viz::SphereWidget sw(Point3f(0, 0, 0), 0.2); viz::ArrowWidget aw(Point3f(0, 0, 0), Point3f(1, 1, 1), 0.01, viz::Color::red()); viz::CircleWidget cw(Point3f(0, 0, 0), 0.5, 0.01, viz::Color::green()); @@ -101,8 +103,10 @@ TEST(Viz_viz3d, accuracy) viz::CloudWidget pcw2(cloud, viz::Color::magenta()); // viz.showWidget("line", lw); -// viz.showWidget("plane", pw); - viz.showWidget("sphere", sw); + viz.showWidget("plane", pw); + viz.showWidget("plane2", pw2); + viz.showWidget("plane3", pw3); +// viz.showWidget("sphere", sw); // viz.showWidget("arrow", aw); // viz.showWidget("circle", cw); // viz.showWidget("cylinder", cyw); @@ -145,16 +149,33 @@ TEST(Viz_viz3d, accuracy) viz::CameraPositionWidget cpw(Vec3f(0.5, 0.5, 3.0), Vec3f(0.0,0.0,0.0), Vec3f(0.0,-1.0,0.0), 0.5); viz::CameraPositionWidget cpw2(0.5); viz::CameraPositionWidget frustum(K, 2.0, viz::Color::green()); +// viz::CameraPositionWidget frustum2(K, 4.0, viz::Color::red()); viz::CameraPositionWidget frustum2(K, 4.0, viz::Color::red()); + viz::CameraPositionWidget frustum3(Vec2f(CV_PI, CV_PI/2), 4.0); viz::Text3DWidget t3w1("Camera1", Point3f(0.4, 0.6, 3.0), 0.1); viz::Text3DWidget t3w2("Camera2", Point3f(0,0,0), 0.1); - viz.showWidget("CameraPositionWidget", cpw); - viz.showWidget("CameraPositionWidget2", cpw2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); - viz.showWidget("camera_label", t3w1); - viz.showWidget("camera_label2", t3w2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); - viz.showWidget("frustrum", frustum, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); - viz.showWidget("frustrum2", frustum2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); +// viz.showWidget("CameraPositionWidget", cpw); +// viz.showWidget("CameraPositionWidget2", cpw2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); +// viz.showWidget("camera_label", t3w1); +// viz.showWidget("camera_label2", t3w2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); +// viz.showWidget("frustrum", frustum, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); +// viz.showWidget("frustrum2", frustum2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); +// viz.showWidget("frustum3", frustum3, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); + + std::vector trajectory; + + trajectory.push_back(Affine3f().translate(Vec3f(0.5,0.5,0.5))); + trajectory.push_back(Affine3f().translate(Vec3f(1.0,0.0,0.0))); + trajectory.push_back(Affine3f().translate(Vec3f(2.0,0.5,0.0))); + trajectory.push_back(Affine3f(0.5, 0.0, 0.0, Vec3f(1.0,0.0,1.0))); +// + viz.showWidget("trajectory1", viz::TrajectoryWidget(trajectory, viz::Color(0,255,255), true, 0.5)); + viz.showWidget("trajectory2", viz::TrajectoryWidget(trajectory, K, 1.0, viz::Color(255,0,255))); + + + +// viz.showWidget("trajectory1", viz::TrajectoryWidget(trajectory/*, viz::Color::yellow()*/)); // viz.showWidget("CameraPositionWidget2", cpw2); // viz.showWidget("CameraPositionWidget3", cpw3); From 540f9a67f3d7ae9d28d16eaed031509662620a30 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 15:14:33 +0200 Subject: [PATCH 103/205] remove unnecessary declaration --- modules/viz/src/shape_widgets.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index ed07691bb..3bc94534e 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1095,9 +1095,7 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c } cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale, const Color &color) -{ - vtkIdType nr_points = path.size(); - +{ vtkSmartPointer appendFilter = vtkSmartPointer::New(); vtkSmartPointer camera = vtkSmartPointer::New(); From 27f5cd2afdb5f54c609a039c1dea9ce3b9582e99 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 16:12:22 +0200 Subject: [PATCH 104/205] overlay image widget constructor with Rect --- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/shape_widgets.cpp | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 101d8568d..7b7d09725 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -147,7 +147,7 @@ namespace cv class CV_EXPORTS ImageOverlayWidget : public Widget2D { public: - ImageOverlayWidget(const Mat &image, const Point2i &pos); + ImageOverlayWidget(const Mat &image, const Rect &rect); void setImage(const Mat &image); diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 3bc94534e..4b999a20b 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -622,7 +622,7 @@ struct cv::viz::ImageOverlayWidget::CopyImpl } }; -cv::viz::ImageOverlayWidget::ImageOverlayWidget(const Mat &image, const Point2i &pos) +cv::viz::ImageOverlayWidget::ImageOverlayWidget(const Mat &image, const Rect &rect) { CV_Assert(!image.empty() && image.depth() == CV_8U); @@ -641,14 +641,25 @@ cv::viz::ImageOverlayWidget::ImageOverlayWidget(const Mat &image, const Point2i flipFilter->SetInputConnection(vtk_image->GetProducerPort()); flipFilter->Update(); + // Scale the image based on the Rect + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->Scale(double(image.cols)/rect.width,double(image.rows)/rect.height,1.0); + + vtkSmartPointer image_reslice = vtkSmartPointer::New(); + image_reslice->SetResliceTransform(transform); + image_reslice->SetInputConnection(flipFilter->GetOutputPort()); + image_reslice->SetOutputDimensionality(2); + image_reslice->InterpolateOn(); + image_reslice->AutoCropOutputOn(); + vtkSmartPointer imageMapper = vtkSmartPointer::New(); - imageMapper->SetInputConnection(flipFilter->GetOutputPort()); + imageMapper->SetInputConnection(image_reslice->GetOutputPort()); imageMapper->SetColorWindow(255); // OpenCV color imageMapper->SetColorLevel(127.5); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(imageMapper); - actor->SetPosition(pos.x, pos.y); + actor->SetPosition(rect.x, rect.y); WidgetAccessor::setProp(*this, actor); } From d0bd344a42e90f07856b22aa2626dd5b827fc71c Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 16:48:17 +0200 Subject: [PATCH 105/205] image 3d widget use texture instead of imageactor for more flexibility (such as resizing) --- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/precomp.hpp | 1 + modules/viz/src/shape_widgets.cpp | 42 ++++++++++++++++++--- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 7b7d09725..3559a093d 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -158,7 +158,7 @@ namespace cv class CV_EXPORTS Image3DWidget : public Widget3D { public: - Image3DWidget(const Mat &image); + Image3DWidget(const Mat &image, const Size &size); void setImage(const Mat &image); diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 148fbb54d..12a042c15 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -135,6 +135,7 @@ #include #include #include +#include #include #include diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 4b999a20b..18e232f97 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -752,7 +752,7 @@ struct cv::viz::Image3DWidget::CopyImpl } }; -cv::viz::Image3DWidget::Image3DWidget(const Mat &image) +cv::viz::Image3DWidget::Image3DWidget(const Mat &image, const Size &size) { CV_Assert(!image.empty() && image.depth() == CV_8U); @@ -771,9 +771,37 @@ cv::viz::Image3DWidget::Image3DWidget(const Mat &image) flipFilter->SetInputConnection(vtk_image->GetProducerPort()); flipFilter->Update(); - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetInput(flipFilter->GetOutput()); + Vec3d plane_center(size.width * 0.5, size.height * 0.5, 0.0); + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); + plane->SetNormal(0.0, 0.0, 1.0); + + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->Translate(plane_center[0], plane_center[1], plane_center[2]); + transform->Scale(size.width, size.height, 1.0); + transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(plane->GetOutputPort()); + transform_filter->Update(); + + // Apply the texture + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(flipFilter->GetOutputPort()); + + vtkSmartPointer texturePlane = vtkSmartPointer::New(); + texturePlane->SetInputConnection(transform_filter->GetOutputPort()); + + vtkSmartPointer planeMapper = vtkSmartPointer::New(); + planeMapper->SetInputConnection(texturePlane->GetOutputPort()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(planeMapper); + actor->SetTexture(texture); + WidgetAccessor::setProp(*this, actor); } @@ -781,7 +809,7 @@ void cv::viz::Image3DWidget::setImage(const Mat &image) { CV_Assert(!image.empty() && image.depth() == CV_8U); - vtkImageActor *actor = vtkImageActor::SafeDownCast(WidgetAccessor::getProp(*this)); + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); // Create the vtk image and set its parameters based on input image @@ -799,7 +827,11 @@ void cv::viz::Image3DWidget::setImage(const Mat &image) flipFilter->SetInputConnection(vtk_image->GetProducerPort()); flipFilter->Update(); - actor->SetInput(flipFilter->GetOutput()); + // Apply the texture + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(flipFilter->GetOutputPort()); + + actor->SetTexture(texture); } template<> cv::viz::Image3DWidget cv::viz::Widget::cast() From f9938da67dba5836f09525573943c690360d1a46 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 22 Jul 2013 17:18:19 +0200 Subject: [PATCH 106/205] image 3d widget with position, normal, up_vector --- modules/viz/include/opencv2/viz/widgets.hpp | 1 + modules/viz/src/shape_widgets.cpp | 75 +++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 3559a093d..1ca792539 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -159,6 +159,7 @@ namespace cv { public: Image3DWidget(const Mat &image, const Size &size); + Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); void setImage(const Mat &image); diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 18e232f97..737b6928f 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -805,6 +805,81 @@ cv::viz::Image3DWidget::Image3DWidget(const Mat &image, const Size &size) WidgetAccessor::setProp(*this, actor); } +cv::viz::Image3DWidget::Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + // Create the vtk image and set its parameters based on input image + vtkSmartPointer vtk_image = vtkSmartPointer::New(); + vtk_image->SetDimensions(image.cols, image.rows, 1); + vtk_image->SetNumberOfScalarComponents(image.channels()); + vtk_image->SetScalarTypeToUnsignedChar(); + vtk_image->AllocateScalars(); + + CopyImpl::copyImage(image, vtk_image); + + // Need to flip the image as the coordinates are different in OpenCV and VTK + vtkSmartPointer flipFilter = vtkSmartPointer::New(); + flipFilter->SetFilteredAxis(1); // Vertical flip + flipFilter->SetInputConnection(vtk_image->GetProducerPort()); + flipFilter->Update(); + + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetCenter(0.0, 0.0, 0.0); + plane->SetNormal(0.0, 0.0, 1.0); + + // Compute the transformation matrix for drawing the camera frame in a scene + Vec3f u,v,n; + n = normalize(normal); + u = normalize(up_vector.cross(n)); + v = n.cross(u); + + vtkSmartPointer mat_trans = vtkSmartPointer::New(); + mat_trans->SetElement(0,0,u[0]); + mat_trans->SetElement(0,1,u[1]); + mat_trans->SetElement(0,2,u[2]); + mat_trans->SetElement(1,0,v[0]); + mat_trans->SetElement(1,1,v[1]); + mat_trans->SetElement(1,2,v[2]); + mat_trans->SetElement(2,0,n[0]); + mat_trans->SetElement(2,1,n[1]); + mat_trans->SetElement(2,2,n[2]); + // Inverse rotation (orthogonal, so just take transpose) + mat_trans->Transpose(); + // Then translate the coordinate frame to camera position + mat_trans->SetElement(0,3,position[0]); + mat_trans->SetElement(1,3,position[1]); + mat_trans->SetElement(2,3,position[2]); + mat_trans->SetElement(3,3,1); + + // Apply the texture + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(flipFilter->GetOutputPort()); + + vtkSmartPointer texturePlane = vtkSmartPointer::New(); + texturePlane->SetInputConnection(plane->GetOutputPort()); + + // Apply the transform after texture mapping + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->SetMatrix(mat_trans); + transform->Scale(size.width, size.height, 1.0); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(texturePlane->GetOutputPort()); + transform_filter->Update(); + + vtkSmartPointer planeMapper = vtkSmartPointer::New(); + planeMapper->SetInputConnection(transform_filter->GetOutputPort()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(planeMapper); + actor->SetTexture(texture); + + WidgetAccessor::setProp(*this, actor); +} + void cv::viz::Image3DWidget::setImage(const Mat &image) { CV_Assert(!image.empty() && image.depth() == CV_8U); From 4d70671231d8a366794be5406fe8c67a978c26dc Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 23 Jul 2013 15:43:23 +0200 Subject: [PATCH 107/205] intial implementation of frustum + image (the color of the frustum is currently dependent on the first pixel of the image) --- modules/viz/include/opencv2/viz/widgets.hpp | 4 + modules/viz/src/shape_widgets.cpp | 149 ++++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 1ca792539..735b9d2b9 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -174,6 +174,10 @@ namespace cv CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale = 1.0); CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0); + + private: + struct CopyImpl; }; class CV_EXPORTS TrajectoryWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 737b6928f..47e20d360 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -918,6 +918,58 @@ template<> cv::viz::Image3DWidget cv::viz::Widget::cast( /////////////////////////////////////////////////////////////////////////////////////////////// /// camera position widget implementation +struct cv::viz::CameraPositionWidget::CopyImpl +{ + struct Impl + { + static void copyImageMultiChannel(const Mat &image, vtkSmartPointer output) + { + int i_chs = image.channels(); + + for (int i = 0; i < image.rows; ++i) + { + const unsigned char * irows = image.ptr(i); + for (int j = 0; j < image.cols; ++j, irows += i_chs) + { + unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); + memcpy(vrows, irows, i_chs); + std::swap(vrows[0], vrows[2]); // BGR -> RGB + } + } + output->Modified(); + } + + static void copyImageSingleChannel(const Mat &image, vtkSmartPointer output) + { + for (int i = 0; i < image.rows; ++i) + { + const unsigned char * irows = image.ptr(i); + for (int j = 0; j < image.cols; ++j, ++irows) + { + unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); + *vrows = *irows; + } + } + output->Modified(); + } + }; + + static void copyImage(const Mat &image, vtkSmartPointer output) + { + int i_chs = image.channels(); + if (i_chs > 1) + { + // Multi channel images are handled differently because of BGR <-> RGB + Impl::copyImageMultiChannel(image, output); + } + else + { + Impl::copyImageSingleChannel(image, output); + } + } +}; + + cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) { vtkSmartPointer axes = vtkSmartPointer::New (); @@ -1099,6 +1151,103 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double sca setColor(color); } +cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat &image, double scale) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + // Create a camera + vtkSmartPointer camera = vtkSmartPointer::New(); + float f_x = K(0,0); + float f_y = K(1,1); + float c_y = K(1,2); + float aspect_ratio = float(image.cols)/float(image.rows); + // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) + float fovy = 2.0f * atan2(c_y,f_y) * 180 / CV_PI; + float far_end_height = 2.0f * c_y * scale / f_y; + + // Create the vtk image and set its parameters based on input image + vtkSmartPointer vtk_image = vtkSmartPointer::New(); + vtk_image->SetDimensions(image.cols, image.rows, 1); + vtk_image->SetNumberOfScalarComponents(image.channels()); + vtk_image->SetScalarTypeToUnsignedChar(); + vtk_image->AllocateScalars(); + + CopyImpl::copyImage(image, vtk_image); + + // Need to flip the image as the coordinates are different in OpenCV and VTK + vtkSmartPointer flipFilter = vtkSmartPointer::New(); + flipFilter->SetFilteredAxis(1); // Vertical flip + flipFilter->SetInputConnection(vtk_image->GetProducerPort()); + flipFilter->Update(); + + Vec3d plane_center(0.0, 0.0, scale); + + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); + plane->SetNormal(0.0, 0.0, 1.0); + + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->Translate(plane_center[0], plane_center[1], plane_center[2]); + transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0); + transform->RotateY(180.0); + transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); + + // Apply the texture + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(flipFilter->GetOutputPort()); + + vtkSmartPointer texturePlane = vtkSmartPointer::New(); + texturePlane->SetInputConnection(plane->GetOutputPort()); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(texturePlane->GetOutputPort()); + transform_filter->Update(); + + // Create frustum + camera->SetViewAngle(fovy); + camera->SetPosition(0.0,0.0,0.0); + camera->SetViewUp(0.0,1.0,0.0); + camera->SetFocalPoint(0.0,0.0,1.0); + camera->SetClippingRange(0.01, scale); + + double planesArray[24]; + camera->GetFrustumPlanes(aspect_ratio, planesArray); + + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planesArray); + + vtkSmartPointer frustumSource = + vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + frustumSource->Update(); + + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(frustumSource->GetOutput()); + filter->Update(); + + // Frustum needs to be textured or else it can't be combined with image + vtkSmartPointer frustum_texture = vtkSmartPointer::New(); + frustum_texture->SetInputConnection(filter->GetOutputPort()); + // Texture mapping with only one pixel from the image to have constant color + frustum_texture->SetSRange(0.0, 0.0); + frustum_texture->SetTRange(0.0, 0.0); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + appendFilter->AddInputConnection(frustum_texture->GetOutputPort()); + appendFilter->AddInputConnection(transform_filter->GetOutputPort()); + + vtkSmartPointer planeMapper = vtkSmartPointer::New(); + planeMapper->SetInputConnection(appendFilter->GetOutputPort()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(planeMapper); + actor->SetTexture(texture); + + WidgetAccessor::setProp(*this, actor); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// trajectory widget implementation From 40b50755d3c09da760f5662397a51534edb0ae06 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 23 Jul 2013 15:46:14 +0200 Subject: [PATCH 108/205] add const keywords to gridwidget constructor --- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/shape_widgets.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 735b9d2b9..bb5a968f7 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -123,7 +123,7 @@ namespace cv class CV_EXPORTS GridWidget : public Widget3D { public: - GridWidget(Vec2i dimensions, Vec2d spacing, const Color &color = Color::white()); + GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); }; class CV_EXPORTS Text3DWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 47e20d360..e96f07cf0 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -440,7 +440,7 @@ template<> cv::viz::PolyLineWidget cv::viz::Widget::cast grid = vtkSmartPointer::New(); From 6e5a712f6e7b008667ade289aa177973e367d59b Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 24 Jul 2013 10:02:33 +0200 Subject: [PATCH 109/205] Gridwidget with plane coefficients --- modules/viz/include/opencv2/viz/widgets.hpp | 2 + modules/viz/src/shape_widgets.cpp | 63 +++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index bb5a968f7..95a63df29 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -124,6 +124,8 @@ namespace cv { public: GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + }; class CV_EXPORTS Text3DWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index e96f07cf0..bb274a662 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -468,6 +468,69 @@ cv::viz::GridWidget::GridWidget(const Vec2i &dimensions, const Vec2d &spacing, c setColor(color); } +cv::viz::GridWidget::GridWidget(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color) +{ + // Create the grid using image data + vtkSmartPointer grid = vtkSmartPointer::New(); + + // Add 1 to dimensions because in ImageData dimensions is the number of lines + // - however here it means number of cells + grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1); + grid->SetSpacing(spacing[0], spacing[1], 0.); + + // Set origin of the grid to be the middle of the grid + grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0.0f); + + // Extract the edges so we have the grid + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInputConnection(grid->GetProducerPort()); + filter->Update(); + + // Estimate the transform to set the normal based on the coefficients + Vec3f normal(coefs[0], coefs[1], coefs[2]); + Vec3f up_vector(0.0f, 1.0f, 0.0f); // Just set as default + double push_distance = -coefs[3]/cv::norm(Vec3f(coefs.val)); + Vec3f u,v,n; + n = normalize(normal); + u = normalize(up_vector.cross(n)); + v = n.cross(u); + + vtkSmartPointer mat_trans = vtkSmartPointer::New(); + mat_trans->SetElement(0,0,u[0]); + mat_trans->SetElement(0,1,u[1]); + mat_trans->SetElement(0,2,u[2]); + mat_trans->SetElement(1,0,v[0]); + mat_trans->SetElement(1,1,v[1]); + mat_trans->SetElement(1,2,v[2]); + mat_trans->SetElement(2,0,n[0]); + mat_trans->SetElement(2,1,n[1]); + mat_trans->SetElement(2,2,n[2]); + // Inverse rotation (orthogonal, so just take transpose) + mat_trans->Transpose(); + mat_trans->SetElement(0,3,n[0] * push_distance); + mat_trans->SetElement(1,3,n[1] * push_distance); + mat_trans->SetElement(2,3,n[2] * push_distance); + mat_trans->SetElement(3,3,1); + + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->SetMatrix(mat_trans); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(filter->GetOutputPort()); + transform_filter->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(transform_filter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + template<> cv::viz::GridWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); From 952029a47bff8731ae549f3fa040034b5f0fd868 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 24 Jul 2013 10:13:01 +0200 Subject: [PATCH 110/205] GridImpl structure to shorten grid widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 3 + modules/viz/src/shape_widgets.cpp | 61 ++++++++++----------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 95a63df29..54edf205e 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -125,6 +125,9 @@ namespace cv public: GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + + private: + struct GridImpl; }; diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index bb274a662..fc8e80ea6 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -440,26 +440,35 @@ template<> cv::viz::PolyLineWidget cv::viz::Widget::cast createGrid(const Vec2i &dimensions, const Vec2d &spacing) + { + // Create the grid using image data + vtkSmartPointer grid = vtkSmartPointer::New(); + + // Add 1 to dimensions because in ImageData dimensions is the number of lines + // - however here it means number of cells + grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1); + grid->SetSpacing(spacing[0], spacing[1], 0.); + + // Set origin of the grid to be the middle of the grid + grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0); + + // Extract the edges so we have the grid + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInputConnection(grid->GetProducerPort()); + filter->Update(); + return filter->GetOutput(); + } +}; + cv::viz::GridWidget::GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color) { - // Create the grid using image data - vtkSmartPointer grid = vtkSmartPointer::New(); - - // Add 1 to dimensions because in ImageData dimensions is the number of lines - // - however here it means number of cells - grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1); - grid->SetSpacing(spacing[0], spacing[1], 0.); - - // Set origin of the grid to be the middle of the grid - grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0); - - // Extract the edges so we have the grid - vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInputConnection(grid->GetProducerPort()); - filter->Update(); + vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(filter->GetOutput()); + mapper->SetInputConnection(grid->GetProducerPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -470,21 +479,7 @@ cv::viz::GridWidget::GridWidget(const Vec2i &dimensions, const Vec2d &spacing, c cv::viz::GridWidget::GridWidget(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color) { - // Create the grid using image data - vtkSmartPointer grid = vtkSmartPointer::New(); - - // Add 1 to dimensions because in ImageData dimensions is the number of lines - // - however here it means number of cells - grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1); - grid->SetSpacing(spacing[0], spacing[1], 0.); - - // Set origin of the grid to be the middle of the grid - grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0.0f); - - // Extract the edges so we have the grid - vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInputConnection(grid->GetProducerPort()); - filter->Update(); + vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); // Estimate the transform to set the normal based on the coefficients Vec3f normal(coefs[0], coefs[1], coefs[2]); @@ -518,11 +513,11 @@ cv::viz::GridWidget::GridWidget(const Vec4f &coefs, const Vec2i &dimensions, con vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); - transform_filter->SetInputConnection(filter->GetOutputPort()); + transform_filter->SetInputConnection(grid->GetProducerPort()); transform_filter->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(transform_filter->GetOutput()); + mapper->SetInputConnection(transform_filter->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); From 769512db2da8b8647fc0df1b10c78438a138fd79 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 24 Jul 2013 10:32:21 +0200 Subject: [PATCH 111/205] move image copying structure to viz3d_impl: ConvertToVtkImage --- modules/viz/include/opencv2/viz/widgets.hpp | 8 - modules/viz/src/shape_widgets.cpp | 198 +------------------- modules/viz/src/viz3d_impl.hpp | 57 ++++++ 3 files changed, 64 insertions(+), 199 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 54edf205e..ba601ca86 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -155,9 +155,6 @@ namespace cv ImageOverlayWidget(const Mat &image, const Rect &rect); void setImage(const Mat &image); - - private: - struct CopyImpl; }; class CV_EXPORTS Image3DWidget : public Widget3D @@ -167,9 +164,6 @@ namespace cv Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); void setImage(const Mat &image); - - private: - struct CopyImpl; }; class CV_EXPORTS CameraPositionWidget : public Widget3D @@ -181,8 +175,6 @@ namespace cv CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0); - private: - struct CopyImpl; }; class CV_EXPORTS TrajectoryWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index fc8e80ea6..4fee4072a 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -629,69 +629,13 @@ cv::String cv::viz::TextWidget::getText() const /////////////////////////////////////////////////////////////////////////////////////////////// /// image overlay widget implementation -struct cv::viz::ImageOverlayWidget::CopyImpl -{ - struct Impl - { - static void copyImageMultiChannel(const Mat &image, vtkSmartPointer output) - { - int i_chs = image.channels(); - - for (int i = 0; i < image.rows; ++i) - { - const unsigned char * irows = image.ptr(i); - for (int j = 0; j < image.cols; ++j, irows += i_chs) - { - unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); - memcpy(vrows, irows, i_chs); - std::swap(vrows[0], vrows[2]); // BGR -> RGB - } - } - output->Modified(); - } - - static void copyImageSingleChannel(const Mat &image, vtkSmartPointer output) - { - for (int i = 0; i < image.rows; ++i) - { - const unsigned char * irows = image.ptr(i); - for (int j = 0; j < image.cols; ++j, ++irows) - { - unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); - *vrows = *irows; - } - } - output->Modified(); - } - }; - - static void copyImage(const Mat &image, vtkSmartPointer output) - { - int i_chs = image.channels(); - if (i_chs > 1) - { - // Multi channel images are handled differently because of BGR <-> RGB - Impl::copyImageMultiChannel(image, output); - } - else - { - Impl::copyImageSingleChannel(image, output); - } - } -}; - cv::viz::ImageOverlayWidget::ImageOverlayWidget(const Mat &image, const Rect &rect) { CV_Assert(!image.empty() && image.depth() == CV_8U); // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); - vtk_image->SetDimensions(image.cols, image.rows, 1); - vtk_image->SetNumberOfScalarComponents(image.channels()); - vtk_image->SetScalarTypeToUnsignedChar(); - vtk_image->AllocateScalars(); - - CopyImpl::copyImage(image, vtk_image); + ConvertToVtkImage::convert(image, vtk_image); // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); @@ -734,12 +678,7 @@ void cv::viz::ImageOverlayWidget::setImage(const Mat &image) // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); - vtk_image->SetDimensions(image.cols, image.rows, 1); - vtk_image->SetNumberOfScalarComponents(image.channels()); - vtk_image->SetScalarTypeToUnsignedChar(); - vtk_image->AllocateScalars(); - - CopyImpl::copyImage(image, vtk_image); + ConvertToVtkImage::convert(image, vtk_image); // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); @@ -759,69 +698,13 @@ template<> cv::viz::ImageOverlayWidget cv::viz::Widget::cast output) - { - int i_chs = image.channels(); - - for (int i = 0; i < image.rows; ++i) - { - const unsigned char * irows = image.ptr(i); - for (int j = 0; j < image.cols; ++j, irows += i_chs) - { - unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); - memcpy(vrows, irows, i_chs); - std::swap(vrows[0], vrows[2]); // BGR -> RGB - } - } - output->Modified(); - } - - static void copyImageSingleChannel(const Mat &image, vtkSmartPointer output) - { - for (int i = 0; i < image.rows; ++i) - { - const unsigned char * irows = image.ptr(i); - for (int j = 0; j < image.cols; ++j, ++irows) - { - unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); - *vrows = *irows; - } - } - output->Modified(); - } - }; - - static void copyImage(const Mat &image, vtkSmartPointer output) - { - int i_chs = image.channels(); - if (i_chs > 1) - { - // Multi channel images are handled differently because of BGR <-> RGB - Impl::copyImageMultiChannel(image, output); - } - else - { - Impl::copyImageSingleChannel(image, output); - } - } -}; - cv::viz::Image3DWidget::Image3DWidget(const Mat &image, const Size &size) { CV_Assert(!image.empty() && image.depth() == CV_8U); // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); - vtk_image->SetDimensions(image.cols, image.rows, 1); - vtk_image->SetNumberOfScalarComponents(image.channels()); - vtk_image->SetScalarTypeToUnsignedChar(); - vtk_image->AllocateScalars(); - - CopyImpl::copyImage(image, vtk_image); + ConvertToVtkImage::convert(image, vtk_image); // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); @@ -869,12 +752,7 @@ cv::viz::Image3DWidget::Image3DWidget(const Vec3f &position, const Vec3f &normal // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); - vtk_image->SetDimensions(image.cols, image.rows, 1); - vtk_image->SetNumberOfScalarComponents(image.channels()); - vtk_image->SetScalarTypeToUnsignedChar(); - vtk_image->AllocateScalars(); - - CopyImpl::copyImage(image, vtk_image); + ConvertToVtkImage::convert(image, vtk_image); // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); @@ -947,12 +825,7 @@ void cv::viz::Image3DWidget::setImage(const Mat &image) // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); - vtk_image->SetDimensions(image.cols, image.rows, 1); - vtk_image->SetNumberOfScalarComponents(image.channels()); - vtk_image->SetScalarTypeToUnsignedChar(); - vtk_image->AllocateScalars(); - - CopyImpl::copyImage(image, vtk_image); + ConvertToVtkImage::convert(image, vtk_image); // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); @@ -976,58 +849,6 @@ template<> cv::viz::Image3DWidget cv::viz::Widget::cast( /////////////////////////////////////////////////////////////////////////////////////////////// /// camera position widget implementation -struct cv::viz::CameraPositionWidget::CopyImpl -{ - struct Impl - { - static void copyImageMultiChannel(const Mat &image, vtkSmartPointer output) - { - int i_chs = image.channels(); - - for (int i = 0; i < image.rows; ++i) - { - const unsigned char * irows = image.ptr(i); - for (int j = 0; j < image.cols; ++j, irows += i_chs) - { - unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); - memcpy(vrows, irows, i_chs); - std::swap(vrows[0], vrows[2]); // BGR -> RGB - } - } - output->Modified(); - } - - static void copyImageSingleChannel(const Mat &image, vtkSmartPointer output) - { - for (int i = 0; i < image.rows; ++i) - { - const unsigned char * irows = image.ptr(i); - for (int j = 0; j < image.cols; ++j, ++irows) - { - unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); - *vrows = *irows; - } - } - output->Modified(); - } - }; - - static void copyImage(const Mat &image, vtkSmartPointer output) - { - int i_chs = image.channels(); - if (i_chs > 1) - { - // Multi channel images are handled differently because of BGR <-> RGB - Impl::copyImageMultiChannel(image, output); - } - else - { - Impl::copyImageSingleChannel(image, output); - } - } -}; - - cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) { vtkSmartPointer axes = vtkSmartPointer::New (); @@ -1223,14 +1044,9 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat float fovy = 2.0f * atan2(c_y,f_y) * 180 / CV_PI; float far_end_height = 2.0f * c_y * scale / f_y; - // Create the vtk image and set its parameters based on input image + // Create the vtk image vtkSmartPointer vtk_image = vtkSmartPointer::New(); - vtk_image->SetDimensions(image.cols, image.rows, 1); - vtk_image->SetNumberOfScalarComponents(image.channels()); - vtk_image->SetScalarTypeToUnsignedChar(); - vtk_image->AllocateScalars(); - - CopyImpl::copyImage(image, vtk_image); + ConvertToVtkImage::convert(image, vtk_image); // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 04b816d48..c6bef0988 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -410,6 +410,63 @@ namespace cv inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } + + struct ConvertToVtkImage + { + struct Impl + { + static void copyImageMultiChannel(const Mat &image, vtkSmartPointer output) + { + int i_chs = image.channels(); + + for (int i = 0; i < image.rows; ++i) + { + const unsigned char * irows = image.ptr(i); + for (int j = 0; j < image.cols; ++j, irows += i_chs) + { + unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); + memcpy(vrows, irows, i_chs); + std::swap(vrows[0], vrows[2]); // BGR -> RGB + } + } + output->Modified(); + } + + static void copyImageSingleChannel(const Mat &image, vtkSmartPointer output) + { + for (int i = 0; i < image.rows; ++i) + { + const unsigned char * irows = image.ptr(i); + for (int j = 0; j < image.cols; ++j, ++irows) + { + unsigned char * vrows = static_cast(output->GetScalarPointer(j,i,0)); + *vrows = *irows; + } + } + output->Modified(); + } + }; + + static void convert(const Mat &image, vtkSmartPointer output) + { + // Create the vtk image + output->SetDimensions(image.cols, image.rows, 1); + output->SetNumberOfScalarComponents(image.channels()); + output->SetScalarTypeToUnsignedChar(); + output->AllocateScalars(); + + int i_chs = image.channels(); + if (i_chs > 1) + { + // Multi channel images are handled differently because of BGR <-> RGB + Impl::copyImageMultiChannel(image, output); + } + else + { + Impl::copyImageSingleChannel(image, output); + } + } + }; } } From aa2594c06c3183131afa6e7cba30ae08b893292d Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 25 Jul 2013 10:23:24 +0200 Subject: [PATCH 112/205] fix aspect_ratio computation from fovs, add casting for camerapositionwidget, trajectorywidget --- modules/viz/include/opencv2/viz/widgets.hpp | 2 ++ modules/viz/src/shape_widgets.cpp | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index ba601ca86..a7b9b3546 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -231,6 +231,8 @@ namespace cv template<> CV_EXPORTS TextWidget Widget::cast(); template<> CV_EXPORTS ImageOverlayWidget Widget::cast(); template<> CV_EXPORTS Image3DWidget Widget::cast(); + template<> CV_EXPORTS CameraPositionWidget Widget::cast(); + template<> CV_EXPORTS TrajectoryWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); template<> CV_EXPORTS MeshWidget Widget::cast(); diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 4fee4072a..64d05360f 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1003,9 +1003,10 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double sca camera->SetFocalPoint(0.0,0.0,1.0); camera->SetClippingRange(0.01, scale); + double aspect_ratio = tan(fov[0] * 0.5) / tan(fov[1] * 0.5); + double planesArray[24]; - // Default aspect ratio = 1.0? fovx/fovy? - camera->GetFrustumPlanes(1.0, planesArray); + camera->GetFrustumPlanes(aspect_ratio, planesArray); vtkSmartPointer planes = vtkSmartPointer::New(); planes->SetFrustumPlanes(planesArray); @@ -1122,6 +1123,12 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat WidgetAccessor::setProp(*this, actor); } +template<> cv::viz::CameraPositionWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// trajectory widget implementation @@ -1279,3 +1286,9 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c WidgetAccessor::setProp(*this, actor); setColor(color); } + +template<> cv::viz::TrajectoryWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} \ No newline at end of file From 7d458e852e73b3fe00f61efc4076c7351f4872d6 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 25 Jul 2013 10:56:54 +0200 Subject: [PATCH 113/205] trajectory widget display options: display path, display frames, display both --- modules/viz/include/opencv2/viz/widgets.hpp | 4 +- modules/viz/src/shape_widgets.cpp | 80 +++++++++++---------- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index a7b9b3546..c63c54f68 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -180,7 +180,9 @@ namespace cv class CV_EXPORTS TrajectoryWidget : public Widget3D { public: - TrajectoryWidget(const std::vector &path, const Color &color = Color::white(), bool show_frames = false, double scale = 1.0); + enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; + + TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); // Camera frustums private: diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 64d05360f..fc13e0f3e 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1162,38 +1162,54 @@ struct cv::viz::TrajectoryWidget::ApplyPath } }; -cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Color &color, bool show_frames, double scale) +cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, int display_mode, const Color &color, double scale) { - vtkIdType nr_points = path.size(); + vtkSmartPointer appendFilter = vtkSmartPointer::New(); - vtkSmartPointer points = vtkSmartPointer::New (); - vtkSmartPointer polyData = vtkSmartPointer::New (); - vtkSmartPointer polyLine = vtkSmartPointer::New (); - - points->SetDataTypeToFloat(); - points->SetNumberOfPoints(nr_points); - polyLine->GetPointIds()->SetNumberOfIds(nr_points); - - Vec3f last_pos(0.0f,0.0f,0.0f); - Vec3f *data_beg = vtkpoints_data(points); - *data_beg = path[0] * last_pos; - - for (vtkIdType i = 0; i < nr_points; ++i) + if (display_mode & TrajectoryWidget::DISPLAY_PATH) { - last_pos = path[i] * last_pos; - *data_beg++ = last_pos; - polyLine->GetPointIds()->SetId(i,i); + // Create a poly line along the path + vtkIdType nr_points = path.size(); + + vtkSmartPointer points = vtkSmartPointer::New (); + vtkSmartPointer polyData = vtkSmartPointer::New (); + vtkSmartPointer polyLine = vtkSmartPointer::New (); + + points->SetDataTypeToFloat(); + points->SetNumberOfPoints(nr_points); + polyLine->GetPointIds()->SetNumberOfIds(nr_points); + + Vec3f last_pos(0.0f,0.0f,0.0f); + Vec3f *data_beg = vtkpoints_data(points); + + for (vtkIdType i = 0; i < nr_points; ++i) + { + last_pos = path[i] * last_pos; + *data_beg++ = last_pos; + polyLine->GetPointIds()->SetId(i,i); + } + + vtkSmartPointer cells = vtkSmartPointer::New(); + cells->InsertNextCell(polyLine); + + polyData->SetPoints(points); + polyData->SetLines(cells); + + // Set the color for polyData + vtkSmartPointer colors = vtkSmartPointer::New(); + colors->SetNumberOfComponents(3); + + // TODO Make this more efficient + for (int i = 0; i < nr_points; ++i) + colors->InsertNextTuple3(color[2], color[1], color[0]); + + polyData->GetPointData()->SetScalars(colors); + appendFilter->AddInputConnection(polyData->GetProducerPort()); } - vtkSmartPointer cells = vtkSmartPointer::New(); - cells->InsertNextCell(polyLine); - - polyData->SetPoints(points); - polyData->SetLines(cells); - - vtkSmartPointer appendFilter = vtkSmartPointer::New(); - if (show_frames) + if (display_mode & TrajectoryWidget::DISPLAY_FRAMES) { + // Create frames and transform along the path vtkSmartPointer axes = vtkSmartPointer::New(); axes->SetOrigin (0, 0, 0); axes->SetScaleFactor (scale); @@ -1220,18 +1236,6 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c ApplyPath::applyPath(axes_tubes->GetOutput(), appendFilter, path); } - // Set the color for polyData - vtkSmartPointer colors = vtkSmartPointer::New(); - colors->SetNumberOfComponents(3); - - // TODO Make this more efficient - for (int i = 0; i < nr_points; ++i) - colors->InsertNextTuple3(color[2], color[1], color[0]); - - polyData->GetPointData()->SetScalars(colors); - - appendFilter->AddInputConnection(polyData->GetProducerPort()); - vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUsePointData (); mapper->SetInput(appendFilter->GetOutput()); From 64cdd821466b6440b6c93b0093c321b82b3b3a70 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 25 Jul 2013 15:08:45 +0200 Subject: [PATCH 114/205] trajectory widget constructor with field of view --- modules/viz/include/opencv2/viz/widgets.hpp | 1 + modules/viz/src/shape_widgets.cpp | 43 ++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index c63c54f68..2def82747 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -184,6 +184,7 @@ namespace cv TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); // Camera frustums + TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); // Camera frustums private: struct ApplyPath; diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index fc13e0f3e..8dea213f9 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1248,8 +1248,6 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale, const Color &color) { - vtkSmartPointer appendFilter = vtkSmartPointer::New(); - vtkSmartPointer camera = vtkSmartPointer::New(); float f_x = K(0,0); float f_y = K(1,1); @@ -1279,6 +1277,47 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c filter->SetInput(frustumSource->GetOutput()); filter->Update(); + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(appendFilter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale, const Color &color) +{ + vtkSmartPointer camera = vtkSmartPointer::New(); + + camera->SetViewAngle(fov[1] * 180 / CV_PI); // Vertical field of view + camera->SetPosition(0.0,0.0,0.0); + camera->SetViewUp(0.0,1.0,0.0); + camera->SetFocalPoint(0.0,0.0,1.0); + camera->SetClippingRange(0.01, scale); + + double aspect_ratio = tan(fov[0] * 0.5) / tan(fov[1] * 0.5); + + double planesArray[24]; + camera->GetFrustumPlanes(aspect_ratio, planesArray); + + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planesArray); + + vtkSmartPointer frustumSource = vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + frustumSource->Update(); + + // Extract the edges + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(frustumSource->GetOutput()); + filter->Update(); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); vtkSmartPointer mapper = vtkSmartPointer::New(); From ec756afe87f791c82f499978f290659edc1f9dd3 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 25 Jul 2013 16:08:23 +0200 Subject: [PATCH 115/205] trajectorywidget display modes are combined with & instead of | --- modules/viz/src/shape_widgets.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 8dea213f9..4dbfaee92 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1166,7 +1166,8 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i { vtkSmartPointer appendFilter = vtkSmartPointer::New(); - if (display_mode & TrajectoryWidget::DISPLAY_PATH) + // Bitwise and with 3 in order to limit the domain to 2 bits + if ((~display_mode & 3) ^ TrajectoryWidget::DISPLAY_PATH) { // Create a poly line along the path vtkIdType nr_points = path.size(); @@ -1207,7 +1208,7 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i appendFilter->AddInputConnection(polyData->GetProducerPort()); } - if (display_mode & TrajectoryWidget::DISPLAY_FRAMES) + if ((~display_mode & 3) ^ TrajectoryWidget::DISPLAY_FRAMES) { // Create frames and transform along the path vtkSmartPointer axes = vtkSmartPointer::New(); From b661d72252a4907dd99773b0f53af0335139c38f Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 25 Jul 2013 16:47:30 +0200 Subject: [PATCH 116/205] CameraPositionWidget: a workaround for setting frustum color in the presence of an image --- modules/viz/include/opencv2/viz/widgets.hpp | 2 +- modules/viz/src/shape_widgets.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 2def82747..e36e00439 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -173,7 +173,7 @@ namespace cv CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale = 1.0); CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); - CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0); + CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); }; diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 4dbfaee92..c06e1d741 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1031,7 +1031,7 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double sca setColor(color); } -cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat &image, double scale) +cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat &image, double scale, const Color &color) { CV_Assert(!image.empty() && image.depth() == CV_8U); @@ -1049,6 +1049,11 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat vtkSmartPointer vtk_image = vtkSmartPointer::New(); ConvertToVtkImage::convert(image, vtk_image); + // Adjust a pixel of the vtk_image + vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 0, color[2]); + vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 1, color[1]); + vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 2, color[0]); + // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip From edfad34d390803338cd2e54dde2b19015a7e4755 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 26 Jul 2013 14:50:11 +0200 Subject: [PATCH 117/205] trajectory with spheres and lines (based on the code snippet in gdocs) --- modules/viz/include/opencv2/viz/widgets.hpp | 2 + modules/viz/src/shape_widgets.cpp | 82 +++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index e36e00439..157997c50 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -183,6 +183,8 @@ namespace cv enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); + TrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, + double sphere_radius, const Color &line_color = Color::white(), const Color &sphere_color = Color::white()); TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); // Camera frustums TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); // Camera frustums diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index c06e1d741..aec8ca4f2 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1252,6 +1252,88 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i WidgetAccessor::setProp(*this, actor); } +cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, + double sphere_radius, const Color &line_color, const Color &sphere_color) +{ + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + vtkIdType nr_poses = path.size(); + Point3f last_pos(0.0f,0.0f,0.0f); + + // Create color arrays + vtkSmartPointer line_scalars = vtkSmartPointer::New(); + line_scalars->SetNumberOfComponents(3); + line_scalars->InsertNextTuple3(line_color[2], line_color[1], line_color[0]); + + // Create color array for sphere + vtkSphereSource * dummy_sphere = vtkSphereSource::New(); + // Create the array for big sphere + dummy_sphere->SetRadius(init_sphere_radius); + dummy_sphere->Update(); + vtkIdType nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); + vtkSmartPointer sphere_scalars_init = vtkSmartPointer::New(); + sphere_scalars_init->SetNumberOfComponents(3); + sphere_scalars_init->SetNumberOfTuples(nr_points); + sphere_scalars_init->FillComponent(0, sphere_color[2]); + sphere_scalars_init->FillComponent(1, sphere_color[1]); + sphere_scalars_init->FillComponent(2, sphere_color[0]); + // Create the array for small sphere + dummy_sphere->SetRadius(sphere_radius); + dummy_sphere->Update(); + nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); + vtkSmartPointer sphere_scalars = vtkSmartPointer::New(); + sphere_scalars->SetNumberOfComponents(3); + sphere_scalars->SetNumberOfTuples(nr_points); + sphere_scalars->FillComponent(0, sphere_color[2]); + sphere_scalars->FillComponent(1, sphere_color[1]); + sphere_scalars->FillComponent(2, sphere_color[0]); + dummy_sphere->Delete(); + + for (vtkIdType i = 0; i < nr_poses; ++i) + { + Point3f new_pos = path[i] * last_pos; + + vtkSmartPointer sphere_source = vtkSmartPointer::New(); + sphere_source->SetCenter (new_pos.x, new_pos.y, new_pos.z); + if (i == 0) + { + sphere_source->SetRadius(init_sphere_radius); + sphere_source->Update(); + sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars_init); + appendFilter->AddInputConnection(sphere_source->GetOutputPort()); + last_pos = new_pos; + continue; + } + else + { + sphere_source->SetRadius(sphere_radius); + sphere_source->Update(); + sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars); + appendFilter->AddInputConnection(sphere_source->GetOutputPort()); + } + + Vec3f v = last_pos - new_pos; + v = normalize(v) * line_length; + + vtkSmartPointer line_source = vtkSmartPointer::New(); + line_source->SetPoint1(new_pos.x + v[0], new_pos.y + v[1], new_pos.z + v[2]); + line_source->SetPoint2(new_pos.x, new_pos.y, new_pos.z); + line_source->Update(); + line_source->GetOutput()->GetCellData()->SetScalars(line_scalars); + + appendFilter->AddInputConnection(line_source->GetOutputPort()); + last_pos = new_pos; + } + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUseCellData(); + mapper->SetInput(appendFilter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); From 3fe5984e4694fd4f161de7a227e1f7d00d904843 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 26 Jul 2013 16:55:03 +0200 Subject: [PATCH 118/205] cloud collection widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 13 + modules/viz/src/cloud_widgets.cpp | 250 +++++++++++++++++++- modules/viz/src/shape_widgets.cpp | 8 +- 3 files changed, 266 insertions(+), 5 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 157997c50..5df61eb74 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -202,6 +202,18 @@ namespace cv struct CreateCloudWidget; }; + class CV_EXPORTS CloudCollectionWidget : public Widget3D + { + public: + CloudCollectionWidget(); + + void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); + void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity()); + + private: + struct CreateCloudWidget; + }; + class CV_EXPORTS CloudNormalsWidget : public Widget3D { public: @@ -239,6 +251,7 @@ namespace cv template<> CV_EXPORTS CameraPositionWidget Widget::cast(); template<> CV_EXPORTS TrajectoryWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); + template<> CV_EXPORTS CloudCollectionWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); template<> CV_EXPORTS MeshWidget Widget::cast(); diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index 9eec79074..2d980df10 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -154,7 +154,6 @@ cv::viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) Mat cloud = _cloud.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); - vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); @@ -184,6 +183,255 @@ template<> cv::viz::CloudWidget cv::viz::Widget::cast() return static_cast(widget); } +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Cloud Collection Widget implementation + +struct cv::viz::CloudCollectionWidget::CreateCloudWidget +{ + static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) + { + vtkSmartPointer polydata = vtkSmartPointer::New (); + vtkSmartPointer vertices = vtkSmartPointer::New (); + + polydata->SetVerts (vertices); + + vtkSmartPointer points = polydata->GetPoints(); + vtkSmartPointer initcells; + nr_points = cloud.total(); + + if (!points) + { + points = vtkSmartPointer::New (); + if (cloud.depth() == CV_32F) + points->SetDataTypeToFloat(); + else if (cloud.depth() == CV_64F) + points->SetDataTypeToDouble(); + polydata->SetPoints (points); + } + points->SetNumberOfPoints (nr_points); + + if (cloud.depth() == CV_32F) + { + // Get a pointer to the beginning of the data array + Vec3f *data_beg = vtkpoints_data(points); + Vec3f *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + else if (cloud.depth() == CV_64F) + { + // Get a pointer to the beginning of the data array + Vec3d *data_beg = vtkpoints_data(points); + Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); + nr_points = data_end - data_beg; + } + points->SetNumberOfPoints (nr_points); + + // Update cells + vtkSmartPointer cells = vertices->GetData (); + // If no init cells and cells has not been initialized... + if (!cells) + cells = vtkSmartPointer::New (); + + // If we have less values then we need to recreate the array + if (cells->GetNumberOfTuples () < nr_points) + { + cells = vtkSmartPointer::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::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); + } + + // Set the cells and the vertices + vertices->SetCells (nr_points, cells); + return polydata; + } +}; + +cv::viz::CloudCollectionWidget::CloudCollectionWidget() +{ + // Just create the actor + vtkSmartPointer actor = vtkSmartPointer::New(); + WidgetAccessor::setProp(*this, actor); +} + +void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, InputArray _colors, const Affine3f &pose) +{ + Mat cloud = _cloud.getMat(); + Mat colors = _colors.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); + + if (cloud.isContinuous() && colors.isContinuous()) + { + cloud.reshape(cloud.channels(), 1); + colors.reshape(colors.channels(), 1); + } + + vtkIdType nr_points; + vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + + // Filter colors + Vec3b* colors_data = new Vec3b[nr_points]; + NanFilter::copyColor(colors, colors_data, cloud); + + vtkSmartPointer scalars = vtkSmartPointer::New (); + scalars->SetNumberOfComponents (3); + scalars->SetNumberOfTuples (nr_points); + scalars->SetArray (colors_data->val, 3 * nr_points, 0); + + // Assign the colors + polydata->GetPointData ()->SetScalars (scalars); + + // Transform the poly data based on the pose + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->SetMatrix(convertToVtkMatrix(pose.matrix)); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(polydata->GetProducerPort()); + transform_filter->Update(); + + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper()); + if (!mapper) + { + // This is the first cloud + vtkSmartPointer mapper_new = vtkSmartPointer::New (); + mapper_new->SetInputConnection (transform_filter->GetOutputPort()); + + Vec3d minmax(scalars->GetRange()); + mapper_new->SetScalarRange(minmax.val); + mapper_new->SetScalarModeToUsePointData (); + + bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); + + mapper_new->SetInterpolateScalarsBeforeMapping(interpolation); + mapper_new->ScalarVisibilityOn(); + mapper_new->ImmediateModeRenderingOff(); + + actor->SetNumberOfCloudPoints (int (std::max(1, polydata->GetNumberOfPoints () / 10))); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper_new); + return ; + } + + vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); + CV_Assert(data); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); + appendFilter->AddInputConnection(transform_filter->GetOutputPort()); + mapper->SetInputConnection(appendFilter->GetOutputPort()); + + // Update the number of cloud points + vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); + actor->SetNumberOfCloudPoints (int (std::max(1, old_cloud_points+polydata->GetNumberOfPoints () / 10))); +} + +void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, const Color &color, const Affine3f &pose) +{ + Mat cloud = _cloud.getMat(); + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + + vtkIdType nr_points; + vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); + + vtkSmartPointer scalars = vtkSmartPointer::New (); + scalars->SetNumberOfComponents (3); + scalars->SetNumberOfTuples (nr_points); + scalars->FillComponent(0, color[2]); + scalars->FillComponent(1, color[1]); + scalars->FillComponent(2, color[0]); + + // Assign the colors + polydata->GetPointData ()->SetScalars (scalars); + + // Transform the poly data based on the pose + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->SetMatrix(convertToVtkMatrix(pose.matrix)); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(polydata->GetProducerPort()); + transform_filter->Update(); + + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper()); + if (!mapper) + { + // This is the first cloud + vtkSmartPointer mapper_new = vtkSmartPointer::New (); + mapper_new->SetInputConnection (transform_filter->GetOutputPort()); + + Vec3d minmax(scalars->GetRange()); + mapper_new->SetScalarRange(minmax.val); + mapper_new->SetScalarModeToUsePointData (); + + bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); + + mapper_new->SetInterpolateScalarsBeforeMapping(interpolation); + mapper_new->ScalarVisibilityOn(); + mapper_new->ImmediateModeRenderingOff(); + + actor->SetNumberOfCloudPoints (int (std::max(1, polydata->GetNumberOfPoints () / 10))); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper_new); + return ; + } + + vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); + CV_Assert(data); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); + appendFilter->AddInputConnection(transform_filter->GetOutputPort()); + mapper->SetInputConnection(appendFilter->GetOutputPort()); + + // Update the number of cloud points + vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); + actor->SetNumberOfCloudPoints (int (std::max(1, old_cloud_points+polydata->GetNumberOfPoints () / 10))); +} + +template<> cv::viz::CloudCollectionWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// Cloud Normals Widget implementation diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index aec8ca4f2..569d934ce 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1204,10 +1204,10 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i // Set the color for polyData vtkSmartPointer colors = vtkSmartPointer::New(); colors->SetNumberOfComponents(3); - - // TODO Make this more efficient - for (int i = 0; i < nr_points; ++i) - colors->InsertNextTuple3(color[2], color[1], color[0]); + colors->SetNumberOfTuples(nr_points); + colors->FillComponent(0, color[2]); + colors->FillComponent(1, color[1]); + colors->FillComponent(2, color[0]); polyData->GetPointData()->SetScalars(colors); appendFilter->AddInputConnection(polyData->GetProducerPort()); From 250dac5b71d82eb94d141bd85652b6ec31f6ce16 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 29 Jul 2013 11:01:59 +0200 Subject: [PATCH 119/205] fix: trajectory path is now relative to the global frame --- modules/viz/src/shape_widgets.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 569d934ce..882b82d1e 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1140,10 +1140,7 @@ template<> cv::viz::CameraPositionWidget cv::viz::Widget::cast poly_data, vtkSmartPointer append_filter, const std::vector &path) - { - vtkSmartPointer mat_trans = vtkSmartPointer::New(); - mat_trans->Identity(); - + { vtkIdType nr_points = path.size(); for (vtkIdType i = 0; i < nr_points; ++i) @@ -1154,7 +1151,8 @@ struct cv::viz::TrajectoryWidget::ApplyPath // Transform the default coordinate frame vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); - vtkMatrix4x4::Multiply4x4(convertToVtkMatrix(path[i].matrix), mat_trans, mat_trans); + vtkSmartPointer mat_trans = vtkSmartPointer::New(); + mat_trans = convertToVtkMatrix(path[i].matrix); transform->SetMatrix(mat_trans); vtkSmartPointer filter = vtkSmartPointer::New(); @@ -1185,13 +1183,12 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i points->SetNumberOfPoints(nr_points); polyLine->GetPointIds()->SetNumberOfIds(nr_points); - Vec3f last_pos(0.0f,0.0f,0.0f); Vec3f *data_beg = vtkpoints_data(points); for (vtkIdType i = 0; i < nr_points; ++i) { - last_pos = path[i] * last_pos; - *data_beg++ = last_pos; + Vec3f cam_pose = path[i].translation(); + *data_beg++ = cam_pose; polyLine->GetPointIds()->SetId(i,i); } @@ -1257,7 +1254,6 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, f { vtkSmartPointer appendFilter = vtkSmartPointer::New(); vtkIdType nr_poses = path.size(); - Point3f last_pos(0.0f,0.0f,0.0f); // Create color arrays vtkSmartPointer line_scalars = vtkSmartPointer::New(); @@ -1290,7 +1286,7 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, f for (vtkIdType i = 0; i < nr_poses; ++i) { - Point3f new_pos = path[i] * last_pos; + Point3f new_pos = path[i].translation(); vtkSmartPointer sphere_source = vtkSmartPointer::New(); sphere_source->SetCenter (new_pos.x, new_pos.y, new_pos.z); @@ -1300,7 +1296,6 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, f sphere_source->Update(); sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars_init); appendFilter->AddInputConnection(sphere_source->GetOutputPort()); - last_pos = new_pos; continue; } else @@ -1311,7 +1306,9 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, f appendFilter->AddInputConnection(sphere_source->GetOutputPort()); } - Vec3f v = last_pos - new_pos; + + Affine3f relativeAffine = path[i].inv() * path[i-1]; + Vec3f v = path[i].rotation() * relativeAffine.translation(); v = normalize(v) * line_length; vtkSmartPointer line_source = vtkSmartPointer::New(); @@ -1321,7 +1318,6 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, f line_source->GetOutput()->GetCellData()->SetScalars(line_scalars); appendFilter->AddInputConnection(line_source->GetOutputPort()); - last_pos = new_pos; } vtkSmartPointer mapper = vtkSmartPointer::New(); From 42266b04a5109df879701772a81b68db9a2bba96 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 29 Jul 2013 12:25:46 +0200 Subject: [PATCH 120/205] makeCameraPose implementation --- modules/viz/include/opencv2/viz.hpp | 2 +- modules/viz/include/opencv2/viz/widgets.hpp | 1 - modules/viz/src/shape_widgets.cpp | 68 --------------------- modules/viz/src/viz.cpp | 26 ++++++++ 4 files changed, 27 insertions(+), 70 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 5f1b7766f..7e04f7b94 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -64,7 +64,7 @@ namespace cv CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); //! 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& up_vector); + CV_EXPORTS Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir); //! checks float value for Nan diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 5df61eb74..603d17df8 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -170,7 +170,6 @@ namespace cv { public: CameraPositionWidget(double scale = 1.0); - CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale = 1.0); CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 882b82d1e..caa5bf358 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -883,74 +883,6 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) WidgetAccessor::setProp(*this, actor); } -cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec3f &position, const Vec3f &look_at, const Vec3f &up_vector, double scale) -{ - vtkSmartPointer axes = vtkSmartPointer::New (); - axes->SetOrigin (0, 0, 0); - axes->SetScaleFactor (scale); - - // Compute the transformation matrix for drawing the camera frame in a scene - Vec3f u,v,n; - n = normalize(look_at - position); - u = normalize(up_vector.cross(n)); - v = n.cross(u); - - vtkSmartPointer mat_trans = vtkSmartPointer::New(); - mat_trans->SetElement(0,0,u[0]); - mat_trans->SetElement(0,1,u[1]); - mat_trans->SetElement(0,2,u[2]); - mat_trans->SetElement(1,0,v[0]); - mat_trans->SetElement(1,1,v[1]); - mat_trans->SetElement(1,2,v[2]); - mat_trans->SetElement(2,0,n[0]); - mat_trans->SetElement(2,1,n[1]); - mat_trans->SetElement(2,2,n[2]); - // Inverse rotation (orthogonal, so just take transpose) - mat_trans->Transpose(); - // Then translate the coordinate frame to camera position - mat_trans->SetElement(0,3,position[0]); - mat_trans->SetElement(1,3,position[1]); - mat_trans->SetElement(2,3,position[2]); - mat_trans->SetElement(3,3,1); - - vtkSmartPointer axes_colors = vtkSmartPointer::New (); - axes_colors->Allocate (6); - axes_colors->InsertNextValue (0.0); - axes_colors->InsertNextValue (0.0); - axes_colors->InsertNextValue (0.5); - axes_colors->InsertNextValue (0.5); - axes_colors->InsertNextValue (1.0); - axes_colors->InsertNextValue (1.0); - - vtkSmartPointer axes_data = axes->GetOutput (); - axes_data->Update (); - axes_data->GetPointData ()->SetScalars (axes_colors); - - // Transform the default coordinate frame - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->PreMultiply(); - transform->SetMatrix(mat_trans); - - vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(axes_data); - filter->SetTransform(transform); - filter->Update(); - - vtkSmartPointer axes_tubes = vtkSmartPointer::New (); - axes_tubes->SetInput (filter->GetOutput()); - axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); - axes_tubes->SetNumberOfSides (6); - - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetScalarModeToUsePointData (); - mapper->SetInput(axes_tubes->GetOutput ()); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(mapper); - - WidgetAccessor::setProp(*this, actor); -} - cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 1d53b5d25..94e4be53d 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -19,6 +19,32 @@ cv::Affine3f cv::viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& ax return Affine3f(R, origin); } +cv::Affine3f cv::viz::makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir) +{ + // Compute the transformation matrix for drawing the camera frame in a scene + Vec3f u,v,n; + n = normalize(focal_point - position); + u = normalize(y_dir.cross(n)); + v = n.cross(u); + + Matx44f pose_mat; + pose_mat.zeros(); + pose_mat(0,0) = u[0]; + pose_mat(0,1) = u[1]; + pose_mat(0,2) = u[2]; + pose_mat(1,0) = v[0]; + pose_mat(1,1) = v[1]; + pose_mat(1,2) = v[2]; + pose_mat(2,0) = n[0]; + pose_mat(2,1) = n[1]; + pose_mat(2,2) = n[2]; + pose_mat(3,0) = position[0]; + pose_mat(3,1) = position[1]; + pose_mat(3,2) = position[2]; + pose_mat(3,3) = 1.0f; + pose_mat = pose_mat.t(); + return pose_mat; +} vtkSmartPointer cv::viz::convertToVtkMatrix (const cv::Matx44f &m) { From b64e6ccc6cafa4074c8dd88d25920e2eda88e6de Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 29 Jul 2013 15:06:05 +0200 Subject: [PATCH 121/205] static function for appending clouds in cloud collection widget --- modules/viz/src/cloud_widgets.cpp | 112 +++++++++++------------------- 1 file changed, 42 insertions(+), 70 deletions(-) diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index 2d980df10..a30c97a32 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -271,6 +271,44 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget vertices->SetCells (nr_points, cells); return polydata; } + + static void createMapper(vtkSmartPointer actor, vtkSmartPointer poly_data, Vec3d& minmax) + { + vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper()); + if (!mapper) + { + // This is the first cloud + vtkSmartPointer mapper_new = vtkSmartPointer::New (); + mapper_new->SetInputConnection (poly_data->GetProducerPort()); + + mapper_new->SetScalarRange(minmax.val); + mapper_new->SetScalarModeToUsePointData (); + + bool interpolation = (poly_data && poly_data->GetNumberOfCells () != poly_data->GetNumberOfVerts ()); + + mapper_new->SetInterpolateScalarsBeforeMapping(interpolation); + mapper_new->ScalarVisibilityOn(); + mapper_new->ImmediateModeRenderingOff(); + + actor->SetNumberOfCloudPoints (int (std::max(1, poly_data->GetNumberOfPoints () / 10))); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper_new); + return ; + } + + vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); + CV_Assert(data); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); + appendFilter->AddInputConnection(poly_data->GetProducerPort()); + mapper->SetInputConnection(appendFilter->GetOutputPort()); + + // Update the number of cloud points + vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); + actor->SetNumberOfCloudPoints (int (std::max(1, old_cloud_points+poly_data->GetNumberOfPoints () / 10))); + } }; cv::viz::CloudCollectionWidget::CloudCollectionWidget() @@ -321,41 +359,8 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, InputArray _col vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); - vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper()); - if (!mapper) - { - // This is the first cloud - vtkSmartPointer mapper_new = vtkSmartPointer::New (); - mapper_new->SetInputConnection (transform_filter->GetOutputPort()); - - Vec3d minmax(scalars->GetRange()); - mapper_new->SetScalarRange(minmax.val); - mapper_new->SetScalarModeToUsePointData (); - - bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); - - mapper_new->SetInterpolateScalarsBeforeMapping(interpolation); - mapper_new->ScalarVisibilityOn(); - mapper_new->ImmediateModeRenderingOff(); - - actor->SetNumberOfCloudPoints (int (std::max(1, polydata->GetNumberOfPoints () / 10))); - actor->GetProperty()->SetInterpolationToFlat(); - actor->GetProperty()->BackfaceCullingOn(); - actor->SetMapper(mapper_new); - return ; - } - - vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); - CV_Assert(data); - - vtkSmartPointer appendFilter = vtkSmartPointer::New(); - appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); - appendFilter->AddInputConnection(transform_filter->GetOutputPort()); - mapper->SetInputConnection(appendFilter->GetOutputPort()); - - // Update the number of cloud points - vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); - actor->SetNumberOfCloudPoints (int (std::max(1, old_cloud_points+polydata->GetNumberOfPoints () / 10))); + Vec3d minmax(scalars->GetRange()); + CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax); } void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, const Color &color, const Affine3f &pose) @@ -389,41 +394,8 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, const Color &co vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert(actor); - vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper()); - if (!mapper) - { - // This is the first cloud - vtkSmartPointer mapper_new = vtkSmartPointer::New (); - mapper_new->SetInputConnection (transform_filter->GetOutputPort()); - - Vec3d minmax(scalars->GetRange()); - mapper_new->SetScalarRange(minmax.val); - mapper_new->SetScalarModeToUsePointData (); - - bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); - - mapper_new->SetInterpolateScalarsBeforeMapping(interpolation); - mapper_new->ScalarVisibilityOn(); - mapper_new->ImmediateModeRenderingOff(); - - actor->SetNumberOfCloudPoints (int (std::max(1, polydata->GetNumberOfPoints () / 10))); - actor->GetProperty()->SetInterpolationToFlat(); - actor->GetProperty()->BackfaceCullingOn(); - actor->SetMapper(mapper_new); - return ; - } - - vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); - CV_Assert(data); - - vtkSmartPointer appendFilter = vtkSmartPointer::New(); - appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); - appendFilter->AddInputConnection(transform_filter->GetOutputPort()); - mapper->SetInputConnection(appendFilter->GetOutputPort()); - - // Update the number of cloud points - vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); - actor->SetNumberOfCloudPoints (int (std::max(1, old_cloud_points+polydata->GetNumberOfPoints () / 10))); + Vec3d minmax(scalars->GetRange()); + CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax); } template<> cv::viz::CloudCollectionWidget cv::viz::Widget::cast() From f5816c883f0e324227bf9f5c36475c3ae0cbf18f Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 29 Jul 2013 15:10:48 +0200 Subject: [PATCH 122/205] fix setting color of 3D objects --- modules/viz/src/widget.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 8f9e90404..b295843f9 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -142,10 +142,6 @@ void cv::viz::Widget3D::setColor(const Color &color) actor->GetMapper ()->ScalarVisibilityOff (); actor->GetProperty ()->SetColor (c.val); actor->GetProperty ()->SetEdgeColor (c.val); - actor->GetProperty ()->SetAmbient (0.8); - actor->GetProperty ()->SetDiffuse (0.8); - actor->GetProperty ()->SetSpecular (0.8); - actor->GetProperty ()->SetLighting (0); actor->Modified (); } From 69e66d7bb53abadf15f94cd746dfa3401ea7f271 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 2 Aug 2013 13:37:15 +0400 Subject: [PATCH 123/205] fixed little bug in makeCameraPose --- modules/viz/src/viz.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 94e4be53d..2d563f6c1 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -22,13 +22,11 @@ cv::Affine3f cv::viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& ax cv::Affine3f cv::viz::makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir) { // Compute the transformation matrix for drawing the camera frame in a scene - Vec3f u,v,n; - n = normalize(focal_point - position); - u = normalize(y_dir.cross(n)); - v = n.cross(u); + Vec3f n = normalize(focal_point - position); + Vec3f u = normalize(y_dir.cross(n)); + Vec3f v = n.cross(u); - Matx44f pose_mat; - pose_mat.zeros(); + Matx44f pose_mat = Matx44f::zeros(); pose_mat(0,0) = u[0]; pose_mat(0,1) = u[1]; pose_mat(0,2) = u[2]; @@ -86,4 +84,4 @@ namespace cv return reinterpret_cast(pointer); } } -} \ No newline at end of file +} From 54774f6d3b62209da63f05f368dc0fe455b512c5 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 2 Aug 2013 13:45:43 +0400 Subject: [PATCH 124/205] updated license header --- modules/viz/include/opencv2/viz.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 7e04f7b94..c7976a999 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -10,8 +10,7 @@ // License Agreement // For Open Source Computer Vision Library // -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// 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, @@ -39,11 +38,11 @@ // the use of this software, even if advised of the possibility of such damage. // // Authors: -// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com // * Ozan Tonkal +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com // -// During implementation of OpenCV Viz module, similar module -// from PCL (www.pointclouds.org) was used as reference implementation. +// OpenCV Viz module is complete rewrite of +// PCL visualization module (www.pointclouds.org) // //M*/ From 8fa6b6a6ef4ed9d49c1a3f00de7f38f724a6038e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 1 Aug 2013 15:22:35 +0200 Subject: [PATCH 125/205] initial setViewerPose implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 3 +++ modules/viz/src/viz3d.cpp | 3 +++ modules/viz/src/viz3d_impl.cpp | 22 ++++++++++++++++++++++ modules/viz/src/viz3d_impl.hpp | 1 + 4 files changed, 29 insertions(+) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index db8819afd..8fbaacd55 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -38,6 +38,9 @@ namespace cv void setWidgetPose(const String &id, const Affine3f &pose); void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; + + Affine3f getViewerPose(); + void setViewerPose(const Affine3f &pose); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index f4a300b21..6bf00172c 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -45,3 +45,6 @@ cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_ void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { impl_->setWidgetPose(id, pose); } void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } + +void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } +cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index ca4b75bbf..fb72047c5 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -591,6 +591,28 @@ void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) camera.window_pos = cv::Vec2d::all(0); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) +{ + vtkCamera& camera = *renderer_->GetActiveCamera (); + + // Position = extrinsic translation + cv::Vec3f pos_vec = pose.translation(); + + // Rotate the view vector + cv::Matx33f rotation = pose.rotation(); + cv::Vec3f y_axis (0.f, 1.f, 0.f); + cv::Vec3f up_vec (rotation * y_axis); + + // Compute the new focal point + cv::Vec3f z_axis (0.f, 0.f, 1.f); + cv::Vec3f focal_vec = pos_vec + rotation * z_axis; + + camera.SetPosition(pos_vec[0], pos_vec[1], pos_vec[2]); + camera.SetFocalPoint(focal_vec[0], focal_vec[1], focal_vec[2]); + camera.SetViewUp(up_vec[0], up_vec[1], up_vec[2]); +} + ///////////////////////////////////////////////////////////////////////////////////////////// cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose () { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index c6bef0988..704cf08a8 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -140,6 +140,7 @@ public: void getCameras (Camera& camera); //to implement Viz3d set/getViewerPose() + void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); From a76cc9ef88a3876da371faa4224281ccff6cf1e9 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 2 Aug 2013 16:33:30 +0200 Subject: [PATCH 126/205] initial camera implementation (camera2), fix bug (zeros method) --- modules/viz/include/opencv2/viz/types.hpp | 25 +++++++++++ modules/viz/src/types.cpp | 54 +++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index b0e3efda3..4ef05a68a 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -93,6 +94,30 @@ namespace cv Point pointer; unsigned int key_state; }; + + class CV_EXPORTS Camera2 + { + public: + Camera2(float f_x, float f_y, float c_x, float c_y, const Size &window_size); + Camera2(const Vec2f &fov, const Size &window_size); + Camera2(const cv::Mat &K, const Size &window_size); + + inline const Vec2d & getClip() const { return clip_; } + inline void setClip(const Vec2d &clip) { clip_ = clip; } + + inline const Size & getWindowSize() const { return window_size_; } + void setWindowSize(const Size &window_size); + + inline const Vec2f & getFov() const { return fov_; } + inline void setFov(const Vec2f & fov) { fov_ = fov; } + + private: + Vec2d clip_; + Vec2f fov_; + Size window_size_; + Vec2f principal_point_; + Vec2f focal_; + }; } /* namespace viz */ } /* namespace cv */ diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 871c2dbcb..4ea1b32d3 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -142,3 +142,57 @@ cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file) { return loadMeshImpl::loadMesh(file); } + +//////////////////////////////////////////////////////////////////// +/// Camera implementation + +cv::viz::Camera2::Camera2(float f_x, float f_y, float c_x, float c_y, const Size &window_size) +{ + CV_Assert(window_size.width > 0 && window_size.height > 0); + setClip(Vec2d(0.01, 1000.01));// Default clipping + + fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)) * 180 / CV_PI; + fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)) * 180 / CV_PI; + + principal_point_[0] = c_x; + principal_point_[1] = c_y; + + focal_[0] = f_x; + focal_[1] = f_y; +} + +cv::viz::Camera2::Camera2(const Vec2f &fov, const Size &window_size) +{ + CV_Assert(window_size.width > 0 && window_size.height > 0); + setClip(Vec2d(0.01, 1000.01)); // Default clipping + window_size_ = window_size; + fov_ = fov; + principal_point_ = Vec2f(-1.0f, -1.0f); // Symmetric lens + focal_ = Vec2f(-1.0f, -1.0f); +} + +cv::viz::Camera2::Camera2(const cv::Mat & K, const Size &window_size) +{ + CV_Assert(K.rows == 3 && K.cols == 3); + CV_Assert(window_size.width > 0 && window_size.height > 0); + + float f_x = K.at(0,0); + float f_y = K.at(1,1); + float c_x = K.at(0,2); + float c_y = K.at(1,2); + Camera2(f_x, f_y, c_x, c_y, window_size); +} + +void cv::viz::Camera2::setWindowSize(const Size &window_size) +{ + CV_Assert(window_size.width > 0 && window_size.height > 0); + + // Vertical field of view is fixed! + // Horizontal field of view is expandable based on the aspect ratio + float aspect_ratio_new = window_size.width / window_size.height; + + if (principal_point_[0] < 0.0f) + fov_[0] = 2 * atan2(tan(fov_[0] * 0.5), aspect_ratio_new); // This assumes that the lens is symmetric! + else + fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])) * 180 / CV_PI; +} From e4e9ed876f2170409e74bd7dbca33dc3cca72413 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 3 Aug 2013 15:40:36 +0200 Subject: [PATCH 127/205] spheres trajectory widget implementation --- modules/viz/include/opencv2/viz/widgets.hpp | 10 +- modules/viz/src/shape_widgets.cpp | 171 ++++++++++---------- 2 files changed, 98 insertions(+), 83 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 603d17df8..c74633049 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -182,14 +182,19 @@ namespace cv enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); - TrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, - double sphere_radius, const Color &line_color = Color::white(), const Color &sphere_color = Color::white()); TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); // Camera frustums TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); // Camera frustums private: struct ApplyPath; }; + + class CV_EXPORTS SpheresTrajectoryWidget : public Widget3D + { + public: + SpheresTrajectoryWidget(const std::vector &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()); + }; class CV_EXPORTS CloudWidget : public Widget3D { @@ -249,6 +254,7 @@ namespace cv template<> CV_EXPORTS Image3DWidget Widget::cast(); template<> CV_EXPORTS CameraPositionWidget Widget::cast(); template<> CV_EXPORTS TrajectoryWidget Widget::cast(); + template<> CV_EXPORTS SpheresTrajectoryWidget Widget::cast(); template<> CV_EXPORTS CloudWidget Widget::cast(); template<> CV_EXPORTS CloudCollectionWidget Widget::cast(); template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index caa5bf358..050b978ef 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1181,87 +1181,6 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i WidgetAccessor::setProp(*this, actor); } -cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, - double sphere_radius, const Color &line_color, const Color &sphere_color) -{ - vtkSmartPointer appendFilter = vtkSmartPointer::New(); - vtkIdType nr_poses = path.size(); - - // Create color arrays - vtkSmartPointer line_scalars = vtkSmartPointer::New(); - line_scalars->SetNumberOfComponents(3); - line_scalars->InsertNextTuple3(line_color[2], line_color[1], line_color[0]); - - // Create color array for sphere - vtkSphereSource * dummy_sphere = vtkSphereSource::New(); - // Create the array for big sphere - dummy_sphere->SetRadius(init_sphere_radius); - dummy_sphere->Update(); - vtkIdType nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); - vtkSmartPointer sphere_scalars_init = vtkSmartPointer::New(); - sphere_scalars_init->SetNumberOfComponents(3); - sphere_scalars_init->SetNumberOfTuples(nr_points); - sphere_scalars_init->FillComponent(0, sphere_color[2]); - sphere_scalars_init->FillComponent(1, sphere_color[1]); - sphere_scalars_init->FillComponent(2, sphere_color[0]); - // Create the array for small sphere - dummy_sphere->SetRadius(sphere_radius); - dummy_sphere->Update(); - nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); - vtkSmartPointer sphere_scalars = vtkSmartPointer::New(); - sphere_scalars->SetNumberOfComponents(3); - sphere_scalars->SetNumberOfTuples(nr_points); - sphere_scalars->FillComponent(0, sphere_color[2]); - sphere_scalars->FillComponent(1, sphere_color[1]); - sphere_scalars->FillComponent(2, sphere_color[0]); - dummy_sphere->Delete(); - - for (vtkIdType i = 0; i < nr_poses; ++i) - { - Point3f new_pos = path[i].translation(); - - vtkSmartPointer sphere_source = vtkSmartPointer::New(); - sphere_source->SetCenter (new_pos.x, new_pos.y, new_pos.z); - if (i == 0) - { - sphere_source->SetRadius(init_sphere_radius); - sphere_source->Update(); - sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars_init); - appendFilter->AddInputConnection(sphere_source->GetOutputPort()); - continue; - } - else - { - sphere_source->SetRadius(sphere_radius); - sphere_source->Update(); - sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars); - appendFilter->AddInputConnection(sphere_source->GetOutputPort()); - } - - - Affine3f relativeAffine = path[i].inv() * path[i-1]; - Vec3f v = path[i].rotation() * relativeAffine.translation(); - v = normalize(v) * line_length; - - vtkSmartPointer line_source = vtkSmartPointer::New(); - line_source->SetPoint1(new_pos.x + v[0], new_pos.y + v[1], new_pos.z + v[2]); - line_source->SetPoint2(new_pos.x, new_pos.y, new_pos.z); - line_source->Update(); - line_source->GetOutput()->GetCellData()->SetScalars(line_scalars); - - appendFilter->AddInputConnection(line_source->GetOutputPort()); - } - - vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetScalarModeToUseCellData(); - mapper->SetInput(appendFilter->GetOutput()); - - vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(mapper); - - WidgetAccessor::setProp(*this, actor); -} - cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); @@ -1350,4 +1269,94 @@ template<> cv::viz::TrajectoryWidget cv::viz::Widget::castcast(); return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// spheres trajectory widget implementation + +cv::viz::SpheresTrajectoryWidget::SpheresTrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, double sphere_radius, + const Color &line_color, const Color &sphere_color) +{ + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + vtkIdType nr_poses = path.size(); + + // Create color arrays + vtkSmartPointer line_scalars = vtkSmartPointer::New(); + line_scalars->SetNumberOfComponents(3); + line_scalars->InsertNextTuple3(line_color[2], line_color[1], line_color[0]); + + // Create color array for sphere + vtkSphereSource * dummy_sphere = vtkSphereSource::New(); + // Create the array for big sphere + dummy_sphere->SetRadius(init_sphere_radius); + dummy_sphere->Update(); + vtkIdType nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); + vtkSmartPointer sphere_scalars_init = vtkSmartPointer::New(); + sphere_scalars_init->SetNumberOfComponents(3); + sphere_scalars_init->SetNumberOfTuples(nr_points); + sphere_scalars_init->FillComponent(0, sphere_color[2]); + sphere_scalars_init->FillComponent(1, sphere_color[1]); + sphere_scalars_init->FillComponent(2, sphere_color[0]); + // Create the array for small sphere + dummy_sphere->SetRadius(sphere_radius); + dummy_sphere->Update(); + nr_points = dummy_sphere->GetOutput()->GetNumberOfCells(); + vtkSmartPointer sphere_scalars = vtkSmartPointer::New(); + sphere_scalars->SetNumberOfComponents(3); + sphere_scalars->SetNumberOfTuples(nr_points); + sphere_scalars->FillComponent(0, sphere_color[2]); + sphere_scalars->FillComponent(1, sphere_color[1]); + sphere_scalars->FillComponent(2, sphere_color[0]); + dummy_sphere->Delete(); + + for (vtkIdType i = 0; i < nr_poses; ++i) + { + Point3f new_pos = path[i].translation(); + + vtkSmartPointer sphere_source = vtkSmartPointer::New(); + sphere_source->SetCenter (new_pos.x, new_pos.y, new_pos.z); + if (i == 0) + { + sphere_source->SetRadius(init_sphere_radius); + sphere_source->Update(); + sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars_init); + appendFilter->AddInputConnection(sphere_source->GetOutputPort()); + continue; + } + else + { + sphere_source->SetRadius(sphere_radius); + sphere_source->Update(); + sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars); + appendFilter->AddInputConnection(sphere_source->GetOutputPort()); + } + + + Affine3f relativeAffine = path[i].inv() * path[i-1]; + Vec3f v = path[i].rotation() * relativeAffine.translation(); + v = normalize(v) * line_length; + + vtkSmartPointer line_source = vtkSmartPointer::New(); + line_source->SetPoint1(new_pos.x + v[0], new_pos.y + v[1], new_pos.z + v[2]); + line_source->SetPoint2(new_pos.x, new_pos.y, new_pos.z); + line_source->Update(); + line_source->GetOutput()->GetCellData()->SetScalars(line_scalars); + + appendFilter->AddInputConnection(line_source->GetOutputPort()); + } + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUseCellData(); + mapper->SetInput(appendFilter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::SpheresTrajectoryWidget cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); } \ No newline at end of file From 4953786de1e1c21b43bbda79155177368bd1853d Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 3 Aug 2013 15:42:10 +0200 Subject: [PATCH 128/205] remove boost include (caused by Kdevelop autocomplete) --- modules/viz/include/opencv2/viz/types.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 4ef05a68a..33b22325f 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include From f445f76213be9337077cf78bc790ba39b2c452fc Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 3 Aug 2013 16:33:11 +0200 Subject: [PATCH 129/205] initial setCamera implementation --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/types.cpp | 2 +- modules/viz/src/viz3d.cpp | 1 + modules/viz/src/viz3d_impl.cpp | 12 ++++++++++++ modules/viz/src/viz3d_impl.hpp | 2 ++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 8fbaacd55..e173fcfca 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -39,6 +39,7 @@ namespace cv void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; + void setCamera(const Camera2 &camera); Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 4ea1b32d3..e95f67e56 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -167,7 +167,7 @@ cv::viz::Camera2::Camera2(const Vec2f &fov, const Size &window_size) setClip(Vec2d(0.01, 1000.01)); // Default clipping window_size_ = window_size; fov_ = fov; - principal_point_ = Vec2f(-1.0f, -1.0f); // Symmetric lens + principal_point_ = Vec2f(-1.0f, -1.0f); // Default symmetric lens focal_ = Vec2f(-1.0f, -1.0f); } diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 6bf00172c..8aa97419f 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -46,5 +46,6 @@ void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { imp void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } +void cv::viz::Viz3d::setCamera(const Camera2 &camera) { impl_->setCamera(camera); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index fb72047c5..78c1441a3 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -591,6 +591,18 @@ void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) camera.window_pos = cv::Vec2d::all(0); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) +{ + vtkCamera& active_camera = *renderer_->GetActiveCamera(); + + // Set the intrinsic parameters of the camera + active_camera.SetUseHorizontalViewAngle (0); // Horizontal view angle is set based on the window size + active_camera.SetViewAngle (camera.getFov()[1] * 180.0f / CV_PI); + active_camera.SetClippingRange (camera.getClip()[0], camera.getClip()[1]); + window_->SetSize (static_cast (camera.getWindowSize().width), static_cast (camera.getWindowSize().height)); +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 704cf08a8..26bafd342 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -109,6 +109,8 @@ public: // //////////////////////////////////////////////////////////////////////////////////// // All camera methods to refactor into set/getViewwerPose, setCamera() // and 'Camera' class itself with various constructors/fields + + void setCamera(const Camera2 &camera); void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ From 0bb89e767a8f40f6a14683fd0288d8739a18d297 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sun, 4 Aug 2013 17:01:41 +0200 Subject: [PATCH 130/205] fix field of view formula in camera class, implement get camera --- modules/viz/src/types.cpp | 2 +- modules/viz/src/viz3d_impl.cpp | 10 ++++++++++ modules/viz/src/viz3d_impl.hpp | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index e95f67e56..827b8b3bc 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -192,7 +192,7 @@ void cv::viz::Camera2::setWindowSize(const Size &window_size) float aspect_ratio_new = window_size.width / window_size.height; if (principal_point_[0] < 0.0f) - fov_[0] = 2 * atan2(tan(fov_[0] * 0.5), aspect_ratio_new); // This assumes that the lens is symmetric! + fov_[0] = 2 * atan2(tan(fov_[1] * 0.5), aspect_ratio_new); // This assumes that the lens is symmetric! else fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])) * 180 / CV_PI; } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 78c1441a3..f764c7755 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -603,6 +603,16 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) window_->SetSize (static_cast (camera.getWindowSize().width), static_cast (camera.getWindowSize().height)); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::getCamera(viz::Camera2 &camera) +{ + vtkCamera& active_camera = *renderer_->GetActiveCamera(); + camera.setFov(Vec2f(0.0, active_camera.GetViewAngle() * CV_PI / 180.0f)); + camera.setClip(Vec2d(active_camera.GetClippingRange())); + camera.setWindowSize(Size(renderer_->GetRenderWindow()->GetSize()[0], + renderer_->GetRenderWindow()->GetSize()[1])); +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 26bafd342..5bd4ebdea 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -111,6 +111,7 @@ public: // and 'Camera' class itself with various constructors/fields void setCamera(const Camera2 &camera); + void getCamera(Camera2 &camera); void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ From 439ba98e0a14a0f382e58720f5601854e3c1330a Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 13:01:21 +0200 Subject: [PATCH 131/205] initial implementation of projection matrix, 3D to window coordinates, window coordinates to 3D ray (not yet tested) --- modules/viz/include/opencv2/viz/types.hpp | 2 ++ modules/viz/include/opencv2/viz/viz3d.hpp | 3 ++ modules/viz/src/types.cpp | 23 ++++++++++++ modules/viz/src/viz3d.cpp | 3 ++ modules/viz/src/viz3d_impl.cpp | 44 ++++++++++++++++++++--- modules/viz/src/viz3d_impl.hpp | 6 ++-- 6 files changed, 73 insertions(+), 8 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 33b22325f..8dd68196b 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -110,6 +110,8 @@ namespace cv inline const Vec2f & getFov() const { return fov_; } inline void setFov(const Vec2f & fov) { fov_ = fov; } + void computeProjectionMatrix(Matx44f &proj) const; + private: Vec2d clip_; Vec2f fov_; diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index e173fcfca..eff8ac000 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -42,6 +42,9 @@ namespace cv void setCamera(const Camera2 &camera); Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); + + void convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord); + void converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 827b8b3bc..e32cf54cb 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -196,3 +196,26 @@ void cv::viz::Camera2::setWindowSize(const Size &window_size) else fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])) * 180 / CV_PI; } + +void cv::viz::Camera2::computeProjectionMatrix(Matx44f &proj) const +{ + double top = clip_[0] * tan (0.5 * fov_[1]); + double left = -(top * window_size_.width) / window_size_.height; + double right = -left; + double bottom = -top; + + double temp1 = 2.0 * clip_[0]; + double temp2 = 1.0 / (right - left); + double temp3 = 1.0 / (top - bottom); + double temp4 = 1.0 / clip_[1] - clip_[0]; + + proj = Matx44d::zeros(); + + proj(0,0) = temp1 * temp2; + proj(1,1) = temp1 * temp3; + proj(0,2) = (right + left) * temp2; + proj(1,2) = (top + bottom) * temp3; + proj(2,2) = (-clip_[1] - clip_[0]) * temp4; + proj(3,2) = -1.0; + proj(2,3) = (-temp1 * clip_[1]) * temp4; +} \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 8aa97419f..2c6702580 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -49,3 +49,6 @@ cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl void cv::viz::Viz3d::setCamera(const Camera2 &camera) { impl_->setCamera(camera); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } + +void cv::viz::Viz3d::convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } +void cv::viz::Viz3d::converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction) { impl_->converTo3DRay(window_coord, origin, direction); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index f764c7755..70d1e6fee 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -604,13 +604,18 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::getCamera(viz::Camera2 &camera) +cv::viz::Camera2 cv::viz::Viz3d::VizImpl::getCamera() const { vtkCamera& active_camera = *renderer_->GetActiveCamera(); - camera.setFov(Vec2f(0.0, active_camera.GetViewAngle() * CV_PI / 180.0f)); - camera.setClip(Vec2d(active_camera.GetClippingRange())); - camera.setWindowSize(Size(renderer_->GetRenderWindow()->GetSize()[0], - renderer_->GetRenderWindow()->GetSize()[1])); + + Vec2f fov(0.0, active_camera.GetViewAngle() * CV_PI / 180.0f); + Vec2d clip(active_camera.GetClippingRange()); + Size window_size(renderer_->GetRenderWindow()->GetSize()[0], + renderer_->GetRenderWindow()->GetSize()[1]); + + Camera2 camera(fov, window_size); + camera.setClip(clip); + return camera; } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -664,6 +669,35 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose () return cv::Affine3f(R, pos); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord) +{ + // Use the built in function of renderer + double point_wcs[3] = {pt.x, pt.y, pt.z}; + renderer_->WorldToView(point_wcs[0], point_wcs[1], point_wcs[2]); + window_coord.x = point_wcs[0]; + window_coord.y = point_wcs[1]; + window_coord.z = point_wcs[2]; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction) +{ + // Use the built in function of renderer + double point_view[3] = {window_coord.x, window_coord.y, window_coord.z}; + renderer_->ViewToWorld(point_view[0], point_view[1], point_view[2]); + + vtkCamera &active_camera = *renderer_->GetActiveCamera(); + double *cam_pos = active_camera.GetPosition(); + origin.x = cam_pos[0]; + origin.y = cam_pos[1]; + origin.z = cam_pos[2]; + direction[0] = point_view[0] - cam_pos[0]; + direction[1] = point_view[1] - cam_pos[1]; + direction[2] = point_view[2] - cam_pos[2]; + normalize(direction); +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::resetCamera () { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 5bd4ebdea..3b3018ff2 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -111,7 +111,7 @@ public: // and 'Camera' class itself with various constructors/fields void setCamera(const Camera2 &camera); - void getCamera(Camera2 &camera); + Camera2 getCamera() const; void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ @@ -146,8 +146,8 @@ public: void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); - - + void convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord); + void converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction); From f060eee5a5d5e190b7ee5527d8a5ab42efd5f17f Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 15:10:17 +0200 Subject: [PATCH 132/205] fix window_size setter, remove camera related old methods from viz3d --- modules/viz/src/types.cpp | 6 +- modules/viz/src/viz3d_impl.cpp | 148 +++++---------------------------- modules/viz/src/viz3d_impl.hpp | 22 +---- 3 files changed, 25 insertions(+), 151 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index e32cf54cb..ebaf9d324 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -165,10 +165,10 @@ cv::viz::Camera2::Camera2(const Vec2f &fov, const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); setClip(Vec2d(0.01, 1000.01)); // Default clipping - window_size_ = window_size; - fov_ = fov; principal_point_ = Vec2f(-1.0f, -1.0f); // Default symmetric lens focal_ = Vec2f(-1.0f, -1.0f); + setFov(fov); + setWindowSize(window_size); } cv::viz::Camera2::Camera2(const cv::Mat & K, const Size &window_size) @@ -195,6 +195,8 @@ void cv::viz::Camera2::setWindowSize(const Size &window_size) fov_[0] = 2 * atan2(tan(fov_[1] * 0.5), aspect_ratio_new); // This assumes that the lens is symmetric! else fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])) * 180 / CV_PI; + + window_size_ = window_size; } void cv::viz::Camera2::computeProjectionMatrix(Matx44f &proj) const diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 70d1e6fee..ee59b9413 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -542,25 +542,12 @@ bool cv::viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::initCameraParameters () { - Camera camera_temp; - // Set default camera parameters to something meaningful - camera_temp.clip = Vec2d(0.01, 1000.01); - - // Look straight along the z-axis - camera_temp.focal = Vec3d(0.0, 0.0, 1.0); - - // Position the camera at the origin - camera_temp.pos = Vec3d(0.0, 0.0, 0.0); - - // Set the up-vector of the camera to be the y-axis - camera_temp.view_up = Vec3d(0.0, 1.0, 0.0); - - // Set the camera field of view to about - camera_temp.fovy = 0.8575; - camera_temp.window_size = Vec2i(window_->GetScreenSize()) / 2; - camera_temp.window_pos = Vec2i(0, 0); - - setCameraParameters (camera_temp); + Vec2i window_size(window_->GetScreenSize()); + window_size /= 2; + + Camera2 camera_temp(Vec2f(0.0,0.8575), Size(window_size[0], window_size[1])); + setCamera(camera_temp); + setViewerPose(makeCameraPose(Vec3f(0.0f,0.0f,0.0f), Vec3f(0.0f, 0.0f, 1.0f), Vec3f(0.0f, 1.0f, 0.0f))); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -577,19 +564,19 @@ void cv::viz::Viz3d::VizImpl::updateCamera () } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) -{ - vtkCamera* active_camera = renderer_->GetActiveCamera (); - - camera.pos = cv::Vec3d(active_camera->GetPosition()); - camera.focal = cv::Vec3d(active_camera->GetFocalPoint()); - camera.clip = cv::Vec2d(active_camera->GetClippingRange()); - camera.view_up = cv::Vec3d(active_camera->GetViewUp()); - - camera.fovy = active_camera->GetViewAngle()/ 180.0 * CV_PI; - camera.window_size = cv::Vec2i(renderer_->GetRenderWindow()->GetSize()); - camera.window_pos = cv::Vec2d::all(0); -} +// void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) +// { +// vtkCamera* active_camera = renderer_->GetActiveCamera (); +// +// camera.pos = cv::Vec3d(active_camera->GetPosition()); +// camera.focal = cv::Vec3d(active_camera->GetFocalPoint()); +// camera.clip = cv::Vec2d(active_camera->GetClippingRange()); +// camera.view_up = cv::Vec3d(active_camera->GetViewUp()); +// +// camera.fovy = active_camera->GetViewAngle()/ 180.0 * CV_PI; +// camera.window_size = cv::Vec2i(renderer_->GetRenderWindow()->GetSize()); +// camera.window_pos = cv::Vec2d::all(0); +// } ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) @@ -704,105 +691,10 @@ void cv::viz::Viz3d::VizImpl::resetCamera () renderer_->ResetCamera (); } -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up) -{ - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (pos[0], pos[1], pos[2]); - cam->SetFocalPoint (view[0], view[1], view[2]); - cam->SetViewUp (up[0], up[1], up[2]); - renderer_->Render (); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z) -{ - //rens_->InitTraversal (); - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (pos_x, pos_y, pos_z); - cam->SetViewUp (up_x, up_y, up_z); - renderer_->Render (); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraParameters (const cv::Matx33f& intrinsics, const cv::Affine3f& extrinsics) -{ - // Position = extrinsic translation - cv::Vec3f pos_vec = extrinsics.translation(); - - - // Rotate the view vector - cv::Matx33f rotation = extrinsics.rotation(); - cv::Vec3f y_axis (0.f, 1.f, 0.f); - cv::Vec3f up_vec (rotation * y_axis); - - // Compute the new focal point - cv::Vec3f z_axis (0.f, 0.f, 1.f); - cv::Vec3f focal_vec = pos_vec + rotation * z_axis; - - // Get the width and height of the image - assume the calibrated centers are at the center of the image - Eigen::Vector2i window_size; - window_size[0] = static_cast (intrinsics(0, 2)); - window_size[1] = static_cast (intrinsics(1, 2)); - - // Compute the vertical field of view based on the focal length and image heigh - double fovy = 2 * atan (window_size[1] / (2. * intrinsics (1, 1))) * 180.0 / M_PI; - - //rens_->InitTraversal (); - - - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (pos_vec[0], pos_vec[1], pos_vec[2]); - cam->SetFocalPoint (focal_vec[0], focal_vec[1], focal_vec[2]); - cam->SetViewUp (up_vec[0], up_vec[1], up_vec[2]); - cam->SetUseHorizontalViewAngle (0); - cam->SetViewAngle (fovy); - cam->SetClippingRange (0.01, 1000.01); - window_->SetSize (window_size[0], window_size[1]); - - renderer_->Render (); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraParameters (const cv::viz::Camera &camera) -{ - //rens_->InitTraversal (); - - - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (camera.pos[0], camera.pos[1], camera.pos[2]); - cam->SetFocalPoint (camera.focal[0], camera.focal[1], camera.focal[2]); - cam->SetViewUp (camera.view_up[0], camera.view_up[1], camera.view_up[2]); - cam->SetClippingRange (camera.clip.val); - cam->SetUseHorizontalViewAngle (0); - cam->SetViewAngle (camera.fovy * 180.0 / M_PI); - - window_->SetSize (static_cast (camera.window_size[0]), static_cast (camera.window_size[1])); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraClipDistances (double near, double far) -{ - //rens_->InitTraversal (); - - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetClippingRange (near, far); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCameraFieldOfView (double fovy) -{ - //rens_->InitTraversal (); - - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetUseHorizontalViewAngle (0); - cam->SetViewAngle (fovy * 180.0 / M_PI); - -} - ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) { + // TODO Cloud actor is not used vtkSmartPointer camera_pose; static CloudActorMap::iterator it = cloud_actor_map_->find (id); if (it != cloud_actor_map_->end ()) diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 3b3018ff2..86789c806 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -121,27 +121,7 @@ public: /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset. * \param[in] id the point cloud object id (default: cloud) */ void resetCameraViewpoint (const String& id = "cloud"); - /** \brief Set the camera pose given by position, viewpoint and up vector - * \param[in] pos camera location - * \param[in] view the view point of the camera - * \param[in] up the view up direction of the camera */ - void setCameraPosition (const cv::Vec3d& pos, const cv::Vec3d& view, const cv::Vec3d& up); - - /** \brief Set the camera location and viewup according to the given arguments - * \param[in] pos_x,y,z the x,y,z coordinate of the camera location - * \param[in] up_x,y,z the x,y,z component of the view up direction of the camera */ - void setCameraPosition (double pos_x, double pos_y, double pos_z, double up_x, double up_y, double up_z); - - /** \brief Set the camera parameters via an intrinsics and and extrinsics matrix - * \note This assumes that the pixels are square and that the center of the image is at the center of the sensor. - * \param[in] intrinsics the intrinsics that will be used to compute the VTK camera parameters - * \param[in] extrinsics the extrinsics that will be used to compute the VTK camera parameters */ - void setCameraParameters (const cv::Matx33f& intrinsics, const Affine3f& extrinsics); - void setCameraParameters (const Camera &camera); - void setCameraClipDistances (double near, double far); - void setCameraFieldOfView (double fovy); - void getCameras (Camera& camera); - + //to implement Viz3d set/getViewerPose() void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); From 119d97f1f638f6f757dd66f23ceead10888730de Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 15:37:08 +0200 Subject: [PATCH 133/205] remove old camera, rename new camera --- modules/viz/include/opencv2/viz/types.hpp | 8 +-- modules/viz/include/opencv2/viz/viz3d.hpp | 3 +- modules/viz/src/common.cpp | 45 -------------- modules/viz/src/common.h | 73 ----------------------- modules/viz/src/types.cpp | 12 ++-- modules/viz/src/viz3d.cpp | 3 +- modules/viz/src/viz3d_impl.cpp | 23 ++----- modules/viz/src/viz3d_impl.hpp | 4 +- 8 files changed, 20 insertions(+), 151 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 8dd68196b..2ebca5d32 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -94,12 +94,12 @@ namespace cv unsigned int key_state; }; - class CV_EXPORTS Camera2 + class CV_EXPORTS Camera { public: - Camera2(float f_x, float f_y, float c_x, float c_y, const Size &window_size); - Camera2(const Vec2f &fov, const Size &window_size); - Camera2(const cv::Mat &K, const Size &window_size); + Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); + Camera(const Vec2f &fov, const Size &window_size); + Camera(const cv::Mat &K, const Size &window_size); inline const Vec2d & getClip() const { return clip_; } inline void setClip(const Vec2d &clip) { clip_ = clip; } diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index eff8ac000..921eb3223 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -39,7 +39,8 @@ namespace cv void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; - void setCamera(const Camera2 &camera); + void setCamera(const Camera &camera); + Camera getCamera() const; Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); diff --git a/modules/viz/src/common.cpp b/modules/viz/src/common.cpp index 08da19b5d..3c40a00f5 100644 --- a/modules/viz/src/common.cpp +++ b/modules/viz/src/common.cpp @@ -263,48 +263,3 @@ int hull_vertex_table[43][7] = { // return (fabsf (float (sum * 0.5f))); //} - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Camera::computeViewMatrix (Affine3d& view_mat) const -{ - //constructs view matrix from camera pos, view up, and the point it is looking at - //this code is based off of gluLookAt http://www.opengl.org/wiki/GluLookAt_code - - Vec3d zAxis = normalized(focal - pos); - Vec3d xAxis = normalized(zAxis.cross(view_up)); - Vec3d yAxis = xAxis.cross (zAxis); - - Matx33d R; - - R(0, 0) = xAxis[0]; R(0, 1) = xAxis[1]; R(0, 2) = xAxis[2]; - R(1, 0) = yAxis[0]; R(1, 1) = yAxis[1]; R(1, 2) = yAxis[2]; - R(1, 0) = -zAxis[0]; R(2, 1) = -zAxis[1]; R(2, 2) = -zAxis[2]; - - Vec3d t = R * (-pos); - - view_mat = Affine3d(R, t); -} - -/////////////////////////////////////////////////////////////////////// -void cv::viz::Camera::computeProjectionMatrix (Matx44d& proj) const -{ - double top = clip[0] * tan (0.5 * fovy); - double left = -(top * window_size[0]) / window_size[1]; - double right = -left; - double bottom = -top; - - double temp1 = 2.0 * clip[0]; - double temp2 = 1.0 / (right - left); - double temp3 = 1.0 / (top - bottom); - double temp4 = 1.0 / clip[1] - clip[0]; - - proj = Matx44d::zeros(); - - proj(0,0) = temp1 * temp2; - proj(1,1) = temp1 * temp3; - proj(0,2) = (right + left) * temp2; - proj(1,2) = (top + bottom) * temp3; - proj(2,2) = (-clip[1] - clip[0]) * temp4; - proj(3,2) = -1.0; - proj(2,3) = (-temp1 * clip[1]) * temp4; -} diff --git a/modules/viz/src/common.h b/modules/viz/src/common.h index c19dd8979..ea8933417 100644 --- a/modules/viz/src/common.h +++ b/modules/viz/src/common.h @@ -48,79 +48,6 @@ namespace cv SHADING_PHONG }; - class CV_EXPORTS Camera - { - public: - /** Focal point or lookAt. The view direction can be obtained by (focal-pos).normalized () */ - Vec3d focal; - - /** \brief Position of the camera. */ - Vec3d pos; - - /** \brief Up vector of the camera. */ - Vec3d view_up; - - /** \brief Near/far clipping planes depths */ - Vec2d clip; - - /** \brief Field of view angle in y direction (radians). */ - double fovy; - - // the following variables are the actual position and size of the window on the screen and NOT the viewport! - // except for the size, which is the same the viewport is assumed to be centered and same size as the window. - Vec2i window_size; - Vec2i window_pos; - - /** \brief Computes View matrix for Camera (Based on gluLookAt) - * \param[out] view_mat the resultant matrix - */ - void computeViewMatrix(Affine3d& view_mat) const; - - /** \brief Computes Projection Matrix for Camera - * \param[out] proj the resultant matrix - */ - void computeProjectionMatrix(Matx44d& proj) const; - - /** \brief converts point to window coordiantes - * \param[in] pt xyz point to be converted - * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 - * - * This function computes the projection and view matrix every time. - * It is very inefficient to use this for every point in the point cloud! - */ - void cvtWindowCoordinates (const cv::Point3f& pt, Vec4d& window_cord) const - { - Affine3d view; - computeViewMatrix (view); - - Matx44d proj; - computeProjectionMatrix (proj); - cvtWindowCoordinates (pt, proj * view.matrix, window_cord); - return; - } - - /** \brief converts point to window coordiantes - * \param[in] pt xyz point to be converted - * \param[out] window_cord vector containing the pts' window X,Y, Z and 1 - * \param[in] composite_mat composite transformation matrix (proj*view) - * - * Use this function to compute window coordinates with a precomputed - * transformation function. The typical composite matrix will be - * the projection matrix * the view matrix. However, additional - * matrices like a camera disortion matrix can also be added. - */ - void cvtWindowCoordinates (const Point3f& pt, const Matx44d& composite_mat, Vec4d& window_cord) const - { - Vec4d pte (pt.x, pt.y, pt.z, 1); - window_cord = composite_mat * pte; - window_cord = window_cord/window_cord[3]; - - window_cord[0] = (window_cord[0]+1.0) / 2.0*window_size[0]; - window_cord[1] = (window_cord[1]+1.0) / 2.0*window_size[1]; - window_cord[2] = (window_cord[2]+1.0) / 2.0; - } - }; - } } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index ebaf9d324..a7ec893cf 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -146,7 +146,7 @@ cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file) //////////////////////////////////////////////////////////////////// /// Camera implementation -cv::viz::Camera2::Camera2(float f_x, float f_y, float c_x, float c_y, const Size &window_size) +cv::viz::Camera::Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); setClip(Vec2d(0.01, 1000.01));// Default clipping @@ -161,7 +161,7 @@ cv::viz::Camera2::Camera2(float f_x, float f_y, float c_x, float c_y, const Size focal_[1] = f_y; } -cv::viz::Camera2::Camera2(const Vec2f &fov, const Size &window_size) +cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); setClip(Vec2d(0.01, 1000.01)); // Default clipping @@ -171,7 +171,7 @@ cv::viz::Camera2::Camera2(const Vec2f &fov, const Size &window_size) setWindowSize(window_size); } -cv::viz::Camera2::Camera2(const cv::Mat & K, const Size &window_size) +cv::viz::Camera::Camera(const cv::Mat & K, const Size &window_size) { CV_Assert(K.rows == 3 && K.cols == 3); CV_Assert(window_size.width > 0 && window_size.height > 0); @@ -180,10 +180,10 @@ cv::viz::Camera2::Camera2(const cv::Mat & K, const Size &window_size) float f_y = K.at(1,1); float c_x = K.at(0,2); float c_y = K.at(1,2); - Camera2(f_x, f_y, c_x, c_y, window_size); + Camera(f_x, f_y, c_x, c_y, window_size); } -void cv::viz::Camera2::setWindowSize(const Size &window_size) +void cv::viz::Camera::setWindowSize(const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); @@ -199,7 +199,7 @@ void cv::viz::Camera2::setWindowSize(const Size &window_size) window_size_ = window_size; } -void cv::viz::Camera2::computeProjectionMatrix(Matx44f &proj) const +void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const { double top = clip_[0] * tan (0.5 * fov_[1]); double left = -(top * window_size_.width) / window_size_.height; diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 2c6702580..9a6574085 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -46,7 +46,8 @@ void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { imp void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } -void cv::viz::Viz3d::setCamera(const Camera2 &camera) { impl_->setCamera(camera); } +void cv::viz::Viz3d::setCamera(const Camera &camera) { impl_->setCamera(camera); } +cv::viz::Camera cv::viz::Viz3d::getCamera() const { return impl_->getCamera(); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index ee59b9413..6bddd0260 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -545,7 +545,7 @@ void cv::viz::Viz3d::VizImpl::initCameraParameters () Vec2i window_size(window_->GetScreenSize()); window_size /= 2; - Camera2 camera_temp(Vec2f(0.0,0.8575), Size(window_size[0], window_size[1])); + Camera camera_temp(Vec2f(0.0,0.8575), Size(window_size[0], window_size[1])); setCamera(camera_temp); setViewerPose(makeCameraPose(Vec3f(0.0f,0.0f,0.0f), Vec3f(0.0f, 0.0f, 1.0f), Vec3f(0.0f, 1.0f, 0.0f))); } @@ -564,22 +564,7 @@ void cv::viz::Viz3d::VizImpl::updateCamera () } ///////////////////////////////////////////////////////////////////////////////////////////// -// void cv::viz::Viz3d::VizImpl::getCameras (cv::viz::Camera& camera) -// { -// vtkCamera* active_camera = renderer_->GetActiveCamera (); -// -// camera.pos = cv::Vec3d(active_camera->GetPosition()); -// camera.focal = cv::Vec3d(active_camera->GetFocalPoint()); -// camera.clip = cv::Vec2d(active_camera->GetClippingRange()); -// camera.view_up = cv::Vec3d(active_camera->GetViewUp()); -// -// camera.fovy = active_camera->GetViewAngle()/ 180.0 * CV_PI; -// camera.window_size = cv::Vec2i(renderer_->GetRenderWindow()->GetSize()); -// camera.window_pos = cv::Vec2d::all(0); -// } - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) +void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) { vtkCamera& active_camera = *renderer_->GetActiveCamera(); @@ -591,7 +576,7 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera2 &camera) } ///////////////////////////////////////////////////////////////////////////////////////////// -cv::viz::Camera2 cv::viz::Viz3d::VizImpl::getCamera() const +cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const { vtkCamera& active_camera = *renderer_->GetActiveCamera(); @@ -600,7 +585,7 @@ cv::viz::Camera2 cv::viz::Viz3d::VizImpl::getCamera() const Size window_size(renderer_->GetRenderWindow()->GetSize()[0], renderer_->GetRenderWindow()->GetSize()[1]); - Camera2 camera(fov, window_size); + Camera camera(fov, window_size); camera.setClip(clip); return camera; } diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 86789c806..b0e87f018 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -110,8 +110,8 @@ public: // All camera methods to refactor into set/getViewwerPose, setCamera() // and 'Camera' class itself with various constructors/fields - void setCamera(const Camera2 &camera); - Camera2 getCamera() const; + void setCamera(const Camera &camera); + Camera getCamera() const; void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ From f8ad3c02049e9f316928c67ad7eb8556f070209c Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 16:06:02 +0200 Subject: [PATCH 134/205] fix field of view computation in setWindowSize --- modules/viz/src/types.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index a7ec893cf..9de385ce0 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -189,10 +189,10 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) // Vertical field of view is fixed! // Horizontal field of view is expandable based on the aspect ratio - float aspect_ratio_new = window_size.width / window_size.height; + float aspect_ratio_new = static_cast(window_size.width) / static_cast(window_size.height); if (principal_point_[0] < 0.0f) - fov_[0] = 2 * atan2(tan(fov_[1] * 0.5), aspect_ratio_new); // This assumes that the lens is symmetric! + fov_[0] = 2.f * atan(tan(fov_[1] * 0.5) * aspect_ratio_new); // This assumes that the lens is symmetric! else fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])) * 180 / CV_PI; From 9c20e77013312ce43fb959c1054b9f27cb866d3c Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 18:39:36 +0200 Subject: [PATCH 135/205] fix conversion functions to use appropriate vtk function --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 +-- modules/viz/src/viz3d.cpp | 4 +-- modules/viz/src/viz3d_impl.cpp | 34 +++++++++-------------- modules/viz/src/viz3d_impl.hpp | 4 +-- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 921eb3223..72e3076df 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -44,8 +44,8 @@ namespace cv Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); - void convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord); - void converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction); + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 9a6574085..6908bc8a4 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -51,5 +51,5 @@ cv::viz::Camera cv::viz::Viz3d::getCamera() const { return impl_->getCamera(); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } -void cv::viz::Viz3d::convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } -void cv::viz::Viz3d::converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction) { impl_->converTo3DRay(window_coord, origin, direction); } \ No newline at end of file +void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } +void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 6bddd0260..8dbf1fb10 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -642,32 +642,24 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose () } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord) +void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { - // Use the built in function of renderer - double point_wcs[3] = {pt.x, pt.y, pt.z}; - renderer_->WorldToView(point_wcs[0], point_wcs[1], point_wcs[2]); - window_coord.x = point_wcs[0]; - window_coord.y = point_wcs[1]; - window_coord.z = point_wcs[2]; + Vec3d window_pt; + vtkInteractorObserver::ComputeWorldToDisplay(renderer_, pt.x, pt.y, pt.z, window_pt.val); + window_coord = window_pt; } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction) -{ - // Use the built in function of renderer - double point_view[3] = {window_coord.x, window_coord.y, window_coord.z}; - renderer_->ViewToWorld(point_view[0], point_view[1], point_view[2]); - +void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) +{ + Vec4d world_pt; + vtkInteractorObserver::ComputeDisplayToWorld(renderer_, window_coord.x, window_coord.y, window_coord.z, world_pt.val); + vtkCamera &active_camera = *renderer_->GetActiveCamera(); - double *cam_pos = active_camera.GetPosition(); - origin.x = cam_pos[0]; - origin.y = cam_pos[1]; - origin.z = cam_pos[2]; - direction[0] = point_view[0] - cam_pos[0]; - direction[1] = point_view[1] - cam_pos[1]; - direction[2] = point_view[2] - cam_pos[2]; - normalize(direction); + Vec3d cam_pos; + active_camera.GetPosition(cam_pos.val); + origin = cam_pos; + direction = normalize(Vec3d(world_pt.val) - cam_pos); } ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index b0e87f018..d38204a25 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -126,8 +126,8 @@ public: void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); - void convertToWindowCoordinates(const Point3f &pt, Point3f &window_coord); - void converTo3DRay(const Point3f &window_coord, Point3f &origin, Vec3f &direction); + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); From 32985aa7248bf99c19dcae53da7057d823c6e2aa Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 19:22:43 +0200 Subject: [PATCH 136/205] fix camera constructor, add tentative KinectCamera method --- modules/viz/include/opencv2/viz/types.hpp | 6 ++- modules/viz/src/types.cpp | 52 +++++++++++++++-------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 2ebca5d32..d12a4df13 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -99,7 +99,7 @@ namespace cv public: Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); Camera(const Vec2f &fov, const Size &window_size); - Camera(const cv::Mat &K, const Size &window_size); + Camera(const cv::Matx33f &K, const Size &window_size); inline const Vec2d & getClip() const { return clip_; } inline void setClip(const Vec2d &clip) { clip_ = clip; } @@ -112,7 +112,11 @@ namespace cv void computeProjectionMatrix(Matx44f &proj) const; + static Camera KinectCamera(const Size &window_size); + private: + void init(float f_x, float f_y, float c_x, float c_y, const Size &window_size); + Vec2d clip_; Vec2f fov_; Size window_size_; diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 9de385ce0..08fa62882 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -148,17 +148,7 @@ cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file) cv::viz::Camera::Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size) { - CV_Assert(window_size.width > 0 && window_size.height > 0); - setClip(Vec2d(0.01, 1000.01));// Default clipping - - fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)) * 180 / CV_PI; - fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)) * 180 / CV_PI; - - principal_point_[0] = c_x; - principal_point_[1] = c_y; - - focal_[0] = f_x; - focal_[1] = f_y; + init(f_x, f_y, c_x, c_y, window_size); } cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size) @@ -171,16 +161,30 @@ cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size) setWindowSize(window_size); } -cv::viz::Camera::Camera(const cv::Mat & K, const Size &window_size) +cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size) +{ + float f_x = K(0,0); + float f_y = K(1,1); + float c_x = K(0,2); + float c_y = K(1,2); + init(f_x, f_y, c_x, c_y, window_size); +} + +void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size) { - CV_Assert(K.rows == 3 && K.cols == 3); CV_Assert(window_size.width > 0 && window_size.height > 0); + setClip(Vec2d(0.01, 1000.01));// Default clipping - float f_x = K.at(0,0); - float f_y = K.at(1,1); - float c_x = K.at(0,2); - float c_y = K.at(1,2); - Camera(f_x, f_y, c_x, c_y, window_size); + fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)) * 180 / CV_PI; + fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)) * 180 / CV_PI; + + principal_point_[0] = c_x; + principal_point_[1] = c_y; + + focal_[0] = f_x; + focal_[1] = f_y; + + setWindowSize(window_size); } void cv::viz::Camera::setWindowSize(const Size &window_size) @@ -220,4 +224,16 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const proj(2,2) = (-clip_[1] - clip_[0]) * temp4; proj(3,2) = -1.0; proj(2,3) = (-temp1 * clip_[1]) * temp4; +} + +cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) +{ + // Without distortion + Matx33f K = Matx33f::zeros(); + K(0,0) = 5.2921508098293293e+02; + K(0,2) = 3.2894272028759258e+02; + K(1,1) = 5.2556393630057437e+02; + K(1,2) = 2.6748068171871557e+02; + K(2,2) = 1.0f; + return Camera(K, window_size); } \ No newline at end of file From 731a931c0ce71a868bbe2c6ec1979cb6af12610e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 5 Aug 2013 19:35:20 +0200 Subject: [PATCH 137/205] field of views are in radians --- modules/viz/src/types.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 08fa62882..3395b0e66 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -175,8 +175,8 @@ void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Siz CV_Assert(window_size.width > 0 && window_size.height > 0); setClip(Vec2d(0.01, 1000.01));// Default clipping - fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)) * 180 / CV_PI; - fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)) * 180 / CV_PI; + fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)); + fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)); principal_point_[0] = c_x; principal_point_[1] = c_y; @@ -198,7 +198,7 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) if (principal_point_[0] < 0.0f) fov_[0] = 2.f * atan(tan(fov_[1] * 0.5) * aspect_ratio_new); // This assumes that the lens is symmetric! else - fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])) * 180 / CV_PI; + fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); // TODO I need to check this window_size_ = window_size; } @@ -228,7 +228,8 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) { - // Without distortion + // Without distortion, RGB Camera + // Received from http://nicolas.burrus.name/index.php/Research/KinectCalibration Matx33f K = Matx33f::zeros(); K(0,0) = 5.2921508098293293e+02; K(0,2) = 3.2894272028759258e+02; From 5335489daab048e0869ac81680941137c7d56618 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 7 Aug 2013 09:28:39 +0200 Subject: [PATCH 138/205] viz getWindowSize, setWindowSize --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 ++++ modules/viz/src/types.cpp | 2 +- modules/viz/src/viz3d.cpp | 5 ++++- modules/viz/src/viz3d_impl.cpp | 1 + modules/viz/src/viz3d_impl.hpp | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 72e3076df..33b274325 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace cv { @@ -46,6 +47,9 @@ namespace cv void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); + + Size getWindowSize() const; + void setWindowSize(const Size &window_size); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 3395b0e66..7ab918fdd 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -196,7 +196,7 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) float aspect_ratio_new = static_cast(window_size.width) / static_cast(window_size.height); if (principal_point_[0] < 0.0f) - fov_[0] = 2.f * atan(tan(fov_[1] * 0.5) * aspect_ratio_new); // This assumes that the lens is symmetric! + fov_[0] = 2.f * atan(tan(fov_[1] * 0.5f) * aspect_ratio_new); // This assumes that the lens is symmetric! else fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); // TODO I need to check this diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 6908bc8a4..ced6e73e1 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -52,4 +52,7 @@ void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose( cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } -void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } \ No newline at end of file +void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } + +cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } +void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 8dbf1fb10..fc2b3a55d 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -963,6 +963,7 @@ void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPosition (x, y); } void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } +cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); } bool cv::viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& /*mesh*/, const Mat& /*mask*/, const std::string &/*id*/) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index d38204a25..e190b720b 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -135,10 +135,10 @@ public: - //to implemnt in Viz3d void saveScreenshot (const String &file); void setWindowPosition (int x, int y); + Size getWindowSize() const; void setWindowSize (int xw, int yw); void setFullScreen (bool mode); void setWindowName (const String &name); From 422b967e9ae802cc0b4aefcabe78a9568a71754b Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 7 Aug 2013 15:52:24 +0200 Subject: [PATCH 139/205] fix computeProjectionMatrix in Camera class, also check if there is principal point defined --- modules/viz/src/types.cpp | 30 ++++++++++++++++++++++++------ modules/viz/src/viz3d_impl.cpp | 2 +- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 7ab918fdd..631582a64 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -195,35 +195,53 @@ void cv::viz::Camera::setWindowSize(const Size &window_size) // Horizontal field of view is expandable based on the aspect ratio float aspect_ratio_new = static_cast(window_size.width) / static_cast(window_size.height); + // Get the scale factor and update the principal points + if (window_size_.height != 0) + { + float aspect_ratio_old = window_size_.width / window_size_.height; + float expected_width = aspect_ratio_old * window_size.height; + float scale = window_size_.width / expected_width; + principal_point_[0] *= scale; + principal_point_[1] *= static_cast(window_size.height) / static_cast(window_size_.height); + } + if (principal_point_[0] < 0.0f) fov_[0] = 2.f * atan(tan(fov_[1] * 0.5f) * aspect_ratio_new); // This assumes that the lens is symmetric! else - fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); // TODO I need to check this + fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); window_size_ = window_size; } void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const { + // Symmetric case double top = clip_[0] * tan (0.5 * fov_[1]); double left = -(top * window_size_.width) / window_size_.height; double right = -left; double bottom = -top; - + // If principal point is defined + if (principal_point_[0] > 0.0f) + { + top = clip_[0] * principal_point_[1] / focal_[1]; + left = -clip_[0] * principal_point_[0] / focal_[0]; + right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0]; + bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1]; + } + double temp1 = 2.0 * clip_[0]; double temp2 = 1.0 / (right - left); double temp3 = 1.0 / (top - bottom); - double temp4 = 1.0 / clip_[1] - clip_[0]; + double temp4 = 1.0 / (clip_[0] - clip_[1]); proj = Matx44d::zeros(); - proj(0,0) = temp1 * temp2; proj(1,1) = temp1 * temp3; proj(0,2) = (right + left) * temp2; proj(1,2) = (top + bottom) * temp3; - proj(2,2) = (-clip_[1] - clip_[0]) * temp4; + proj(2,2) = (clip_[1]+clip_[0]) * temp4; proj(3,2) = -1.0; - proj(2,3) = (-temp1 * clip_[1]) * temp4; + proj(2,3) = (temp1 * clip_[1]) * temp4; } cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index fc2b3a55d..a24700ce9 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -572,7 +572,7 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) active_camera.SetUseHorizontalViewAngle (0); // Horizontal view angle is set based on the window size active_camera.SetViewAngle (camera.getFov()[1] * 180.0f / CV_PI); active_camera.SetClippingRange (camera.getClip()[0], camera.getClip()[1]); - window_->SetSize (static_cast (camera.getWindowSize().width), static_cast (camera.getWindowSize().height)); + window_->SetSize (camera.getWindowSize().width, camera.getWindowSize().height); } ///////////////////////////////////////////////////////////////////////////////////////////// From 71dc5f8291af1272349e188d8e83f96ae79560fd Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 7 Aug 2013 16:20:23 +0200 Subject: [PATCH 140/205] simulate real cameras by working around vtkUserTransform to set projection matrix --- modules/viz/src/viz3d_impl.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index a24700ce9..cc732f6d7 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -573,6 +573,16 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) active_camera.SetViewAngle (camera.getFov()[1] * 180.0f / CV_PI); active_camera.SetClippingRange (camera.getClip()[0], camera.getClip()[1]); window_->SetSize (camera.getWindowSize().width, camera.getWindowSize().height); + + // Use the intrinsic parameters of the camera to simulate more realistically + Matx44f proj_matrix; + camera.computeProjectionMatrix(proj_matrix); + Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(((float)camera.getWindowSize().width) / camera.getWindowSize().height, -1.0f, 1.0f)); + vtkTransform * transform = vtkTransform::New(); + // This is a hack around not being able to set Projection Matrix + transform->SetMatrix(convertToVtkMatrix(proj_matrix * old_proj_matrix.inv())); + active_camera.SetUserTransform(transform); + transform->Delete(); } ///////////////////////////////////////////////////////////////////////////////////////////// From bb057491eae3ca3b1e39b2d4892f95c0fb06b27e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 8 Aug 2013 12:14:27 +0200 Subject: [PATCH 141/205] create camera from projection matrix (used for getCamera in viz) --- modules/viz/include/opencv2/viz/types.hpp | 1 + modules/viz/src/types.cpp | 41 +++++++++++++++++++++-- modules/viz/src/viz3d_impl.cpp | 8 ++--- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index d12a4df13..54b47140e 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -100,6 +100,7 @@ namespace cv Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); Camera(const Vec2f &fov, const Size &window_size); Camera(const cv::Matx33f &K, const Size &window_size); + Camera(const cv::Matx44f &proj, const Size &window_size); inline const Vec2d & getClip() const { return clip_; } inline void setClip(const Vec2d &clip) { clip_ = clip; } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 631582a64..ad9eb2731 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -170,6 +170,43 @@ cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size) init(f_x, f_y, c_x, c_y, window_size); } +cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size) +{ + double near = proj(2,3) / (proj(2,2) - 1.0); + double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0); + double left = near * (proj(0,2)-1) / proj(0,0); + double right = 2.0 * near / proj(0,0) + left; + double bottom = near * (proj(1,2)-1) / proj(1,1); + double top = 2.0 * near / proj(1,1) + bottom; + + if (fabs(left-right) < std::numeric_limits::epsilon()) + { + principal_point_[0] = -1.0f; + focal_[0] = -1.0f; + } + else + { + principal_point_[0] = (left * static_cast(window_size.width)) / (left - right); + focal_[0] = - near * principal_point_[0] / left; + } + + if (fabs(top-bottom) < std::numeric_limits::epsilon()) + { + principal_point_[1] = -1.0f; + focal_[1] = -1.0f; + } + else + { + principal_point_[1] = (top * static_cast(window_size.height)) / (top - bottom); + focal_[1] = near * principal_point_[1] / top; + } + + setClip(Vec2d(near, far)); + // Set the vertical field of view + fov_[1] = (atan2(principal_point_[1],focal_[1]) + atan2(window_size.height-principal_point_[1],focal_[1])); + setWindowSize(window_size); +} + void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); @@ -220,7 +257,7 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const double left = -(top * window_size_.width) / window_size_.height; double right = -left; double bottom = -top; - // If principal point is defined + // If principal point is defined (i.e intrinsic parameters are known) if (principal_point_[0] > 0.0f) { top = clip_[0] * principal_point_[1] / focal_[1]; @@ -233,7 +270,7 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const double temp2 = 1.0 / (right - left); double temp3 = 1.0 / (top - bottom); double temp4 = 1.0 / (clip_[0] - clip_[1]); - + proj = Matx44d::zeros(); proj(0,0) = temp1 * temp2; proj(1,1) = temp1 * temp3; diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index cc732f6d7..a236b683c 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -577,7 +577,7 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) // Use the intrinsic parameters of the camera to simulate more realistically Matx44f proj_matrix; camera.computeProjectionMatrix(proj_matrix); - Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(((float)camera.getWindowSize().width) / camera.getWindowSize().height, -1.0f, 1.0f)); + Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(static_cast(camera.getWindowSize().width) / static_cast(camera.getWindowSize().height), -1.0f, 1.0f)); vtkTransform * transform = vtkTransform::New(); // This is a hack around not being able to set Projection Matrix transform->SetMatrix(convertToVtkMatrix(proj_matrix * old_proj_matrix.inv())); @@ -594,9 +594,9 @@ cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const Vec2d clip(active_camera.GetClippingRange()); Size window_size(renderer_->GetRenderWindow()->GetSize()[0], renderer_->GetRenderWindow()->GetSize()[1]); - - Camera camera(fov, window_size); - camera.setClip(clip); + Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(((float)window_size.width) / window_size.height, -1.0f, 1.0f)); + Camera camera(old_proj_matrix, window_size); +// camera.setClip(clip); return camera; } From 4a1573de9b779d343cdba3668720a2470d990de9 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 9 Aug 2013 10:39:30 +0200 Subject: [PATCH 142/205] principal point is always set even though the intrinsic parameters are not given (center of window), fixed computation mistakes in setWindowSize in camera class --- modules/viz/src/types.cpp | 84 ++++++++++++---------------------- modules/viz/src/viz3d_impl.cpp | 23 ++++------ 2 files changed, 38 insertions(+), 69 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index ad9eb2731..104fc5a1e 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -155,10 +155,11 @@ cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); setClip(Vec2d(0.01, 1000.01)); // Default clipping - principal_point_ = Vec2f(-1.0f, -1.0f); // Default symmetric lens - focal_ = Vec2f(-1.0f, -1.0f); setFov(fov); - setWindowSize(window_size); + window_size_ = window_size; + // Principal point at the center + principal_point_ = Vec2f(static_cast(window_size.width)*0.5f, static_cast(window_size.height)*0.5f); + focal_ = Vec2f(principal_point_[0] / tan(fov_[0]*0.5f), principal_point_[1] / tan(fov_[1]*0.5f)); } cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size) @@ -172,6 +173,8 @@ cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size) cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size) { + CV_Assert(window_size.width > 0 && window_size.height > 0); + double near = proj(2,3) / (proj(2,2) - 1.0); double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0); double left = near * (proj(0,2)-1) / proj(0,0); @@ -179,32 +182,19 @@ cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size) double bottom = near * (proj(1,2)-1) / proj(1,1); double top = 2.0 * near / proj(1,1) + bottom; - if (fabs(left-right) < std::numeric_limits::epsilon()) - { - principal_point_[0] = -1.0f; - focal_[0] = -1.0f; - } - else - { - principal_point_[0] = (left * static_cast(window_size.width)) / (left - right); - focal_[0] = - near * principal_point_[0] / left; - } + if (fabs(left-right) < std::numeric_limits::epsilon()) principal_point_[0] = static_cast(window_size.width) * 0.5f; + else principal_point_[0] = (left * static_cast(window_size.width)) / (left - right); + focal_[0] = -near * principal_point_[0] / left; - if (fabs(top-bottom) < std::numeric_limits::epsilon()) - { - principal_point_[1] = -1.0f; - focal_[1] = -1.0f; - } - else - { - principal_point_[1] = (top * static_cast(window_size.height)) / (top - bottom); - focal_[1] = near * principal_point_[1] / top; - } + if (fabs(top-bottom) < std::numeric_limits::epsilon()) principal_point_[1] = static_cast(window_size.height) * 0.5f; + else principal_point_[1] = (top * static_cast(window_size.height)) / (top - bottom); + focal_[1] = near * principal_point_[1] / top; setClip(Vec2d(near, far)); - // Set the vertical field of view + fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); fov_[1] = (atan2(principal_point_[1],focal_[1]) + atan2(window_size.height-principal_point_[1],focal_[1])); - setWindowSize(window_size); + + window_size_ = window_size; } void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size) @@ -221,50 +211,32 @@ void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Siz focal_[0] = f_x; focal_[1] = f_y; - setWindowSize(window_size); + window_size_ = window_size; } void cv::viz::Camera::setWindowSize(const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); - // Vertical field of view is fixed! - // Horizontal field of view is expandable based on the aspect ratio - float aspect_ratio_new = static_cast(window_size.width) / static_cast(window_size.height); - // Get the scale factor and update the principal points - if (window_size_.height != 0) - { - float aspect_ratio_old = window_size_.width / window_size_.height; - float expected_width = aspect_ratio_old * window_size.height; - float scale = window_size_.width / expected_width; - principal_point_[0] *= scale; - principal_point_[1] *= static_cast(window_size.height) / static_cast(window_size_.height); - } - - if (principal_point_[0] < 0.0f) - fov_[0] = 2.f * atan(tan(fov_[1] * 0.5f) * aspect_ratio_new); // This assumes that the lens is symmetric! - else - fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); + float scalex = static_cast(window_size.width) / static_cast(window_size_.width); + float scaley = static_cast(window_size.height) / static_cast(window_size_.height); + + principal_point_[0] *= scalex; + principal_point_[1] *= scaley; + focal_ *= scaley; + // Vertical field of view is fixed! Update horizontal field of view + fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); window_size_ = window_size; } void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const { - // Symmetric case - double top = clip_[0] * tan (0.5 * fov_[1]); - double left = -(top * window_size_.width) / window_size_.height; - double right = -left; - double bottom = -top; - // If principal point is defined (i.e intrinsic parameters are known) - if (principal_point_[0] > 0.0f) - { - top = clip_[0] * principal_point_[1] / focal_[1]; - left = -clip_[0] * principal_point_[0] / focal_[0]; - right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0]; - bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1]; - } + double top = clip_[0] * principal_point_[1] / focal_[1]; + double left = -clip_[0] * principal_point_[0] / focal_[0]; + double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0]; + double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1]; double temp1 = 2.0 * clip_[0]; double temp2 = 1.0 / (right - left); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index a236b683c..a2aa31bed 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -569,18 +569,16 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) vtkCamera& active_camera = *renderer_->GetActiveCamera(); // Set the intrinsic parameters of the camera - active_camera.SetUseHorizontalViewAngle (0); // Horizontal view angle is set based on the window size - active_camera.SetViewAngle (camera.getFov()[1] * 180.0f / CV_PI); - active_camera.SetClippingRange (camera.getClip()[0], camera.getClip()[1]); window_->SetSize (camera.getWindowSize().width, camera.getWindowSize().height); + double aspect_ratio = static_cast(camera.getWindowSize().width)/static_cast(camera.getWindowSize().height); + Matx44f proj_mat; + camera.computeProjectionMatrix(proj_mat); // Use the intrinsic parameters of the camera to simulate more realistically - Matx44f proj_matrix; - camera.computeProjectionMatrix(proj_matrix); - Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(static_cast(camera.getWindowSize().width) / static_cast(camera.getWindowSize().height), -1.0f, 1.0f)); - vtkTransform * transform = vtkTransform::New(); + Matx44f old_proj_mat = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0, 1.0)); + vtkTransform *transform = vtkTransform::New(); // This is a hack around not being able to set Projection Matrix - transform->SetMatrix(convertToVtkMatrix(proj_matrix * old_proj_matrix.inv())); + transform->SetMatrix(convertToVtkMatrix(proj_mat * old_proj_mat.inv())); active_camera.SetUserTransform(transform); transform->Delete(); } @@ -590,13 +588,12 @@ cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const { vtkCamera& active_camera = *renderer_->GetActiveCamera(); - Vec2f fov(0.0, active_camera.GetViewAngle() * CV_PI / 180.0f); - Vec2d clip(active_camera.GetClippingRange()); Size window_size(renderer_->GetRenderWindow()->GetSize()[0], renderer_->GetRenderWindow()->GetSize()[1]); - Matx44f old_proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(((float)window_size.width) / window_size.height, -1.0f, 1.0f)); - Camera camera(old_proj_matrix, window_size); -// camera.setClip(clip); + double aspect_ratio = static_cast(window_size.width) / static_cast(window_size.height); + + Matx44f proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f)); + Camera camera(proj_matrix, window_size); return camera; } From b69a97bef356ee2f0e431753a5163e7dc5ba8029 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 12 Aug 2013 09:07:50 +0200 Subject: [PATCH 143/205] access focal length and principal point in camera --- modules/viz/include/opencv2/viz/types.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 54b47140e..f41b5fa0f 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -111,6 +111,9 @@ namespace cv inline const Vec2f & getFov() const { return fov_; } inline void setFov(const Vec2f & fov) { fov_ = fov; } + inline const Vec2f & getPrincipalPoint() const { return principal_point_; } + inline const Vec2f & getFocalLength() const { return focal_; } + void computeProjectionMatrix(Matx44f &proj) const; static Camera KinectCamera(const Size &window_size); From 669abd58bceb22ddc55bd011507bfc448e0f60e6 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Mon, 19 Aug 2013 20:09:47 +0200 Subject: [PATCH 144/205] initial shared pointer implementation for Viz3d, singleton VizAccessor, cv::viz::get function initial implementation --- modules/viz/include/opencv2/viz.hpp | 24 +++++++++- modules/viz/include/opencv2/viz/viz3d.hpp | 9 +++- modules/viz/src/viz.cpp | 55 +++++++++++++++++++++++ modules/viz/src/viz3d.cpp | 43 ++++++++++++++++-- modules/viz/src/viz3d_impl.cpp | 7 ++- modules/viz/src/viz3d_impl.hpp | 3 ++ 6 files changed, 134 insertions(+), 7 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index c7976a999..f3745767a 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -58,13 +58,17 @@ namespace cv { namespace viz - { + { + typedef std::map VizMap; + typedef std::pair VizPair; + //! takes coordiante frame data and builds transfrom to global coordinate frame CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); //! 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); + CV_EXPORTS Viz3d get(const String &window_name); //! checks float value for Nan inline bool isNan(float x) @@ -87,6 +91,24 @@ namespace cv //! checks point for Nans template inline bool isNan(const Point3_<_Tp>& p) { return isNan(p.x) || isNan(p.y) || isNan(p.z); } + + class CV_EXPORTS VizAccessor + { + public: + ~VizAccessor(); + static VizAccessor * getInstance(); + + Viz3d get(const String &window_name); + void add(Viz3d window); + void remove(const String &window_name); + + private: + VizAccessor(); // Singleton + + static VizAccessor * instance_; + static bool is_instantiated_; + static VizMap viz_map_; + }; } } diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 33b274325..f4adcd835 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -21,6 +21,8 @@ namespace cv typedef void (*MouseCallback)(const MouseEvent&, void*); Viz3d(const String& window_name = String()); + Viz3d(const Viz3d&); + Viz3d& operator=(const Viz3d&); ~Viz3d(); void setBackgroundColor(const Color& color = Color::black()); @@ -50,6 +52,8 @@ namespace cv Size getWindowSize() const; void setWindowSize(const Size &window_size); + + String getWindowName() const; void spin(); void spinOnce(int time = 1, bool force_redraw = false); @@ -58,11 +62,12 @@ namespace cv void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); void registerMouseCallback(MouseCallback callback, void* cookie = 0); private: - Viz3d(const Viz3d&); - Viz3d& operator=(const Viz3d&); struct VizImpl; VizImpl* impl_; + + void create(const String &window_name); + void release(); }; } /* namespace viz */ diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 2d563f6c1..a1e56134f 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -85,3 +85,58 @@ namespace cv } } } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Viz accessor implementation + +cv::viz::VizAccessor * cv::viz::VizAccessor::instance_ = 0; +bool cv::viz::VizAccessor::is_instantiated_ = false; +cv::viz::VizMap cv::viz::VizAccessor::viz_map_; + +cv::viz::VizAccessor::VizAccessor() {} + +cv::viz::VizAccessor::~VizAccessor() +{ + is_instantiated_ = false; +} + +cv::viz::VizAccessor * cv::viz::VizAccessor::getInstance() +{ + if (is_instantiated_) + { + std::cout << "HERE" << std::endl; + instance_ = new VizAccessor(); + is_instantiated_ = true; + } + return instance_; +} + +cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name) +{ + VizMap::iterator vm_itr = viz_map_.find(window_name); + bool exists = vm_itr != viz_map_.end(); + if (exists) return vm_itr->second; + else return viz_map_.insert(VizPair(window_name, Viz3d(window_name))).first->second; +} + +void cv::viz::VizAccessor::add(Viz3d window) +{ + String window_name = window.getWindowName(); + VizMap::iterator vm_itr = viz_map_.find(window_name); + bool exists = vm_itr != viz_map_.end(); + if (exists) return ; + viz_map_.insert(std::pair(window_name, window)); +} + +void cv::viz::VizAccessor::remove(const String &window_name) +{ + VizMap::iterator vm_itr = viz_map_.find(window_name); + bool exists = vm_itr != viz_map_.end(); + if (!exists) return ; + viz_map_.erase(vm_itr); +} + +cv::viz::Viz3d cv::viz::get(const String &window_name) +{ + return cv::viz::VizAccessor::getInstance()->get(window_name); +} \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index ced6e73e1..61502a7d3 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -2,8 +2,44 @@ #include "viz3d_impl.hpp" -cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_name)) {} -cv::viz::Viz3d::~Viz3d() { delete impl_; } +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); +} + +cv::viz::Viz3d& cv::viz::Viz3d::operator=(const Viz3d& other) +{ + if (this != &other) + { + release(); + impl_ = other.impl_; + if (impl_) CV_XADD(&impl_->ref_counter, 1); + } + return *this; +} + +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); +} + +void cv::viz::Viz3d::release() +{ + if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) + { + cv::viz::VizAccessor::getInstance()->remove(getWindowName()); + delete impl_; + impl_ = 0; + } +} void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } @@ -55,4 +91,5 @@ void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &wind void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } -void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } \ No newline at end of file +void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } +cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index a2aa31bed..be389b241 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -86,7 +86,7 @@ cv::viz::Viz3d::VizImpl::~VizImpl () if (interactor_ != NULL) interactor_->DestroyTimer (timer_id_); - renderer_->Clear(); + if (renderer_) renderer_->Clear(); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -968,6 +968,11 @@ void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) window_->SetWindowName (name.c_str ()); } +cv::String cv::viz::Viz3d::VizImpl::getWindowName() const +{ + return (window_ ? window_->GetWindowName() : ""); +} + void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPosition (x, y); } void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); } diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index e190b720b..5f8ad367b 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -11,6 +11,8 @@ public: typedef cv::Ptr Ptr; typedef Viz3d::KeyboardCallback KeyboardCallback; typedef Viz3d::MouseCallback MouseCallback; + + int ref_counter; VizImpl (const String &name); virtual ~VizImpl (); @@ -142,6 +144,7 @@ public: void setWindowSize (int xw, int yw); void setFullScreen (bool mode); void setWindowName (const String &name); + String getWindowName() const; void setBackgroundColor (const Color& color); void spin (); From c37f091cc541576a6f2426d4bcc55c91b6b9d627 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 20 Aug 2013 18:18:01 +0200 Subject: [PATCH 145/205] remove redundant statement --- modules/viz/src/viz.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index a1e56134f..dbd312000 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -104,7 +104,6 @@ cv::viz::VizAccessor * cv::viz::VizAccessor::getInstance() { if (is_instantiated_) { - std::cout << "HERE" << std::endl; instance_ = new VizAccessor(); is_instantiated_ = true; } From 6bc393676df8083595a3ebb773f3cf7b3b89205d Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 20 Aug 2013 20:22:14 +0200 Subject: [PATCH 146/205] cv::viz::get(window_name) implementation --- modules/viz/src/viz.cpp | 6 +++++- modules/viz/src/viz3d.cpp | 3 ++- modules/viz/src/viz3d_impl.cpp | 6 ++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index dbd312000..f3059a606 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -112,7 +112,11 @@ cv::viz::VizAccessor * cv::viz::VizAccessor::getInstance() cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name) { - VizMap::iterator vm_itr = viz_map_.find(window_name); + // Add the prefix Viz + String name("Viz"); + name = window_name.empty() ? name : name + " - " + window_name; + + VizMap::iterator vm_itr = viz_map_.find(name); bool exists = vm_itr != viz_map_.end(); if (exists) return vm_itr->second; else return viz_map_.insert(VizPair(window_name, Viz3d(window_name))).first->second; diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 61502a7d3..c31d5880a 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -28,13 +28,14 @@ void cv::viz::Viz3d::create(const String &window_name) impl_ = new VizImpl(window_name); impl_->ref_counter = 1; // Register the window -// cv::viz::VizAccessor::getInstance()->add(*this); + cv::viz::VizAccessor::getInstance()->add(*this); } void cv::viz::Viz3d::release() { if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) { + // Erase the window cv::viz::VizAccessor::getInstance()->remove(getWindowName()); delete impl_; impl_ = 0; diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index be389b241..c1807a015 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -83,10 +83,8 @@ cv::viz::Viz3d::VizImpl::VizImpl (const std::string &name) ///////////////////////////////////////////////////////////////////////////////////////////// cv::viz::Viz3d::VizImpl::~VizImpl () { - if (interactor_ != NULL) - interactor_->DestroyTimer (timer_id_); - - if (renderer_) renderer_->Clear(); + if (interactor_) + interactor_->DestroyTimer(timer_id_); } ///////////////////////////////////////////////////////////////////////////////////////////// From d83be1dcccf2b9eb7d8f4cb5562a70460207d0db Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Fri, 23 Aug 2013 18:49:21 +0200 Subject: [PATCH 147/205] fixes based on the feedback: window name prefix is automatically added when it is not there, singleton class returns reference instead of pointer, destructor is private, release function implemented --- modules/viz/include/opencv2/viz.hpp | 7 +++-- modules/viz/src/viz.cpp | 47 +++++++++++++++++++++-------- modules/viz/src/viz3d.cpp | 4 +-- modules/viz/src/viz3d_impl.cpp | 6 ++-- modules/viz/src/viz3d_impl.hpp | 6 +++- 5 files changed, 50 insertions(+), 20 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index f3745767a..0a82a9ebb 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -95,15 +95,18 @@ namespace cv class CV_EXPORTS VizAccessor { public: - ~VizAccessor(); - static VizAccessor * getInstance(); + static VizAccessor & getInstance(); + static void release(); Viz3d get(const String &window_name); void add(Viz3d window); void remove(const String &window_name); + static void generateWindowName(const String &window_name, String &output); + private: VizAccessor(); // Singleton + ~VizAccessor(); static VizAccessor * instance_; static bool is_instantiated_; diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index f3059a606..c8e09ba9e 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -95,27 +95,34 @@ cv::viz::VizMap cv::viz::VizAccessor::viz_map_; cv::viz::VizAccessor::VizAccessor() {} -cv::viz::VizAccessor::~VizAccessor() -{ - is_instantiated_ = false; -} +cv::viz::VizAccessor::~VizAccessor() {} -cv::viz::VizAccessor * cv::viz::VizAccessor::getInstance() +cv::viz::VizAccessor & cv::viz::VizAccessor::getInstance() { - if (is_instantiated_) + if (!is_instantiated_) { instance_ = new VizAccessor(); is_instantiated_ = true; } - return instance_; + return *instance_; +} + +void cv::viz::VizAccessor::release() +{ + if (is_instantiated_) + { + delete instance_; + instance_ = 0; + is_instantiated_ = false; + } } cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name) { // Add the prefix Viz - String name("Viz"); - name = window_name.empty() ? name : name + " - " + window_name; - + String name; + generateWindowName(window_name, name); + VizMap::iterator vm_itr = viz_map_.find(name); bool exists = vm_itr != viz_map_.end(); if (exists) return vm_itr->second; @@ -133,13 +140,29 @@ void cv::viz::VizAccessor::add(Viz3d window) void cv::viz::VizAccessor::remove(const String &window_name) { - VizMap::iterator vm_itr = viz_map_.find(window_name); + // Add the prefix Viz + String name; + generateWindowName(window_name, name); + + VizMap::iterator vm_itr = viz_map_.find(name); bool exists = vm_itr != viz_map_.end(); if (!exists) return ; viz_map_.erase(vm_itr); } +void cv::viz::VizAccessor::generateWindowName(const String &window_name, String &output) +{ + output = "Viz"; + // Already is Viz + if (window_name == output) return; + + String prefixed = output + " - "; + if (window_name.substr(0, prefixed.length()) == prefixed) output = window_name; // Already has "Viz - " + else if (window_name.substr(0, output.length()) == output) 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 cv::viz::VizAccessor::getInstance().get(window_name); } \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index c31d5880a..583ece096 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -28,7 +28,7 @@ void cv::viz::Viz3d::create(const String &window_name) impl_ = new VizImpl(window_name); impl_->ref_counter = 1; // Register the window - cv::viz::VizAccessor::getInstance()->add(*this); + cv::viz::VizAccessor::getInstance().add(*this); } void cv::viz::Viz3d::release() @@ -36,7 +36,7 @@ void cv::viz::Viz3d::release() if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) { // Erase the window - cv::viz::VizAccessor::getInstance()->remove(getWindowName()); + cv::viz::VizAccessor::getInstance().remove(getWindowName()); delete impl_; impl_ = 0; } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index c1807a015..95f93b115 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -74,9 +74,8 @@ cv::viz::Viz3d::VizImpl::VizImpl (const std::string &name) ////////////////////////////// - - String window_name("Viz"); - window_name = name.empty() ? window_name : window_name + " - " + name; + String window_name; + VizAccessor::generateWindowName(name, window_name); window_->SetWindowName (window_name.c_str ()); } @@ -85,6 +84,7 @@ cv::viz::Viz3d::VizImpl::~VizImpl () { if (interactor_) interactor_->DestroyTimer(timer_id_); + if (renderer_) renderer_->Clear(); } ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 5f8ad367b..ef23cc1b9 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -69,7 +69,11 @@ public: void close () { stopped_ = true; - interactor_->TerminateApp (); // This tends to close the window... + if (interactor_) + { + interactor_->GetRenderWindow()->Finalize(); + interactor_->TerminateApp (); // This tends to close the window... + } } From 35e7952909ca6a61f36109c28f651ee71a0b1bb1 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Tue, 3 Sep 2013 01:25:04 +0400 Subject: [PATCH 148/205] simplify modules/viz/CMakeLists.txt --- modules/viz/CMakeLists.txt | 59 +++++++++----------------------------- 1 file changed, 13 insertions(+), 46 deletions(-) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 9310b2443..05388d745 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -1,24 +1,12 @@ -set(BUILD_opencv_viz_INIT OFF) - - -############################################################################### -# Find qvtk -# This sets the following variables: -# QVTK_FOUND - True if QVTK was found. -# QVTK_INCLUDE_DIR - Directory containing the QVTK include files. -# QVTK_LIBRARY - QVTK library. -# if QVTK_FOUND then QVTK_INCLUDE_DIR is appended to VTK_INCLUDE_DIRS and QVTK_LIBRARY is appended to QVTK_LIBRARY_DIR 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(NOT QVTK_FOUND) - set (VTK_USE_QVTK OFF) - else(NOT QVTK_FOUND) + if(QVTK_FOUND) get_filename_component (QVTK_LIBRARY_DIR ${QVTK_LIBRARY} PATH) - set (VTK_LIBRARY_DIRS ${VTK_LIBRARY_DIRS} ${QVTK_LIBRARY_DIR}) - set (VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${QVTK_INCLUDE_DIR}) + list(APPEND VTK_LIBRARY_DIRS ${QVTK_LIBRARY_DIR}) + list(APPEND VTK_INCLUDE_DIRS ${QVTK_INCLUDE_DIR}) set (VTK_USE_QVTK ON) endif() endmacro() @@ -34,52 +22,31 @@ macro(find_vtk) set(HAVE_VTK ON) else () set(HAVE_VTK OFF) - message ("Warning: VTK disabled. You are to build OpenCV in STATIC but VTK is SHARED!") + message (WARNING "VTK disabled. You are to build OpenCV in STATIC but VTK is SHARED!") endif () endif() endmacro() - - - -#find_package(OpenGL) -#if (OPENGL_FOUND) -# if(OPENGL_INCLUDE_DIR) -# include_directories("${OPENGL_INCLUDE_DIR}") -# endif() -# if(OPENGL_DEFINITIONS) -# add_definitions("${OPENGL_DEFINITIONS}") -# endif() -#endif() - - find_vtk() - -if(NOT HAVE_VTK) - set(DEFAULT FALSE) - set(REASON "VTK was not found.") -else() - set(DEFAULT TRUE) - set(REASON) +if(HAVE_VTK) set(VTK_USE_FILE ${VTK_USE_FILE} CACHE INTERNAL "VTK_USE_FILE") include (${VTK_USE_FILE}) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + add_definitions(-DHAVE_VTK) +else() + return() endif() -add_definitions(-DHAVE_VTK) - - set(the_description "Viz") set(BUILD_opencv_viz_INIT OFF) include_directories(src) ocv_define_module(viz opencv_core) -target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkFiltering vtkRendering) -#${OPENGL_LIBRARIES}) - -if(APPLE) - target_link_libraries(opencv_viz "-framework Cocoa") +if(BUILD_opencv_viz) + target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkFiltering vtkRendering) + if(APPLE) + target_link_libraries(opencv_viz "-framework Cocoa") + endif() endif() From e106dcc606fe6b185e8799467ea0b2088be5912a Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 22 Aug 2013 18:28:37 +0200 Subject: [PATCH 149/205] remove include vtk headers from outside of precomp.hpp --- modules/viz/src/viz3d_impl.cpp | 1 - modules/viz/src/widget.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 95f93b115..4b7d1271f 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1,7 +1,6 @@ #include "precomp.hpp" #include "viz3d_impl.hpp" -#include #ifndef __APPLE__ vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew () { diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index b295843f9..65c5b1aca 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -1,4 +1,3 @@ - #include "precomp.hpp" /////////////////////////////////////////////////////////////////////////////////////////////// From 0bbaf5d47a104b338aa18442049d4360415b1274 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 22 Aug 2013 19:04:42 +0200 Subject: [PATCH 150/205] removeAllWidgets implementation, removed other remove methods --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 + modules/viz/src/viz3d.cpp | 1 + modules/viz/src/viz3d_impl.cpp | 99 +---------------------- modules/viz/src/viz3d_impl.hpp | 18 +---- 4 files changed, 7 insertions(+), 112 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index f4adcd835..96f999bed 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -37,6 +37,7 @@ namespace cv void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); void removeWidget(const String &id); Widget getWidget(const String &id) const; + void removeAllWidgets(); void setWidgetPose(const String &id, const Affine3f &pose); void updateWidgetPose(const String &id, const Affine3f &pose); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 583ece096..bb88e1337 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -79,6 +79,7 @@ void cv::viz::Viz3d::registerMouseCallback(MouseCallback callback, void* cookie) void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { impl_->showWidget(id, widget, pose); } void cv::viz::Viz3d::removeWidget(const String &id) { impl_->removeWidget(id); } cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_->getWidget(id); } +void cv::viz::Viz3d::removeAllWidgets() { impl_->removeAllWidgets(); } void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3f &pose) { impl_->setWidgetPose(id, pose); } void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3f &pose) { impl_->updateWidgetPose(id, pose); } cv::Affine3f cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 4b7d1271f..12a3de15f 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -128,104 +128,13 @@ void cv::viz::Viz3d::VizImpl::spinOnce (int time, bool force_redraw) } } -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::removePointCloud (const std::string &id) +////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::removeAllWidgets() { - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - if (am_it == cloud_actor_map_->end ()) - return false; - - if (removeActorFromRenderer (am_it->second.actor)) - return cloud_actor_map_->erase (am_it), true; - - return false; + widget_actor_map_->clear(); + renderer_->RemoveAllViewProps(); } -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::removeShape (const std::string &id) -{ - // Check to see if the given ID entry exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - // Extra step: check if there is a cloud with the same ID - CloudActorMap::iterator ca_it = cloud_actor_map_->find (id); - - bool shape = true; - // Try to find a shape first - if (am_it == shape_actor_map_->end ()) - { - // There is no cloud or shape with this ID, so just exit - if (ca_it == cloud_actor_map_->end ()) - return false; - // Cloud found, set shape to false - shape = false; - } - - // Remove the pointer/ID pair to the global actor map - if (shape) - { - if (removeActorFromRenderer (am_it->second)) - { - shape_actor_map_->erase (am_it); - return (true); - } - } - else - { - if (removeActorFromRenderer (ca_it->second.actor)) - { - cloud_actor_map_->erase (ca_it); - return true; - } - } - return false; -} - -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::removeText3D (const std::string &id) -{ - // Check to see if the given ID entry exists - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it == shape_actor_map_->end ()) - return false; - - // Remove it from all renderers - if (removeActorFromRenderer (am_it->second)) - return shape_actor_map_->erase (am_it), true; - - return false; -} - -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::removeAllPointClouds () -{ - // Check to see if the given ID entry exists - CloudActorMap::iterator am_it = cloud_actor_map_->begin (); - while (am_it != cloud_actor_map_->end () ) - { - if (removePointCloud (am_it->first)) - am_it = cloud_actor_map_->begin (); - else - ++am_it; - } - return (true); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::removeAllShapes () -{ - // Check to see if the given ID entry exists - ShapeActorMap::iterator am_it = shape_actor_map_->begin (); - while (am_it != shape_actor_map_->end ()) - { - if (removeShape (am_it->first)) - am_it = shape_actor_map_->begin (); - else - ++am_it; - } - return (true); -} - - ////////////////////////////////////////////////////////////////////////////////////////// bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index ef23cc1b9..83e41e499 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -17,23 +17,7 @@ public: VizImpl (const String &name); virtual ~VizImpl (); - - - - - - - - - //to refactor - bool removePointCloud (const String& id = "cloud"); - inline bool removePolygonMesh (const String& id = "polygon") { return removePointCloud (id); } - bool removeShape (const String& id = "cloud"); - bool removeText3D (const String& id = "cloud"); - bool removeAllPointClouds (); - - //create Viz3d::removeAllWidgets() - bool removeAllShapes (); + void removeAllWidgets(); //to refactor bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); From b032b4dded5f62e8893737166a0a58e31b71c5c5 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 22 Aug 2013 19:42:19 +0200 Subject: [PATCH 151/205] move frompolyfile to widget class as static method, remove addpolygon and its alikes --- modules/viz/include/opencv2/viz/viz3d.hpp | 7 - modules/viz/include/opencv2/viz/widgets.hpp | 2 + modules/viz/src/shape_widgets.cpp | 1 - modules/viz/src/viz3d.cpp | 22 +- modules/viz/src/viz3d_impl.cpp | 609 -------------------- modules/viz/src/viz3d_impl.hpp | 43 -- modules/viz/src/widget.cpp | 40 ++ 7 files changed, 43 insertions(+), 681 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 96f999bed..c27b08df5 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -27,13 +27,6 @@ namespace cv void setBackgroundColor(const Color& color = Color::black()); - //to refactor - bool addPolygonMesh(const Mesh3d& mesh, const String& id = "polygon"); - bool updatePolygonMesh(const Mesh3d& mesh, const String& id = "polygon"); - bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - bool addPolygon(const Mat& cloud, const Color& color, const String& id = "polygon"); - - void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); void removeWidget(const String &id); Widget getWidget(const String &id) const; diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index c74633049..8ad9b3d31 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -16,6 +16,8 @@ namespace cv Widget(); Widget(const Widget &other); Widget& operator =(const Widget &other); + + static Widget fromPlyFile(const String &file_name); ~Widget(); diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 050b978ef..cb66e80b3 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -969,7 +969,6 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat // Create a camera vtkSmartPointer camera = vtkSmartPointer::New(); - float f_x = K(0,0); float f_y = K(1,1); float c_y = K(1,2); float aspect_ratio = float(image.cols)/float(image.rows); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index bb88e1337..696976d76 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -44,26 +44,6 @@ void cv::viz::Viz3d::release() void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } -bool cv::viz::Viz3d::addPolygonMesh (const Mesh3d& mesh, const String& id) -{ - return impl_->addPolygonMesh(mesh, Mat(), id); -} - -bool cv::viz::Viz3d::updatePolygonMesh (const Mesh3d& mesh, const String& id) -{ - return impl_->updatePolygonMesh(mesh, Mat(), id); -} - -bool cv::viz::Viz3d::addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id) -{ - return impl_->addPolylineFromPolygonMesh(mesh, id); -} - -bool cv::viz::Viz3d::addPolygon(const Mat& cloud, const Color& color, const String& id) -{ - return impl_->addPolygon(cloud, color, id); -} - void cv::viz::Viz3d::spin() { impl_->spin(); } void cv::viz::Viz3d::spinOnce (int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); } bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } @@ -94,4 +74,4 @@ void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } -cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } \ No newline at end of file +cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 12a3de15f..f1417053b 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -331,29 +331,6 @@ bool cv::viz::Viz3d::VizImpl::setPointCloudRenderingProperties (int property, do return true; } -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::setPointCloudSelected (const bool selected, const std::string &id) -{ - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - if (am_it == cloud_actor_map_->end ()) - return std::cout << "[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <" << id << ">!" << std::endl, false; - - vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); - if (selected) - { - actor->GetProperty ()->EdgeVisibilityOn (); - actor->GetProperty ()->SetEdgeColor (1.0, 0.0, 0.0); - actor->Modified (); - } - else - { - actor->GetProperty ()->EdgeVisibilityOff (); - actor->Modified (); - } - - return true; -} - ///////////////////////////////////////////////////////////////////////////////////////////// bool cv::viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double value, const std::string &id) { @@ -618,148 +595,6 @@ void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) renderer_->Render (); } -//////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, const std::string & id) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addModelFromPolyData] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; - return (false); - } - - vtkSmartPointer actor; - createActorFromVTKDataSet (polydata, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const std::string & id) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addModelFromPolyData] A shape with id <"< already exists! Please choose a different id and retry." << std::endl; - return (false); - } - - vtkSmartPointer trans_filter = vtkSmartPointer::New (); - trans_filter->SetTransform (transform); - trans_filter->SetInput (polydata); - trans_filter->Update(); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (trans_filter->GetOutput (), actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - renderer_->AddActor(actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - return (true); -} - - -//////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, const std::string &id) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addModelFromPLYFile] A shape with id <"< already exists! Please choose a different id and retry.." << std::endl, false; - - vtkSmartPointer reader = vtkSmartPointer::New (); - reader->SetFileName (filename.c_str ()); - - vtkSmartPointer actor; - createActorFromVTKDataSet (reader->GetOutput (), actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - renderer_->AddActor(actor); - - (*shape_actor_map_)[id] = actor; - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::addModelFromPLYFile (const std::string &filename, vtkSmartPointer transform, const std::string &id) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addModelFromPLYFile] A shape with id <"< already exists! Please choose a different id and retry." << std::endl, false; - - vtkSmartPointer reader = vtkSmartPointer::New (); - reader->SetFileName (filename.c_str ()); - - vtkSmartPointer trans_filter = vtkSmartPointer::New (); - trans_filter->SetTransform (transform); - trans_filter->SetInputConnection (reader->GetOutputPort ()); - - vtkSmartPointer actor; - createActorFromVTKDataSet (trans_filter->GetOutput (), actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - renderer_->AddActor(actor); - - (*shape_actor_map_)[id] = actor; - return (true); -} - -bool cv::viz::Viz3d::VizImpl::addPolylineFromPolygonMesh (const Mesh3d& /*mesh*/, const std::string &/*id*/) -{ -// CV_Assert(mesh.cloud.rows == 1 && mesh.cloud.type() == CV_32FC3); -// -// ShapeActorMap::iterator am_it = shape_actor_map_->find (id); -// if (am_it != shape_actor_map_->end ()) -// return std::cout << "[addPolylineFromPolygonMesh] A shape with id <"<< id << "> already exists! Please choose a different id and retry.\n" << std::endl, false; -// -// vtkSmartPointer poly_points = vtkSmartPointer::New (); -// poly_points->SetNumberOfPoints (mesh.cloud.size().area()); -// -// const cv::Point3f *cdata = mesh.cloud.ptr(); -// for (int i = 0; i < mesh.cloud.cols; ++i) -// poly_points->InsertPoint (i, cdata[i].x, cdata[i].y,cdata[i].z); -// -// -// // Create a cell array to store the lines in and add the lines to it -// vtkSmartPointer cells = vtkSmartPointer::New (); -// vtkSmartPointer polyData; -// allocVtkPolyData (polyData); -// -// for (size_t i = 0; i < mesh.polygons.size (); i++) -// { -// vtkSmartPointer polyLine = vtkSmartPointer::New(); -// polyLine->GetPointIds()->SetNumberOfIds(mesh.polygons[i].vertices.size()); -// for(unsigned int k = 0; k < mesh.polygons[i].vertices.size(); k++) -// { -// polyLine->GetPointIds()->SetId(k,mesh. polygons[i].vertices[k]); -// } -// -// cells->InsertNextCell (polyLine); -// } -// -// // Add the points to the dataset -// polyData->SetPoints (poly_points); -// -// // Add the lines to the dataset -// polyData->SetLines (cells); -// -// // Setup actor and mapper -// vtkSmartPointer < vtkPolyDataMapper > mapper = vtkSmartPointer::New (); -// mapper->SetInput (polyData); -// -// vtkSmartPointer actor = vtkSmartPointer::New (); -// actor->SetMapper (mapper); -// renderer_->AddActor(actor); -// -// // Save the pointer/ID pair to the global actor map -// (*shape_actor_map_)[id] = actor; - return (true); -} - - /////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setRepresentationToSurfaceForAllActors () { @@ -883,450 +718,6 @@ void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPos void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); } -bool cv::viz::Viz3d::VizImpl::addPolygonMesh (const Mesh3d& /*mesh*/, const Mat& /*mask*/, const std::string &/*id*/) -{ -// CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); -// CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); -// CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); -// -// if (cloud_actor_map_->find (id) != cloud_actor_map_->end ()) -// return std::cout << "[addPolygonMesh] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; -// -// // int rgb_idx = -1; -// // std::vector fields; -// -// -// // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgb", fields); -// // if (rgb_idx == -1) -// // rgb_idx = temp_viz::getFieldIndex (*cloud, "rgba", fields); -// -// vtkSmartPointer colors_array; -// #if 1 -// if (!mesh.colors.empty()) -// { -// colors_array = vtkSmartPointer::New (); -// colors_array->SetNumberOfComponents (3); -// colors_array->SetName ("Colors"); -// -// const unsigned char* data = mesh.colors.ptr(); -// -// //TODO check mask -// CV_Assert(mask.empty()); //because not implemented; -// -// for(int i = 0; i < mesh.colors.cols; ++i) -// colors_array->InsertNextTupleValue(&data[i*3]); -// -// // temp_viz::RGB rgb_data; -// // for (size_t i = 0; i < cloud->size (); ++i) -// // { -// // if (!isFinite (cloud->points[i])) -// // continue; -// // memcpy (&rgb_data, reinterpret_cast (&cloud->points[i]) + fields[rgb_idx].offset, sizeof (temp_viz::RGB)); -// // unsigned char color[3]; -// // color[0] = rgb_data.r; -// // color[1] = rgb_data.g; -// // color[2] = rgb_data.b; -// // colors->InsertNextTupleValue (color); -// // } -// } -// #endif -// -// // Create points from polyMesh.cloud -// vtkSmartPointer points = vtkSmartPointer::New (); -// vtkIdType nr_points = mesh.cloud.size().area(); -// -// points->SetNumberOfPoints (nr_points); -// -// -// // Get a pointer to the beginning of the data array -// float *data = static_cast (points->GetData ())->GetPointer (0); -// -// -// std::vector lookup; -// // If the dataset is dense (no NaNs) -// if (mask.empty()) -// { -// cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); -// mesh.cloud.copyTo(hdr); -// } -// else -// { -// lookup.resize (nr_points); -// -// const unsigned char *mdata = mask.ptr(); -// const cv::Point3f *cdata = mesh.cloud.ptr(); -// cv::Point3f* out = reinterpret_cast(data); -// -// int j = 0; // true point index -// for (int i = 0; i < nr_points; ++i) -// if(mdata[i]) -// { -// lookup[i] = j; -// out[j++] = cdata[i]; -// } -// nr_points = j; -// points->SetNumberOfPoints (nr_points); -// } -// -// // Get the maximum size of a polygon -// int max_size_of_polygon = -1; -// for (size_t i = 0; i < mesh.polygons.size (); ++i) -// if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) -// max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); -// -// vtkSmartPointer actor; -// -// if (mesh.polygons.size () > 1) -// { -// // Create polys from polyMesh.polygons -// vtkSmartPointer cell_array = vtkSmartPointer::New (); -// vtkIdType *cell = cell_array->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); -// int idx = 0; -// if (lookup.size () > 0) -// { -// for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) -// { -// size_t n_points = mesh.polygons[i].vertices.size (); -// *cell++ = n_points; -// //cell_array->InsertNextCell (n_points); -// for (size_t j = 0; j < n_points; j++, ++idx) -// *cell++ = lookup[mesh.polygons[i].vertices[j]]; -// //cell_array->InsertCellPoint (lookup[vertices[i].vertices[j]]); -// } -// } -// else -// { -// for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) -// { -// size_t n_points = mesh.polygons[i].vertices.size (); -// *cell++ = n_points; -// //cell_array->InsertNextCell (n_points); -// for (size_t j = 0; j < n_points; j++, ++idx) -// *cell++ = mesh.polygons[i].vertices[j]; -// //cell_array->InsertCellPoint (vertices[i].vertices[j]); -// } -// } -// vtkSmartPointer polydata; -// allocVtkPolyData (polydata); -// cell_array->GetData ()->SetNumberOfValues (idx); -// cell_array->Squeeze (); -// polydata->SetStrips (cell_array); -// polydata->SetPoints (points); -// -// if (colors_array) -// polydata->GetPointData ()->SetScalars (colors_array); -// -// createActorFromVTKDataSet (polydata, actor, false); -// } -// else -// { -// vtkSmartPointer polygon = vtkSmartPointer::New (); -// size_t n_points = mesh.polygons[0].vertices.size (); -// polygon->GetPointIds ()->SetNumberOfIds (n_points - 1); -// -// if (lookup.size () > 0) -// { -// for (size_t j = 0; j < n_points - 1; ++j) -// polygon->GetPointIds ()->SetId (j, lookup[mesh.polygons[0].vertices[j]]); -// } -// else -// { -// for (size_t j = 0; j < n_points - 1; ++j) -// polygon->GetPointIds ()->SetId (j, mesh.polygons[0].vertices[j]); -// } -// vtkSmartPointer poly_grid; -// allocVtkUnstructuredGrid (poly_grid); -// poly_grid->Allocate (1, 1); -// poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); -// poly_grid->SetPoints (points); -// poly_grid->Update (); -// if (colors_array) -// poly_grid->GetPointData ()->SetScalars (colors_array); -// -// createActorFromVTKDataSet (poly_grid, actor, false); -// } -// renderer_->AddActor (actor); -// actor->GetProperty ()->SetRepresentationToSurface (); -// // Backface culling renders the visualization slower, but guarantees that we see all triangles -// actor->GetProperty ()->BackfaceCullingOff (); -// actor->GetProperty ()->SetInterpolationToFlat (); -// actor->GetProperty ()->EdgeVisibilityOff (); -// actor->GetProperty ()->ShadingOff (); -// -// // Save the pointer/ID pair to the global actor map -// (*cloud_actor_map_)[id].actor = actor; -// //if (vertices.size () > 1) -// // (*cloud_actor_map_)[id].cells = static_cast(actor->GetMapper ())->GetInput ()->GetVerts ()->GetData (); -// -// const Eigen::Vector4f& sensor_origin = Eigen::Vector4f::Zero (); -// const Eigen::Quaternion& sensor_orientation = Eigen::Quaternionf::Identity (); -// -// // Save the viewpoint transformation matrix to the global actor map -// vtkSmartPointer transformation = vtkSmartPointer::New(); -// convertToVtkMatrix (sensor_origin, sensor_orientation, transformation); -// (*cloud_actor_map_)[id].viewpoint_transformation_ = transformation; -// -// return (true); -return true; -} - - -bool cv::viz::Viz3d::VizImpl::updatePolygonMesh (const Mesh3d& /*mesh*/, const cv::Mat& /*mask*/, const std::string &/*id*/) -{ -// CV_Assert(mesh.cloud.type() == CV_32FC3 && mesh.cloud.rows == 1 && !mesh.polygons.empty ()); -// CV_Assert(mesh.colors.empty() || (!mesh.colors.empty() && mesh.colors.size() == mesh.cloud.size() && mesh.colors.type() == CV_8UC3)); -// CV_Assert(mask.empty() || (!mask.empty() && mask.size() == mesh.cloud.size() && mask.type() == CV_8U)); -// -// // Check to see if this ID entry already exists (has it been already added to the visualizer?) -// CloudActorMap::iterator am_it = cloud_actor_map_->find (id); -// if (am_it == cloud_actor_map_->end ()) -// return (false); -// -// // Get the current poly data -// vtkSmartPointer polydata = static_cast(am_it->second.actor->GetMapper ())->GetInput (); -// if (!polydata) -// return (false); -// vtkSmartPointer cells = polydata->GetStrips (); -// if (!cells) -// return (false); -// vtkSmartPointer points = polydata->GetPoints (); -// // Copy the new point array in -// vtkIdType nr_points = mesh.cloud.size().area(); -// points->SetNumberOfPoints (nr_points); -// -// // Get a pointer to the beginning of the data array -// float *data = (static_cast (points->GetData ()))->GetPointer (0); -// -// int ptr = 0; -// std::vector lookup; -// // If the dataset is dense (no NaNs) -// if (mask.empty()) -// { -// cv::Mat hdr(mesh.cloud.size(), CV_32FC3, (void*)data); -// mesh.cloud.copyTo(hdr); -// -// } -// else -// { -// lookup.resize (nr_points); -// -// const unsigned char *mdata = mask.ptr(); -// const cv::Point3f *cdata = mesh.cloud.ptr(); -// cv::Point3f* out = reinterpret_cast(data); -// -// int j = 0; // true point index -// for (int i = 0; i < nr_points; ++i) -// if(mdata[i]) -// { -// lookup[i] = j; -// out[j++] = cdata[i]; -// } -// nr_points = j; -// points->SetNumberOfPoints (nr_points);; -// } -// -// // Update colors -// vtkUnsignedCharArray* colors_array = vtkUnsignedCharArray::SafeDownCast (polydata->GetPointData ()->GetScalars ()); -// -// if (!mesh.colors.empty() && colors_array) -// { -// if (mask.empty()) -// { -// const unsigned char* data = mesh.colors.ptr(); -// for(int i = 0; i < mesh.colors.cols; ++i) -// colors_array->InsertNextTupleValue(&data[i*3]); -// } -// else -// { -// const unsigned char* color = mesh.colors.ptr(); -// const unsigned char* mdata = mask.ptr(); -// -// int j = 0; -// for(int i = 0; i < mesh.colors.cols; ++i) -// if (mdata[i]) -// colors_array->SetTupleValue (j++, &color[i*3]); -// -// } -// } -// -// // Get the maximum size of a polygon -// int max_size_of_polygon = -1; -// for (size_t i = 0; i < mesh.polygons.size (); ++i) -// if (max_size_of_polygon < static_cast (mesh.polygons[i].vertices.size ())) -// max_size_of_polygon = static_cast (mesh.polygons[i].vertices.size ()); -// -// // Update the cells -// cells = vtkSmartPointer::New (); -// vtkIdType *cell = cells->WritePointer (mesh.polygons.size (), mesh.polygons.size () * (max_size_of_polygon + 1)); -// int idx = 0; -// if (lookup.size () > 0) -// { -// for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) -// { -// size_t n_points = mesh.polygons[i].vertices.size (); -// *cell++ = n_points; -// for (size_t j = 0; j < n_points; j++, cell++, ++idx) -// *cell = lookup[mesh.polygons[i].vertices[j]]; -// } -// } -// else -// { -// for (size_t i = 0; i < mesh.polygons.size (); ++i, ++idx) -// { -// size_t n_points = mesh.polygons[i].vertices.size (); -// *cell++ = n_points; -// for (size_t j = 0; j < n_points; j++, cell++, ++idx) -// *cell = mesh.polygons[i].vertices[j]; -// } -// } -// cells->GetData ()->SetNumberOfValues (idx); -// cells->Squeeze (); -// // Set the the vertices -// polydata->SetStrips (cells); -// polydata->Update (); - return (true); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color, bool display_length, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - return std::cout << "[addArrow] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl, false; - - // Create an Actor - vtkSmartPointer leader = vtkSmartPointer::New (); - leader->GetPositionCoordinate()->SetCoordinateSystemToWorld (); - leader->GetPositionCoordinate()->SetValue (p1.x, p1.y, p1.z); - leader->GetPosition2Coordinate()->SetCoordinateSystemToWorld (); - leader->GetPosition2Coordinate()->SetValue (p2.x, p2.y, p2.z); - leader->SetArrowStyleToFilled(); - leader->SetArrowPlacementToPoint2 (); - - if (display_length) - leader->AutoLabelOn (); - else - leader->AutoLabelOff (); - - Color c = vtkcolor(color); - leader->GetProperty ()->SetColor (c.val); - renderer_->AddActor (leader); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = leader; - return (true); -} -//////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::addArrow (const cv::Point3f &p1, const cv::Point3f &p2, const Color& color_line, const Color& color_text, const std::string &id) -{ - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - std::cout << "[addArrow] A shape with id <" << id << "> already exists! Please choose a different id and retry." << std::endl; - return (false); - } - - // Create an Actor - vtkSmartPointer leader = vtkSmartPointer::New (); - leader->GetPositionCoordinate ()->SetCoordinateSystemToWorld (); - leader->GetPositionCoordinate ()->SetValue (p1.x, p1.y, p1.z); - leader->GetPosition2Coordinate ()->SetCoordinateSystemToWorld (); - leader->GetPosition2Coordinate ()->SetValue (p2.x, p2.y, p2.z); - leader->SetArrowStyleToFilled (); - leader->AutoLabelOn (); - - Color ct = vtkcolor(color_text); - leader->GetLabelTextProperty()->SetColor(ct.val); - - Color cl = vtkcolor(color_line); - leader->GetProperty ()->SetColor (cl.val); - renderer_->AddActor (leader); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = leader; - return (true); -} - -bool cv::viz::Viz3d::VizImpl::addPolygon (const cv::Mat& cloud, const Color& color, const std::string &id) -{ - CV_Assert(cloud.type() == CV_32FC3 && cloud.rows == 1); - - vtkSmartPointer points = vtkSmartPointer::New (); - vtkSmartPointer polygon = vtkSmartPointer::New (); - - int total = cloud.size().area(); - points->SetNumberOfPoints (total); - polygon->GetPointIds ()->SetNumberOfIds (total); - - for (int i = 0; i < total; ++i) - { - cv::Point3f p = cloud.ptr()[i]; - points->SetPoint (i, p.x, p.y, p.z); - polygon->GetPointIds ()->SetId (i, i); - } - - vtkSmartPointer poly_grid; - allocVtkUnstructuredGrid (poly_grid); - poly_grid->Allocate (1, 1); - poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); - poly_grid->SetPoints (points); - poly_grid->Update (); - - - ////////////////////////////////////////////////////// - vtkSmartPointer data = poly_grid; - - Color c = vtkcolor(color); - - // Check to see if this ID entry already exists (has it been already added to the visualizer?) - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it != shape_actor_map_->end ()) - { - vtkSmartPointer all_data = vtkSmartPointer::New (); - - // Add old data - all_data->AddInput (reinterpret_cast ((vtkActor::SafeDownCast (am_it->second))->GetMapper ())->GetInput ()); - - // Add new data - vtkSmartPointer surface_filter = vtkSmartPointer::New (); - surface_filter->SetInput (vtkUnstructuredGrid::SafeDownCast (data)); - vtkSmartPointer poly_data = surface_filter->GetOutput (); - all_data->AddInput (poly_data); - - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (all_data->GetOutput (), actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetProperty ()->BackfaceCullingOff (); - - removeActorFromRenderer (am_it->second); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } - else - { - // Create an Actor - vtkSmartPointer actor; - createActorFromVTKDataSet (data, actor); - actor->GetProperty ()->SetRepresentationToWireframe (); - actor->GetProperty ()->SetColor (c.val); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetProperty ()->BackfaceCullingOff (); - renderer_->AddActor (actor); - - // Save the pointer/ID pair to the global actor map - (*shape_actor_map_)[id] = actor; - } - - return (true); -} - void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 83e41e499..085a718c1 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -19,30 +19,11 @@ public: void removeAllWidgets(); - //to refactor - bool addPolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); - bool updatePolygonMesh (const Mesh3d& mesh, const cv::Mat& mask, const String& id = "polygon"); - bool addPolylineFromPolygonMesh (const Mesh3d& mesh, const String& id = "polyline"); - // to refactor: Widget3D:: & Viz3d:: bool setPointCloudRenderingProperties (int property, double value, const String& id = "cloud"); bool getPointCloudRenderingProperties (int property, double &value, const String& id = "cloud"); bool setShapeRenderingProperties (int property, double value, const String& id); - /** \brief Set whether the point cloud is selected or not - * \param[in] selected whether the cloud is selected or not (true = selected) - * \param[in] id the point cloud object id (default: cloud) - */ - // probably should just remove - bool setPointCloudSelected (const bool selected, const String& id = "cloud" ); - - - - - - - - /** \brief Returns true when the user tried to close the window */ bool wasStopped () const { if (interactor_ != NULL) return (stopped_); else return true; } @@ -60,30 +41,6 @@ public: } } - - - - - - - - - - - // to refactor - bool addPolygon(const cv::Mat& cloud, const Color& color, const String& id = "polygon"); - bool addArrow (const Point3f& pt1, const Point3f& pt2, const Color& color, bool display_length, const String& id = "arrow"); - bool addArrow (const Point3f& pt1, const Point3f& pt2, const Color& color_line, const Color& color_text, const String& id = "arrow"); - - // Probably remove this - bool addModelFromPolyData (vtkSmartPointer polydata, const String& id = "PolyData"); - bool addModelFromPolyData (vtkSmartPointer polydata, vtkSmartPointer transform, const String& id = "PolyData"); - - // I think this should be moved to 'static Widget Widget::fromPlyFile(const String&)'; - bool addModelFromPLYFile (const String &filename, const String& id = "PLYModel"); - bool addModelFromPLYFile (const String &filename, vtkSmartPointer transform, const String& id = "PLYModel"); - - // to implement in Viz3d with shorter name void setRepresentationToSurfaceForAllActors(); void setRepresentationToPointsForAllActors(); diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 65c5b1aca..a70409772 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -54,6 +54,46 @@ void cv::viz::Widget::release() } } +cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) +{ + vtkSmartPointer reader = vtkSmartPointer::New (); + reader->SetFileName (file_name.c_str ()); + + vtkSmartPointer data = reader->GetOutput(); + CV_Assert(data); + + vtkSmartPointer actor = vtkSmartPointer::New(); + + vtkSmartPointer mapper = vtkSmartPointer::New (); + mapper->SetInput (data); + + vtkSmartPointer 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 (1, data->GetNumberOfPoints () / 10))); + actor->GetProperty ()->SetInterpolationToFlat (); + actor->GetProperty ()->BackfaceCullingOn (); + + actor->SetMapper (mapper); + + Widget widget; + widget.impl_->prop = actor; + return widget; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// widget accessor implementaion From cf36b8f817b025ad4b9e4883e12355680ce5685e Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 24 Aug 2013 11:49:56 +0200 Subject: [PATCH 152/205] rendering properties in Widget and Viz3d --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 +- modules/viz/include/opencv2/viz/widgets.hpp | 7 +- modules/viz/src/viz3d.cpp | 5 +- modules/viz/src/viz3d_impl.cpp | 173 -------------------- modules/viz/src/viz3d_impl.hpp | 6 +- modules/viz/src/widget.cpp | 125 ++++++++++++++ 6 files changed, 137 insertions(+), 183 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index c27b08df5..7b0875513 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -7,7 +7,6 @@ #include #include #include -#include namespace cv { @@ -55,6 +54,9 @@ namespace cv void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); void registerMouseCallback(MouseCallback callback, void* cookie = 0); + + void setRenderingProperty(int property, double value, const String &id); + double getRenderingProperty(int property, const String &id); private: struct VizImpl; diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 8ad9b3d31..99f4bd420 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -16,10 +16,12 @@ namespace cv Widget(); Widget(const Widget &other); Widget& operator =(const Widget &other); + ~Widget(); static Widget fromPlyFile(const String &file_name); - - ~Widget(); + + void setRenderingProperty(int property, double value); + double getRenderingProperty(int property) const; template _W cast(); private: @@ -43,7 +45,6 @@ namespace cv Affine3f getPose() const; void setColor(const Color &color); - private: struct MatrixConverter; diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 696976d76..fc9ce01c0 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -54,8 +54,6 @@ void cv::viz::Viz3d::registerKeyboardCallback(KeyboardCallback callback, void* c void cv::viz::Viz3d::registerMouseCallback(MouseCallback callback, void* cookie) { impl_->registerMouseCallback(callback, cookie); } - - void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose) { impl_->showWidget(id, widget, pose); } void cv::viz::Viz3d::removeWidget(const String &id) { impl_->removeWidget(id); } cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_->getWidget(id); } @@ -75,3 +73,6 @@ void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } + +void cv::viz::Viz3d::setRenderingProperty(int property, double value, const String &id) { getWidget(id).setRenderingProperty(property, value); } +double cv::viz::Viz3d::getRenderingProperty(int property, const String &id) { return getWidget(id).getRenderingProperty(property); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index f1417053b..aa51b1015 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -249,179 +249,6 @@ void cv::viz::Viz3d::VizImpl::setBackgroundColor (const Color& color) renderer_->SetBackground (c.val); } -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::getPointCloudRenderingProperties (int property, double &value, const std::string &id) -{ - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - if (am_it == cloud_actor_map_->end ()) - return false; - - vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); - - switch (property) - { - case VIZ_POINT_SIZE: - { - value = actor->GetProperty ()->GetPointSize (); - actor->Modified (); - break; - } - case VIZ_OPACITY: - { - value = actor->GetProperty ()->GetOpacity (); - actor->Modified (); - break; - } - case VIZ_LINE_WIDTH: - { - value = actor->GetProperty ()->GetLineWidth (); - actor->Modified (); - break; - } - default: - CV_Assert("getPointCloudRenderingProperties: Unknown property"); - } - - return true; -} - -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::setPointCloudRenderingProperties (int property, double value, const std::string &id) -{ - CloudActorMap::iterator am_it = cloud_actor_map_->find (id); - if (am_it == cloud_actor_map_->end ()) - return std::cout << "[setPointCloudRenderingProperties] Could not find any PointCloud datasets with id <" << id << ">!" << std::endl, false; - - vtkLODActor* actor = vtkLODActor::SafeDownCast (am_it->second.actor); - - switch (property) - { - case VIZ_POINT_SIZE: - { - actor->GetProperty ()->SetPointSize (float (value)); - actor->Modified (); - break; - } - case VIZ_OPACITY: - { - actor->GetProperty ()->SetOpacity (value); - actor->Modified (); - break; - } - // Turn on/off flag to control whether data is rendered using immediate - // mode or note. Immediate mode rendering tends to be slower but it can - // handle larger datasets. The default value is immediate mode off. If you - // are having problems rendering a large dataset you might want to consider - // using immediate more rendering. - case VIZ_IMMEDIATE_RENDERING: - { - actor->GetMapper ()->SetImmediateModeRendering (int (value)); - actor->Modified (); - break; - } - case VIZ_LINE_WIDTH: - { - actor->GetProperty ()->SetLineWidth (float (value)); - actor->Modified (); - break; - } - default: - CV_Assert("setPointCloudRenderingProperties: Unknown property"); - } - return true; -} - -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::setShapeRenderingProperties (int property, double value, const std::string &id) -{ - ShapeActorMap::iterator am_it = shape_actor_map_->find (id); - if (am_it == shape_actor_map_->end ()) - return std::cout << "[setShapeRenderingProperties] Could not find any shape with id <" << id << ">!\n" << std::endl, false; - - vtkActor* actor = vtkActor::SafeDownCast (am_it->second); - - switch (property) - { - case VIZ_POINT_SIZE: - { - actor->GetProperty ()->SetPointSize (float (value)); - actor->Modified (); - break; - } - case VIZ_OPACITY: - { - actor->GetProperty ()->SetOpacity (value); - actor->Modified (); - break; - } - case VIZ_LINE_WIDTH: - { - actor->GetProperty ()->SetLineWidth (float (value)); - actor->Modified (); - break; - } - case VIZ_FONT_SIZE: - { - vtkTextActor* text_actor = vtkTextActor::SafeDownCast (am_it->second); - vtkSmartPointer tprop = text_actor->GetTextProperty (); - tprop->SetFontSize (int (value)); - text_actor->Modified (); - break; - } - case VIZ_REPRESENTATION: - { - switch (int (value)) - { - case REPRESENTATION_POINTS: actor->GetProperty ()->SetRepresentationToPoints (); break; - case REPRESENTATION_WIREFRAME: actor->GetProperty ()->SetRepresentationToWireframe (); break; - case REPRESENTATION_SURFACE: actor->GetProperty ()->SetRepresentationToSurface (); break; - } - actor->Modified (); - break; - } - case VIZ_SHADING: - { - switch (int (value)) - { - case SHADING_FLAT: actor->GetProperty ()->SetInterpolationToFlat (); break; - case SHADING_GOURAUD: - { - if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) - { - std::cout << "[cv::viz::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Gouraud shading was requested. Estimating normals...\n" << std::endl; - - vtkSmartPointer normals = vtkSmartPointer::New (); - normals->SetInput (actor->GetMapper ()->GetInput ()); - normals->Update (); - vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ()); - } - actor->GetProperty ()->SetInterpolationToGouraud (); - break; - } - case SHADING_PHONG: - { - if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) - { - std::cout << "[cv::viz::PCLVisualizer::setShapeRenderingProperties] Normals do not exist in the dataset, but Phong shading was requested. Estimating normals...\n" << std::endl; - vtkSmartPointer normals = vtkSmartPointer::New (); - normals->SetInput (actor->GetMapper ()->GetInput ()); - normals->Update (); - vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ()); - } - actor->GetProperty ()->SetInterpolationToPhong (); - break; - } - } - actor->Modified (); - break; - } - default: - CV_Assert("setShapeRenderingProperties: Unknown property"); - - } - return true; -} - ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::initCameraParameters () { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 085a718c1..60ec70762 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -19,10 +19,8 @@ public: void removeAllWidgets(); - // to refactor: Widget3D:: & Viz3d:: - bool setPointCloudRenderingProperties (int property, double value, const String& id = "cloud"); - bool getPointCloudRenderingProperties (int property, double &value, const String& id = "cloud"); - bool setShapeRenderingProperties (int property, double value, const String& id); + void setRenderingProperty(int property, double value, const String &id); + double getRenderingProperty(int property, const String &id); /** \brief Returns true when the user tried to close the window */ bool wasStopped () const { if (interactor_ != NULL) return (stopped_); else return true; } diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index a70409772..808e3f047 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -94,6 +94,131 @@ cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) return widget; } +void cv::viz::Widget::setRenderingProperty(int property, double value) +{ + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + switch (property) + { + case VIZ_POINT_SIZE: + { + actor->GetProperty ()->SetPointSize (float (value)); + actor->Modified (); + break; + } + case VIZ_OPACITY: + { + actor->GetProperty ()->SetOpacity (value); + actor->Modified (); + break; + } + // Turn on/off flag to control whether data is rendered using immediate + // mode or note. Immediate mode rendering tends to be slower but it can + // handle larger datasets. The default value is immediate mode off. If you + // are having problems rendering a large dataset you might want to consider + // using immediate more rendering. + case VIZ_IMMEDIATE_RENDERING: + { + actor->GetMapper ()->SetImmediateModeRendering (int (value)); + actor->Modified (); + break; + } + case VIZ_LINE_WIDTH: + { + actor->GetProperty ()->SetLineWidth (float (value)); + actor->Modified (); + break; + } + default: + CV_Assert("setPointCloudRenderingProperties: Unknown property"); + } +} + +double cv::viz::Widget::getRenderingProperty(int property) const +{ + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert(actor); + + double value = 0.0; + switch (property) + { + case VIZ_POINT_SIZE: + { + value = actor->GetProperty ()->GetPointSize (); + actor->Modified (); + break; + } + case VIZ_OPACITY: + { + value = actor->GetProperty ()->GetOpacity (); + actor->Modified (); + break; + } + case VIZ_LINE_WIDTH: + { + value = actor->GetProperty ()->GetLineWidth (); + actor->Modified (); + break; + } + case VIZ_FONT_SIZE: + { + vtkTextActor* text_actor = vtkTextActor::SafeDownCast (actor); + vtkSmartPointer tprop = text_actor->GetTextProperty (); + tprop->SetFontSize (int (value)); + text_actor->Modified (); + break; + } + case VIZ_REPRESENTATION: + { + switch (int (value)) + { + case REPRESENTATION_POINTS: actor->GetProperty ()->SetRepresentationToPoints (); break; + case REPRESENTATION_WIREFRAME: actor->GetProperty ()->SetRepresentationToWireframe (); break; + case REPRESENTATION_SURFACE: actor->GetProperty ()->SetRepresentationToSurface (); break; + } + actor->Modified (); + break; + } + case VIZ_SHADING: + { + switch (int (value)) + { + case SHADING_FLAT: actor->GetProperty ()->SetInterpolationToFlat (); break; + case SHADING_GOURAUD: + { + if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) + { + vtkSmartPointer normals = vtkSmartPointer::New (); + normals->SetInput (actor->GetMapper ()->GetInput ()); + normals->Update (); + vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ()); + } + actor->GetProperty ()->SetInterpolationToGouraud (); + break; + } + case SHADING_PHONG: + { + if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) + { + vtkSmartPointer normals = vtkSmartPointer::New (); + normals->SetInput (actor->GetMapper ()->GetInput ()); + normals->Update (); + vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ()); + } + actor->GetProperty ()->SetInterpolationToPhong (); + break; + } + } + actor->Modified (); + break; + } + default: + CV_Assert("getPointCloudRenderingProperties: Unknown property"); + } + return value; +} + /////////////////////////////////////////////////////////////////////////////////////////////// /// widget accessor implementaion From 4f416352e1143f1d29d04292426f8003e67f5370 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 24 Aug 2013 11:58:32 +0200 Subject: [PATCH 153/205] implemented actor representation methods in viz3d --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 +++ modules/viz/src/viz3d.cpp | 4 +++ modules/viz/src/viz3d_impl.cpp | 30 +++++++++++------------ modules/viz/src/viz3d_impl.hpp | 13 +++------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 7b0875513..16e491144 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -57,6 +57,10 @@ namespace cv void setRenderingProperty(int property, double value, const String &id); double getRenderingProperty(int property, const String &id); + + void setRepresentationToSurface(); + void setRepresentationToWireframe(); + void setRepresentationToPoints(); private: struct VizImpl; diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index fc9ce01c0..8f1d12c89 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -76,3 +76,7 @@ cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName() void cv::viz::Viz3d::setRenderingProperty(int property, double value, const String &id) { getWidget(id).setRenderingProperty(property, value); } double cv::viz::Viz3d::getRenderingProperty(int property, const String &id) { return getWidget(id).getRenderingProperty(property); } + +void cv::viz::Viz3d::setRepresentationToSurface() { impl_->setRepresentationToSurface(); } +void cv::viz::Viz3d::setRepresentationToWireframe() { impl_->setRepresentationToWireframe(); } +void cv::viz::Viz3d::setRepresentationToPoints() { impl_->setRepresentationToPoints(); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index aa51b1015..880224799 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -423,33 +423,33 @@ void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) } /////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setRepresentationToSurfaceForAllActors () +void cv::viz::Viz3d::VizImpl::setRepresentationToSurface() { - vtkActorCollection * actors = renderer_->GetActors (); - actors->InitTraversal (); + vtkActorCollection * actors = renderer_->GetActors(); + actors->InitTraversal(); vtkActor * actor; - while ((actor = actors->GetNextActor ()) != NULL) - actor->GetProperty ()->SetRepresentationToSurface (); + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToSurface(); } /////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setRepresentationToPointsForAllActors () +void cv::viz::Viz3d::VizImpl::setRepresentationToPoints() { - vtkActorCollection * actors = renderer_->GetActors (); - actors->InitTraversal (); + vtkActorCollection * actors = renderer_->GetActors(); + actors->InitTraversal(); vtkActor * actor; - while ((actor = actors->GetNextActor ()) != NULL) - actor->GetProperty ()->SetRepresentationToPoints (); + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToPoints(); } /////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setRepresentationToWireframeForAllActors () +void cv::viz::Viz3d::VizImpl::setRepresentationToWireframe() { - vtkActorCollection * actors = renderer_->GetActors (); - actors->InitTraversal (); + vtkActorCollection * actors = renderer_->GetActors(); + actors->InitTraversal(); vtkActor *actor; - while ((actor = actors->GetNextActor ()) != NULL) - actor->GetProperty ()->SetRepresentationToWireframe (); + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToWireframe(); } ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 60ec70762..7bb008a3a 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -39,16 +39,9 @@ public: } } - // to implement in Viz3d with shorter name - void setRepresentationToSurfaceForAllActors(); - void setRepresentationToPointsForAllActors(); - void setRepresentationToWireframeForAllActors(); - - - - - - + void setRepresentationToSurface(); + void setRepresentationToPoints(); + void setRepresentationToWireframe(); // //////////////////////////////////////////////////////////////////////////////////// From f6e1a093cd401ced065f9b50b325be5d6d166319 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 24 Aug 2013 12:18:42 +0200 Subject: [PATCH 154/205] implement window relevant methods in Viz3d --- modules/viz/include/opencv2/viz/viz3d.hpp | 8 +++-- modules/viz/src/viz3d.cpp | 7 +++-- modules/viz/src/viz3d_impl.cpp | 30 ------------------ modules/viz/src/viz3d_impl.hpp | 38 +++++------------------ 4 files changed, 18 insertions(+), 65 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 16e491144..89e1841db 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -24,8 +24,6 @@ namespace cv Viz3d& operator=(const Viz3d&); ~Viz3d(); - void setBackgroundColor(const Color& color = Color::black()); - void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); void removeWidget(const String &id); Widget getWidget(const String &id) const; @@ -45,8 +43,12 @@ namespace cv Size getWindowSize() const; void setWindowSize(const Size &window_size); - String getWindowName() const; + void saveScreenshot (const String &file); + void setWindowPosition (int x, int y); + void setFullScreen (bool mode); + void setWindowName (const String &name); + void setBackgroundColor(const Color& color = Color::black()); void spin(); void spinOnce(int time = 1, bool force_redraw = false); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 8f1d12c89..5a2ae0531 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -42,8 +42,6 @@ void cv::viz::Viz3d::release() } } -void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } - void cv::viz::Viz3d::spin() { impl_->spin(); } void cv::viz::Viz3d::spinOnce (int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); } bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } @@ -73,6 +71,11 @@ void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } +void cv::viz::Viz3d::saveScreenshot (const String &file) { impl_->saveScreenshot(file); } +void cv::viz::Viz3d::setWindowPosition (int x, int y) { impl_->setWindowPosition(x,y); } +void cv::viz::Viz3d::setFullScreen (bool mode) { impl_->setFullScreen(mode); } +void cv::viz::Viz3d::setWindowName (const String &name) { impl_->setWindowName(name); } +void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } void cv::viz::Viz3d::setRenderingProperty(int property, double value, const String &id) { getWidget(id).setRenderingProperty(property, value); } double cv::viz::Viz3d::getRenderingProperty(int property, const String &id) { return getWidget(id).getRenderingProperty(property); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 880224799..1c35216fc 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -249,30 +249,6 @@ void cv::viz::Viz3d::VizImpl::setBackgroundColor (const Color& color) renderer_->SetBackground (c.val); } -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::initCameraParameters () -{ - Vec2i window_size(window_->GetScreenSize()); - window_size /= 2; - - Camera camera_temp(Vec2f(0.0,0.8575), Size(window_size[0], window_size[1])); - setCamera(camera_temp); - setViewerPose(makeCameraPose(Vec3f(0.0f,0.0f,0.0f), Vec3f(0.0f, 0.0f, 1.0f), Vec3f(0.0f, 1.0f, 0.0f))); -} - -///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::cameraParamsSet () const { return (camera_set_); } - -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::updateCamera () -{ - std::cout << "[cv::viz::PCLVisualizer::updateCamera()] This method was deprecated, just re-rendering all scenes now." << std::endl; - //rens_->InitTraversal (); - // Update the camera parameters - - renderer_->Render (); -} - ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) { @@ -379,12 +355,6 @@ void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d direction = normalize(Vec3d(world_pt.val) - cam_pos); } -///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::resetCamera () -{ - renderer_->ResetCamera (); -} - ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 7bb008a3a..67f7c2701 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -16,8 +16,15 @@ public: VizImpl (const String &name); virtual ~VizImpl (); - + + void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; void removeAllWidgets(); + + void setWidgetPose(const String &id, const Affine3f &pose); + void updateWidgetPose(const String &id, const Affine3f &pose); + Affine3f getWidgetPose(const String &id) const; void setRenderingProperty(int property, double value, const String &id); double getRenderingProperty(int property, const String &id); @@ -51,29 +58,16 @@ public: void setCamera(const Camera &camera); Camera getCamera() const; - void initCameraParameters (); /** \brief Initialize camera parameters with some default values. */ - bool cameraParamsSet () const; /** \brief Checks whether the camera parameters were manually loaded from file.*/ - void updateCamera (); /** \brief Update camera parameters and render. */ - void resetCamera (); /** \brief Reset camera parameters and render. */ - /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset. * \param[in] id the point cloud object id (default: cloud) */ void resetCameraViewpoint (const String& id = "cloud"); - //to implement Viz3d set/getViewerPose() void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); - - - - - - - //to implemnt in Viz3d void saveScreenshot (const String &file); void setWindowPosition (int x, int y); Size getWindowSize() const; @@ -89,22 +83,6 @@ public: void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); void registerMouseCallback(MouseCallback callback, void* cookie = 0); - - - - - - - - //declare above (to move to up) - void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); - void removeWidget(const String &id); - Widget getWidget(const String &id) const; - - void setWidgetPose(const String &id, const Affine3f &pose); - void updateWidgetPose(const String &id, const Affine3f &pose); - Affine3f getWidgetPose(const String &id) const; - private: vtkSmartPointer interactor_; From f98614ece0de86c26ea59ee3d2a47c9c212503ec Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 24 Aug 2013 12:52:34 +0200 Subject: [PATCH 155/205] remove cloudactormap, shapeactormap. only vtkProp is stored and view transformation can be obtained using GetUserMatrix of vtkProp3D --- modules/viz/src/interactor_style.cpp | 38 ++++++++++++++-------------- modules/viz/src/interactor_style.h | 6 ++--- modules/viz/src/viz3d_impl.cpp | 32 ++++++++++------------- modules/viz/src/viz3d_impl.hpp | 4 +-- modules/viz/src/viz_types.h | 24 +----------------- 5 files changed, 39 insertions(+), 65 deletions(-) diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 2daec8126..db3d97979 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -432,17 +432,17 @@ cv::viz::InteractorStyle::OnKeyDown () vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); - static CloudActorMap::iterator it = actors_->begin (); + static 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. bool found_transformation = false; - for (size_t idx = 0; idx < actors_->size (); ++idx, ++it) + for (size_t idx = 0; idx < widget_actor_map_->size (); ++idx, ++it) { - if (it == actors_->end ()) - it = actors_->begin (); - - const CloudActor& actor = it->second; - if (actor.viewpoint_transformation_.GetPointer ()) + if (it == widget_actor_map_->end ()) + it = widget_actor_map_->begin (); + + vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); + if (actor && actor->GetUserMatrix()) { found_transformation = true; break; @@ -452,18 +452,18 @@ cv::viz::InteractorStyle::OnKeyDown () // if a valid transformation was found, use it otherwise fall back to default view point. if (found_transformation) { - const CloudActor& actor = it->second; - cam->SetPosition (actor.viewpoint_transformation_->GetElement (0, 3), - actor.viewpoint_transformation_->GetElement (1, 3), - actor.viewpoint_transformation_->GetElement (2, 3)); + vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); + cam->SetPosition (actor->GetUserMatrix()->GetElement (0, 3), + actor->GetUserMatrix()->GetElement (1, 3), + actor->GetUserMatrix()->GetElement (2, 3)); - cam->SetFocalPoint (actor.viewpoint_transformation_->GetElement (0, 3) - actor.viewpoint_transformation_->GetElement (0, 2), - actor.viewpoint_transformation_->GetElement (1, 3) - actor.viewpoint_transformation_->GetElement (1, 2), - actor.viewpoint_transformation_->GetElement (2, 3) - actor.viewpoint_transformation_->GetElement (2, 2)); + cam->SetFocalPoint (actor->GetUserMatrix()->GetElement (0, 3) - actor->GetUserMatrix()->GetElement (0, 2), + actor->GetUserMatrix()->GetElement (1, 3) - actor->GetUserMatrix()->GetElement (1, 2), + actor->GetUserMatrix()->GetElement (2, 3) - actor->GetUserMatrix()->GetElement (2, 2)); - cam->SetViewUp (actor.viewpoint_transformation_->GetElement (0, 1), - actor.viewpoint_transformation_->GetElement (1, 1), - actor.viewpoint_transformation_->GetElement (2, 1)); + cam->SetViewUp (actor->GetUserMatrix()->GetElement (0, 1), + actor->GetUserMatrix()->GetElement (1, 1), + actor->GetUserMatrix()->GetElement (2, 1)); } else { @@ -473,10 +473,10 @@ cv::viz::InteractorStyle::OnKeyDown () } // go to the next actor for the next key-press event. - if (it != actors_->end ()) + if (it != widget_actor_map_->end ()) ++it; else - it = actors_->begin (); + it = widget_actor_map_->begin (); CurrentRenderer->SetActiveCamera (cam); CurrentRenderer->ResetCameraClippingRange (); diff --git a/modules/viz/src/interactor_style.h b/modules/viz/src/interactor_style.h index db20a1ad9..aba03a373 100644 --- a/modules/viz/src/interactor_style.h +++ b/modules/viz/src/interactor_style.h @@ -50,7 +50,7 @@ namespace cv /** \brief Initialization routine. Must be called before anything else. */ virtual void Initialize (); - inline void setCloudActorMap (const Ptr& actors) { actors_ = actors; } + inline void setWidgetActorMap (const Ptr& actors) { widget_actor_map_ = actors; } void setRenderer (vtkSmartPointer& ren) { renderer_ = ren; } void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0); @@ -73,8 +73,8 @@ namespace cv vtkSmartPointer renderer_; /** \brief Actor map stored internally. */ - cv::Ptr actors_; - + cv::Ptr widget_actor_map_; + /** \brief The current window width/height. */ Vec2i win_size_; diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 1c35216fc..6e91338d3 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -11,8 +11,6 @@ vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew () ///////////////////////////////////////////////////////////////////////////////////////////// cv::viz::Viz3d::VizImpl::VizImpl (const std::string &name) : style_ (vtkSmartPointer::New ()) - , cloud_actor_map_ (new CloudActorMap) - , shape_actor_map_ (new ShapeActorMap) , widget_actor_map_ (new WidgetActorMap) , s_lastDone_(0.0) { @@ -30,7 +28,7 @@ cv::viz::Viz3d::VizImpl::VizImpl (const std::string &name) // Create the interactor style style_->Initialize (); style_->setRenderer (renderer_); - style_->setCloudActorMap (cloud_actor_map_); + style_->setWidgetActorMap (widget_actor_map_); style_->UseTimersOn (); ///////////////////////////////////////////////// @@ -358,11 +356,13 @@ void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) { - // TODO Cloud actor is not used vtkSmartPointer camera_pose; - static CloudActorMap::iterator it = cloud_actor_map_->find (id); - if (it != cloud_actor_map_->end ()) - camera_pose = it->second.viewpoint_transformation_; + static WidgetActorMap::iterator it = widget_actor_map_->find (id); + if (it != widget_actor_map_->end ()) + { + vtkProp3D *actor = vtkProp3D::SafeDownCast(it->second); + camera_pose = actor->GetUserMatrix(); + } else return; @@ -370,10 +370,6 @@ void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) if (!camera_pose) return; - // set all renderer to this viewpoint - //rens_->InitTraversal (); - - vtkSmartPointer cam = renderer_->GetActiveCamera (); cam->SetPosition (camera_pose->GetElement (0, 3), camera_pose->GetElement (1, 3), @@ -522,7 +518,7 @@ void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, if (exists) { // Remove it if it exists and add it again - removeActorFromRenderer(wam_itr->second.actor); + removeActorFromRenderer(wam_itr->second); } // Get the actor and set the user matrix vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget)); @@ -541,7 +537,7 @@ void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, } renderer_->AddActor(WidgetAccessor::getProp(widget)); - (*widget_actor_map_)[id].actor = WidgetAccessor::getProp(widget); + (*widget_actor_map_)[id] = WidgetAccessor::getProp(widget); } void cv::viz::Viz3d::VizImpl::removeWidget(const String &id) @@ -549,7 +545,7 @@ void cv::viz::Viz3d::VizImpl::removeWidget(const String &id) WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); CV_Assert(exists); - CV_Assert(removeActorFromRenderer (wam_itr->second.actor)); + CV_Assert(removeActorFromRenderer (wam_itr->second)); widget_actor_map_->erase(wam_itr); } @@ -560,7 +556,7 @@ cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const CV_Assert(exists); Widget widget; - WidgetAccessor::setProp(widget, wam_itr->second.actor); + WidgetAccessor::setProp(widget, wam_itr->second); return widget; } @@ -570,7 +566,7 @@ void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &po bool exists = wam_itr != widget_actor_map_->end(); CV_Assert(exists); - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); CV_Assert(actor); vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); @@ -584,7 +580,7 @@ void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f bool exists = wam_itr != widget_actor_map_->end(); CV_Assert(exists); - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); CV_Assert(actor); vtkSmartPointer matrix = actor->GetUserMatrix(); @@ -607,7 +603,7 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const bool exists = wam_itr != widget_actor_map_->end(); CV_Assert(exists); - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second.actor); + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); CV_Assert(actor); vtkSmartPointer matrix = actor->GetUserMatrix(); diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 67f7c2701..988b732f1 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -144,10 +144,10 @@ private: vtkSmartPointer style_; /** \brief Internal list with actor pointers and name IDs for point clouds. */ - cv::Ptr cloud_actor_map_; +// cv::Ptr cloud_actor_map_; /** \brief Internal list with actor pointers and name IDs for shapes. */ - cv::Ptr shape_actor_map_; +// cv::Ptr shape_actor_map_; /** \brief Internal list with actor pointers and name IDs for all widget actors */ cv::Ptr widget_actor_map_; diff --git a/modules/viz/src/viz_types.h b/modules/viz/src/viz_types.h index 9d47a0c8b..33de56af3 100644 --- a/modules/viz/src/viz_types.h +++ b/modules/viz/src/viz_types.h @@ -6,29 +6,7 @@ namespace cv { namespace viz { - struct CV_EXPORTS CloudActor - { - /** \brief The actor holding the data to render. */ - vtkSmartPointer actor; - - /** \brief The viewpoint transformation matrix. */ - vtkSmartPointer viewpoint_transformation_; - - /** \brief Internal cell array. Used for optimizing updatePointCloud. */ - vtkSmartPointer cells; - }; - - // TODO This will be used to contain both cloud and shape actors - struct CV_EXPORTS WidgetActor - { - vtkSmartPointer actor; - vtkSmartPointer viewpoint_transformation_; - vtkSmartPointer cells; - }; - - typedef std::map CloudActorMap; - typedef std::map > ShapeActorMap; - typedef std::map WidgetActorMap; + typedef std::map > WidgetActorMap; } } From 08917908f3c0ed5300a13e115c611e3efa9dd7c7 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 24 Aug 2013 13:15:44 +0200 Subject: [PATCH 156/205] remove eigen dependency --- modules/viz/src/precomp.hpp | 2 -- modules/viz/src/viz3d_impl.cpp | 18 ------------------ modules/viz/src/viz3d_impl.hpp | 8 -------- 3 files changed, 28 deletions(-) diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 12a042c15..69d20a535 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -5,8 +5,6 @@ #include #include -#include - #if defined __GNUC__ #pragma GCC system_header #ifdef __DEPRECATED diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 6e91338d3..f6d560da9 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -472,24 +472,6 @@ void cv::viz::Viz3d::VizImpl::allocVtkUnstructuredGrid (vtkSmartPointer::New (); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix) -{ - // set rotation - Eigen::Matrix3f rot = orientation.toRotationMatrix (); - for (int i = 0; i < 3; i++) - for (int k = 0; k < 3; k++) - vtk_matrix->SetElement (i, k, rot (i, k)); - - // set translation - vtk_matrix->SetElement (0, 3, origin (0)); - vtk_matrix->SetElement (1, 3, origin (1)); - vtk_matrix->SetElement (2, 3, origin (2)); - vtk_matrix->SetElement (3, 3, 1.0f); -} - - -////////////////////////////////////////////////////////////////////////////////////////////// - void cv::viz::Viz3d::VizImpl::setFullScreen (bool mode) { if (window_) diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 988b732f1..5dcd4bf85 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -190,17 +190,9 @@ namespace cv { namespace viz { - //void getTransformationMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternionf& orientation, Eigen::Matrix4f &transformation); vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m); cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix); - /** \brief Convert origin and orientation to vtkMatrix4x4 - * \param[in] origin the point cloud origin - * \param[in] orientation the point cloud orientation - * \param[out] vtk_matrix the resultant VTK 4x4 matrix - */ - void convertToVtkMatrix (const Eigen::Vector4f &origin, const Eigen::Quaternion &orientation, vtkSmartPointer &vtk_matrix); - struct NanFilter { template From ed0162ad0b943bf5bf14ecf7531c0a615834ca00 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 24 Aug 2013 15:12:16 +0200 Subject: [PATCH 157/205] remove reference counting in widgets --- modules/viz/include/opencv2/viz/widgets.hpp | 6 --- modules/viz/src/widget.cpp | 43 +-------------------- 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 99f4bd420..caaee9e69 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -14,9 +14,6 @@ namespace cv { public: Widget(); - Widget(const Widget &other); - Widget& operator =(const Widget &other); - ~Widget(); static Widget fromPlyFile(const String &file_name); @@ -28,9 +25,6 @@ namespace cv class Impl; Impl *impl_; friend struct WidgetAccessor; - - void create(); - void release(); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 808e3f047..485e35ed7 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -7,52 +7,11 @@ class cv::viz::Widget::Impl { public: vtkSmartPointer prop; - int ref_counter; Impl() : prop(0) {} }; -cv::viz::Widget::Widget() : impl_(0) -{ - create(); -} - -cv::viz::Widget::Widget(const Widget &other) : impl_(other.impl_) -{ - if (impl_) CV_XADD(&impl_->ref_counter, 1); -} - -cv::viz::Widget& cv::viz::Widget::operator=(const Widget &other) -{ - if (this != &other) - { - release(); - impl_ = other.impl_; - if (impl_) CV_XADD(&impl_->ref_counter, 1); - } - return *this; -} - -cv::viz::Widget::~Widget() -{ - release(); -} - -void cv::viz::Widget::create() -{ - if (impl_) release(); - impl_ = new Impl(); - impl_->ref_counter = 1; -} - -void cv::viz::Widget::release() -{ - if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) - { - delete impl_; - impl_ = 0; - } -} +cv::viz::Widget::Widget() : impl_( new Impl() ) { } cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) { From 3038ffb886bc696efac112a746f29ac29b96bd1c Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sun, 25 Aug 2013 12:24:59 +0200 Subject: [PATCH 158/205] setDesiredUpdateRate implementation in Viz3d --- modules/viz/include/opencv2/viz/viz3d.hpp | 3 + modules/viz/src/viz3d.cpp | 5 +- modules/viz/src/viz3d_impl.cpp | 221 ++++++++++++---------- modules/viz/src/viz3d_impl.hpp | 4 +- 4 files changed, 130 insertions(+), 103 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 89e1841db..a80fd3748 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -60,6 +60,9 @@ namespace cv void setRenderingProperty(int property, double value, const String &id); double getRenderingProperty(int property, const String &id); + void setDesiredUpdateRate(double time); + double getDesiredUpdateRate(); + void setRepresentationToSurface(); void setRepresentationToWireframe(); void setRepresentationToPoints(); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 5a2ae0531..96483f43a 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -80,6 +80,9 @@ void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgrou void cv::viz::Viz3d::setRenderingProperty(int property, double value, const String &id) { getWidget(id).setRenderingProperty(property, value); } double cv::viz::Viz3d::getRenderingProperty(int property, const String &id) { return getWidget(id).getRenderingProperty(property); } +void cv::viz::Viz3d::setDesiredUpdateRate(double time) { impl_->setDesiredUpdateRate(time); } +double cv::viz::Viz3d::getDesiredUpdateRate() { return impl_->getDesiredUpdateRate(); } + void cv::viz::Viz3d::setRepresentationToSurface() { impl_->setRepresentationToSurface(); } void cv::viz::Viz3d::setRepresentationToWireframe() { impl_->setRepresentationToWireframe(); } -void cv::viz::Viz3d::setRepresentationToPoints() { impl_->setRepresentationToPoints(); } +void cv::viz::Viz3d::setRepresentationToPoints() { impl_->setRepresentationToPoints(); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index f6d560da9..f0157331e 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -84,6 +84,127 @@ cv::viz::Viz3d::VizImpl::~VizImpl () if (renderer_) renderer_->Clear(); } +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + if (exists) + { + // Remove it if it exists and add it again + removeActorFromRenderer(wam_itr->second); + } + // Get the actor and set the user matrix + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget)); + if (actor) + { + // If the actor is 3D, apply pose + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified(); + } + // If the actor is a vtkFollower, then it should always face the camera + vtkFollower *follower = vtkFollower::SafeDownCast(actor); + if (follower) + { + follower->SetCamera(renderer_->GetActiveCamera()); + } + + renderer_->AddActor(WidgetAccessor::getProp(widget)); + (*widget_actor_map_)[id] = WidgetAccessor::getProp(widget); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::removeWidget(const String &id) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + CV_Assert(removeActorFromRenderer (wam_itr->second)); + widget_actor_map_->erase(wam_itr); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const +{ + WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + Widget widget; + WidgetAccessor::setProp(widget, wam_itr->second); + return widget; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); + CV_Assert(actor); + + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); + actor->SetUserMatrix (matrix); + actor->Modified (); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); + CV_Assert(actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + if (!matrix) + { + setWidgetPose(id, pose); + return ; + } + Matx44f matrix_cv = convertToMatx(matrix); + Affine3f updated_pose = pose * Affine3f(matrix_cv); + matrix = convertToVtkMatrix(updated_pose.matrix); + + actor->SetUserMatrix (matrix); + actor->Modified (); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const +{ + WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert(exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); + CV_Assert(actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + Matx44f matrix_cv = convertToMatx(matrix); + return Affine3f(matrix_cv); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setDesiredUpdateRate(double time) +{ + if (interactor_) + interactor_->SetDesiredUpdateRate(time); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +double cv::viz::Viz3d::VizImpl::getDesiredUpdateRate() +{ + if (interactor_) + return interactor_->GetDesiredUpdateRate(); + return 0.0; +} + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } @@ -492,103 +613,3 @@ cv::String cv::viz::Viz3d::VizImpl::getWindowName() const void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPosition (x, y); } void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); } - -void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose) -{ - WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - if (exists) - { - // Remove it if it exists and add it again - removeActorFromRenderer(wam_itr->second); - } - // Get the actor and set the user matrix - vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget)); - if (actor) - { - // If the actor is 3D, apply pose - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified(); - } - // If the actor is a vtkFollower, then it should always face the camera - vtkFollower *follower = vtkFollower::SafeDownCast(actor); - if (follower) - { - follower->SetCamera(renderer_->GetActiveCamera()); - } - - renderer_->AddActor(WidgetAccessor::getProp(widget)); - (*widget_actor_map_)[id] = WidgetAccessor::getProp(widget); -} - -void cv::viz::Viz3d::VizImpl::removeWidget(const String &id) -{ - WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - CV_Assert(removeActorFromRenderer (wam_itr->second)); - widget_actor_map_->erase(wam_itr); -} - -cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const -{ - WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - - Widget widget; - WidgetAccessor::setProp(widget, wam_itr->second); - return widget; -} - -void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose) -{ - WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); - CV_Assert(actor); - - vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); -} - -void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose) -{ - WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); - CV_Assert(actor); - - vtkSmartPointer matrix = actor->GetUserMatrix(); - if (!matrix) - { - setWidgetPose(id, pose); - return ; - } - Matx44f matrix_cv = convertToMatx(matrix); - Affine3f updated_pose = pose * Affine3f(matrix_cv); - matrix = convertToVtkMatrix(updated_pose.matrix); - - actor->SetUserMatrix (matrix); - actor->Modified (); -} - -cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const -{ - WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); - bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - - vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); - CV_Assert(actor); - - vtkSmartPointer matrix = actor->GetUserMatrix(); - Matx44f matrix_cv = convertToMatx(matrix); - return Affine3f(matrix_cv); -} diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 5dcd4bf85..4d24fb86e 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -26,8 +26,8 @@ public: void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; - void setRenderingProperty(int property, double value, const String &id); - double getRenderingProperty(int property, const String &id); + void setDesiredUpdateRate(double time); + double getDesiredUpdateRate(); /** \brief Returns true when the user tried to close the window */ bool wasStopped () const { if (interactor_ != NULL) return (stopped_); else return true; } From 9086cf5d79ceb3fa10fcc6a8ecf618a0f530b772 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sun, 25 Aug 2013 15:39:39 +0200 Subject: [PATCH 159/205] remove unused includes and libraries from linking --- modules/viz/CMakeLists.txt | 1 - modules/viz/src/precomp.hpp | 79 +--------------------------------- modules/viz/src/viz3d_impl.cpp | 12 +----- modules/viz/src/viz3d_impl.hpp | 4 -- 4 files changed, 3 insertions(+), 93 deletions(-) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 05388d745..5de29bbc6 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -49,4 +49,3 @@ if(BUILD_opencv_viz) target_link_libraries(opencv_viz "-framework Cocoa") endif() endif() - diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 69d20a535..9dafeecc8 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -15,34 +15,19 @@ #include #include -#include -#include -#include -#include -#include #include -#include -#include #include -#include -#include -#include #include -#include #include #include -#include -#include #include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -57,18 +42,12 @@ #include #include #include -#include #include -#include #include #include #include -#include #include -#include -#include #include -#include #include #include #include @@ -76,78 +55,22 @@ #include #include #include -#include -#include -#include #include -#include #include -#include #include -#include -#include -#include -#include #include -#include #include #include -#include -#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include #include - #include -#include -#include -#include -#include -#include -#include -#include -#include #include - - #if defined __GNUC__ && defined __DEPRECATED_DISABLED__ #define __DEPRECATED #undef __DEPRECATED_DISABLED__ diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index f0157331e..d04bb5426 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -582,16 +582,6 @@ void cv::viz::Viz3d::VizImpl::updateCells (vtkSmartPointer &cell } } -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) -{polydata = vtkSmartPointer::New (); } - -void cv::viz::Viz3d::VizImpl::allocVtkPolyData (vtkSmartPointer &polydata) -{ polydata = vtkSmartPointer::New (); } - -void cv::viz::Viz3d::VizImpl::allocVtkUnstructuredGrid (vtkSmartPointer &polydata) -{ polydata = vtkSmartPointer::New (); } - ////////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setFullScreen (bool mode) { @@ -599,6 +589,7 @@ void cv::viz::Viz3d::VizImpl::setFullScreen (bool mode) window_->SetFullScreen (mode); } +////////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) { if (window_) @@ -610,6 +601,7 @@ cv::String cv::viz::Viz3d::VizImpl::getWindowName() const return (window_ ? window_->GetWindowName() : ""); } +////////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPosition (x, y); } void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); } diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 4d24fb86e..61948f912 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -178,10 +178,6 @@ private: * generate */ void updateCells (vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points); - - void allocVtkPolyData (vtkSmartPointer &polydata); - void allocVtkPolyData (vtkSmartPointer &polydata); - void allocVtkUnstructuredGrid (vtkSmartPointer &polydata); }; From 3da7dd9849c41ae19f4bc4b584c0dba34b40df8b Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sun, 25 Aug 2013 15:55:36 +0200 Subject: [PATCH 160/205] fix yellow and magenta color bgr codes --- modules/viz/src/types.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 104fc5a1e..6d3e3d589 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -14,8 +14,8 @@ cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); } cv::viz::Color cv::viz::Color::cyan() { return Color(255, 255, 0); } cv::viz::Color cv::viz::Color::red() { return Color( 0, 0, 255); } -cv::viz::Color cv::viz::Color::magenta() { return Color( 0, 255, 255); } -cv::viz::Color cv::viz::Color::yellow() { return Color(255, 0, 255); } +cv::viz::Color cv::viz::Color::yellow() { return Color( 0, 255, 255); } +cv::viz::Color cv::viz::Color::magenta() { return Color(255, 0, 255); } cv::viz::Color cv::viz::Color::white() { return Color(255, 255, 255); } cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); } From e4b13f2ef0148d1704d1af194c738701652584b5 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Tue, 27 Aug 2013 20:09:54 +0200 Subject: [PATCH 161/205] update reader after setting file name --- modules/viz/src/widget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 485e35ed7..ba21b6785 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -17,6 +17,7 @@ cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) { vtkSmartPointer reader = vtkSmartPointer::New (); reader->SetFileName (file_name.c_str ()); + reader->Update(); vtkSmartPointer data = reader->GetOutput(); CV_Assert(data); From 8007e07ad2ded72132f8a15e71e28519ffd540d1 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 28 Aug 2013 19:13:34 +0200 Subject: [PATCH 162/205] load mesh function is finalized: color range is always 0-255 and RGB due to vtkPLYReader limitations --- modules/viz/src/types.cpp | 19 ++++++------------- modules/viz/src/widget.cpp | 1 - 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 6d3e3d589..64d6f91a1 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -72,11 +72,12 @@ struct cv::viz::Mesh3d::loadMeshImpl vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(file.c_str()); reader->Update(); + vtkSmartPointer poly_data = reader->GetOutput (); + CV_Assert(poly_data); vtkSmartPointer mesh_points = poly_data->GetPoints (); vtkIdType nr_points = mesh_points->GetNumberOfPoints (); - //vtkIdType nr_polygons = poly_data->GetNumberOfPolys (); mesh.cloud.create(1, nr_points, CV_32FC3); @@ -89,18 +90,10 @@ struct cv::viz::Mesh3d::loadMeshImpl } // Then the color information, if any - vtkUnsignedCharArray* poly_colors = NULL; - if (poly_data->GetPointData() != NULL) - poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("Colors")); - - // some applications do not save the name of scalars (including PCL's native vtk_io) - if (!poly_colors && poly_data->GetPointData () != NULL) - poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("scalars")); - - if (!poly_colors && poly_data->GetPointData () != NULL) - poly_colors = vtkUnsignedCharArray::SafeDownCast (poly_data->GetPointData ()->GetScalars ("RGB")); - - // TODO: currently only handles rgb values with 3 components + vtkUnsignedCharArray* poly_colors = 0; + if (poly_data->GetPointData()) + poly_colors = vtkUnsignedCharArray::SafeDownCast(poly_data->GetPointData()->GetScalars()); + if (poly_colors && (poly_colors->GetNumberOfComponents () == 3)) { mesh.colors.create(1, nr_points, CV_8UC3); diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index ba21b6785..485e35ed7 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -17,7 +17,6 @@ cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) { vtkSmartPointer reader = vtkSmartPointer::New (); reader->SetFileName (file_name.c_str ()); - reader->Update(); vtkSmartPointer data = reader->GetOutput(); CV_Assert(data); From 4b443059ec5a5cf33bd2a55be6dd3e137579d743 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Wed, 28 Aug 2013 21:27:30 +0200 Subject: [PATCH 163/205] reverted widget reference count in order to avoid memory leak --- modules/viz/include/opencv2/viz/widgets.hpp | 6 +++ modules/viz/src/widget.cpp | 43 ++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index caaee9e69..01ed3ea8d 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -14,6 +14,9 @@ namespace cv { public: Widget(); + Widget(const Widget& other); + Widget& operator=(const Widget& other); + ~Widget(); static Widget fromPlyFile(const String &file_name); @@ -25,6 +28,9 @@ namespace cv class Impl; Impl *impl_; friend struct WidgetAccessor; + + void create(); + void release(); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 485e35ed7..b3f147978 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -7,11 +7,52 @@ class cv::viz::Widget::Impl { public: vtkSmartPointer prop; + int ref_counter; Impl() : prop(0) {} }; -cv::viz::Widget::Widget() : impl_( new Impl() ) { } +cv::viz::Widget::Widget() : impl_(0) +{ + create(); +} + +cv::viz::Widget::Widget(const Widget& other) : impl_(other.impl_) +{ + if (impl_) CV_XADD(&impl_->ref_counter, 1); +} + +cv::viz::Widget& cv::viz::Widget::operator=(const Widget& other) +{ + if (this != &other) + { + release(); + impl_ = other.impl_; + if (impl_) CV_XADD(&impl_->ref_counter, 1); + } + return *this; +} + +cv::viz::Widget::~Widget() +{ + release(); +} + +void cv::viz::Widget::create() +{ + if (impl_) release(); + impl_ = new Impl(); + impl_->ref_counter = 1; +} + +void cv::viz::Widget::release() +{ + if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) + { + delete impl_; + impl_ = 0; + } +} cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) { From 6c0c21756280eca3181d9ef0a0b9037ad8bd9f9d Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 29 Aug 2013 18:41:12 +0200 Subject: [PATCH 164/205] removed reference counter in widgets, fixed memory leak --- modules/viz/include/opencv2/viz/widgets.hpp | 3 -- modules/viz/src/widget.cpp | 32 ++++----------------- 2 files changed, 6 insertions(+), 29 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 01ed3ea8d..3f631c011 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -28,9 +28,6 @@ namespace cv class Impl; Impl *impl_; friend struct WidgetAccessor; - - void create(); - void release(); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index b3f147978..b0b76c435 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -7,47 +7,27 @@ class cv::viz::Widget::Impl { public: vtkSmartPointer prop; - int ref_counter; Impl() : prop(0) {} }; -cv::viz::Widget::Widget() : impl_(0) -{ - create(); -} +cv::viz::Widget::Widget() : impl_( new Impl() ) { } -cv::viz::Widget::Widget(const Widget& other) : impl_(other.impl_) +cv::viz::Widget::Widget(const Widget& other) : impl_( new Impl() ) { - if (impl_) CV_XADD(&impl_->ref_counter, 1); + if (other.impl_ && other.impl_->prop) impl_->prop = other.impl_->prop; } cv::viz::Widget& cv::viz::Widget::operator=(const Widget& other) { - if (this != &other) - { - release(); - impl_ = other.impl_; - if (impl_) CV_XADD(&impl_->ref_counter, 1); - } + if (!impl_) impl_ = new Impl(); + if (other.impl_) impl_->prop = other.impl_->prop; return *this; } cv::viz::Widget::~Widget() { - release(); -} - -void cv::viz::Widget::create() -{ - if (impl_) release(); - impl_ = new Impl(); - impl_->ref_counter = 1; -} - -void cv::viz::Widget::release() -{ - if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) + if (impl_) { delete impl_; impl_ = 0; From 69f135ec57e02f2c6315063eede1f64a9df079cf Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Thu, 29 Aug 2013 19:06:12 +0200 Subject: [PATCH 165/205] fix memory leak in viz3d --- modules/viz/src/viz3d.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 96483f43a..48f6ea304 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -33,7 +33,9 @@ void cv::viz::Viz3d::create(const String &window_name) void cv::viz::Viz3d::release() { - if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) + // 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) { // Erase the window cv::viz::VizAccessor::getInstance().remove(getWindowName()); From af8a918e04f58afdd28bdc4d94191533943b8653 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 31 Aug 2013 11:30:37 +0200 Subject: [PATCH 166/205] fix minor bug, minor cleaning, cv_assert with messages --- modules/viz/include/opencv2/viz/widgets.hpp | 3 - modules/viz/src/cloud_widgets.cpp | 6 +- modules/viz/src/interactor_style.cpp | 14 +--- modules/viz/src/shape_widgets.cpp | 32 +++------ modules/viz/src/types.cpp | 2 +- modules/viz/src/viz3d_impl.cpp | 72 +++------------------ modules/viz/src/viz3d_impl.hpp | 12 +--- modules/viz/src/widget.cpp | 20 +++--- 8 files changed, 36 insertions(+), 125 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 3f631c011..9f1d14f13 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -61,9 +61,6 @@ namespace cv { public: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); - - void setLineWidth(float line_width); - float getLineWidth(); }; class CV_EXPORTS PlaneWidget : public Widget3D diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index a30c97a32..adf842a0f 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -298,7 +298,7 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget } vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); - CV_Assert(data); + CV_Assert("Cloud Widget without data" && data); vtkSmartPointer appendFilter = vtkSmartPointer::New(); appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); @@ -357,7 +357,7 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, InputArray _col transform_filter->Update(); vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Incompatible widget type." && actor); Vec3d minmax(scalars->GetRange()); CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax); @@ -392,7 +392,7 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, const Color &co transform_filter->Update(); vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Incompatible widget type." && actor); Vec3d minmax(scalars->GetRange()); CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax); diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index db3d97979..06e7af4c2 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -152,17 +152,9 @@ void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const K void cv::viz::InteractorStyle::OnKeyDown () { - if (!init_) - { - std::cout << "Interactor style not initialized. Please call Initialize () before continuing" << std::endl; - return; - } - - if (!renderer_) - { - std::cout << "No renderer given! Use SetRendererCollection () before continuing." << std::endl; - return; - } + + CV_Assert("Interactor style not initialized. Please call Initialize () before continuing" && init_); + CV_Assert("No renderer given! Use SetRendererCollection () before continuing." && renderer_); FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index cb66e80b3..84fdc7728 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -27,20 +27,6 @@ cv::viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Co setColor(color); } -void cv::viz::LineWidget::setLineWidth(float line_width) -{ - vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); - actor->GetProperty()->SetLineWidth(line_width); -} - -float cv::viz::LineWidget::getLineWidth() -{ - vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); - return actor->GetProperty()->GetLineWidth(); -} - template<> cv::viz::LineWidget cv::viz::Widget::cast() { Widget3D widget = this->cast(); @@ -556,12 +542,12 @@ cv::viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position, void cv::viz::Text3DWidget::setText(const String &text) { vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("This widget does not support text." && actor); // Update text source vtkPolyDataMapper *mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); vtkVectorText * textSource = vtkVectorText::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); - CV_Assert(textSource); + CV_Assert("This widget does not support text." && textSource); textSource->SetText(text.c_str()); textSource->Update(); @@ -570,11 +556,11 @@ void cv::viz::Text3DWidget::setText(const String &text) cv::String cv::viz::Text3DWidget::getText() const { vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("This widget does not support text." && actor); vtkPolyDataMapper *mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); vtkVectorText * textSource = vtkVectorText::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); - CV_Assert(textSource); + CV_Assert("This widget does not support text." && textSource); return textSource->GetText(); } @@ -615,14 +601,14 @@ template<> cv::viz::TextWidget cv::viz::Widget::cast() void cv::viz::TextWidget::setText(const String &text) { vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("This widget does not support text." && actor); actor->SetInput(text.c_str()); } cv::String cv::viz::TextWidget::getText() const { vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("This widget does not support text." && actor); return actor->GetInput(); } @@ -671,10 +657,10 @@ void cv::viz::ImageOverlayWidget::setImage(const Mat &image) CV_Assert(!image.empty() && image.depth() == CV_8U); vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("This widget does not support overlay image." && actor); vtkImageMapper *mapper = vtkImageMapper::SafeDownCast(actor->GetMapper()); - CV_Assert(mapper); + CV_Assert("This widget does not support overlay image." && mapper); // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); @@ -821,7 +807,7 @@ void cv::viz::Image3DWidget::setImage(const Mat &image) CV_Assert(!image.empty() && image.depth() == CV_8U); vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("This widget does not support 3D image." && actor); // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 64d6f91a1..e915207e3 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -74,7 +74,7 @@ struct cv::viz::Mesh3d::loadMeshImpl reader->Update(); vtkSmartPointer poly_data = reader->GetOutput (); - CV_Assert(poly_data); + CV_Assert("File does not exist or file format is not supported." && poly_data); vtkSmartPointer mesh_points = poly_data->GetPoints (); vtkIdType nr_points = mesh_points->GetNumberOfPoints (); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index d04bb5426..7a1518c2c 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -34,9 +34,6 @@ cv::viz::Viz3d::VizImpl::VizImpl (const std::string &name) ///////////////////////////////////////////////// interactor_ = vtkSmartPointer ::Take (vtkRenderWindowInteractorFixNew ()); - //win_->PointSmoothingOn (); - //win_->LineSmoothingOn (); - //win_->PolygonSmoothingOn (); window_->AlphaBitPlanesOff (); window_->PointSmoothingOff (); window_->LineSmoothingOff (); @@ -46,7 +43,6 @@ cv::viz::Viz3d::VizImpl::VizImpl (const std::string &name) interactor_->SetRenderWindow (window_); interactor_->SetInteractorStyle (style_); - //interactor_->SetStillUpdateRate (30.0); interactor_->SetDesiredUpdateRate (30.0); // Initialize and create timer, also create window @@ -119,8 +115,8 @@ void cv::viz::Viz3d::VizImpl::removeWidget(const String &id) { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); - CV_Assert(removeActorFromRenderer (wam_itr->second)); + CV_Assert("Widget does not exist." && exists); + CV_Assert("Widget could not be removed." && removeActorFromRenderer (wam_itr->second)); widget_actor_map_->erase(wam_itr); } @@ -129,7 +125,7 @@ cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const { WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); + CV_Assert("Widget does not exist." && exists); Widget widget; WidgetAccessor::setProp(widget, wam_itr->second); @@ -141,10 +137,10 @@ void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &po { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); + CV_Assert("Widget does not exist." && exists); vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); - CV_Assert(actor); + CV_Assert("Widget is not 3D." && actor); vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); actor->SetUserMatrix (matrix); @@ -156,10 +152,10 @@ void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f { WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); + CV_Assert("Widget does not exist." && exists); vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); - CV_Assert(actor); + CV_Assert("Widget is not 3D." && actor); vtkSmartPointer matrix = actor->GetUserMatrix(); if (!matrix) @@ -180,10 +176,10 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const { WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); - CV_Assert(exists); + CV_Assert("Widget does not exist." && exists); vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); - CV_Assert(actor); + CV_Assert("Widget is not 3D." && actor); vtkSmartPointer matrix = actor->GetUserMatrix(); Matx44f matrix_cv = convertToMatx(matrix); @@ -254,56 +250,6 @@ void cv::viz::Viz3d::VizImpl::removeAllWidgets() renderer_->RemoveAllViewProps(); } -////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) -{ - vtkLODActor* actor_to_remove = vtkLODActor::SafeDownCast (actor); - - - - // Iterate over all actors in this renderer - vtkPropCollection* actors = renderer_->GetViewProps (); - actors->InitTraversal (); - - vtkProp* current_actor = NULL; - while ((current_actor = actors->GetNextProp ()) != NULL) - { - if (current_actor != actor_to_remove) - continue; - renderer_->RemoveActor (actor); - // renderer->Render (); - // Found the correct viewport and removed the actor - return (true); - } - - return false; -} - -////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) -{ - vtkActor* actor_to_remove = vtkActor::SafeDownCast (actor); - - // Add it to all renderers - //rens_->InitTraversal (); - - - // Iterate over all actors in this renderer - vtkPropCollection* actors = renderer_->GetViewProps (); - actors->InitTraversal (); - vtkProp* current_actor = NULL; - while ((current_actor = actors->GetNextProp ()) != NULL) - { - if (current_actor != actor_to_remove) - continue; - renderer_->RemoveActor (actor); - // renderer->Render (); - // Found the correct viewport and removed the actor - return (true); - } - return false; -} - ///////////////////////////////////////////////////////////////////////////////////////////// bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 61948f912..b2339c40c 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -119,6 +119,7 @@ private: if (event_id == vtkCommand::ExitEvent) { viz_->stopped_ = true; + viz_->interactor_->GetRenderWindow()->Finalize(); viz_->interactor_->TerminateApp (); } } @@ -142,12 +143,6 @@ private: /** \brief The render window interactor style. */ vtkSmartPointer style_; - - /** \brief Internal list with actor pointers and name IDs for point clouds. */ -// cv::Ptr cloud_actor_map_; - - /** \brief Internal list with actor pointers and name IDs for shapes. */ -// cv::Ptr shape_actor_map_; /** \brief Internal list with actor pointers and name IDs for all widget actors */ cv::Ptr widget_actor_map_; @@ -155,13 +150,8 @@ private: /** \brief Boolean that holds whether or not the camera parameters were manually initialized*/ bool camera_set_; - bool removeActorFromRenderer (const vtkSmartPointer &actor); - bool removeActorFromRenderer (const vtkSmartPointer &actor); bool removeActorFromRenderer (const vtkSmartPointer &actor); - //void addActorToRenderer (const vtkSmartPointer &actor); - - /** \brief Internal method. Creates a vtk actor from a vtk polydata object. * \param[in] data the vtk polydata object to create an actor for * \param[out] actor the resultant vtk actor object diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index b0b76c435..196ec9939 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -40,7 +40,7 @@ cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) reader->SetFileName (file_name.c_str ()); vtkSmartPointer data = reader->GetOutput(); - CV_Assert(data); + CV_Assert("File does not exist or file format is not supported." && data); vtkSmartPointer actor = vtkSmartPointer::New(); @@ -77,7 +77,7 @@ cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) void cv::viz::Widget::setRenderingProperty(int property, double value) { vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget type is not supported." && actor); switch (property) { @@ -118,7 +118,7 @@ void cv::viz::Widget::setRenderingProperty(int property, double value) double cv::viz::Widget::getRenderingProperty(int property) const { vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget type is not supported." && actor); double value = 0.0; switch (property) @@ -239,7 +239,7 @@ struct cv::viz::Widget3D::MatrixConverter void cv::viz::Widget3D::setPose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget is not 3D." && actor); vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); actor->SetUserMatrix (matrix); @@ -249,7 +249,7 @@ void cv::viz::Widget3D::setPose(const Affine3f &pose) void cv::viz::Widget3D::updatePose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget is not 3D." && actor); vtkSmartPointer matrix = actor->GetUserMatrix(); if (!matrix) @@ -269,7 +269,7 @@ void cv::viz::Widget3D::updatePose(const Affine3f &pose) cv::Affine3f cv::viz::Widget3D::getPose() const { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget is not 3D." && actor); vtkSmartPointer matrix = actor->GetUserMatrix(); Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix); @@ -280,7 +280,7 @@ void cv::viz::Widget3D::setColor(const Color &color) { // Cast to actor instead of prop3d since prop3d doesn't provide getproperty vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget type is not supported." && actor); Color c = vtkcolor(color); actor->GetMapper ()->ScalarVisibilityOff (); @@ -292,7 +292,7 @@ void cv::viz::Widget3D::setColor(const Color &color) template<> cv::viz::Widget3D cv::viz::Widget::cast() { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget cannot be cast." && actor); Widget3D widget; WidgetAccessor::setProp(widget, actor); @@ -305,7 +305,7 @@ template<> cv::viz::Widget3D cv::viz::Widget::cast() void cv::viz::Widget2D::setColor(const Color &color) { vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget type is not supported." && actor); Color c = vtkcolor(color); actor->GetProperty ()->SetColor (c.val); actor->Modified (); @@ -314,7 +314,7 @@ void cv::viz::Widget2D::setColor(const Color &color) template<> cv::viz::Widget2D cv::viz::Widget::cast() { vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert(actor); + CV_Assert("Widget cannot be cast." && actor); Widget2D widget; WidgetAccessor::setProp(widget, actor); From 4aa61dee5046b185cbbe1a43093c4e4f2e0c7ddd Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 31 Aug 2013 11:54:49 +0200 Subject: [PATCH 167/205] minor refactoring interactor_style --- modules/viz/src/interactor_style.cpp | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 06e7af4c2..ace60c860 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -1,9 +1,6 @@ #include "precomp.hpp" - #include "interactor_style.h" -//#include - using namespace cv; ////////////////////////////////////////////////////////////////////////////////////////////// @@ -227,7 +224,7 @@ cv::viz::InteractorStyle::OnKeyDown () { for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) { - vtkSmartPointer apart = reinterpret_cast (path->GetLastNode ()->GetViewProp ()); + vtkActor* apart = reinterpret_cast (path->GetLastNode ()->GetViewProp ()); apart->GetProperty ()->SetRepresentationToPoints (); } } @@ -250,15 +247,12 @@ cv::viz::InteractorStyle::OnKeyDown () cam->GetFocalPoint (focal); cam->GetPosition (pos); cam->GetViewUp (view); -#ifndef M_PI - # define M_PI 3.14159265358979323846 // pi -#endif int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); int *win_size = Interactor->GetRenderWindow ()->GetSize (); ofs_cam << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << - cam->GetViewAngle () / 180.0 * M_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] + cam->GetViewAngle () / 180.0 * CV_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] << endl; ofs_cam.close (); @@ -302,7 +296,7 @@ cv::viz::InteractorStyle::OnKeyDown () { for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) { - vtkSmartPointer apart = reinterpret_cast (path->GetLastNode ()->GetViewProp ()); + vtkActor* apart = reinterpret_cast (path->GetLastNode ()->GetViewProp ()); float psize = apart->GetProperty ()->GetPointSize (); if (psize < 63.0f) apart->GetProperty ()->SetPointSize (psize + 1.0f); @@ -323,7 +317,7 @@ cv::viz::InteractorStyle::OnKeyDown () { for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) { - vtkSmartPointer apart = static_cast (path->GetLastNode ()->GetViewProp ()); + vtkActor* apart = static_cast (path->GetLastNode ()->GetViewProp ()); float psize = apart->GetProperty ()->GetPointSize (); if (psize > 1.0f) apart->GetProperty ()->SetPointSize (psize - 1.0f); @@ -651,17 +645,8 @@ void cv::viz::InteractorStyle::OnMouseWheelBackward () ////////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::InteractorStyle::OnTimer () { - if (!init_) - { - std::cout << "[PCLVisualizerInteractorStyle] Interactor style not initialized. Please call Initialize () before continuing.\n" << std::endl; - return; - } - - if (!renderer_) - { - std::cout << "[PCLVisualizerInteractorStyle] No renderer collection given! Use SetRendererCollection () before continuing." << std::endl; - return; - } + CV_Assert("Interactor style not initialized." && init_); + CV_Assert("Renderer has not been set." && renderer_); renderer_->Render (); Interactor->Render (); } From ffbb5e9524816450eb429fb10ab082aa3913f0fc Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 31 Aug 2013 12:16:47 +0200 Subject: [PATCH 168/205] resetCamera, resetViewpoint in Viz3d --- modules/viz/include/opencv2/viz/viz3d.hpp | 3 +++ modules/viz/src/viz3d.cpp | 3 +++ modules/viz/src/viz3d_impl.cpp | 12 +++++++++--- modules/viz/src/viz3d_impl.hpp | 8 ++------ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index a80fd3748..a54493611 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -38,6 +38,9 @@ namespace cv Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); + void resetCameraViewpoint (const String &id); + void resetCamera(); + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 48f6ea304..61911ca42 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -67,6 +67,9 @@ cv::viz::Camera cv::viz::Viz3d::getCamera() const { return impl_->getCamera(); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } +void cv::viz::Viz3d::resetCameraViewpoint (const String &id) { impl_->resetCameraViewpoint(id); } +void cv::viz::Viz3d::resetCamera() { impl_->resetCamera(); } + void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 7a1518c2c..00a5cae78 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -421,21 +421,21 @@ void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) +void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const String &id) { vtkSmartPointer camera_pose; static WidgetActorMap::iterator it = widget_actor_map_->find (id); if (it != widget_actor_map_->end ()) { vtkProp3D *actor = vtkProp3D::SafeDownCast(it->second); + CV_Assert("Widget is not 3D." && actor); camera_pose = actor->GetUserMatrix(); } else return; // Prevent a segfault - if (!camera_pose) - return; + if (!camera_pose) return; vtkSmartPointer cam = renderer_->GetActiveCamera (); cam->SetPosition (camera_pose->GetElement (0, 3), @@ -455,6 +455,12 @@ void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const std::string &id) renderer_->Render (); } +/////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::resetCamera() +{ + renderer_->ResetCamera(); +} + /////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setRepresentationToSurface() { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index b2339c40c..0eab85bc5 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -49,18 +49,14 @@ public: void setRepresentationToSurface(); void setRepresentationToPoints(); void setRepresentationToWireframe(); - - - // //////////////////////////////////////////////////////////////////////////////////// - // All camera methods to refactor into set/getViewwerPose, setCamera() - // and 'Camera' class itself with various constructors/fields void setCamera(const Camera &camera); Camera getCamera() const; /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset. * \param[in] id the point cloud object id (default: cloud) */ - void resetCameraViewpoint (const String& id = "cloud"); + void resetCameraViewpoint(const String& id); + void resetCamera(); void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); From 2705113bc4c82c17c984da77e2d2921747ae3489 Mon Sep 17 00:00:00 2001 From: ozantonkal Date: Sat, 31 Aug 2013 12:39:41 +0200 Subject: [PATCH 169/205] remove common.cpp, remove commented code in common.h --- modules/viz/src/common.cpp | 265 ------------------------------------- modules/viz/src/common.h | 14 -- 2 files changed, 279 deletions(-) delete mode 100644 modules/viz/src/common.cpp diff --git a/modules/viz/src/common.cpp b/modules/viz/src/common.cpp deleted file mode 100644 index 3c40a00f5..000000000 --- a/modules/viz/src/common.cpp +++ /dev/null @@ -1,265 +0,0 @@ -#include -#include -#include -#include "viz3d_impl.hpp" - - -/////////////////////////////////////////////////////////////////////////////////////////////// -//Eigen::Vector2i cv::viz::worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height) -//{ -// // Transform world to clipping coordinates -// Eigen::Vector4d world (view_projection_matrix * world_pt); -// // Normalize w-component -// world /= world.w (); - -// // X/Y screen space coordinate -// int screen_x = int (floor (double (((world.x () + 1) / 2.0) * width) + 0.5)); -// int screen_y = int (floor (double (((world.y () + 1) / 2.0) * height) + 0.5)); - -// // Calculate -world_pt.y () because the screen Y axis is oriented top->down, ie 0 is top-left -// //int winY = (int) floor ( (double) (((1 - world_pt.y ()) / 2.0) * height) + 0.5); // top left - -// return (Eigen::Vector2i (screen_x, screen_y)); -//} - -///////////////////////////////////////////////////////////////////////////////////////////// -//void cv::viz::getViewFrustum (const Eigen::Matrix4d &view_projection_matrix, double planes[24]) -//{ -// // Set up the normals -// Eigen::Vector4d normals[6]; -// for (int i=0; i < 6; i++) -// { -// normals[i] = Eigen::Vector4d (0.0, 0.0, 0.0, 1.0); - -// // if i is even set to -1, if odd set to +1 -// normals[i] (i/2) = 1 - (i%2)*2; -// } - -// // Transpose the matrix for use with normals -// Eigen::Matrix4d view_matrix = view_projection_matrix.transpose (); - -// // Transform the normals to world coordinates -// for (int i=0; i < 6; i++) -// { -// normals[i] = view_matrix * normals[i]; - -// double f = 1.0/sqrt (normals[i].x () * normals[i].x () + -// normals[i].y () * normals[i].y () + -// normals[i].z () * normals[i].z ()); - -// planes[4*i + 0] = normals[i].x ()*f; -// planes[4*i + 1] = normals[i].y ()*f; -// planes[4*i + 2] = normals[i].z ()*f; -// planes[4*i + 3] = normals[i].w ()*f; -// } -//} - -//int cv::viz::cullFrustum (double frustum[24], const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb) -//{ -// int result = PCL_INSIDE_FRUSTUM; - -// for(int i =0; i < 6; i++){ -// double a = frustum[(i*4)]; -// double b = frustum[(i*4)+1]; -// double c = frustum[(i*4)+2]; -// double d = frustum[(i*4)+3]; - -// //cout << i << ": " << a << "x + " << b << "y + " << c << "z + " << d << endl; - -// // Basic VFC algorithm -// Eigen::Vector3d center ((max_bb.x () - min_bb.x ()) / 2 + min_bb.x (), -// (max_bb.y () - min_bb.y ()) / 2 + min_bb.y (), -// (max_bb.z () - min_bb.z ()) / 2 + min_bb.z ()); - -// Eigen::Vector3d radius (fabs (static_cast (max_bb.x () - center.x ())), -// fabs (static_cast (max_bb.y () - center.y ())), -// fabs (static_cast (max_bb.z () - center.z ()))); - -// double m = (center.x () * a) + (center.y () * b) + (center.z () * c) + d; -// double n = (radius.x () * fabs(a)) + (radius.y () * fabs(b)) + (radius.z () * fabs(c)); - -// if (m + n < 0){ -// result = PCL_OUTSIDE_FRUSTUM; -// break; -// } - -// if (m - n < 0) -// { -// result = PCL_INTERSECT_FRUSTUM; -// } -// } - -// return result; -//} - -//void -//cv::viz::getModelViewPosition (Eigen::Matrix4d model_view_matrix, Eigen::Vector3d &position) -//{ -// //Compute eye or position from model view matrix -// Eigen::Matrix4d inverse_model_view_matrix = model_view_matrix.inverse(); -// for (int i=0; i < 3; i++) -// { -// position(i) = inverse_model_view_matrix(i, 3); -// } -//} - -// Lookup table of max 6 bounding box vertices, followed by number of vertices, ie {v0, v1, v2, v3, v4, v5, nv} -// -// 3--------2 -// /| /| Y 0 = xmin, ymin, zmin -// / | / | | 6 = xmax, ymax. zmax -// 7--------6 | | -// | | | | | -// | 0-----|--1 +------X -// | / | / / -// |/ |/ / -// 4--------5 Z - -int hull_vertex_table[43][7] = { - { 0, 0, 0, 0, 0, 0, 0 }, // inside - { 0, 4, 7, 3, 0, 0, 4 }, // left - { 1, 2, 6, 5, 0, 0, 4 }, // right - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 1, 5, 4, 0, 0, 4 }, // bottom - { 0, 1, 5, 4, 7, 3, 6 }, // bottom, left - { 0, 1, 2, 6, 5, 4, 6 }, // bottom, right - { 0, 0, 0, 0, 0, 0, 0 }, - { 2, 3, 7, 6, 0, 0, 4 }, // top - { 4, 7, 6, 2, 3, 0, 6 }, // top, left - { 2, 3, 7, 6, 5, 1, 6 }, // top, right - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 3, 2, 1, 0, 0, 4 }, // front - { 0, 4, 7, 3, 2, 1, 6 }, // front, left - { 0, 3, 2, 6, 5, 1, 6 }, // front, right - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 3, 2, 1, 5, 4, 6 }, // front, bottom - { 2, 1, 5, 4, 7, 3, 6 }, // front, bottom, left - { 0, 3, 2, 6, 5, 4, 6 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 3, 7, 6, 2, 1, 6 }, // front, top - { 0, 4, 7, 6, 2, 1, 6 }, // front, top, left - { 0, 3, 7, 6, 5, 1, 6 }, // front, top, right - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 4, 5, 6, 7, 0, 0, 4 }, // back - { 4, 5, 6, 7, 3, 0, 6 }, // back, left - { 1, 2, 6, 7, 4, 5, 6 }, // back, right - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 1, 5, 6, 7, 4, 6 }, // back, bottom - { 0, 1, 5, 6, 7, 3, 6 }, // back, bottom, left - { 0, 1, 2, 6, 7, 4, 6 }, // back, bottom, right - { 0, 0, 0, 0, 0, 0, 0 }, - { 2, 3, 7, 4, 5, 6, 6 }, // back, top - { 0, 4, 5, 6, 2, 3, 6 }, // back, top, left - { 1, 2, 3, 7, 4, 5, 6 } // back, top, right -}; - -///////////////////////////////////////////////////////////////////////////////////////////// -//float -//cv::viz::viewScreenArea ( -// const Eigen::Vector3d &eye, -// const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, -// const Eigen::Matrix4d &view_projection_matrix, int width, int height) -//{ -// Eigen::Vector4d bounding_box[8]; -// bounding_box[0] = Eigen::Vector4d(min_bb.x (), min_bb.y (), min_bb.z (), 1.0); -// bounding_box[1] = Eigen::Vector4d(max_bb.x (), min_bb.y (), min_bb.z (), 1.0); -// bounding_box[2] = Eigen::Vector4d(max_bb.x (), max_bb.y (), min_bb.z (), 1.0); -// bounding_box[3] = Eigen::Vector4d(min_bb.x (), max_bb.y (), min_bb.z (), 1.0); -// bounding_box[4] = Eigen::Vector4d(min_bb.x (), min_bb.y (), max_bb.z (), 1.0); -// bounding_box[5] = Eigen::Vector4d(max_bb.x (), min_bb.y (), max_bb.z (), 1.0); -// bounding_box[6] = Eigen::Vector4d(max_bb.x (), max_bb.y (), max_bb.z (), 1.0); -// bounding_box[7] = Eigen::Vector4d(min_bb.x (), max_bb.y (), max_bb.z (), 1.0); - -// // Compute 6-bit code to classify eye with respect to the 6 defining planes -// int pos = ((eye.x () < bounding_box[0].x ()) ) // 1 = left -// + ((eye.x () > bounding_box[6].x ()) << 1) // 2 = right -// + ((eye.y () < bounding_box[0].y ()) << 2) // 4 = bottom -// + ((eye.y () > bounding_box[6].y ()) << 3) // 8 = top -// + ((eye.z () < bounding_box[0].z ()) << 4) // 16 = front -// + ((eye.z () > bounding_box[6].z ()) << 5); // 32 = back - -// // Look up number of vertices -// int num = hull_vertex_table[pos][6]; -// if (num == 0) -// { -// return (float (width * height)); -// } -// //return 0.0; - - -// // cout << "eye: " << eye.x() << " " << eye.y() << " " << eye.z() << endl; -// // cout << "min: " << bounding_box[0].x() << " " << bounding_box[0].y() << " " << bounding_box[0].z() << endl; -// // -// // cout << "pos: " << pos << " "; -// // switch(pos){ -// // case 0: cout << "inside" << endl; break; -// // case 1: cout << "left" << endl; break; -// // case 2: cout << "right" << endl; break; -// // case 3: -// // case 4: cout << "bottom" << endl; break; -// // case 5: cout << "bottom, left" << endl; break; -// // case 6: cout << "bottom, right" << endl; break; -// // case 7: -// // case 8: cout << "top" << endl; break; -// // case 9: cout << "top, left" << endl; break; -// // case 10: cout << "top, right" << endl; break; -// // case 11: -// // case 12: -// // case 13: -// // case 14: -// // case 15: -// // case 16: cout << "front" << endl; break; -// // case 17: cout << "front, left" << endl; break; -// // case 18: cout << "front, right" << endl; break; -// // case 19: -// // case 20: cout << "front, bottom" << endl; break; -// // case 21: cout << "front, bottom, left" << endl; break; -// // case 22: -// // case 23: -// // case 24: cout << "front, top" << endl; break; -// // case 25: cout << "front, top, left" << endl; break; -// // case 26: cout << "front, top, right" << endl; break; -// // case 27: -// // case 28: -// // case 29: -// // case 30: -// // case 31: -// // case 32: cout << "back" << endl; break; -// // case 33: cout << "back, left" << endl; break; -// // case 34: cout << "back, right" << endl; break; -// // case 35: -// // case 36: cout << "back, bottom" << endl; break; -// // case 37: cout << "back, bottom, left" << endl; break; -// // case 38: cout << "back, bottom, right" << endl; break; -// // case 39: -// // case 40: cout << "back, top" << endl; break; -// // case 41: cout << "back, top, left" << endl; break; -// // case 42: cout << "back, top, right" << endl; break; -// // } - -// //return -1 if inside -// Eigen::Vector2d dst[8]; -// for (int i = 0; i < num; i++) -// { -// Eigen::Vector4d world_pt = bounding_box[hull_vertex_table[pos][i]]; -// Eigen::Vector2i screen_pt = cv::viz::worldToView(world_pt, view_projection_matrix, width, height); -// // cout << "point[" << i << "]: " << screen_pt.x() << " " << screen_pt.y() << endl; -// dst[i] = Eigen::Vector2d(screen_pt.x (), screen_pt.y ()); -// } - -// double sum = 0.0; -// for (int i = 0; i < num; ++i) -// { -// sum += (dst[i].x () - dst[(i+1) % num].x ()) * (dst[i].y () + dst[(i+1) % num].y ()); -// } - -// return (fabsf (float (sum * 0.5f))); -//} diff --git a/modules/viz/src/common.h b/modules/viz/src/common.h index ea8933417..7e13b0fee 100644 --- a/modules/viz/src/common.h +++ b/modules/viz/src/common.h @@ -8,20 +8,6 @@ namespace cv { namespace viz { - //CV_EXPORTS Eigen::Matrix4d vtkToEigen (vtkMatrix4x4* vtk_matrix); - //CV_EXPORTS Eigen::Vector2i worldToView (const Eigen::Vector4d &world_pt, const Eigen::Matrix4d &view_projection_matrix, int width, int height); - //CV_EXPORTS void getViewFrustum (const Eigen::Matrix4d &view_projection_matrix, double planes[24]); - - // enum FrustumCull - // { - // PCL_INSIDE_FRUSTUM, - // PCL_INTERSECT_FRUSTUM, - // PCL_OUTSIDE_FRUSTUM - // }; - - //CV_EXPORTS int cullFrustum (double planes[24], const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb); - //CV_EXPORTS float viewScreenArea (const Eigen::Vector3d &eye, const Eigen::Vector3d &min_bb, const Eigen::Vector3d &max_bb, const Eigen::Matrix4d &view_projection_matrix, int width, int height); - enum RenderingProperties { VIZ_POINT_SIZE, From 21be9796ae3a0705124c9dc4971f6351eb839fcc Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 1 Sep 2013 12:29:01 +0200 Subject: [PATCH 170/205] comments on widgets where constructors might be confusing --- modules/viz/include/opencv2/viz.hpp | 9 +++++--- modules/viz/include/opencv2/viz/types.hpp | 11 +++------- modules/viz/include/opencv2/viz/widgets.hpp | 23 ++++++++++++++++++--- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 0a82a9ebb..7f7cc7d2f 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -65,9 +65,10 @@ namespace cv //! takes coordiante frame data and builds transfrom to global coordinate frame CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); - //! constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation + //! 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 CV_EXPORTS Viz3d get(const String &window_name); //! checks float value for Nan @@ -92,6 +93,7 @@ namespace cv template 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: @@ -102,6 +104,7 @@ namespace cv void add(Viz3d window); void remove(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: @@ -112,8 +115,8 @@ namespace cv static bool is_instantiated_; static VizMap viz_map_; }; - } -} + } /* namespace viz */ +} /* namespace cv */ #endif /* __OPENCV_VIZ_HPP__ */ diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index f41b5fa0f..26aa20440 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -39,6 +39,7 @@ namespace cv Mat cloud, colors; Mat polygons; + //! Loads mesh from a given ply file static cv::viz::Mesh3d loadMesh(const String& file); private: @@ -52,14 +53,8 @@ namespace cv static const unsigned int Ctrl = 2; static const unsigned int Shift = 4; - /** \brief Constructor - * \param[in] action true for key was pressed, false for released - * \param[in] key_sym the key-name that caused the action - * \param[in] key the key code that caused the action - * \param[in] alt whether the alt key was pressed at the time where this event was triggered - * \param[in] ctrl whether the ctrl was pressed at the time where this event was triggered - * \param[in] shift whether the shift was pressed at the time where this event was triggered - */ + //! Create a keyboard event + //! - Note that action is true if key is pressed, false if released KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); bool isAltPressed () const; diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 9f1d14f13..fb2d6ca34 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -18,11 +18,14 @@ namespace cv Widget& operator=(const Widget& other); ~Widget(); + //! Create a widget directly from ply file static Widget fromPlyFile(const String &file_name); + //! Rendering properties of this particular widget void setRenderingProperty(int property, double value); double getRenderingProperty(int property) const; + //! Casting between widgets template _W cast(); private: class Impl; @@ -120,7 +123,9 @@ namespace cv class CV_EXPORTS GridWidget : public Widget3D { public: + //! Creates grid at the origin GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + //! Creates grid based on the plane equation GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); private: @@ -157,7 +162,9 @@ namespace cv class CV_EXPORTS Image3DWidget : public Widget3D { public: + //! Creates 3D image at the origin Image3DWidget(const Mat &image, const Size &size); + //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); void setImage(const Mat &image); @@ -166,11 +173,14 @@ namespace cv class CV_EXPORTS CameraPositionWidget : public Widget3D { public: + //! Creates camera coordinate frame (axes) at the origin CameraPositionWidget(double scale = 1.0); + //! Creates frustum based on the intrinsic marix K at the origin CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum based on the field of view at the origin CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); - }; class CV_EXPORTS TrajectoryWidget : public Widget3D @@ -178,9 +188,12 @@ namespace cv public: enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; + //! Displays trajectory of the given path either by coordinate frames or polyline TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); - TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); // Camera frustums - TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); // Camera frustums + //! Displays trajectory of the given path by frustums + TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + //! Displays trajectory of the given path by frustums + TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); private: struct ApplyPath; @@ -196,7 +209,9 @@ namespace cv class CV_EXPORTS CloudWidget : public Widget3D { public: + //! Each point in cloud is mapped to a color in colors CloudWidget(InputArray cloud, InputArray colors); + //! All points in cloud have the same color CloudWidget(InputArray cloud, const Color &color = Color::white()); private: @@ -208,7 +223,9 @@ namespace cv public: CloudCollectionWidget(); + //! Each point in cloud is mapped to a color in colors void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); + //! All points in cloud have the same color void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity()); private: From 9d4fe6984b694596003e809d84808a7c646f1d6c Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 1 Sep 2013 14:59:14 +0200 Subject: [PATCH 171/205] remove setWindowName method to avoid complications --- modules/viz/include/opencv2/viz/viz3d.hpp | 1 - modules/viz/src/viz3d.cpp | 1 - modules/viz/src/viz3d_impl.cpp | 6 ------ modules/viz/src/viz3d_impl.hpp | 1 - 4 files changed, 9 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index a54493611..988f7ed5f 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -50,7 +50,6 @@ namespace cv void saveScreenshot (const String &file); void setWindowPosition (int x, int y); void setFullScreen (bool mode); - void setWindowName (const String &name); void setBackgroundColor(const Color& color = Color::black()); void spin(); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 61911ca42..1b45f3a56 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -79,7 +79,6 @@ cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName() void cv::viz::Viz3d::saveScreenshot (const String &file) { impl_->saveScreenshot(file); } void cv::viz::Viz3d::setWindowPosition (int x, int y) { impl_->setWindowPosition(x,y); } void cv::viz::Viz3d::setFullScreen (bool mode) { impl_->setFullScreen(mode); } -void cv::viz::Viz3d::setWindowName (const String &name) { impl_->setWindowName(name); } void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } void cv::viz::Viz3d::setRenderingProperty(int property, double value, const String &id) { getWidget(id).setRenderingProperty(property, value); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 00a5cae78..f99fd8e1f 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -542,12 +542,6 @@ void cv::viz::Viz3d::VizImpl::setFullScreen (bool mode) } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) -{ - if (window_) - window_->SetWindowName (name.c_str ()); -} - cv::String cv::viz::Viz3d::VizImpl::getWindowName() const { return (window_ ? window_->GetWindowName() : ""); diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 0eab85bc5..7e31501ed 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -69,7 +69,6 @@ public: Size getWindowSize() const; void setWindowSize (int xw, int yw); void setFullScreen (bool mode); - void setWindowName (const String &name); String getWindowName() const; void setBackgroundColor (const Color& color); From 2822845ba6ba8c3637b30e86fa345f6de5178f24 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 1 Sep 2013 15:46:46 +0200 Subject: [PATCH 172/205] set get RenderingProperty id comes first --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 ++-- modules/viz/src/viz3d.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 988f7ed5f..4c6015d7d 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -59,8 +59,8 @@ namespace cv void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); void registerMouseCallback(MouseCallback callback, void* cookie = 0); - void setRenderingProperty(int property, double value, const String &id); - double getRenderingProperty(int property, const String &id); + void setRenderingProperty(const String &id, int property, double value); + double getRenderingProperty(const String &id, int property); void setDesiredUpdateRate(double time); double getDesiredUpdateRate(); diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 1b45f3a56..068d9b1b7 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -81,8 +81,8 @@ void cv::viz::Viz3d::setWindowPosition (int x, int y) { impl_->setWindowPosition void cv::viz::Viz3d::setFullScreen (bool mode) { impl_->setFullScreen(mode); } void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } -void cv::viz::Viz3d::setRenderingProperty(int property, double value, const String &id) { getWidget(id).setRenderingProperty(property, value); } -double cv::viz::Viz3d::getRenderingProperty(int property, const String &id) { return getWidget(id).getRenderingProperty(property); } +void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double value) { getWidget(id).setRenderingProperty(property, value); } +double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { return getWidget(id).getRenderingProperty(property); } void cv::viz::Viz3d::setDesiredUpdateRate(double time) { impl_->setDesiredUpdateRate(time); } double cv::viz::Viz3d::getDesiredUpdateRate() { return impl_->getDesiredUpdateRate(); } From a5b75769a3150d723026c40fe41e588c7f6e144c Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 1 Sep 2013 19:34:17 +0200 Subject: [PATCH 173/205] initial documentation --- modules/viz/doc/viz.rst | 11 + modules/viz/doc/viz3d.rst | 556 +++++++++++++++++++++++++ modules/viz/doc/widget.rst | 811 +++++++++++++++++++++++++++++++++++++ 3 files changed, 1378 insertions(+) create mode 100644 modules/viz/doc/viz.rst create mode 100644 modules/viz/doc/viz3d.rst create mode 100644 modules/viz/doc/widget.rst diff --git a/modules/viz/doc/viz.rst b/modules/viz/doc/viz.rst new file mode 100644 index 000000000..f51a151e0 --- /dev/null +++ b/modules/viz/doc/viz.rst @@ -0,0 +1,11 @@ +*********************** +viz. 3D Visualizer +*********************** + +.. toctree:: + :maxdepth: 2 + + viz3d.rst + widget.rst + types.rst + widget_accessor.rst diff --git a/modules/viz/doc/viz3d.rst b/modules/viz/doc/viz3d.rst new file mode 100644 index 000000000..e7dcc358c --- /dev/null +++ b/modules/viz/doc/viz3d.rst @@ -0,0 +1,556 @@ +Viz3d +===== + +.. highlight:: cpp + +Viz3d +----- +.. ocv:class:: Viz3d + +The Viz3d class represents a 3D visualizer window. This class is implicitly shared. :: + + class CV_EXPORTS Viz3d + { + public: + typedef cv::Ptr Ptr; + typedef void (*KeyboardCallback)(const KeyboardEvent&, void*); + typedef void (*MouseCallback)(const MouseEvent&, void*); + + Viz3d(const String& window_name = String()); + Viz3d(const Viz3d&); + Viz3d& operator=(const Viz3d&); + ~Viz3d(); + + void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; + void removeAllWidgets(); + + void setWidgetPose(const String &id, const Affine3f &pose); + void updateWidgetPose(const String &id, const Affine3f &pose); + Affine3f getWidgetPose(const String &id) const; + + void setCamera(const Camera &camera); + Camera getCamera() const; + Affine3f getViewerPose(); + void setViewerPose(const Affine3f &pose); + + void resetCameraViewpoint (const String &id); + void resetCamera(); + + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); + + Size getWindowSize() const; + void setWindowSize(const Size &window_size); + String getWindowName() const; + void saveScreenshot (const String &file); + void setWindowPosition (int x, int y); + void setFullScreen (bool mode); + void setBackgroundColor(const Color& color = Color::black()); + + void spin(); + void spinOnce(int time = 1, bool force_redraw = false); + bool wasStopped() const; + + void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); + void registerMouseCallback(MouseCallback callback, void* cookie = 0); + + void setRenderingProperty(const String &id, int property, double value); + double getRenderingProperty(const String &id, int property); + + void setDesiredUpdateRate(double rate); + double getDesiredUpdateRate(); + + void setRepresentationToSurface(); + void setRepresentationToWireframe(); + void setRepresentationToPoints(); + private: + /* hidden */ + }; + +Viz3d::Viz3d +------------ +The constructors. + +.. ocv:function:: Viz3d::Viz3d(const String& window_name = String()) + + :param window_name: Name of the window. + +Viz3d::showWidget +----------------- +Shows a widget in the window. + +.. ocv:function:: void Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()) + + :param id: A unique id for the widget. + :param widget: The widget to be rendered in the window. + :param pose: Pose of the widget. + +Viz3d::removeWidget +------------------- +Removes a widget from the window. + +.. ocv:function:: void removeWidget(const String &id) + + :param id: The id of the widget that will be removed. + +Viz3d::getWidget +---------------- +Retrieves a widget from the window. A widget is implicitly shared; +that is, if the returned widget is modified, the changes will be +immediately visible in the window. + +.. ocv:function:: Widget getWidget(const String &id) const + + :param id: The id of the widget that will be returned. + +Viz3d::removeAllWidgets +----------------------- +Removes all widgets from the window. + +.. ocv:function:: void removeAllWidgets() + +Viz3d::setWidgetPose +-------------------- +Sets pose of a widget in the window. + +.. ocv:function:: void setWidgetPose(const String &id, const Affine3f &pose) + + :param id: The id of the widget whose pose will be set. + :param pose: The new pose of the widget. + +Viz3d::updateWidgetPose +----------------------- +Updates pose of a widget in the window by pre-multiplying its current pose. + +.. ocv:function:: void updateWidgetPose(const String &id, const Affine3f &pose) + + :param id: The id of the widget whose pose will be updated. + :param pose: The pose that the current pose of the widget will be pre-multiplied by. + +Viz3d::getWidgetPose +-------------------- +Returns the current pose of a widget in the window. + +.. ocv:function:: Affine3f getWidgetPose(const String &id) const + + :param id: The id of the widget whose pose will be returned. + +Viz3d::setCamera +---------------- +Sets the intrinsic parameters of the viewer using Camera. + +.. ocv:function:: void setCamera(const Camera &camera) + + :param camera: Camera object wrapping intrinsinc parameters. + +Viz3d::getCamera +---------------- +Returns a camera object that contains intrinsic parameters of the current viewer. + +.. ocv:function:: Camera getCamera() const + +Viz3d::getViewerPose +-------------------- +Returns the current pose of the viewer. + +..ocv:function:: Affine3f getViewerPose() + +Viz3d::setViewerPose +-------------------- +Sets pose of the viewer. + +.. ocv:function:: void setViewerPose(const Affine3f &pose) + + :param pose: The new pose of the viewer. + +Viz3d::resetCameraViewpoint +--------------------------- +Resets camera viewpoint to a 3D widget in the scene. + +.. ocv:function:: void resetCameraViewpoint (const String &id) + + :param pose: Id of a 3D widget. + +Viz3d::resetCamera +------------------ +Resets camera. + +.. ocv:function:: void resetCamera() + +Viz3d::convertToWindowCoordinates +--------------------------------- +Transforms a point in world coordinate system to window coordinate system. + +.. ocv:function:: void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) + + :param pt: Point in world coordinate system. + :param window_coord: Output point in window coordinate system. + +Viz3d::converTo3DRay +-------------------- +Transforms a point in window coordinate system to a 3D ray in world coordinate system. + +.. ocv:function:: void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) + + :param window_coord: Point in window coordinate system. + :param origin: Output origin of the ray. + :param direction: Output direction of the ray. + +Viz3d::getWindowSize +-------------------- +Returns the current size of the window. + +.. ocv:function:: Size getWindowSize() const + +Viz3d::setWindowSize +-------------------- +Sets the size of the window. + +.. ocv:function:: void setWindowSize(const Size &window_size) + + :param window_size: New size of the window. + +Viz3d::getWindowName +-------------------- +Returns the name of the window which has been set in the constructor. + +.. ocv:function:: String getWindowName() const + +Viz3d::saveScreenshot +--------------------- +Saves screenshot of the current scene. + +.. ocv:function:: void saveScreenshot(const String &file) + + :param file: Name of the file. + +Viz3d::setWindowPosition +------------------------ +Sets the position of the window in the screen. + +.. ocv:function:: void setWindowPosition(int x, int y) + + :param x: x coordinate of the window + :param y: y coordinate of the window + +Viz3d::setFullScreen +-------------------- +Sets or unsets full-screen rendering mode. + +.. ocv:function:: void setFullScreen(bool mode) + + :param mode: If true, window will use full-screen mode. + +Viz3d::setBackgroundColor +------------------------- +Sets background color. + +.. ocv:function:: void setBackgroundColor(const Color& color = Color::black()) + +Viz3d::spin +----------- +The window renders and starts the event loop. + +.. ocv:function:: void spin() + +Viz3d::spinOnce +--------------- +Starts the event loop for a given time. + +.. ocv:function:: void spinOnce(int time = 1, bool force_redraw = false) + + :param time: Amount of time in milliseconds for the event loop to keep running. + :param force_draw: If true, window renders. + +Viz3d::wasStopped +----------------- +Returns whether the event loop has been stopped. + +.. ocv:function:: bool wasStopped() + +Viz3d::registerKeyboardCallback +------------------------------- +Sets keyboard handler. + +.. ocv:function:: void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0) + + :param callback: Keyboard callback. + :param cookie: The optional parameter passed to the callback. + +Viz3d::registerMouseCallback +---------------------------- +Sets mouse handler. + +.. ocv:function:: void registerMouseCallback(MouseCallback callback, void* cookie = 0) + + :param callback: Mouse callback. + :param cookie: The optional parameter passed to the callback. + +Viz3d::setRenderingProperty +--------------------------- +Sets rendering property of a widget. + +.. ocv:function:: void setRenderingProperty(const String &id, int property, double value) + + :param id: Id of the widget. + :param property: Property that will be modified. + :param value: The new value of the property. + +Viz3d::getRenderingProperty +--------------------------- +Returns rendering property of a widget. + +.. ocv:function:: double getRenderingProperty(const String &id, int property) + + :param id: Id of the widget. + :param property: Property. + +Viz3d::setDesiredUpdateRate +--------------------------- +Sets desired update rate of the window. + +.. ocv:function:: void setDesiredUpdateRate(double rate) + + :param rate: Desired update rate. The default is 30. + +Viz3d::getDesiredUpdateRate +--------------------------- +Returns desired update rate of the window. + +.. ocv:function:: double getDesiredUpdateRate() + +Viz3d::setRepresentationToSurface +--------------------------------- +Sets geometry representation of the widgets to surface. + +.. ocv:function:: void setRepresentationToSurface() + +Viz3d::setRepresentationToWireframe +----------------------------------- +Sets geometry representation of the widgets to wireframe. + +.. ocv:function:: void setRepresentationToWireframe() + +Viz3d::setRepresentationToPoints +-------------------------------- +Sets geometry representation of the widgets to points. + +.. ocv:function:: void setRepresentationToPoints() + +Color +----- +.. ocv:class:: Color + +This class a represents BGR color. :: + + class CV_EXPORTS Color : public Scalar + { + public: + Color(); + Color(double gray); + Color(double blue, double green, double red); + + Color(const Scalar& color); + + static Color black(); + static Color blue(); + static Color green(); + static Color cyan(); + + static Color red(); + static Color magenta(); + static Color yellow(); + static Color white(); + + static Color gray(); + }; + +Mesh3d +------ +.. ocv:class:: Mesh3d + +This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. :: + + class CV_EXPORTS Mesh3d + { + public: + + Mat cloud, colors; + Mat polygons; + + //! Loads mesh from a given ply file + static Mesh3d loadMesh(const String& file); + + private: + /* hidden */ + }; + +Mesh3d::loadMesh +---------------- +Loads a mesh from a ``ply`` file. + +.. ocv:function:: static Mesh3d loadMesh(const String& file) + + :param file: File name. + + +KeyboardEvent +------------- +.. ocv:class:: KeyboardEvent + +This class represents a keyboard event. :: + + class CV_EXPORTS KeyboardEvent + { + public: + static const unsigned int Alt = 1; + static const unsigned int Ctrl = 2; + static const unsigned int Shift = 4; + + //! Create a keyboard event + //! - Note that action is true if key is pressed, false if released + KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); + + bool isAltPressed () const; + bool isCtrlPressed () const; + bool isShiftPressed () const; + + unsigned char getKeyCode () const; + + const String& getKeySym () const; + bool keyDown () const; + bool keyUp () const; + + protected: + /* hidden */ + }; + +KeyboardEvent::KeyboardEvent +---------------------------- +Constructs a KeyboardEvent. + +.. ocv:function:: KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift) + + :param action: If true, key is pressed. If false, key is released. + :param key_sym: Name of the key. + :param key: Code of the key. + :param alt: If true, ``alt`` is pressed. + :param ctrl: If true, ``ctrl`` is pressed. + :param shift: If true, ``shift`` is pressed. + +MouseEvent +---------- +.. ocv:class:: MouseEvent + +This class represents a mouse event. :: + + class CV_EXPORTS MouseEvent + { + public: + enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ; + enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ; + + MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); + + Type type; + MouseButton button; + Point pointer; + unsigned int key_state; + }; + +MouseEvent::MouseEvent +---------------------- +Constructs a MouseEvent. + +.. ocv:function:: MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift) + + :param type: Type of the event. This can be **MouseMove**, **MouseButtonPress**, **MouseButtonRelease**, **MouseScrollDown**, **MouseScrollUp**, **MouseDblClick**. + :param button: Mouse button. This can be **NoButton**, **LeftButton**, **MiddleButton**, **RightButton**, **VScroll**. + :param p: Position of the event. + :param alt: If true, ``alt`` is pressed. + :param ctrl: If true, ``ctrl`` is pressed. + :param shift: If true, ``shift`` is pressed. + +Camera +------ +.. ocv:class:: Camera + +This class wraps intrinsic parameters of a camera. It provides several constructors +that can extract the intrinsic parameters from ``field of view``, ``intrinsic matrix`` and +``projection matrix``. :: + + class CV_EXPORTS Camera + { + public: + Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); + Camera(const Vec2f &fov, const Size &window_size); + Camera(const cv::Matx33f &K, const Size &window_size); + Camera(const cv::Matx44f &proj, const Size &window_size); + + inline const Vec2d & getClip() const { return clip_; } + inline void setClip(const Vec2d &clip) { clip_ = clip; } + + inline const Size & getWindowSize() const { return window_size_; } + void setWindowSize(const Size &window_size); + + inline const Vec2f & getFov() const { return fov_; } + inline void setFov(const Vec2f & fov) { fov_ = fov; } + + inline const Vec2f & getPrincipalPoint() const { return principal_point_; } + inline const Vec2f & getFocalLength() const { return focal_; } + + void computeProjectionMatrix(Matx44f &proj) const; + + static Camera KinectCamera(const Size &window_size); + + private: + /* hidden */ + }; + +Camera::Camera +-------------- +Constructs a Camera. + +.. ocv:function:: Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size) + + :param f_x: Horizontal focal length. + :param f_y: Vertical focal length. + :param c_x: x coordinate of the principal point. + :param c_y: y coordinate of the principal point. + :param window_size: Size of the window. This together with focal length and principal point determines the field of view. + +.. ocv:function:: Camera(const Vec2f &fov, const Size &window_size) + + :param fov: Field of view (horizontal, vertical) + :param window_size: Size of the window. + + Principal point is at the center of the window by default. + +.. ocv:function:: Camera(const cv::Matx33f &K, const Size &window_size) + + :param K: Intrinsic matrix of the camera. + :param window_size: Size of the window. This together with intrinsic matrix determines the field of view. + +.. ocv:function:: Camera(const cv::Matx44f &proj, const Size &window_size) + + :param proj: Projection matrix of the camera. + :param window_size: Size of the window. This together with projection matrix determines the field of view. + +Camera::computeProjectionMatrix +------------------------------- +Computes projection matrix using intrinsic parameters of the camera. + +.. ocv:function:: void computeProjectionMatrix(Matx44f &proj) const + + :param proj: Output projection matrix. + +Camera::KinectCamera +-------------------- +Creates a Kinect Camera. + +.. ocv:function:: static Camera KinectCamera(const Size &window_size) + + :param window_size: Size of the window. This together with intrinsic matrix of a Kinect Camera determines the field of view. + diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst new file mode 100644 index 000000000..d4199fdc4 --- /dev/null +++ b/modules/viz/doc/widget.rst @@ -0,0 +1,811 @@ +Widget +====== + +.. highlight:: cpp + +In this section, the built-in widgets are presented. + +Widget +------ +.. ocv:class:: Widget + +Base class of all widgets. Widget is implicitly shared.:: + + class CV_EXPORTS Widget + { + public: + Widget(); + Widget(const Widget& other); + Widget& operator=(const Widget& other); + ~Widget(); + + //! Create a widget directly from ply file + static Widget fromPlyFile(const String &file_name); + + //! Rendering properties of this particular widget + void setRenderingProperty(int property, double value); + double getRenderingProperty(int property) const; + + //! Casting between widgets + template _W cast(); + private: + /* hidden */ + }; + +Widget::fromPlyFile +------------------- +Creates a widget from ply file. + +.. ocv:function:: static Widget fromPlyFile(const String &file_name) + + :param file_name: Ply file name. + +Widget::setRenderingProperty +---------------------------- +Sets rendering property of the widget. + +.. ocv:function:: void setRenderingProperty(int property, double value) + + :param property: Property that will be modified. + :param value: The new value of the property. + +Widget::getRenderingProperty +---------------------------- +Returns rendering property of the widget. + +.. ocv:function:: double getRenderingProperty(int property) const + + :param property: Property. + +Widget::cast +------------ +Casts a widget to another. + +.. ocv:function:: template _W cast() + +Widget3D +-------- +.. ocv:class:: Widget3D + +Base class of all 3D widgets. :: + + class CV_EXPORTS Widget3D : public Widget + { + public: + Widget3D() {} + + void setPose(const Affine3f &pose); + void updatePose(const Affine3f &pose); + Affine3f getPose() const; + + void setColor(const Color &color); + private: + /* hidden */ + }; + +Widget3D::setPose +----------------- +Sets pose of the widget. + +.. ocv:function:: void setPose(const Affine3f &pose) + + :param pose: The new pose of the widget. + +Widget3D::updateWidgetPose +-------------------------- +Updates pose of the widget by pre-multiplying its current pose. + +.. ocv:function:: void updateWidgetPose(const Affine3f &pose) + + :param pose: The pose that the current pose of the widget will be pre-multiplied by. + +Widget3D::getPose +----------------- +Returns the current pose of the widget. + +.. ocv:function:: Affine3f getWidgetPose() const + +Widget3D::setColor +------------------ +Sets the color of the widget. + +.. ocv:function:: void setColor(const Color &color) + + :param color: Color + +Widget2D +-------- +.. ocv:class:: Widget2D + +Base class of all 2D widgets. :: + + class CV_EXPORTS Widget2D : public Widget + { + public: + Widget2D() {} + + void setColor(const Color &color); + }; + +Widget2D::setColor +------------------ +Sets the color of the widget. + +.. ocv:function:: void setColor(const Color &color) + + :param color: Color + +LineWidget +---------- +.. ocv:class:: LineWidget + +This 3D Widget defines a finite line. :: + + class CV_EXPORTS LineWidget : public Widget3D + { + public: + LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + }; + +LineWidget::LineWidget +---------------------- +Constructs a LineWidget. + +.. ocv:function:: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()) + + :param pt1: Start point of the line. + :param pt2: End point of the line. + :param color: Color of the line. + +PlaneWidget +----------- +.. ocv:class:: PlaneWidget + +This 3D Widget defines a finite plane. :: + + class CV_EXPORTS PlaneWidget : public Widget3D + { + public: + PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); + PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); + private: + /* hidden */ + }; + +PlaneWidget::PlaneWidget +------------------------ +Constructs a PlaneWidget. + +.. ocv:function:: PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()) + + :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. + :param size: Size of the plane. + :param color: Color of the plane. + +.. ocv:function:: PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()) + + :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. + :param pt: Position of the plane. + :param color: Color of the plane. + +SphereWidget +------------ +.. ocv:class:: SphereWidget + +This 3D Widget defines a sphere. :: + + class CV_EXPORTS SphereWidget : public Widget3D + { + public: + SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) + }; + +SphereWidget::SphereWidget +-------------------------- +Constructs a SphereWidget. + +.. ocv:function:: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) + + :param center: Center of the sphere. + :param radius: Radius of the sphere. + :param sphere_resolution: Resolution of the sphere. + :param color: Color of the sphere. + +ArrowWidget +----------- +.. ocv:class:: ArrowWidget + +This 3D Widget defines an arrow. :: + + class CV_EXPORTS ArrowWidget : public Widget3D + { + public: + ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); + }; + +ArrowWidget::ArrowWidget +------------------------ +Constructs an ArrowWidget. + +.. ocv:function:: ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()) + + :param pt1: Start point of the arrow. + :param pt2: End point of the arrow. + :param thickness: Thickness of the arrow. Thickness of arrow head is also adjusted accordingly. + :param color: Color of the arrow. + +Arrow head is located at the end point of the arrow. + +CircleWidget +------------ +.. ocv:class:: CircleWidget + +This 3D Widget defines a circle. :: + + class CV_EXPORTS CircleWidget : public Widget3D + { + public: + CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); + }; + +CircleWidget::CircleWidget +-------------------------- +Constructs a CircleWidget. + +.. ocv:function:: CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()) + + :param pt: Center of the circle. + :param radius: Radius of the circle. + :param thickness: Thickness of the circle. + :param color: Color of the circle. + +CylinderWidget +-------------- +.. ocv:class:: CylinderWidget + +This 3D Widget defines a cylinder. :: + + class CV_EXPORTS CylinderWidget : public Widget3D + { + public: + CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); + }; + +CylinderWidget::CylinderWidget +------------------------------ +Constructs a CylinderWidget. + +.. ocv:function:: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()) + + :param pt_on_axis: A point on the axis of the cylinder. + :param axis_direction: Direction of the axis of the cylinder. + :param radius: Radius of the cylinder. + :param numsides: Resolution of the cylinder. + :param color: Color of the cylinder. + +CubeWidget +---------- +.. ocv:class:: CubeWidget + +This 3D Widget defines a cube. :: + + class CV_EXPORTS CubeWidget : public Widget3D + { + public: + CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); + }; + +CubeWidget::CubeWidget +---------------------- +Constructs a CudeWidget. + +.. ocv:function:: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()) + + :param pt_min: Specifies minimum point of the bounding box. + :param pt_max: Specifies maximum point of the bounding box. + :param wire_frame: If true, cube is represented as wireframe. + :param color: Color of the cube. + +CoordinateSystemWidget +---------------------- +.. ocv:class:: CoordinateSystemWidget + +This 3D Widget represents a coordinate system. :: + + class CV_EXPORTS CoordinateSystemWidget : public Widget3D + { + public: + CoordinateSystemWidget(double scale = 1.0); + }; + +CoordinateSystemWidget::CoordinateSystemWidget +---------------------------------------------- +Constructs a CoordinateSystemWidget. + +.. ocv:function:: CoordinateSystemWidget(double scale = 1.0) + + :param scale: Determines the size of the axes. + +PolyLineWidget +-------------- +.. ocv:class:: PolyLineWidget + +This 3D Widget defines a poly line. :: + + class CV_EXPORTS PolyLineWidget : public Widget3D + { + public: + PolyLineWidget(InputArray points, const Color &color = Color::white()); + + private: + /* hidden */ + }; + +PolyLineWidget::PolyLineWidget +------------------------------ +Constructs a PolyLineWidget. + +.. ocv:function:: PolyLineWidget(InputArray points, const Color &color = Color::white()) + + :param points: Point set. + :param color: Color of the poly line. + +GridWidget +---------- +.. ocv:class:: GridWidget + +This 3D Widget defines a grid. :: + + class CV_EXPORTS GridWidget : public Widget3D + { + public: + //! Creates grid at the origin + GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + //! Creates grid based on the plane equation + GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + private: + /* hidden */ + }; + +GridWidget::GridWidget +---------------------- +Constructs a GridWidget. + +.. ocv:function:: GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) + + :param dimensions: Number of columns and rows, respectively. + :param spacing: Size of each column and row, respectively. + :param color: Color of the grid. + +.. ocv:function: GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) + + :param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. + :param dimensions: Number of columns and rows, respectively. + :param spacing: Size of each column and row, respectively. + :param color: Color of the grid. + +Text3DWidget +------------ +.. ocv:class:: Text3DWidget + +This 3D Widget represents 3D text. The text always faces the camera. :: + + class CV_EXPORTS Text3DWidget : public Widget3D + { + public: + Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + +Text3DWidget::Text3DWidget +-------------------------- +Constructs a Text3DWidget. + +.. ocv:function:: Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()) + + :param text: Text content of the widget. + :param position: Position of the text. + :param text_scale: Size of the text. + :param color: Color of the text. + +Text3DWidget::setText +--------------------- +Sets the text content of the widget. + +.. ocv:function:: void setText(const String &text) + + :param text: Text content of the widget. + +Text3DWidget::getText +--------------------- +Returns the current text content of the widget. + +.. ocv:function:: String getText() const + +TextWidget +---------- +.. ocv:class:: TextWidget + +This 2D Widget represents text overlay. :: + + class CV_EXPORTS TextWidget : public Widget2D + { + public: + TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + +TextWidget::TextWidget +---------------------- +Constructs a TextWidget. + +.. ocv:function:: TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()) + + :param text: Text content of the widget. + :param pos: Position of the text. + :param font_size: Font size. + :param color: Color of the text. + +TextWidget::setText +--------------------- +Sets the text content of the widget. + +.. ocv:function:: void setText(const String &text) + + :param text: Text content of the widget. + +TextWidget::getText +--------------------- +Returns the current text content of the widget. + +.. ocv:function:: String getText() const + +ImageOverlayWidget +------------------ +.. ocv:class:: ImageOverlayWidget + +This 2D Widget represents an image overlay. :: + + class CV_EXPORTS ImageOverlayWidget : public Widget2D + { + public: + ImageOverlayWidget(const Mat &image, const Rect &rect); + + void setImage(const Mat &image); + }; + +ImageOverlayWidget::ImageOverlayWidget +-------------------------------------- +Constructs a ImageOverlayWidget. + +.. ocv:function:: ImageOverlayWidget(const Mat &image, const Rect &rect) + + :param image: BGR or Gray-Scale image. + :param rect: Image is scaled and positioned based on rect. + +ImageOverlayWidget::setImage +---------------------------- +Sets the image content of the widget. + +.. ocv:function:: void setImage(const Mat &image) + + :param image: BGR or Gray-Scale image. + +Image3DWidget +------------- +.. ocv:class:: Image3DWidget + +This 3D Widget represents 3D image. :: + + class CV_EXPORTS Image3DWidget : public Widget3D + { + public: + //! Creates 3D image at the origin + Image3DWidget(const Mat &image, const Size &size); + //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation + Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); + + void setImage(const Mat &image); + }; + +Image3DWidget::Image3DWidget +---------------------------- +Constructs a Image3DWidget. + +.. ocv:function:: Image3DWidget(const Mat &image, const Size &size) + + :param image: BGR or Gray-Scale image. + :param size: Size of the image. + +.. ocv:function:: Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) + + :param position: Position of the image. + :param normal: Normal of the plane that represents the image. + :param up_vector: Determines orientation of the image. + :param image: BGR or Gray-Scale image. + :param size: Size of the image. + +Image3DWidget::setImage +----------------------- +Sets the image content of the widget. + +.. ocv:function:: void setImage(const Mat &image) + + :param image: BGR or Gray-Scale image. + +CameraPositionWidget +-------------------- +.. ocv:class:: CameraPositionWidget + +This 3D Widget represents camera position. :: + + class CV_EXPORTS CameraPositionWidget : public Widget3D + { + public: + //! Creates camera coordinate frame (axes) at the origin + CameraPositionWidget(double scale = 1.0); + //! Creates frustum based on the intrinsic marix K at the origin + CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum based on the field of view at the origin + CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane + CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + }; + +CameraPositionWidget::CameraPositionWidget +------------------------------------------ +Constructs a CameraPositionWidget. + +.. ocv:function:: CameraPositionWidget(double scale = 1.0) + + Creates camera coordinate frame at the origin. + +.. ocv:function:: CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) + + :param K: Intrinsic matrix of the camera. + :param scale: Scale of the frustum. + :param color: Color of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K. + +.. ocv:function:: CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) + + :param fov: Field of view of the camera (horizontal, vertical). + :param scale: Scale of the frustum. + :param color: Color of the frustum. + + Creates viewing frustum of the camera based on its field of view fov. + +.. ocv:function:: CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()) + + :param K: Intrinsic matrix of the camera. + :param img: BGR or Gray-Scale image that is going to be displayed at the far plane of the frustum. + :param scale: Scale of the frustum and image. + :param color: Color of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. + +TrajectoryWidget +---------------- +.. ocv:class:: TrajectoryWidget + +This 3D Widget represents a trajectory. :: + + class CV_EXPORTS TrajectoryWidget : public Widget3D + { + public: + enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; + + //! Displays trajectory of the given path either by coordinate frames or polyline + TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); + //! Displays trajectory of the given path by frustums + TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + //! Displays trajectory of the given path by frustums + TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + + private: + /* hidden */ + }; + +TrajectoryWidget::TrajectoryWidget +---------------------------------- +Constructs a TrajectoryWidget. + +.. ocv:function:: TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0) + + :param path: List of poses on a trajectory. + :param display_mode: Display mode. This can be DISPLAY_PATH, DISPLAY_FRAMES, DISPLAY_PATH & DISPLAY_FRAMES. + :param color: Color of the polyline that represents path. Frames are not affected. + :param scale: Scale of the frames. Polyline is not affected. + + Displays trajectory of the given path as follows: + + * DISPLAY_PATH : Displays a poly line that represents the path. + * DISPLAY_FRAMES : Displays coordinate frames at each pose. + * DISPLAY_PATH & DISPLAY_FRAMES : Displays both poly line and coordinate frames. + +.. ocv:function:: TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) + + :param path: List of poses on a trajectory. + :param K: Intrinsic matrix of the camera. + :param scale: Scale of the frustums. + :param color: Color of the frustums. + + Displays frustums at each pose of the trajectory. + +.. ocv:function:: TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) + + :param path: List of poses on a trajectory. + :param fov: Field of view of the camera (horizontal, vertical). + :param scale: Scale of the frustums. + :param color: Color of the frustums. + + Displays frustums at each pose of the trajectory. + +SpheresTrajectoryWidget +----------------------- +.. ocv:class:: SpheresTrajectoryWidget + +This 3D Widget represents a trajectory using spheres and lines, where spheres represent the positions of the camera, and lines +represent the direction from previous position to the current. :: + + class CV_EXPORTS SpheresTrajectoryWidget : public Widget3D + { + public: + SpheresTrajectoryWidget(const std::vector &path, float line_length = 0.05f, + double init_sphere_radius = 0.021, sphere_radius = 0.007, + Color &line_color = Color::white(), const Color &sphere_color = Color::white()); + }; + +SpheresTrajectoryWidget::SpheresTrajectoryWidget +------------------------------------------------ +Constructs a SpheresTrajectoryWidget. + +.. ocv:function:: SpheresTrajectoryWidget(const std::vector &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()) + + :param path: List of poses on a trajectory. + :param line_length: Length of the lines. + :param init_sphere_radius: Radius of the first sphere which represents the initial position of the camera. + :param sphere_radius: Radius of the rest of the spheres. + :param line_color: Color of the lines. + :param sphere_color: Color of the spheres. + +CloudWidget +----------- +.. ocv:class:: CloudWidget + +This 3D Widget defines a point cloud. :: + + class CV_EXPORTS CloudWidget : public Widget3D + { + public: + //! Each point in cloud is mapped to a color in colors + CloudWidget(InputArray cloud, InputArray colors); + //! All points in cloud have the same color + CloudWidget(InputArray cloud, const Color &color = Color::white()); + + private: + /* hidden */ + }; + +CloudWidget::CloudWidget +------------------------ +Constructs a CloudWidget. + +.. ocv:function:: CloudWidget(InputArray cloud, InputArray colors) + + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param colors: Set of colors. It has to be of the same size with cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +.. ocv:function:: CloudWidget(InputArray cloud, const Color &color = Color::white()) + + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param color: A single color for the whole cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +CloudCollectionWidget +--------------------- +.. ocv:class:: CloudCollectionWidget + +This 3D Widget defines a collection of clouds. :: + + class CV_EXPORTS CloudCollectionWidget : public Widget3D + { + public: + CloudCollectionWidget(); + + //! Each point in cloud is mapped to a color in colors + void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); + //! All points in cloud have the same color + void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3f &pose = Affine3f::Identity()); + + private: + /* hidden */ + }; + +CloudCollectionWidget::CloudCollectionWidget +-------------------------------------------- +Constructs a CloudCollectionWidget. + +.. ocv:function:: CloudCollectionWidget() + +CloudCollectionWidget::addCloud +------------------------------- +Adds a cloud to the collection. + +.. ocv:function:: void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()) + + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param colors: Set of colors. It has to be of the same size with cloud. + :param pose: Pose of the cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +.. ocv:function:: void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity()) + + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param colors: A single color for the whole cloud. + :param pose: Pose of the cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +CloudNormalsWidget +------------------ +.. ocv:class:: CloudNormalsWidget + +This 3D Widget represents normals of a point cloud. :: + + class CV_EXPORTS CloudNormalsWidget : public Widget3D + { + public: + CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); + + private: + /* hidden */ + }; + +CloudNormalsWidget::CloudNormalsWidget +-------------------------------------- +Constructs a CloudNormalsWidget. + +.. ocv:function:: CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()) + + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param normals: A set of normals that has to be of same type with cloud. + :param level: Display only every levelth normal. + :param scale: Scale of the arrows that represent normals. + :param color: Color of the arrows that represent normals. + +MeshWidget +---------- +.. ocv:class:: MeshWidget + +This 3D Widget defines a mesh. :: + + class CV_EXPORTS MeshWidget : public Widget3D + { + public: + MeshWidget(const Mesh3d &mesh); + + private: + /* hidden */ + }; + +MeshWidget::MeshWidget +---------------------- +Constructs a MeshWidget. + +.. ocv:function:: MeshWidget(const Mesh3d &mesh) + + :param mesh: Mesh object that will be displayed. + + + + From 31501ebf4f1d11b9b4b729b24543e5d59a9559d2 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 1 Sep 2013 20:12:31 +0200 Subject: [PATCH 174/205] replace tabs by spaces --- modules/viz/doc/viz.rst | 2 - modules/viz/doc/viz3d.rst | 444 ++++++++++---------- modules/viz/doc/widget.rst | 802 +++++++++++++++++++------------------ 3 files changed, 629 insertions(+), 619 deletions(-) diff --git a/modules/viz/doc/viz.rst b/modules/viz/doc/viz.rst index f51a151e0..2f1bf0456 100644 --- a/modules/viz/doc/viz.rst +++ b/modules/viz/doc/viz.rst @@ -7,5 +7,3 @@ viz. 3D Visualizer viz3d.rst widget.rst - types.rst - widget_accessor.rst diff --git a/modules/viz/doc/viz3d.rst b/modules/viz/doc/viz3d.rst index e7dcc358c..b2e2d4914 100644 --- a/modules/viz/doc/viz3d.rst +++ b/modules/viz/doc/viz3d.rst @@ -7,67 +7,67 @@ Viz3d ----- .. ocv:class:: Viz3d -The Viz3d class represents a 3D visualizer window. This class is implicitly shared. :: +The Viz3d class represents a 3D visualizer window. This class is implicitly shared. :: - class CV_EXPORTS Viz3d - { - public: - typedef cv::Ptr Ptr; - typedef void (*KeyboardCallback)(const KeyboardEvent&, void*); - typedef void (*MouseCallback)(const MouseEvent&, void*); + class CV_EXPORTS Viz3d + { + public: + typedef cv::Ptr Ptr; + typedef void (*KeyboardCallback)(const KeyboardEvent&, void*); + typedef void (*MouseCallback)(const MouseEvent&, void*); - Viz3d(const String& window_name = String()); - Viz3d(const Viz3d&); - Viz3d& operator=(const Viz3d&); - ~Viz3d(); + Viz3d(const String& window_name = String()); + Viz3d(const Viz3d&); + Viz3d& operator=(const Viz3d&); + ~Viz3d(); - void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); - void removeWidget(const String &id); - Widget getWidget(const String &id) const; - void removeAllWidgets(); + void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; + void removeAllWidgets(); - void setWidgetPose(const String &id, const Affine3f &pose); - void updateWidgetPose(const String &id, const Affine3f &pose); - Affine3f getWidgetPose(const String &id) const; - - void setCamera(const Camera &camera); - Camera getCamera() const; - Affine3f getViewerPose(); - void setViewerPose(const Affine3f &pose); - - void resetCameraViewpoint (const String &id); - void resetCamera(); - - void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); - void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); - - Size getWindowSize() const; - void setWindowSize(const Size &window_size); - String getWindowName() const; - void saveScreenshot (const String &file); - void setWindowPosition (int x, int y); - void setFullScreen (bool mode); - void setBackgroundColor(const Color& color = Color::black()); + void setWidgetPose(const String &id, const Affine3f &pose); + void updateWidgetPose(const String &id, const Affine3f &pose); + Affine3f getWidgetPose(const String &id) const; + + void setCamera(const Camera &camera); + Camera getCamera() const; + Affine3f getViewerPose(); + void setViewerPose(const Affine3f &pose); + + void resetCameraViewpoint (const String &id); + void resetCamera(); + + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); + + Size getWindowSize() const; + void setWindowSize(const Size &window_size); + String getWindowName() const; + void saveScreenshot (const String &file); + void setWindowPosition (int x, int y); + void setFullScreen (bool mode); + void setBackgroundColor(const Color& color = Color::black()); - void spin(); - void spinOnce(int time = 1, bool force_redraw = false); - bool wasStopped() const; + void spin(); + void spinOnce(int time = 1, bool force_redraw = false); + bool wasStopped() const; - void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); - void registerMouseCallback(MouseCallback callback, void* cookie = 0); - - void setRenderingProperty(const String &id, int property, double value); - double getRenderingProperty(const String &id, int property); - - void setDesiredUpdateRate(double rate); - double getDesiredUpdateRate(); - - void setRepresentationToSurface(); - void setRepresentationToWireframe(); - void setRepresentationToPoints(); - private: - /* hidden */ - }; + void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); + void registerMouseCallback(MouseCallback callback, void* cookie = 0); + + void setRenderingProperty(const String &id, int property, double value); + double getRenderingProperty(const String &id, int property); + + void setDesiredUpdateRate(double rate); + double getDesiredUpdateRate(); + + void setRepresentationToSurface(); + void setRepresentationToWireframe(); + void setRepresentationToPoints(); + private: + /* hidden */ + }; Viz3d::Viz3d ------------ @@ -75,7 +75,7 @@ The constructors. .. ocv:function:: Viz3d::Viz3d(const String& window_name = String()) - :param window_name: Name of the window. + :param window_name: Name of the window. Viz3d::showWidget ----------------- @@ -83,18 +83,18 @@ Shows a widget in the window. .. ocv:function:: void Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()) - :param id: A unique id for the widget. - :param widget: The widget to be rendered in the window. - :param pose: Pose of the widget. - + :param id: A unique id for the widget. + :param widget: The widget to be rendered in the window. + :param pose: Pose of the widget. + Viz3d::removeWidget ------------------- Removes a widget from the window. .. ocv:function:: void removeWidget(const String &id) - :param id: The id of the widget that will be removed. - + :param id: The id of the widget that will be removed. + Viz3d::getWidget ---------------- Retrieves a widget from the window. A widget is implicitly shared; @@ -103,8 +103,8 @@ immediately visible in the window. .. ocv:function:: Widget getWidget(const String &id) const - :param id: The id of the widget that will be returned. - + :param id: The id of the widget that will be returned. + Viz3d::removeAllWidgets ----------------------- Removes all widgets from the window. @@ -117,8 +117,8 @@ Sets pose of a widget in the window. .. ocv:function:: void setWidgetPose(const String &id, const Affine3f &pose) - :param id: The id of the widget whose pose will be set. - :param pose: The new pose of the widget. + :param id: The id of the widget whose pose will be set. + :param pose: The new pose of the widget. Viz3d::updateWidgetPose ----------------------- @@ -126,8 +126,8 @@ Updates pose of a widget in the window by pre-multiplying its current pose. .. ocv:function:: void updateWidgetPose(const String &id, const Affine3f &pose) - :param id: The id of the widget whose pose will be updated. - :param pose: The pose that the current pose of the widget will be pre-multiplied by. + :param id: The id of the widget whose pose will be updated. + :param pose: The pose that the current pose of the widget will be pre-multiplied by. Viz3d::getWidgetPose -------------------- @@ -135,7 +135,7 @@ Returns the current pose of a widget in the window. .. ocv:function:: Affine3f getWidgetPose(const String &id) const - :param id: The id of the widget whose pose will be returned. + :param id: The id of the widget whose pose will be returned. Viz3d::setCamera ---------------- @@ -143,7 +143,7 @@ Sets the intrinsic parameters of the viewer using Camera. .. ocv:function:: void setCamera(const Camera &camera) - :param camera: Camera object wrapping intrinsinc parameters. + :param camera: Camera object wrapping intrinsinc parameters. Viz3d::getCamera ---------------- @@ -163,7 +163,7 @@ Sets pose of the viewer. .. ocv:function:: void setViewerPose(const Affine3f &pose) - :param pose: The new pose of the viewer. + :param pose: The new pose of the viewer. Viz3d::resetCameraViewpoint --------------------------- @@ -171,8 +171,8 @@ Resets camera viewpoint to a 3D widget in the scene. .. ocv:function:: void resetCameraViewpoint (const String &id) - :param pose: Id of a 3D widget. - + :param pose: Id of a 3D widget. + Viz3d::resetCamera ------------------ Resets camera. @@ -185,19 +185,19 @@ Transforms a point in world coordinate system to window coordinate system. .. ocv:function:: void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) - :param pt: Point in world coordinate system. - :param window_coord: Output point in window coordinate system. - + :param pt: Point in world coordinate system. + :param window_coord: Output point in window coordinate system. + Viz3d::converTo3DRay -------------------- Transforms a point in window coordinate system to a 3D ray in world coordinate system. .. ocv:function:: void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) - :param window_coord: Point in window coordinate system. - :param origin: Output origin of the ray. - :param direction: Output direction of the ray. - + :param window_coord: Point in window coordinate system. + :param origin: Output origin of the ray. + :param direction: Output direction of the ray. + Viz3d::getWindowSize -------------------- Returns the current size of the window. @@ -210,8 +210,8 @@ Sets the size of the window. .. ocv:function:: void setWindowSize(const Size &window_size) - :param window_size: New size of the window. - + :param window_size: New size of the window. + Viz3d::getWindowName -------------------- Returns the name of the window which has been set in the constructor. @@ -224,25 +224,25 @@ Saves screenshot of the current scene. .. ocv:function:: void saveScreenshot(const String &file) - :param file: Name of the file. - + :param file: Name of the file. + Viz3d::setWindowPosition ------------------------ Sets the position of the window in the screen. .. ocv:function:: void setWindowPosition(int x, int y) - :param x: x coordinate of the window - :param y: y coordinate of the window - + :param x: x coordinate of the window + :param y: y coordinate of the window + Viz3d::setFullScreen -------------------- Sets or unsets full-screen rendering mode. .. ocv:function:: void setFullScreen(bool mode) - :param mode: If true, window will use full-screen mode. - + :param mode: If true, window will use full-screen mode. + Viz3d::setBackgroundColor ------------------------- Sets background color. @@ -261,8 +261,8 @@ Starts the event loop for a given time. .. ocv:function:: void spinOnce(int time = 1, bool force_redraw = false) - :param time: Amount of time in milliseconds for the event loop to keep running. - :param force_draw: If true, window renders. + :param time: Amount of time in milliseconds for the event loop to keep running. + :param force_draw: If true, window renders. Viz3d::wasStopped ----------------- @@ -276,17 +276,17 @@ Sets keyboard handler. .. ocv:function:: void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0) - :param callback: Keyboard callback. - :param cookie: The optional parameter passed to the callback. - + :param callback: Keyboard callback. + :param cookie: The optional parameter passed to the callback. + Viz3d::registerMouseCallback ---------------------------- Sets mouse handler. .. ocv:function:: void registerMouseCallback(MouseCallback callback, void* cookie = 0) - :param callback: Mouse callback. - :param cookie: The optional parameter passed to the callback. + :param callback: Mouse callback. + :param cookie: The optional parameter passed to the callback. Viz3d::setRenderingProperty --------------------------- @@ -294,18 +294,18 @@ Sets rendering property of a widget. .. ocv:function:: void setRenderingProperty(const String &id, int property, double value) - :param id: Id of the widget. - :param property: Property that will be modified. - :param value: The new value of the property. - + :param id: Id of the widget. + :param property: Property that will be modified. + :param value: The new value of the property. + Viz3d::getRenderingProperty --------------------------- Returns rendering property of a widget. .. ocv:function:: double getRenderingProperty(const String &id, int property) - :param id: Id of the widget. - :param property: Property. + :param id: Id of the widget. + :param property: Property. Viz3d::setDesiredUpdateRate --------------------------- @@ -313,8 +313,8 @@ Sets desired update rate of the window. .. ocv:function:: void setDesiredUpdateRate(double rate) - :param rate: Desired update rate. The default is 30. - + :param rate: Desired update rate. The default is 30. + Viz3d::getDesiredUpdateRate --------------------------- Returns desired update rate of the window. @@ -345,27 +345,27 @@ Color This class a represents BGR color. :: - class CV_EXPORTS Color : public Scalar - { - public: - Color(); - Color(double gray); - Color(double blue, double green, double red); + class CV_EXPORTS Color : public Scalar + { + public: + Color(); + Color(double gray); + Color(double blue, double green, double red); - Color(const Scalar& color); + Color(const Scalar& color); - static Color black(); - static Color blue(); - static Color green(); - static Color cyan(); + static Color black(); + static Color blue(); + static Color green(); + static Color cyan(); - static Color red(); - static Color magenta(); - static Color yellow(); - static Color white(); + static Color red(); + static Color magenta(); + static Color yellow(); + static Color white(); - static Color gray(); - }; + static Color gray(); + }; Mesh3d ------ @@ -373,27 +373,27 @@ Mesh3d This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. :: - class CV_EXPORTS Mesh3d - { - public: + class CV_EXPORTS Mesh3d + { + public: - Mat cloud, colors; - Mat polygons; + Mat cloud, colors; + Mat polygons; - //! Loads mesh from a given ply file - static Mesh3d loadMesh(const String& file); - - private: - /* hidden */ - }; - + //! Loads mesh from a given ply file + static Mesh3d loadMesh(const String& file); + + private: + /* hidden */ + }; + Mesh3d::loadMesh ---------------- Loads a mesh from a ``ply`` file. .. ocv:function:: static Mesh3d loadMesh(const String& file) - :param file: File name. + :param file: File name. KeyboardEvent @@ -402,30 +402,30 @@ KeyboardEvent This class represents a keyboard event. :: - class CV_EXPORTS KeyboardEvent - { - public: - static const unsigned int Alt = 1; - static const unsigned int Ctrl = 2; - static const unsigned int Shift = 4; + class CV_EXPORTS KeyboardEvent + { + public: + static const unsigned int Alt = 1; + static const unsigned int Ctrl = 2; + static const unsigned int Shift = 4; - //! Create a keyboard event - //! - Note that action is true if key is pressed, false if released - KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); + //! Create a keyboard event + //! - Note that action is true if key is pressed, false if released + KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); - bool isAltPressed () const; - bool isCtrlPressed () const; - bool isShiftPressed () const; + bool isAltPressed () const; + bool isCtrlPressed () const; + bool isShiftPressed () const; - unsigned char getKeyCode () const; + unsigned char getKeyCode () const; - const String& getKeySym () const; - bool keyDown () const; - bool keyUp () const; + const String& getKeySym () const; + bool keyDown () const; + bool keyUp () const; - protected: - /* hidden */ - }; + protected: + /* hidden */ + }; KeyboardEvent::KeyboardEvent ---------------------------- @@ -433,46 +433,46 @@ Constructs a KeyboardEvent. .. ocv:function:: KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift) - :param action: If true, key is pressed. If false, key is released. - :param key_sym: Name of the key. - :param key: Code of the key. - :param alt: If true, ``alt`` is pressed. - :param ctrl: If true, ``ctrl`` is pressed. - :param shift: If true, ``shift`` is pressed. - + :param action: If true, key is pressed. If false, key is released. + :param key_sym: Name of the key. + :param key: Code of the key. + :param alt: If true, ``alt`` is pressed. + :param ctrl: If true, ``ctrl`` is pressed. + :param shift: If true, ``shift`` is pressed. + MouseEvent ---------- .. ocv:class:: MouseEvent This class represents a mouse event. :: - class CV_EXPORTS MouseEvent - { - public: - enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ; - enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ; + class CV_EXPORTS MouseEvent + { + public: + enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ; + enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ; - MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); + MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); - Type type; - MouseButton button; - Point pointer; - unsigned int key_state; - }; - + Type type; + MouseButton button; + Point pointer; + unsigned int key_state; + }; + MouseEvent::MouseEvent ---------------------- Constructs a MouseEvent. .. ocv:function:: MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift) - :param type: Type of the event. This can be **MouseMove**, **MouseButtonPress**, **MouseButtonRelease**, **MouseScrollDown**, **MouseScrollUp**, **MouseDblClick**. - :param button: Mouse button. This can be **NoButton**, **LeftButton**, **MiddleButton**, **RightButton**, **VScroll**. - :param p: Position of the event. - :param alt: If true, ``alt`` is pressed. - :param ctrl: If true, ``ctrl`` is pressed. - :param shift: If true, ``shift`` is pressed. - + :param type: Type of the event. This can be **MouseMove**, **MouseButtonPress**, **MouseButtonRelease**, **MouseScrollDown**, **MouseScrollUp**, **MouseDblClick**. + :param button: Mouse button. This can be **NoButton**, **LeftButton**, **MiddleButton**, **RightButton**, **VScroll**. + :param p: Position of the event. + :param alt: If true, ``alt`` is pressed. + :param ctrl: If true, ``ctrl`` is pressed. + :param shift: If true, ``shift`` is pressed. + Camera ------ .. ocv:class:: Camera @@ -481,33 +481,33 @@ This class wraps intrinsic parameters of a camera. It provides several construct that can extract the intrinsic parameters from ``field of view``, ``intrinsic matrix`` and ``projection matrix``. :: - class CV_EXPORTS Camera - { - public: - Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); - Camera(const Vec2f &fov, const Size &window_size); - Camera(const cv::Matx33f &K, const Size &window_size); - Camera(const cv::Matx44f &proj, const Size &window_size); - - inline const Vec2d & getClip() const { return clip_; } - inline void setClip(const Vec2d &clip) { clip_ = clip; } - - inline const Size & getWindowSize() const { return window_size_; } - void setWindowSize(const Size &window_size); - - inline const Vec2f & getFov() const { return fov_; } - inline void setFov(const Vec2f & fov) { fov_ = fov; } - - inline const Vec2f & getPrincipalPoint() const { return principal_point_; } - inline const Vec2f & getFocalLength() const { return focal_; } - - void computeProjectionMatrix(Matx44f &proj) const; - - static Camera KinectCamera(const Size &window_size); - - private: - /* hidden */ - }; + class CV_EXPORTS Camera + { + public: + Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size); + Camera(const Vec2f &fov, const Size &window_size); + Camera(const cv::Matx33f &K, const Size &window_size); + Camera(const cv::Matx44f &proj, const Size &window_size); + + inline const Vec2d & getClip() const { return clip_; } + inline void setClip(const Vec2d &clip) { clip_ = clip; } + + inline const Size & getWindowSize() const { return window_size_; } + void setWindowSize(const Size &window_size); + + inline const Vec2f & getFov() const { return fov_; } + inline void setFov(const Vec2f & fov) { fov_ = fov; } + + inline const Vec2f & getPrincipalPoint() const { return principal_point_; } + inline const Vec2f & getFocalLength() const { return focal_; } + + void computeProjectionMatrix(Matx44f &proj) const; + + static Camera KinectCamera(const Size &window_size); + + private: + /* hidden */ + }; Camera::Camera -------------- @@ -515,28 +515,28 @@ Constructs a Camera. .. ocv:function:: Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size) - :param f_x: Horizontal focal length. - :param f_y: Vertical focal length. - :param c_x: x coordinate of the principal point. - :param c_y: y coordinate of the principal point. - :param window_size: Size of the window. This together with focal length and principal point determines the field of view. + :param f_x: Horizontal focal length. + :param f_y: Vertical focal length. + :param c_x: x coordinate of the principal point. + :param c_y: y coordinate of the principal point. + :param window_size: Size of the window. This together with focal length and principal point determines the field of view. .. ocv:function:: Camera(const Vec2f &fov, const Size &window_size) - :param fov: Field of view (horizontal, vertical) - :param window_size: Size of the window. + :param fov: Field of view (horizontal, vertical) + :param window_size: Size of the window. - Principal point is at the center of the window by default. - + Principal point is at the center of the window by default. + .. ocv:function:: Camera(const cv::Matx33f &K, const Size &window_size) - :param K: Intrinsic matrix of the camera. - :param window_size: Size of the window. This together with intrinsic matrix determines the field of view. + :param K: Intrinsic matrix of the camera. + :param window_size: Size of the window. This together with intrinsic matrix determines the field of view. .. ocv:function:: Camera(const cv::Matx44f &proj, const Size &window_size) - :param proj: Projection matrix of the camera. - :param window_size: Size of the window. This together with projection matrix determines the field of view. + :param proj: Projection matrix of the camera. + :param window_size: Size of the window. This together with projection matrix determines the field of view. Camera::computeProjectionMatrix ------------------------------- @@ -544,13 +544,13 @@ Computes projection matrix using intrinsic parameters of the camera. .. ocv:function:: void computeProjectionMatrix(Matx44f &proj) const - :param proj: Output projection matrix. - + :param proj: Output projection matrix. + Camera::KinectCamera -------------------- Creates a Kinect Camera. .. ocv:function:: static Camera KinectCamera(const Size &window_size) - :param window_size: Size of the window. This together with intrinsic matrix of a Kinect Camera determines the field of view. + :param window_size: Size of the window. This together with intrinsic matrix of a Kinect Camera determines the field of view. diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index d4199fdc4..bf724956d 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -1,6 +1,6 @@ Widget ====== - + .. highlight:: cpp In this section, the built-in widgets are presented. @@ -11,26 +11,26 @@ Widget Base class of all widgets. Widget is implicitly shared.:: - class CV_EXPORTS Widget - { - public: - Widget(); - Widget(const Widget& other); - Widget& operator=(const Widget& other); - ~Widget(); - - //! Create a widget directly from ply file - static Widget fromPlyFile(const String &file_name); - - //! Rendering properties of this particular widget - void setRenderingProperty(int property, double value); - double getRenderingProperty(int property) const; + class CV_EXPORTS Widget + { + public: + Widget(); + Widget(const Widget& other); + Widget& operator=(const Widget& other); + ~Widget(); + + //! Create a widget directly from ply file + static Widget fromPlyFile(const String &file_name); + + //! Rendering properties of this particular widget + void setRenderingProperty(int property, double value); + double getRenderingProperty(int property) const; - //! Casting between widgets - template _W cast(); - private: - /* hidden */ - }; + //! Casting between widgets + template _W cast(); + private: + /* hidden */ + }; Widget::fromPlyFile ------------------- @@ -38,50 +38,62 @@ Creates a widget from ply file. .. ocv:function:: static Widget fromPlyFile(const String &file_name) - :param file_name: Ply file name. - + :param file_name: Ply file name. + Widget::setRenderingProperty ---------------------------- Sets rendering property of the widget. .. ocv:function:: void setRenderingProperty(int property, double value) - :param property: Property that will be modified. - :param value: The new value of the property. - + :param property: Property that will be modified. + :param value: The new value of the property. + Widget::getRenderingProperty ---------------------------- Returns rendering property of the widget. .. ocv:function:: double getRenderingProperty(int property) const - :param property: Property. - + :param property: Property. + Widget::cast ------------ Casts a widget to another. .. ocv:function:: template _W cast() +WidgetAccessor +-------------- +.. ocv:class:: WidgetAccessor + +This class is for users who want to develop their own widgets using VTK library API. :: + + struct CV_EXPORTS WidgetAccessor + { + static vtkSmartPointer getProp(const Widget &widget); + static void setProp(Widget &widget, vtkSmartPointer prop); + }; + Widget3D -------- .. ocv:class:: Widget3D Base class of all 3D widgets. :: - class CV_EXPORTS Widget3D : public Widget - { - public: - Widget3D() {} + class CV_EXPORTS Widget3D : public Widget + { + public: + Widget3D() {} - void setPose(const Affine3f &pose); - void updatePose(const Affine3f &pose); - Affine3f getPose() const; + void setPose(const Affine3f &pose); + void updatePose(const Affine3f &pose); + Affine3f getPose() const; - void setColor(const Color &color); - private: - /* hidden */ - }; + void setColor(const Color &color); + private: + /* hidden */ + }; Widget3D::setPose ----------------- @@ -89,15 +101,15 @@ Sets pose of the widget. .. ocv:function:: void setPose(const Affine3f &pose) - :param pose: The new pose of the widget. - + :param pose: The new pose of the widget. + Widget3D::updateWidgetPose -------------------------- Updates pose of the widget by pre-multiplying its current pose. .. ocv:function:: void updateWidgetPose(const Affine3f &pose) - :param pose: The pose that the current pose of the widget will be pre-multiplied by. + :param pose: The pose that the current pose of the widget will be pre-multiplied by. Widget3D::getPose ----------------- @@ -111,29 +123,29 @@ Sets the color of the widget. .. ocv:function:: void setColor(const Color &color) - :param color: Color - + :param color: Color + Widget2D -------- .. ocv:class:: Widget2D Base class of all 2D widgets. :: - class CV_EXPORTS Widget2D : public Widget - { - public: - Widget2D() {} + class CV_EXPORTS Widget2D : public Widget + { + public: + Widget2D() {} - void setColor(const Color &color); - }; - + void setColor(const Color &color); + }; + Widget2D::setColor ------------------ Sets the color of the widget. .. ocv:function:: void setColor(const Color &color) - :param color: Color + :param color: Color LineWidget ---------- @@ -141,64 +153,64 @@ LineWidget This 3D Widget defines a finite line. :: - class CV_EXPORTS LineWidget : public Widget3D - { - public: - LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); - }; - + class CV_EXPORTS LineWidget : public Widget3D + { + public: + LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + }; + LineWidget::LineWidget ---------------------- Constructs a LineWidget. .. ocv:function:: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()) - :param pt1: Start point of the line. - :param pt2: End point of the line. - :param color: Color of the line. - + :param pt1: Start point of the line. + :param pt2: End point of the line. + :param color: Color of the line. + PlaneWidget ----------- .. ocv:class:: PlaneWidget This 3D Widget defines a finite plane. :: - class CV_EXPORTS PlaneWidget : public Widget3D - { - public: - PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); - PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); - private: - /* hidden */ - }; - + class CV_EXPORTS PlaneWidget : public Widget3D + { + public: + PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); + PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); + private: + /* hidden */ + }; + PlaneWidget::PlaneWidget ------------------------ Constructs a PlaneWidget. .. ocv:function:: PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()) - - :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. - :param size: Size of the plane. - :param color: Color of the plane. + + :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. + :param size: Size of the plane. + :param color: Color of the plane. .. ocv:function:: PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()) - :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. - :param pt: Position of the plane. - :param color: Color of the plane. - + :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. + :param pt: Position of the plane. + :param color: Color of the plane. + SphereWidget ------------ .. ocv:class:: SphereWidget This 3D Widget defines a sphere. :: - class CV_EXPORTS SphereWidget : public Widget3D - { - public: - SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) - }; + class CV_EXPORTS SphereWidget : public Widget3D + { + public: + SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) + }; SphereWidget::SphereWidget -------------------------- @@ -206,10 +218,10 @@ Constructs a SphereWidget. .. ocv:function:: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) - :param center: Center of the sphere. - :param radius: Radius of the sphere. - :param sphere_resolution: Resolution of the sphere. - :param color: Color of the sphere. + :param center: Center of the sphere. + :param radius: Radius of the sphere. + :param sphere_resolution: Resolution of the sphere. + :param color: Color of the sphere. ArrowWidget ----------- @@ -217,59 +229,59 @@ ArrowWidget This 3D Widget defines an arrow. :: - class CV_EXPORTS ArrowWidget : public Widget3D - { - public: - ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); - }; - + class CV_EXPORTS ArrowWidget : public Widget3D + { + public: + ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); + }; + ArrowWidget::ArrowWidget ------------------------ Constructs an ArrowWidget. .. ocv:function:: ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()) - :param pt1: Start point of the arrow. - :param pt2: End point of the arrow. - :param thickness: Thickness of the arrow. Thickness of arrow head is also adjusted accordingly. - :param color: Color of the arrow. - + :param pt1: Start point of the arrow. + :param pt2: End point of the arrow. + :param thickness: Thickness of the arrow. Thickness of arrow head is also adjusted accordingly. + :param color: Color of the arrow. + Arrow head is located at the end point of the arrow. - + CircleWidget ------------ .. ocv:class:: CircleWidget This 3D Widget defines a circle. :: - class CV_EXPORTS CircleWidget : public Widget3D - { - public: - CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); - }; - + class CV_EXPORTS CircleWidget : public Widget3D + { + public: + CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); + }; + CircleWidget::CircleWidget -------------------------- Constructs a CircleWidget. .. ocv:function:: CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()) - :param pt: Center of the circle. - :param radius: Radius of the circle. - :param thickness: Thickness of the circle. - :param color: Color of the circle. - + :param pt: Center of the circle. + :param radius: Radius of the circle. + :param thickness: Thickness of the circle. + :param color: Color of the circle. + CylinderWidget -------------- .. ocv:class:: CylinderWidget This 3D Widget defines a cylinder. :: - class CV_EXPORTS CylinderWidget : public Widget3D - { - public: - CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); - }; + class CV_EXPORTS CylinderWidget : public Widget3D + { + public: + CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); + }; CylinderWidget::CylinderWidget ------------------------------ @@ -277,146 +289,146 @@ Constructs a CylinderWidget. .. ocv:function:: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()) - :param pt_on_axis: A point on the axis of the cylinder. - :param axis_direction: Direction of the axis of the cylinder. - :param radius: Radius of the cylinder. - :param numsides: Resolution of the cylinder. - :param color: Color of the cylinder. - + :param pt_on_axis: A point on the axis of the cylinder. + :param axis_direction: Direction of the axis of the cylinder. + :param radius: Radius of the cylinder. + :param numsides: Resolution of the cylinder. + :param color: Color of the cylinder. + CubeWidget ---------- .. ocv:class:: CubeWidget This 3D Widget defines a cube. :: - class CV_EXPORTS CubeWidget : public Widget3D - { - public: - CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); - }; - + class CV_EXPORTS CubeWidget : public Widget3D + { + public: + CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); + }; + CubeWidget::CubeWidget ---------------------- Constructs a CudeWidget. .. ocv:function:: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()) - :param pt_min: Specifies minimum point of the bounding box. - :param pt_max: Specifies maximum point of the bounding box. - :param wire_frame: If true, cube is represented as wireframe. - :param color: Color of the cube. - + :param pt_min: Specifies minimum point of the bounding box. + :param pt_max: Specifies maximum point of the bounding box. + :param wire_frame: If true, cube is represented as wireframe. + :param color: Color of the cube. + CoordinateSystemWidget ---------------------- .. ocv:class:: CoordinateSystemWidget This 3D Widget represents a coordinate system. :: - class CV_EXPORTS CoordinateSystemWidget : public Widget3D - { - public: - CoordinateSystemWidget(double scale = 1.0); - }; - + class CV_EXPORTS CoordinateSystemWidget : public Widget3D + { + public: + CoordinateSystemWidget(double scale = 1.0); + }; + CoordinateSystemWidget::CoordinateSystemWidget ---------------------------------------------- Constructs a CoordinateSystemWidget. .. ocv:function:: CoordinateSystemWidget(double scale = 1.0) - :param scale: Determines the size of the axes. - + :param scale: Determines the size of the axes. + PolyLineWidget -------------- .. ocv:class:: PolyLineWidget This 3D Widget defines a poly line. :: - class CV_EXPORTS PolyLineWidget : public Widget3D - { - public: - PolyLineWidget(InputArray points, const Color &color = Color::white()); + class CV_EXPORTS PolyLineWidget : public Widget3D + { + public: + PolyLineWidget(InputArray points, const Color &color = Color::white()); - private: - /* hidden */ - }; + private: + /* hidden */ + }; PolyLineWidget::PolyLineWidget ------------------------------ Constructs a PolyLineWidget. .. ocv:function:: PolyLineWidget(InputArray points, const Color &color = Color::white()) - - :param points: Point set. - :param color: Color of the poly line. - + + :param points: Point set. + :param color: Color of the poly line. + GridWidget ---------- .. ocv:class:: GridWidget This 3D Widget defines a grid. :: - class CV_EXPORTS GridWidget : public Widget3D - { - public: - //! Creates grid at the origin - GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); - //! Creates grid based on the plane equation - GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); - private: - /* hidden */ - }; - + class CV_EXPORTS GridWidget : public Widget3D + { + public: + //! Creates grid at the origin + GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + //! Creates grid based on the plane equation + GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + private: + /* hidden */ + }; + GridWidget::GridWidget ---------------------- Constructs a GridWidget. .. ocv:function:: GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) - :param dimensions: Number of columns and rows, respectively. - :param spacing: Size of each column and row, respectively. - :param color: Color of the grid. - + :param dimensions: Number of columns and rows, respectively. + :param spacing: Size of each column and row, respectively. + :param color: Color of the grid. + .. ocv:function: GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) - - :param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. - :param dimensions: Number of columns and rows, respectively. - :param spacing: Size of each column and row, respectively. - :param color: Color of the grid. - + + :param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. + :param dimensions: Number of columns and rows, respectively. + :param spacing: Size of each column and row, respectively. + :param color: Color of the grid. + Text3DWidget ------------ .. ocv:class:: Text3DWidget This 3D Widget represents 3D text. The text always faces the camera. :: - class CV_EXPORTS Text3DWidget : public Widget3D - { - public: - Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()); + class CV_EXPORTS Text3DWidget : public Widget3D + { + public: + Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()); - void setText(const String &text); - String getText() const; - }; - + void setText(const String &text); + String getText() const; + }; + Text3DWidget::Text3DWidget -------------------------- Constructs a Text3DWidget. .. ocv:function:: Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()) - :param text: Text content of the widget. - :param position: Position of the text. - :param text_scale: Size of the text. - :param color: Color of the text. - + :param text: Text content of the widget. + :param position: Position of the text. + :param text_scale: Size of the text. + :param color: Color of the text. + Text3DWidget::setText --------------------- Sets the text content of the widget. .. ocv:function:: void setText(const String &text) - :param text: Text content of the widget. + :param text: Text content of the widget. Text3DWidget::getText --------------------- @@ -430,33 +442,33 @@ TextWidget This 2D Widget represents text overlay. :: - class CV_EXPORTS TextWidget : public Widget2D - { - public: - TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); + class CV_EXPORTS TextWidget : public Widget2D + { + public: + TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); - void setText(const String &text); - String getText() const; - }; - + void setText(const String &text); + String getText() const; + }; + TextWidget::TextWidget ---------------------- Constructs a TextWidget. .. ocv:function:: TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()) - :param text: Text content of the widget. - :param pos: Position of the text. - :param font_size: Font size. - :param color: Color of the text. - + :param text: Text content of the widget. + :param pos: Position of the text. + :param font_size: Font size. + :param color: Color of the text. + TextWidget::setText --------------------- Sets the text content of the widget. .. ocv:function:: void setText(const String &text) - :param text: Text content of the widget. + :param text: Text content of the widget. TextWidget::getText --------------------- @@ -470,181 +482,181 @@ ImageOverlayWidget This 2D Widget represents an image overlay. :: - class CV_EXPORTS ImageOverlayWidget : public Widget2D - { - public: - ImageOverlayWidget(const Mat &image, const Rect &rect); - - void setImage(const Mat &image); - }; - + class CV_EXPORTS ImageOverlayWidget : public Widget2D + { + public: + ImageOverlayWidget(const Mat &image, const Rect &rect); + + void setImage(const Mat &image); + }; + ImageOverlayWidget::ImageOverlayWidget -------------------------------------- Constructs a ImageOverlayWidget. .. ocv:function:: ImageOverlayWidget(const Mat &image, const Rect &rect) - :param image: BGR or Gray-Scale image. - :param rect: Image is scaled and positioned based on rect. - + :param image: BGR or Gray-Scale image. + :param rect: Image is scaled and positioned based on rect. + ImageOverlayWidget::setImage ---------------------------- Sets the image content of the widget. .. ocv:function:: void setImage(const Mat &image) - :param image: BGR or Gray-Scale image. - + :param image: BGR or Gray-Scale image. + Image3DWidget ------------- .. ocv:class:: Image3DWidget This 3D Widget represents 3D image. :: - class CV_EXPORTS Image3DWidget : public Widget3D - { - public: - //! Creates 3D image at the origin - Image3DWidget(const Mat &image, const Size &size); - //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation - Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); - - void setImage(const Mat &image); - }; + class CV_EXPORTS Image3DWidget : public Widget3D + { + public: + //! Creates 3D image at the origin + Image3DWidget(const Mat &image, const Size &size); + //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation + Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); + + void setImage(const Mat &image); + }; Image3DWidget::Image3DWidget ---------------------------- Constructs a Image3DWidget. .. ocv:function:: Image3DWidget(const Mat &image, const Size &size) - - :param image: BGR or Gray-Scale image. - :param size: Size of the image. - + + :param image: BGR or Gray-Scale image. + :param size: Size of the image. + .. ocv:function:: Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) - :param position: Position of the image. - :param normal: Normal of the plane that represents the image. - :param up_vector: Determines orientation of the image. - :param image: BGR or Gray-Scale image. - :param size: Size of the image. - + :param position: Position of the image. + :param normal: Normal of the plane that represents the image. + :param up_vector: Determines orientation of the image. + :param image: BGR or Gray-Scale image. + :param size: Size of the image. + Image3DWidget::setImage ----------------------- Sets the image content of the widget. .. ocv:function:: void setImage(const Mat &image) - :param image: BGR or Gray-Scale image. - + :param image: BGR or Gray-Scale image. + CameraPositionWidget -------------------- .. ocv:class:: CameraPositionWidget This 3D Widget represents camera position. :: - class CV_EXPORTS CameraPositionWidget : public Widget3D - { - public: - //! Creates camera coordinate frame (axes) at the origin - CameraPositionWidget(double scale = 1.0); - //! Creates frustum based on the intrinsic marix K at the origin - CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); - //! Creates frustum based on the field of view at the origin - CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); - //! Creates frustum and display given image at the far plane - CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); - }; - + class CV_EXPORTS CameraPositionWidget : public Widget3D + { + public: + //! Creates camera coordinate frame (axes) at the origin + CameraPositionWidget(double scale = 1.0); + //! Creates frustum based on the intrinsic marix K at the origin + CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum based on the field of view at the origin + CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane + CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + }; + CameraPositionWidget::CameraPositionWidget ------------------------------------------ Constructs a CameraPositionWidget. .. ocv:function:: CameraPositionWidget(double scale = 1.0) - Creates camera coordinate frame at the origin. - + Creates camera coordinate frame at the origin. + .. ocv:function:: CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) - :param K: Intrinsic matrix of the camera. - :param scale: Scale of the frustum. - :param color: Color of the frustum. - - Creates viewing frustum of the camera based on its intrinsic matrix K. - + :param K: Intrinsic matrix of the camera. + :param scale: Scale of the frustum. + :param color: Color of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K. + .. ocv:function:: CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) - :param fov: Field of view of the camera (horizontal, vertical). - :param scale: Scale of the frustum. - :param color: Color of the frustum. - - Creates viewing frustum of the camera based on its field of view fov. + :param fov: Field of view of the camera (horizontal, vertical). + :param scale: Scale of the frustum. + :param color: Color of the frustum. + + Creates viewing frustum of the camera based on its field of view fov. .. ocv:function:: CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()) - :param K: Intrinsic matrix of the camera. - :param img: BGR or Gray-Scale image that is going to be displayed at the far plane of the frustum. - :param scale: Scale of the frustum and image. - :param color: Color of the frustum. - - Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. - + :param K: Intrinsic matrix of the camera. + :param img: BGR or Gray-Scale image that is going to be displayed at the far plane of the frustum. + :param scale: Scale of the frustum and image. + :param color: Color of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. + TrajectoryWidget ---------------- .. ocv:class:: TrajectoryWidget This 3D Widget represents a trajectory. :: - class CV_EXPORTS TrajectoryWidget : public Widget3D - { - public: - enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; - - //! Displays trajectory of the given path either by coordinate frames or polyline - TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); - //! Displays trajectory of the given path by frustums - TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); - //! Displays trajectory of the given path by frustums - TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); - - private: - /* hidden */ - }; - + class CV_EXPORTS TrajectoryWidget : public Widget3D + { + public: + enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; + + //! Displays trajectory of the given path either by coordinate frames or polyline + TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); + //! Displays trajectory of the given path by frustums + TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + //! Displays trajectory of the given path by frustums + TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + + private: + /* hidden */ + }; + TrajectoryWidget::TrajectoryWidget ---------------------------------- Constructs a TrajectoryWidget. .. ocv:function:: TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0) - :param path: List of poses on a trajectory. - :param display_mode: Display mode. This can be DISPLAY_PATH, DISPLAY_FRAMES, DISPLAY_PATH & DISPLAY_FRAMES. - :param color: Color of the polyline that represents path. Frames are not affected. - :param scale: Scale of the frames. Polyline is not affected. - - Displays trajectory of the given path as follows: - - * DISPLAY_PATH : Displays a poly line that represents the path. - * DISPLAY_FRAMES : Displays coordinate frames at each pose. - * DISPLAY_PATH & DISPLAY_FRAMES : Displays both poly line and coordinate frames. - + :param path: List of poses on a trajectory. + :param display_mode: Display mode. This can be DISPLAY_PATH, DISPLAY_FRAMES, DISPLAY_PATH & DISPLAY_FRAMES. + :param color: Color of the polyline that represents path. Frames are not affected. + :param scale: Scale of the frames. Polyline is not affected. + + Displays trajectory of the given path as follows: + + * DISPLAY_PATH : Displays a poly line that represents the path. + * DISPLAY_FRAMES : Displays coordinate frames at each pose. + * DISPLAY_PATH & DISPLAY_FRAMES : Displays both poly line and coordinate frames. + .. ocv:function:: TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) - :param path: List of poses on a trajectory. - :param K: Intrinsic matrix of the camera. - :param scale: Scale of the frustums. - :param color: Color of the frustums. - - Displays frustums at each pose of the trajectory. - + :param path: List of poses on a trajectory. + :param K: Intrinsic matrix of the camera. + :param scale: Scale of the frustums. + :param color: Color of the frustums. + + Displays frustums at each pose of the trajectory. + .. ocv:function:: TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) - :param path: List of poses on a trajectory. - :param fov: Field of view of the camera (horizontal, vertical). - :param scale: Scale of the frustums. - :param color: Color of the frustums. - - Displays frustums at each pose of the trajectory. + :param path: List of poses on a trajectory. + :param fov: Field of view of the camera (horizontal, vertical). + :param scale: Scale of the frustums. + :param color: Color of the frustums. + + Displays frustums at each pose of the trajectory. SpheresTrajectoryWidget ----------------------- @@ -653,62 +665,62 @@ SpheresTrajectoryWidget This 3D Widget represents a trajectory using spheres and lines, where spheres represent the positions of the camera, and lines represent the direction from previous position to the current. :: - class CV_EXPORTS SpheresTrajectoryWidget : public Widget3D - { - public: - SpheresTrajectoryWidget(const std::vector &path, float line_length = 0.05f, - double init_sphere_radius = 0.021, sphere_radius = 0.007, - Color &line_color = Color::white(), const Color &sphere_color = Color::white()); - }; - + class CV_EXPORTS SpheresTrajectoryWidget : public Widget3D + { + public: + SpheresTrajectoryWidget(const std::vector &path, float line_length = 0.05f, + double init_sphere_radius = 0.021, sphere_radius = 0.007, + Color &line_color = Color::white(), const Color &sphere_color = Color::white()); + }; + SpheresTrajectoryWidget::SpheresTrajectoryWidget ------------------------------------------------ Constructs a SpheresTrajectoryWidget. .. ocv:function:: SpheresTrajectoryWidget(const std::vector &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()) - - :param path: List of poses on a trajectory. - :param line_length: Length of the lines. - :param init_sphere_radius: Radius of the first sphere which represents the initial position of the camera. - :param sphere_radius: Radius of the rest of the spheres. - :param line_color: Color of the lines. - :param sphere_color: Color of the spheres. - + + :param path: List of poses on a trajectory. + :param line_length: Length of the lines. + :param init_sphere_radius: Radius of the first sphere which represents the initial position of the camera. + :param sphere_radius: Radius of the rest of the spheres. + :param line_color: Color of the lines. + :param sphere_color: Color of the spheres. + CloudWidget ----------- .. ocv:class:: CloudWidget This 3D Widget defines a point cloud. :: - class CV_EXPORTS CloudWidget : public Widget3D - { - public: - //! Each point in cloud is mapped to a color in colors - CloudWidget(InputArray cloud, InputArray colors); - //! All points in cloud have the same color - CloudWidget(InputArray cloud, const Color &color = Color::white()); + class CV_EXPORTS CloudWidget : public Widget3D + { + public: + //! Each point in cloud is mapped to a color in colors + CloudWidget(InputArray cloud, InputArray colors); + //! All points in cloud have the same color + CloudWidget(InputArray cloud, const Color &color = Color::white()); - private: - /* hidden */ - }; - + private: + /* hidden */ + }; + CloudWidget::CloudWidget ------------------------ Constructs a CloudWidget. .. ocv:function:: CloudWidget(InputArray cloud, InputArray colors) - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. - :param colors: Set of colors. It has to be of the same size with cloud. - - Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param colors: Set of colors. It has to be of the same size with cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). .. ocv:function:: CloudWidget(InputArray cloud, const Color &color = Color::white()) - - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. - :param color: A single color for the whole cloud. + + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param color: A single color for the whole cloud. - Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). CloudCollectionWidget --------------------- @@ -716,20 +728,20 @@ CloudCollectionWidget This 3D Widget defines a collection of clouds. :: - class CV_EXPORTS CloudCollectionWidget : public Widget3D - { - public: - CloudCollectionWidget(); - - //! Each point in cloud is mapped to a color in colors - void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); - //! All points in cloud have the same color - void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3f &pose = Affine3f::Identity()); - - private: - /* hidden */ - }; - + class CV_EXPORTS CloudCollectionWidget : public Widget3D + { + public: + CloudCollectionWidget(); + + //! Each point in cloud is mapped to a color in colors + void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); + //! All points in cloud have the same color + void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3f &pose = Affine3f::Identity()); + + private: + /* hidden */ + }; + CloudCollectionWidget::CloudCollectionWidget -------------------------------------------- Constructs a CloudCollectionWidget. @@ -742,69 +754,69 @@ Adds a cloud to the collection. .. ocv:function:: void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()) - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. - :param colors: Set of colors. It has to be of the same size with cloud. - :param pose: Pose of the cloud. - - Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). - + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param colors: Set of colors. It has to be of the same size with cloud. + :param pose: Pose of the cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + .. ocv:function:: void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity()) - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. - :param colors: A single color for the whole cloud. - :param pose: Pose of the cloud. - - Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). - + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param colors: A single color for the whole cloud. + :param pose: Pose of the cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + CloudNormalsWidget ------------------ .. ocv:class:: CloudNormalsWidget This 3D Widget represents normals of a point cloud. :: - class CV_EXPORTS CloudNormalsWidget : public Widget3D - { - public: - CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); + class CV_EXPORTS CloudNormalsWidget : public Widget3D + { + public: + CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); - private: - /* hidden */ - }; - + private: + /* hidden */ + }; + CloudNormalsWidget::CloudNormalsWidget -------------------------------------- Constructs a CloudNormalsWidget. .. ocv:function:: CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()) - - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. - :param normals: A set of normals that has to be of same type with cloud. - :param level: Display only every levelth normal. - :param scale: Scale of the arrows that represent normals. - :param color: Color of the arrows that represent normals. - + + :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param normals: A set of normals that has to be of same type with cloud. + :param level: Display only every levelth normal. + :param scale: Scale of the arrows that represent normals. + :param color: Color of the arrows that represent normals. + MeshWidget ---------- .. ocv:class:: MeshWidget This 3D Widget defines a mesh. :: - - class CV_EXPORTS MeshWidget : public Widget3D - { - public: - MeshWidget(const Mesh3d &mesh); - - private: - /* hidden */ - }; - + + class CV_EXPORTS MeshWidget : public Widget3D + { + public: + MeshWidget(const Mesh3d &mesh); + + private: + /* hidden */ + }; + MeshWidget::MeshWidget ---------------------- Constructs a MeshWidget. .. ocv:function:: MeshWidget(const Mesh3d &mesh) - :param mesh: Mesh object that will be displayed. + :param mesh: Mesh object that will be displayed. From b60894c1dd9fe0967f9bcc8481208267619189fe Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 1 Sep 2013 21:43:40 +0200 Subject: [PATCH 175/205] launching viz tutorial --- doc/tutorials/viz/images/window_demo.png | Bin 0 -> 7519 bytes doc/tutorials/viz/viz.rst | 118 ++++++++++++++++++ .../cpp/tutorial_code/viz/launching_viz.cpp | 53 ++++++++ 3 files changed, 171 insertions(+) create mode 100644 doc/tutorials/viz/images/window_demo.png create mode 100644 doc/tutorials/viz/viz.rst create mode 100644 samples/cpp/tutorial_code/viz/launching_viz.cpp diff --git a/doc/tutorials/viz/images/window_demo.png b/doc/tutorials/viz/images/window_demo.png new file mode 100644 index 0000000000000000000000000000000000000000..b853fe29da9b03ce7e606dae6aa743e3822df2df GIT binary patch literal 7519 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 A?*IS* literal 0 HcmV?d00001 diff --git a/doc/tutorials/viz/viz.rst b/doc/tutorials/viz/viz.rst new file mode 100644 index 000000000..ceceaf197 --- /dev/null +++ b/doc/tutorials/viz/viz.rst @@ -0,0 +1,118 @@ +.. _viz: + +Launching Viz +************* + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * Open a visualization window. + * Access a window by its name. + * Start event loop. + * Start event loop for a given amount of time. + +Code +==== + +You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/launching_viz.cpp>`_. + +.. code-block:: cpp + + #include + #include + + using namespace cv; + using namespace std; + + /** + * @function main + */ + int main() + { + /// Create a window + viz::Viz3d myWindow("Viz Demo"); + + /// Start event loop + myWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "First event loop is over" << endl; + + /// Access window via its name + viz::Viz3d sameWindow = viz::get("Viz Demo"); + + /// Start event loop + sameWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "Second event loop is over" << endl; + + /// Event loop is over when pressed q, Q, e, E + /// Start event loop once for 1 millisecond + sameWindow.spinOnce(1, true); + while(!sameWindow.wasStopped()) + { + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); + } + + /// Once more event loop is stopped + cout << "Last event loop is over" << endl; + return 0; + } + +Explanation +=========== + +Here is the general structure of the program: + +* Create a window. + +.. code-block:: cpp + + /// Create a window + viz::Viz3d myWindow("Viz Demo"); + +* Start event loop. This event loop will run until user terminates it by pressing **e**, **E**, **q**, **Q**. + +.. code-block:: cpp + + /// Start event loop + myWindow.spin(); + +* Access same window via its name. Since windows are implicitly shared, **sameWindow** is exactly the same with **myWindow**. If the name does not exist, a new window is created. + +.. code-block:: cpp + + /// Access window via its name + viz::Viz3d sameWindow = viz::get("Viz Demo"); + +* Start a controlled event loop. Once it starts, **wasStopped** is set to false. Inside the while loop, in each iteration, **spinOnce** is called to prevent event loop from completely stopping. Inside the while loop, user can execute other statements including those which interact with the window. + +.. code-block:: cpp + + /// Event loop is over when pressed q, Q, e, E + /// Start event loop once for 1 millisecond + sameWindow.spinOnce(1, true); + while(!sameWindow.wasStopped()) + { + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); + } + +Results +======= + +Here is the result of the program. + +.. image:: images/window_demo.png + :alt: Launching Viz + :align: center diff --git a/samples/cpp/tutorial_code/viz/launching_viz.cpp b/samples/cpp/tutorial_code/viz/launching_viz.cpp new file mode 100644 index 000000000..1827b33ea --- /dev/null +++ b/samples/cpp/tutorial_code/viz/launching_viz.cpp @@ -0,0 +1,53 @@ +#include +#include + +using namespace cv; +using namespace std; + +void help() +{ + cout + << "--------------------------------------------------------------------------" << endl + << "This program shows how to launch a 3D visualization window. You can stop event loop to continue executing. " + << "You can access the same window via its name. You can run event loop for a given period of time. " << endl + << "Usage:" << endl + << "./window_demo" << endl + << endl; +} + +int main() +{ + help(); + /// Create a window + viz::Viz3d myWindow("Viz Demo"); + + /// Start event loop + myWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "First event loop is over" << endl; + + /// Access window via its name + viz::Viz3d sameWindow = viz::get("Viz Demo"); + + /// Start event loop + sameWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "Second event loop is over" << endl; + + /// Event loop is over when pressed q, Q, e, E + /// Start event loop once for 1 millisecond + sameWindow.spinOnce(1, true); + while(!sameWindow.wasStopped()) + { + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); + } + + /// Once more event loop is stopped + cout << "Last event loop is over" << endl; + return 0; +} From f99e874704100bf9279a60611ff13b962c84fff7 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Thu, 5 Sep 2013 20:53:57 +0200 Subject: [PATCH 176/205] tutorial: creating_widgets code --- .../tutorial_code/viz/creating_widgets.cpp | 106 ++++++++++++++++++ .../cpp/tutorial_code/viz/launching_viz.cpp | 23 +++- 2 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 samples/cpp/tutorial_code/viz/creating_widgets.cpp diff --git a/samples/cpp/tutorial_code/viz/creating_widgets.cpp b/samples/cpp/tutorial_code/viz/creating_widgets.cpp new file mode 100644 index 000000000..1c0f9a34e --- /dev/null +++ b/samples/cpp/tutorial_code/viz/creating_widgets.cpp @@ -0,0 +1,106 @@ +/** + * @file creating_widgets.cpp + * @brief Creating custom widgets using VTK + * @author Ozan Cagri Tonkal + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace cv; +using namespace std; + +/** + * @function help + * @brief Display instructions to use this tutorial program + */ +void help() +{ + cout + << "--------------------------------------------------------------------------" << endl + << "This program shows how to create a custom widget. You can create your own " + << "widgets by extending Widget2D/Widget3D, and with the help of WidgetAccessor." << endl + << "Usage:" << endl + << "./creating_widgets" << endl + << endl; +} + +/** + * @class TriangleWidget + * @brief Defining our own 3D Triangle widget + */ +class TriangleWidget : public viz::Widget3D +{ + public: + TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); +}; + +/** + * @function TriangleWidget::TriangleWidget + * @brief Constructor + */ +TriangleWidget::TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color) +{ + // Create a triangle + vtkSmartPointer points = vtkSmartPointer::New(); + points->InsertNextPoint(pt1.x, pt1.y, pt1.z); + points->InsertNextPoint(pt2.x, pt2.y, pt2.z); + points->InsertNextPoint(pt3.x, pt3.y, pt3.z); + + vtkSmartPointer triangle = vtkSmartPointer::New(); + triangle->GetPointIds()->SetId(0,0); + triangle->GetPointIds()->SetId(1,1); + triangle->GetPointIds()->SetId(2,2); + + vtkSmartPointer cells = vtkSmartPointer::New(); + cells->InsertNextCell(triangle); + + // Create a polydata object + vtkSmartPointer polyData = vtkSmartPointer::New(); + + // Add the geometry and topology to the polydata + polyData->SetPoints(points); + polyData->SetPolys(cells); + + // Create mapper and actor + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(polyData); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + // Store this actor in the widget in order that visualizer can access it + viz::WidgetAccessor::setProp(*this, actor); +} + +/** + * @function main + */ +int main() +{ + help(); + + /// Create a window + viz::Viz3d myWindow("Creating Widgets"); + + /// Create a triangle widget + TriangleWidget tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0)); + + /// Show widget in the visualizer window + myWindow.showWidget("TRIANGLE", tw); + + /// Start event loop + myWindow.spin(); + + return 0; +} diff --git a/samples/cpp/tutorial_code/viz/launching_viz.cpp b/samples/cpp/tutorial_code/viz/launching_viz.cpp index 1827b33ea..8dc9a617f 100644 --- a/samples/cpp/tutorial_code/viz/launching_viz.cpp +++ b/samples/cpp/tutorial_code/viz/launching_viz.cpp @@ -1,9 +1,19 @@ +/** + * @file launching_viz.cpp + * @brief Launching visualization window + * @author Ozan Cagri Tonkal + */ + #include #include using namespace cv; using namespace std; +/** + * @function help + * @brief Display instructions to use this tutorial program + */ void help() { cout @@ -11,10 +21,13 @@ void help() << "This program shows how to launch a 3D visualization window. You can stop event loop to continue executing. " << "You can access the same window via its name. You can run event loop for a given period of time. " << endl << "Usage:" << endl - << "./window_demo" << endl + << "./launching_viz" << endl << endl; } +/** + * @function main + */ int main() { help(); @@ -41,10 +54,10 @@ int main() sameWindow.spinOnce(1, true); while(!sameWindow.wasStopped()) { - /// Interact with window - - /// Event loop for 1 millisecond - sameWindow.spinOnce(1, true); + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); } /// Once more event loop is stopped From 5eed0d6beff098f01d90500f3d430be9c75d3195 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Thu, 5 Sep 2013 20:54:41 +0200 Subject: [PATCH 177/205] remove common.h include from widgets.hpp --- modules/viz/include/opencv2/viz/widgets.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index fb2d6ca34..f96d0e610 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -1,8 +1,6 @@ #pragma once #include -#include - namespace cv { From eed7bf69026fdb2b0ffeec51029cdcb4348c7dbc Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 6 Sep 2013 18:43:14 +0400 Subject: [PATCH 178/205] compilation for windows --- modules/viz/src/interactor_style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index ace60c860..42b3f6b0b 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -275,7 +275,7 @@ cv::viz::InteractorStyle::OnKeyDown () std::cerr << Mat(clip, false).reshape(1, 1) << "/" << Mat(focal, false).reshape(1, 1) << "/" << Mat(pose, false).reshape(1, 1) << "/" << Mat(view, false).reshape(1, 1) << "/" << - cam->GetViewAngle () / 180.0 * M_PI << "/" << + cam->GetViewAngle () / 180.0 * CV_PI << "/" << Mat(win_size, false).reshape(1,1) << "/" << Mat(win_pos, false).reshape(1,1) << endl; break; } From 477ca067f06c25bcb5c9c2fcd67d32ee79abfc49 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 6 Sep 2013 19:32:35 +0400 Subject: [PATCH 179/205] compilation for macos --- modules/viz/CMakeLists.txt | 2 +- modules/viz/src/viz3d_impl.cpp | 4 +++- modules/viz/test/test_viz3d.cpp | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 5de29bbc6..a09ad15e1 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -12,7 +12,7 @@ macro(find_qvtk) endmacro() macro(find_vtk) - find_package(VTK 5.8.0 REQUIRED) + find_package(VTK 5.10.0 REQUIRED) if(VTK_FOUND) if (BUILD_SHARED_LIBS OR (NOT BUILD_SHARED_LIBS AND NOT VTK_BUILD_SHARED_LIBS)) find_qvtk() diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index f99fd8e1f..d308ade25 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1,7 +1,9 @@ #include "precomp.hpp" #include "viz3d_impl.hpp" -#ifndef __APPLE__ +#include + +#if 1 || !defined __APPLE__ vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew () { return vtkRenderWindowInteractor::New(); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 66f811884..d8dbb64ca 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -54,7 +54,7 @@ using namespace cv; cv::Mat cvcloud_load() { cv::Mat cloud(1, 20000, CV_32FC3); - std::ifstream ifs("d:/cloud_dragon.ply"); + std::ifstream ifs("/Users/nerei/cloud_dragon.ply"); std::string str; for(size_t i = 0; i < 11; ++i) @@ -72,7 +72,7 @@ TEST(Viz_viz3d, accuracy) cv::Mat cloud = cvcloud_load(); cv::Mat colors(cloud.size(), CV_8UC3, cv::Scalar(0, 255, 0)); cv::Mat normals(cloud.size(), cloud.type(), cv::Scalar(0, 10, 0)); - //cv::viz::Mesh3d::Ptr mesh = cv::viz::Mesh3d::mesh_load("d:/horse.ply"); + //cv::viz::Mesh3d::Ptr mesh = cv::viz::Mesh3d::mesh_load("/Users/nerei/horse.ply"); const Vec4d data[] = { Vec4d(0.0, 0.0, 0.0, 0.0), Vec4d(1.0, 1.0, 1.0, 1.0), cv::Vec4d(0.0, 2.0, 0.0, 0.0), cv::Vec4d(3.0, 4.0, 1.0, 1.0) }; cv::Mat points(1, sizeof(data)/sizeof(data[0]), CV_64FC4, (void*)data); @@ -133,7 +133,7 @@ TEST(Viz_viz3d, accuracy) // viz.showWidget("polyline", plw); // lw = v.getWidget("polyline").cast(); - viz::Mesh3d mesh = cv::viz::Mesh3d::loadMesh("horse.ply"); + viz::Mesh3d mesh = cv::viz::Mesh3d::loadMesh("/Users/nerei/horse.ply"); viz::MeshWidget mw(mesh); // viz.showWidget("mesh", mw); @@ -146,7 +146,7 @@ TEST(Viz_viz3d, accuracy) 0, 657, 240, 0, 0, 1); - viz::CameraPositionWidget cpw(Vec3f(0.5, 0.5, 3.0), Vec3f(0.0,0.0,0.0), Vec3f(0.0,-1.0,0.0), 0.5); + //viz::CameraPositionWidget cpw(Vec3f(0.5, 0.5, 3.0), Vec3f(0.0,0.0,0.0), Vec3f(0.0,-1.0,0.0), 0.5); viz::CameraPositionWidget cpw2(0.5); viz::CameraPositionWidget frustum(K, 2.0, viz::Color::green()); // viz::CameraPositionWidget frustum2(K, 4.0, viz::Color::red()); @@ -170,7 +170,7 @@ TEST(Viz_viz3d, accuracy) trajectory.push_back(Affine3f().translate(Vec3f(2.0,0.5,0.0))); trajectory.push_back(Affine3f(0.5, 0.0, 0.0, Vec3f(1.0,0.0,1.0))); // - viz.showWidget("trajectory1", viz::TrajectoryWidget(trajectory, viz::Color(0,255,255), true, 0.5)); + //viz.showWidget("trajectory1", viz::TrajectoryWidget(trajectory, viz::Color(0,255,255), true, 0.5)); viz.showWidget("trajectory2", viz::TrajectoryWidget(trajectory, K, 1.0, viz::Color(255,0,255))); From 9a91a12fb2b4210150268efce379806ff0bcdafc Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 6 Sep 2013 19:50:22 +0400 Subject: [PATCH 180/205] VIZ disabled by default, VTK search is performed iff BUILD_opencv_viz is enabled --- modules/viz/CMakeLists.txt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index a09ad15e1..84981f6a0 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -22,30 +22,31 @@ macro(find_vtk) set(HAVE_VTK ON) else () set(HAVE_VTK OFF) - message (WARNING "VTK disabled. You are to build OpenCV in STATIC but VTK is SHARED!") + message (FATAL_ERROR "VTK disabled. You are to build OpenCV in STATIC but VTK is SHARED!") endif () endif() endmacro() -find_vtk() +if (NOT OPENCV_INITIAL_PASS AND DEFINED BUILD_opencv_viz AND BUILD_opencv_viz) + find_vtk() +endif() -if(HAVE_VTK) +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) -else() - return() endif() - - + set(the_description "Viz") set(BUILD_opencv_viz_INIT OFF) include_directories(src) ocv_define_module(viz opencv_core) -if(BUILD_opencv_viz) +if(DEFINED BUILD_opencv_viz AND BUILD_opencv_viz AND DEFINED HAVE_VTK AND HAVE_VTK) target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkFiltering vtkRendering) if(APPLE) - target_link_libraries(opencv_viz "-framework Cocoa") + target_link_libraries(opencv_viz "-framework Cocoa") endif() endif() + + From fdbf20c172ef5b48b70e38ff8094d5096fd0d2e2 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sat, 7 Sep 2013 13:20:13 +0200 Subject: [PATCH 181/205] delete common.h, viz_types.hpp, rendering properties are public, setcolor in creating_widgets tutorial --- doc/tutorials/viz/viz.rst | 118 ------------------ modules/viz/include/opencv2/viz/widgets.hpp | 28 +++++ modules/viz/src/common.h | 39 ------ modules/viz/src/interactor_style.h | 1 - modules/viz/src/precomp.hpp | 7 ++ modules/viz/src/viz3d_impl.hpp | 2 - modules/viz/src/viz_types.h | 12 -- modules/viz/test/test_viz3d.cpp | 5 +- .../tutorial_code/viz/creating_widgets.cpp | 5 +- 9 files changed, 43 insertions(+), 174 deletions(-) delete mode 100644 doc/tutorials/viz/viz.rst delete mode 100644 modules/viz/src/common.h delete mode 100644 modules/viz/src/viz_types.h diff --git a/doc/tutorials/viz/viz.rst b/doc/tutorials/viz/viz.rst deleted file mode 100644 index ceceaf197..000000000 --- a/doc/tutorials/viz/viz.rst +++ /dev/null @@ -1,118 +0,0 @@ -.. _viz: - -Launching Viz -************* - -Goal -==== - -In this tutorial you will learn how to - -.. container:: enumeratevisibleitemswithsquare - - * Open a visualization window. - * Access a window by its name. - * Start event loop. - * Start event loop for a given amount of time. - -Code -==== - -You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/launching_viz.cpp>`_. - -.. code-block:: cpp - - #include - #include - - using namespace cv; - using namespace std; - - /** - * @function main - */ - int main() - { - /// Create a window - viz::Viz3d myWindow("Viz Demo"); - - /// Start event loop - myWindow.spin(); - - /// Event loop is over when pressed q, Q, e, E - cout << "First event loop is over" << endl; - - /// Access window via its name - viz::Viz3d sameWindow = viz::get("Viz Demo"); - - /// Start event loop - sameWindow.spin(); - - /// Event loop is over when pressed q, Q, e, E - cout << "Second event loop is over" << endl; - - /// Event loop is over when pressed q, Q, e, E - /// Start event loop once for 1 millisecond - sameWindow.spinOnce(1, true); - while(!sameWindow.wasStopped()) - { - /// Interact with window - - /// Event loop for 1 millisecond - sameWindow.spinOnce(1, true); - } - - /// Once more event loop is stopped - cout << "Last event loop is over" << endl; - return 0; - } - -Explanation -=========== - -Here is the general structure of the program: - -* Create a window. - -.. code-block:: cpp - - /// Create a window - viz::Viz3d myWindow("Viz Demo"); - -* Start event loop. This event loop will run until user terminates it by pressing **e**, **E**, **q**, **Q**. - -.. code-block:: cpp - - /// Start event loop - myWindow.spin(); - -* Access same window via its name. Since windows are implicitly shared, **sameWindow** is exactly the same with **myWindow**. If the name does not exist, a new window is created. - -.. code-block:: cpp - - /// Access window via its name - viz::Viz3d sameWindow = viz::get("Viz Demo"); - -* Start a controlled event loop. Once it starts, **wasStopped** is set to false. Inside the while loop, in each iteration, **spinOnce** is called to prevent event loop from completely stopping. Inside the while loop, user can execute other statements including those which interact with the window. - -.. code-block:: cpp - - /// Event loop is over when pressed q, Q, e, E - /// Start event loop once for 1 millisecond - sameWindow.spinOnce(1, true); - while(!sameWindow.wasStopped()) - { - /// Interact with window - - /// Event loop for 1 millisecond - sameWindow.spinOnce(1, true); - } - -Results -======= - -Here is the result of the program. - -.. image:: images/window_demo.png - :alt: Launching Viz - :align: center diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index f96d0e610..834af227d 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -6,6 +6,34 @@ namespace cv { namespace viz { + ///////////////////////////////////////////////////////////////////////////// + /// Widget rendering properties + enum RenderingProperties + { + VIZ_POINT_SIZE, + VIZ_OPACITY, + VIZ_LINE_WIDTH, + VIZ_FONT_SIZE, + VIZ_COLOR, + VIZ_REPRESENTATION, + VIZ_IMMEDIATE_RENDERING, + VIZ_SHADING + }; + + enum RenderingRepresentationProperties + { + REPRESENTATION_POINTS, + REPRESENTATION_WIREFRAME, + REPRESENTATION_SURFACE + }; + + enum ShadingRepresentationProperties + { + SHADING_FLAT, + SHADING_GOURAUD, + SHADING_PHONG + }; + ///////////////////////////////////////////////////////////////////////////// /// The base class for all widgets class CV_EXPORTS Widget diff --git a/modules/viz/src/common.h b/modules/viz/src/common.h deleted file mode 100644 index 7e13b0fee..000000000 --- a/modules/viz/src/common.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace cv -{ - namespace viz - { - enum RenderingProperties - { - VIZ_POINT_SIZE, - VIZ_OPACITY, - VIZ_LINE_WIDTH, - VIZ_FONT_SIZE, - VIZ_COLOR, - VIZ_REPRESENTATION, - VIZ_IMMEDIATE_RENDERING, - VIZ_SHADING - }; - - enum RenderingRepresentationProperties - { - REPRESENTATION_POINTS, - REPRESENTATION_WIREFRAME, - REPRESENTATION_SURFACE - }; - - enum ShadingRepresentationProperties - { - SHADING_FLAT, - SHADING_GOURAUD, - SHADING_PHONG - }; - - } - -} diff --git a/modules/viz/src/interactor_style.h b/modules/viz/src/interactor_style.h index aba03a373..e48eb3d2c 100644 --- a/modules/viz/src/interactor_style.h +++ b/modules/viz/src/interactor_style.h @@ -1,6 +1,5 @@ #pragma once -#include "viz_types.h" #include namespace cv diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 9dafeecc8..b2a26b541 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -76,6 +76,13 @@ #undef __DEPRECATED_DISABLED__ #endif +namespace cv +{ + namespace viz + { + typedef std::map > WidgetActorMap; + } +} #include "viz3d_impl.hpp" #include diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 7e31501ed..b6986b20c 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -2,8 +2,6 @@ #include #include "interactor_style.h" -#include "viz_types.h" -#include "common.h" struct cv::viz::Viz3d::VizImpl { diff --git a/modules/viz/src/viz_types.h b/modules/viz/src/viz_types.h deleted file mode 100644 index 33de56af3..000000000 --- a/modules/viz/src/viz_types.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "precomp.hpp" - -namespace cv -{ - namespace viz - { - typedef std::map > WidgetActorMap; - } -} - diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index d8dbb64ca..5e9d13c7b 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -100,6 +101,7 @@ TEST(Viz_viz3d, accuracy) viz::CoordinateSystemWidget csw; viz::TextWidget tw("TEST", Point(100, 100), 20); viz::CloudWidget pcw(cloud, colors); +// pcw.setRenderingProperty(VIZ_LINE_WIDTH)); viz::CloudWidget pcw2(cloud, viz::Color::magenta()); // viz.showWidget("line", lw); @@ -135,7 +137,7 @@ TEST(Viz_viz3d, accuracy) viz::Mesh3d mesh = cv::viz::Mesh3d::loadMesh("/Users/nerei/horse.ply"); - viz::MeshWidget mw(mesh); +// viz::MeshWidget mw(mesh); // viz.showWidget("mesh", mw); Mat img = imread("opencv.png"); @@ -173,6 +175,7 @@ TEST(Viz_viz3d, accuracy) //viz.showWidget("trajectory1", viz::TrajectoryWidget(trajectory, viz::Color(0,255,255), true, 0.5)); viz.showWidget("trajectory2", viz::TrajectoryWidget(trajectory, K, 1.0, viz::Color(255,0,255))); +// cv::Rodrigues2(Vec3f(), Mat()); // viz.showWidget("trajectory1", viz::TrajectoryWidget(trajectory/*, viz::Color::yellow()*/)); diff --git a/samples/cpp/tutorial_code/viz/creating_widgets.cpp b/samples/cpp/tutorial_code/viz/creating_widgets.cpp index 1c0f9a34e..9d2b5a313 100644 --- a/samples/cpp/tutorial_code/viz/creating_widgets.cpp +++ b/samples/cpp/tutorial_code/viz/creating_widgets.cpp @@ -81,6 +81,9 @@ TriangleWidget::TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Poi // Store this actor in the widget in order that visualizer can access it viz::WidgetAccessor::setProp(*this, actor); + + // Set the color of the widget. This has to be called after WidgetAccessor. + setColor(color); } /** @@ -94,7 +97,7 @@ int main() viz::Viz3d myWindow("Creating Widgets"); /// Create a triangle widget - TriangleWidget tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0)); + TriangleWidget tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); /// Show widget in the visualizer window myWindow.showWidget("TRIANGLE", tw); From 94ca5d65d0aee4c739be4a581b99d199323433b0 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sat, 7 Sep 2013 14:48:46 +0200 Subject: [PATCH 182/205] remove VIZ prefix from rendering properties, fix setRenderingProperties and getRenderingProperties methods --- modules/viz/include/opencv2/viz/widgets.hpp | 16 +- modules/viz/src/widget.cpp | 214 +++++++++++--------- 2 files changed, 129 insertions(+), 101 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 834af227d..1adc9fccd 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -10,14 +10,14 @@ namespace cv /// Widget rendering properties enum RenderingProperties { - VIZ_POINT_SIZE, - VIZ_OPACITY, - VIZ_LINE_WIDTH, - VIZ_FONT_SIZE, - VIZ_COLOR, - VIZ_REPRESENTATION, - VIZ_IMMEDIATE_RENDERING, - VIZ_SHADING + POINT_SIZE, + OPACITY, + LINE_WIDTH, + FONT_SIZE, + COLOR, + REPRESENTATION, + IMMEDIATE_RENDERING, + SHADING }; enum RenderingRepresentationProperties diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 196ec9939..5f52b9281 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -36,38 +36,38 @@ cv::viz::Widget::~Widget() cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) { - vtkSmartPointer reader = vtkSmartPointer::New (); - reader->SetFileName (file_name.c_str ()); + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(file_name.c_str()); vtkSmartPointer data = reader->GetOutput(); CV_Assert("File does not exist or file format is not supported." && data); vtkSmartPointer actor = vtkSmartPointer::New(); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (data); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(data); - vtkSmartPointer scalars = data->GetPointData ()->GetScalars (); + vtkSmartPointer scalars = data->GetPointData()->GetScalars(); if (scalars) { cv::Vec3d minmax(scalars->GetRange()); mapper->SetScalarRange(minmax.val); - mapper->SetScalarModeToUsePointData (); + 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 ()); + vtkPolyData* polyData = vtkPolyData::SafeDownCast(data); + bool interpolation = (polyData && polyData->GetNumberOfCells() != polyData->GetNumberOfVerts()); - mapper->SetInterpolateScalarsBeforeMapping (interpolation); - mapper->ScalarVisibilityOn (); + mapper->SetInterpolateScalarsBeforeMapping(interpolation); + mapper->ScalarVisibilityOn(); } - mapper->ImmediateModeRenderingOff (); + mapper->ImmediateModeRenderingOff(); - actor->SetNumberOfCloudPoints (int (std::max (1, data->GetNumberOfPoints () / 10))); - actor->GetProperty ()->SetInterpolationToFlat (); - actor->GetProperty ()->BackfaceCullingOn (); + actor->SetNumberOfCloudPoints(int(std::max(1, data->GetNumberOfPoints() / 10))); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); - actor->SetMapper (mapper); + actor->SetMapper(mapper); Widget widget; widget.impl_->prop = actor; @@ -81,35 +81,85 @@ void cv::viz::Widget::setRenderingProperty(int property, double value) switch (property) { - case VIZ_POINT_SIZE: + case POINT_SIZE: { - actor->GetProperty ()->SetPointSize (float (value)); - actor->Modified (); + actor->GetProperty()->SetPointSize(float(value)); + actor->Modified(); break; } - case VIZ_OPACITY: + case OPACITY: { - actor->GetProperty ()->SetOpacity (value); - actor->Modified (); + actor->GetProperty()->SetOpacity(value); + actor->Modified(); break; } - // Turn on/off flag to control whether data is rendered using immediate - // mode or note. Immediate mode rendering tends to be slower but it can - // handle larger datasets. The default value is immediate mode off. If you - // are having problems rendering a large dataset you might want to consider - // using immediate more rendering. - case VIZ_IMMEDIATE_RENDERING: + case IMMEDIATE_RENDERING: { - actor->GetMapper ()->SetImmediateModeRendering (int (value)); - actor->Modified (); + actor->GetMapper()->SetImmediateModeRendering(int(value)); + actor->Modified(); break; } - case VIZ_LINE_WIDTH: + case LINE_WIDTH: { - actor->GetProperty ()->SetLineWidth (float (value)); - actor->Modified (); + actor->GetProperty()->SetLineWidth(float(value)); + actor->Modified(); break; } + case FONT_SIZE: + { + vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor); + CV_Assert("Widget does not have text content." && text_actor); + vtkSmartPointer tprop = text_actor->GetTextProperty(); + tprop->SetFontSize(int(value)); + text_actor->Modified(); + break; + } + case REPRESENTATION: + { + switch (int(value)) + { + case REPRESENTATION_POINTS: actor->GetProperty()->SetRepresentationToPoints(); break; + case REPRESENTATION_WIREFRAME: actor->GetProperty()->SetRepresentationToWireframe(); break; + case REPRESENTATION_SURFACE: actor->GetProperty()->SetRepresentationToSurface(); break; + } + actor->Modified(); + break; + } + case SHADING: + { + switch (int(value)) + { + case SHADING_FLAT: actor->GetProperty()->SetInterpolationToFlat(); break; + case SHADING_GOURAUD: + { + if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) + { + vtkSmartPointer normals = vtkSmartPointer::New(); + normals->SetInput(actor->GetMapper()->GetInput()); + normals->Update(); + vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInput(normals->GetOutput()); + } + actor->GetProperty()->SetInterpolationToGouraud(); + break; + } + case SHADING_PHONG: + { + if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) + { + vtkSmartPointer normals = vtkSmartPointer::New(); + normals->SetInput(actor->GetMapper()->GetInput()); + normals->Update(); + vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInput(normals->GetOutput()); + } + actor->GetProperty()->SetInterpolationToPhong(); + break; + } + } + actor->Modified(); + break; + } + + default: CV_Assert("setPointCloudRenderingProperties: Unknown property"); } @@ -123,74 +173,52 @@ double cv::viz::Widget::getRenderingProperty(int property) const double value = 0.0; switch (property) { - case VIZ_POINT_SIZE: + case POINT_SIZE: { - value = actor->GetProperty ()->GetPointSize (); - actor->Modified (); + value = actor->GetProperty()->GetPointSize(); break; } - case VIZ_OPACITY: + case OPACITY: { - value = actor->GetProperty ()->GetOpacity (); - actor->Modified (); + value = actor->GetProperty()->GetOpacity(); break; } - case VIZ_LINE_WIDTH: + case IMMEDIATE_RENDERING: { - value = actor->GetProperty ()->GetLineWidth (); - actor->Modified (); + value = actor->GetMapper()->GetImmediateModeRendering(); break; } - case VIZ_FONT_SIZE: + case LINE_WIDTH: { - vtkTextActor* text_actor = vtkTextActor::SafeDownCast (actor); - vtkSmartPointer tprop = text_actor->GetTextProperty (); - tprop->SetFontSize (int (value)); - text_actor->Modified (); + value = actor->GetProperty()->GetLineWidth(); break; } - case VIZ_REPRESENTATION: + case FONT_SIZE: { - switch (int (value)) + vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor); + CV_Assert("Widget does not have text content." && text_actor); + vtkSmartPointer tprop = text_actor->GetTextProperty(); + value = tprop->GetFontSize(); + break; + } + case REPRESENTATION: + { + switch (actor->GetProperty()->GetRepresentation()) { - case REPRESENTATION_POINTS: actor->GetProperty ()->SetRepresentationToPoints (); break; - case REPRESENTATION_WIREFRAME: actor->GetProperty ()->SetRepresentationToWireframe (); break; - case REPRESENTATION_SURFACE: actor->GetProperty ()->SetRepresentationToSurface (); break; + case VTK_POINTS: value = REPRESENTATION_POINTS; break; + case VTK_WIREFRAME: value = REPRESENTATION_WIREFRAME; break; + case VTK_SURFACE: value = REPRESENTATION_SURFACE; break; } - actor->Modified (); break; } - case VIZ_SHADING: + case SHADING: { - switch (int (value)) + switch (actor->GetProperty()->GetInterpolation()) { - case SHADING_FLAT: actor->GetProperty ()->SetInterpolationToFlat (); break; - case SHADING_GOURAUD: - { - if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) - { - vtkSmartPointer normals = vtkSmartPointer::New (); - normals->SetInput (actor->GetMapper ()->GetInput ()); - normals->Update (); - vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ()); - } - actor->GetProperty ()->SetInterpolationToGouraud (); - break; - } - case SHADING_PHONG: - { - if (!actor->GetMapper ()->GetInput ()->GetPointData ()->GetNormals ()) - { - vtkSmartPointer normals = vtkSmartPointer::New (); - normals->SetInput (actor->GetMapper ()->GetInput ()); - normals->Update (); - vtkDataSetMapper::SafeDownCast (actor->GetMapper ())->SetInput (normals->GetOutput ()); - } - actor->GetProperty ()->SetInterpolationToPhong (); - break; - } + case VTK_FLAT: value = SHADING_FLAT; break; + case VTK_GOURAUD: value = SHADING_GOURAUD; break; + case VTK_PHONG: value = SHADING_PHONG; break; } - actor->Modified (); break; } default: @@ -222,13 +250,13 @@ struct cv::viz::Widget3D::MatrixConverter Matx44f m; for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) - m(i, k) = vtk_matrix->GetElement (i, k); + m(i, k) = vtk_matrix->GetElement(i, k); return m; } - static vtkSmartPointer convertToVtkMatrix (const Matx44f& m) + static vtkSmartPointer convertToVtkMatrix(const Matx44f& m) { - vtkSmartPointer vtk_matrix = vtkSmartPointer::New (); + vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) vtk_matrix->SetElement(i, k, m(i, k)); @@ -242,8 +270,8 @@ void cv::viz::Widget3D::setPose(const Affine3f &pose) CV_Assert("Widget is not 3D." && actor); vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); + actor->SetUserMatrix(matrix); + actor->Modified(); } void cv::viz::Widget3D::updatePose(const Affine3f &pose) @@ -262,8 +290,8 @@ void cv::viz::Widget3D::updatePose(const Affine3f &pose) Affine3f updated_pose = pose * Affine3f(matrix_cv); matrix = MatrixConverter::convertToVtkMatrix(updated_pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); + actor->SetUserMatrix(matrix); + actor->Modified(); } cv::Affine3f cv::viz::Widget3D::getPose() const @@ -283,10 +311,10 @@ void cv::viz::Widget3D::setColor(const Color &color) CV_Assert("Widget type is not supported." && actor); Color c = vtkcolor(color); - actor->GetMapper ()->ScalarVisibilityOff (); - actor->GetProperty ()->SetColor (c.val); - actor->GetProperty ()->SetEdgeColor (c.val); - actor->Modified (); + actor->GetMapper()->ScalarVisibilityOff(); + actor->GetProperty()->SetColor(c.val); + actor->GetProperty()->SetEdgeColor(c.val); + actor->Modified(); } template<> cv::viz::Widget3D cv::viz::Widget::cast() @@ -307,8 +335,8 @@ void cv::viz::Widget2D::setColor(const Color &color) vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Widget type is not supported." && actor); Color c = vtkcolor(color); - actor->GetProperty ()->SetColor (c.val); - actor->Modified (); + actor->GetProperty()->SetColor(c.val); + actor->Modified(); } template<> cv::viz::Widget2D cv::viz::Widget::cast() From fcf437cf69ecfea9754f81641393fe6b716d4f86 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sat, 7 Sep 2013 15:16:26 +0200 Subject: [PATCH 183/205] combine representation methods to one as setRepresentation --- modules/viz/include/opencv2/viz/viz3d.hpp | 4 +- modules/viz/src/viz3d.cpp | 4 +- modules/viz/src/viz3d_impl.cpp | 45 +++++++++++------------ modules/viz/src/viz3d_impl.hpp | 4 +- 4 files changed, 25 insertions(+), 32 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 4c6015d7d..3e7d99935 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -65,9 +65,7 @@ namespace cv void setDesiredUpdateRate(double time); double getDesiredUpdateRate(); - void setRepresentationToSurface(); - void setRepresentationToWireframe(); - void setRepresentationToPoints(); + void setRepresentation(int representation); private: struct VizImpl; diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 068d9b1b7..ba323c243 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -87,6 +87,4 @@ double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { re void cv::viz::Viz3d::setDesiredUpdateRate(double time) { impl_->setDesiredUpdateRate(time); } double cv::viz::Viz3d::getDesiredUpdateRate() { return impl_->getDesiredUpdateRate(); } -void cv::viz::Viz3d::setRepresentationToSurface() { impl_->setRepresentationToSurface(); } -void cv::viz::Viz3d::setRepresentationToWireframe() { impl_->setRepresentationToWireframe(); } -void cv::viz::Viz3d::setRepresentationToPoints() { impl_->setRepresentationToPoints(); } \ No newline at end of file +void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index d308ade25..765e71b22 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -464,33 +464,32 @@ void cv::viz::Viz3d::VizImpl::resetCamera() } /////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setRepresentationToSurface() +void cv::viz::Viz3d::VizImpl::setRepresentation(int representation) { vtkActorCollection * actors = renderer_->GetActors(); actors->InitTraversal(); vtkActor * actor; - while ((actor = actors->GetNextActor()) != NULL) - actor->GetProperty()->SetRepresentationToSurface(); -} - -/////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setRepresentationToPoints() -{ - vtkActorCollection * actors = renderer_->GetActors(); - actors->InitTraversal(); - vtkActor * actor; - while ((actor = actors->GetNextActor()) != NULL) - actor->GetProperty()->SetRepresentationToPoints(); -} - -/////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setRepresentationToWireframe() -{ - vtkActorCollection * actors = renderer_->GetActors(); - actors->InitTraversal(); - vtkActor *actor; - while ((actor = actors->GetNextActor()) != NULL) - actor->GetProperty()->SetRepresentationToWireframe(); + switch (representation) + { + case REPRESENTATION_POINTS: + { + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToPoints(); + break; + } + case REPRESENTATION_SURFACE: + { + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToSurface(); + break; + } + case REPRESENTATION_WIREFRAME: + { + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToWireframe(); + break; + } + } } ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index b6986b20c..98c2c4554 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -44,9 +44,7 @@ public: } } - void setRepresentationToSurface(); - void setRepresentationToPoints(); - void setRepresentationToWireframe(); + void setRepresentation(int representation); void setCamera(const Camera &camera); Camera getCamera() const; From 7116e22b5247ffffa82298ed48da9edc369f3b5e Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sat, 7 Sep 2013 15:44:26 +0200 Subject: [PATCH 184/205] some of the tutorials --- doc/tutorials/viz/creating_widgets.rst | 155 +++++++++++++++++ doc/tutorials/viz/launching_viz.rst | 118 +++++++++++++ doc/tutorials/viz/widget_pose.rst | 162 ++++++++++++++++++ samples/cpp/tutorial_code/viz/widget_pose.cpp | 79 +++++++++ 4 files changed, 514 insertions(+) create mode 100644 doc/tutorials/viz/creating_widgets.rst create mode 100644 doc/tutorials/viz/launching_viz.rst create mode 100644 doc/tutorials/viz/widget_pose.rst create mode 100644 samples/cpp/tutorial_code/viz/widget_pose.cpp diff --git a/doc/tutorials/viz/creating_widgets.rst b/doc/tutorials/viz/creating_widgets.rst new file mode 100644 index 000000000..a0e9da36c --- /dev/null +++ b/doc/tutorials/viz/creating_widgets.rst @@ -0,0 +1,155 @@ +.. _creating_widgets: + +Creating Widgets +**************** + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * Create your own widgets using WidgetAccessor and VTK. + * Show your widget in the visualization window. + +Code +==== + +You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/creating_widgets.cpp>`_. + +.. code-block:: cpp + + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + + using namespace cv; + using namespace std; + + /** + * @class TriangleWidget + * @brief Defining our own 3D Triangle widget + */ + class TriangleWidget : public viz::Widget3D + { + public: + TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + }; + + /** + * @function TriangleWidget::TriangleWidget + */ + TriangleWidget::TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color) + { + // Create a triangle + vtkSmartPointer points = vtkSmartPointer::New(); + points->InsertNextPoint(pt1.x, pt1.y, pt1.z); + points->InsertNextPoint(pt2.x, pt2.y, pt2.z); + points->InsertNextPoint(pt3.x, pt3.y, pt3.z); + + vtkSmartPointer triangle = vtkSmartPointer::New(); + triangle->GetPointIds()->SetId(0,0); + triangle->GetPointIds()->SetId(1,1); + triangle->GetPointIds()->SetId(2,2); + + vtkSmartPointer cells = vtkSmartPointer::New(); + cells->InsertNextCell(triangle); + + // Create a polydata object + vtkSmartPointer polyData = vtkSmartPointer::New(); + + // Add the geometry and topology to the polydata + polyData->SetPoints(points); + polyData->SetPolys(cells); + + // Create mapper and actor + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(polyData); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + // Store this actor in the widget in order that visualizer can access it + viz::WidgetAccessor::setProp(*this, actor); + + // Set the color of the widget. This has to be called after WidgetAccessor. + setColor(color); + } + + /** + * @function main + */ + int main() + { + /// Create a window + viz::Viz3d myWindow("Creating Widgets"); + + /// Create a triangle widget + TriangleWidget tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); + + /// Show widget in the visualizer window + myWindow.showWidget("TRIANGLE", tw); + + /// Start event loop + myWindow.spin(); + + return 0; + } + +Explanation +=========== + +Here is the general structure of the program: + +* Extend Widget3D class to create a new 3D widget. + +.. code-block:: cpp + + class TriangleWidget : public viz::Widget3D + { + public: + TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + }; + +* Assign a VTK actor to the widget. + +.. code-block:: cpp + + // Store this actor in the widget in order that visualizer can access it + viz::WidgetAccessor::setProp(*this, actor); + +* Set color of the widget. + +.. code-block:: cpp + + // Set the color of the widget. This has to be called after WidgetAccessor. + setColor(color); + +* Construct a triangle widget and display it in the window. + +.. code-block:: cpp + + /// Create a triangle widget + TriangleWidget tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); + + /// Show widget in the visualizer window + myWindow.showWidget("TRIANGLE", tw); + +Results +======= + +Here is the result of the program. + +.. image:: images/red_triangle.png + :alt: Creating Widgets + :align: center diff --git a/doc/tutorials/viz/launching_viz.rst b/doc/tutorials/viz/launching_viz.rst new file mode 100644 index 000000000..4b8bd5f93 --- /dev/null +++ b/doc/tutorials/viz/launching_viz.rst @@ -0,0 +1,118 @@ +.. _launching_viz: + +Launching Viz +************* + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * Open a visualization window. + * Access a window by its name. + * Start event loop. + * Start event loop for a given amount of time. + +Code +==== + +You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/launching_viz.cpp>`_. + +.. code-block:: cpp + + #include + #include + + using namespace cv; + using namespace std; + + /** + * @function main + */ + int main() + { + /// Create a window + viz::Viz3d myWindow("Viz Demo"); + + /// Start event loop + myWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "First event loop is over" << endl; + + /// Access window via its name + viz::Viz3d sameWindow = viz::get("Viz Demo"); + + /// Start event loop + sameWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "Second event loop is over" << endl; + + /// Event loop is over when pressed q, Q, e, E + /// Start event loop once for 1 millisecond + sameWindow.spinOnce(1, true); + while(!sameWindow.wasStopped()) + { + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); + } + + /// Once more event loop is stopped + cout << "Last event loop is over" << endl; + return 0; + } + +Explanation +=========== + +Here is the general structure of the program: + +* Create a window. + +.. code-block:: cpp + + /// Create a window + viz::Viz3d myWindow("Viz Demo"); + +* Start event loop. This event loop will run until user terminates it by pressing **e**, **E**, **q**, **Q**. + +.. code-block:: cpp + + /// Start event loop + myWindow.spin(); + +* Access same window via its name. Since windows are implicitly shared, **sameWindow** is exactly the same with **myWindow**. If the name does not exist, a new window is created. + +.. code-block:: cpp + + /// Access window via its name + viz::Viz3d sameWindow = viz::get("Viz Demo"); + +* Start a controlled event loop. Once it starts, **wasStopped** is set to false. Inside the while loop, in each iteration, **spinOnce** is called to prevent event loop from completely stopping. Inside the while loop, user can execute other statements including those which interact with the window. + +.. code-block:: cpp + + /// Event loop is over when pressed q, Q, e, E + /// Start event loop once for 1 millisecond + sameWindow.spinOnce(1, true); + while(!sameWindow.wasStopped()) + { + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); + } + +Results +======= + +Here is the result of the program. + +.. image:: images/window_demo.png + :alt: Launching Viz + :align: center diff --git a/doc/tutorials/viz/widget_pose.rst b/doc/tutorials/viz/widget_pose.rst new file mode 100644 index 000000000..22dfb2867 --- /dev/null +++ b/doc/tutorials/viz/widget_pose.rst @@ -0,0 +1,162 @@ +.. _widget_pose: + +Pose of a widget +**************** + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * Add widgets to the visualization window + * Use Affine3 to set pose of a widget + * Rotating and translating a widget along an axis + +Code +==== + +You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/widget_pose.cpp>`_. + +.. code-block:: cpp + + #include + #include + #include + + using namespace cv; + using namespace std; + + /** + * @function main + */ + int main() + { + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + + /// Add line to represent (1,1,1) axis + viz::LineWidget axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f)); + axis.setRenderingProperty(viz::VIZ_LINE_WIDTH, 4.0); + myWindow.showWidget("Line Widget", axis); + + /// Construct a cube widget + viz::CubeWidget cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue()); + cube_widget.setRenderingProperty(viz::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(0,0) += CV_PI * 0.01f; + rot_vec.at(0,1) += CV_PI * 0.01f; + rot_vec.at(0,2) += CV_PI * 0.01f; + + /// Shift on (1,1,1) + translation_phase += CV_PI * 0.01f; + translation = sin(translation_phase); + + Mat rot_mat; + Rodrigues(rot_vec, rot_mat); + + /// Construct pose + Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); + + myWindow.setWidgetPose("Cube Widget", pose); + + myWindow.spinOnce(1, true); + } + + return 0; + } + +Explanation +=========== + +Here is the general structure of the program: + +* Create a visualization window. + +.. code-block:: cpp + + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + +* Show coordinate axes in the window using CoordinateSystemWidget. + +.. code-block:: cpp + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + +* Display a line representing the axis (1,1,1). + +.. code-block:: cpp + + /// Add line to represent (1,1,1) axis + viz::LineWidget axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f)); + axis.setRenderingProperty(viz::VIZ_LINE_WIDTH, 4.0); + myWindow.showWidget("Line Widget", axis); + +* Construct a cube. + +.. code-block:: cpp + + /// Construct a cube widget + viz::CubeWidget cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue()); + cube_widget.setRenderingProperty(viz::VIZ_LINE_WIDTH, 4.0); + myWindow.showWidget("Cube Widget", cube_widget); + +* Create rotation matrix from rodrigues vector + +.. code-block:: cpp + + /// Rotate around (1,1,1) + rot_vec.at(0,0) += CV_PI * 0.01f; + rot_vec.at(0,1) += CV_PI * 0.01f; + rot_vec.at(0,2) += CV_PI * 0.01f; + + ... + + Mat rot_mat; + Rodrigues(rot_vec, rot_mat); + +* Use Affine3f to set pose of the cube. + +.. code-block:: cpp + + /// Construct pose + Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); + myWindow.setWidgetPose("Cube Widget", pose); + +* Animate the rotation using wasStopped and spinOnce + +.. code-block:: cpp + + while(!myWindow.wasStopped()) + { + ... + + myWindow.spinOnce(1, true); + } + +Results +======= + +Here is the result of the program. + +.. raw:: html + +
+ +
diff --git a/samples/cpp/tutorial_code/viz/widget_pose.cpp b/samples/cpp/tutorial_code/viz/widget_pose.cpp new file mode 100644 index 000000000..1689a9cc6 --- /dev/null +++ b/samples/cpp/tutorial_code/viz/widget_pose.cpp @@ -0,0 +1,79 @@ +/** + * @file creating_widgets.cpp + * @brief Creating custom widgets using VTK + * @author Ozan Cagri Tonkal + */ + +#include +#include +#include + +using namespace cv; +using namespace std; + +/** + * @function help + * @brief Display instructions to use this tutorial program + */ +void help() +{ + cout + << "--------------------------------------------------------------------------" << endl + << "This program shows how to visualize a cube rotated around (1,1,1) and shifted " + << "using Rodrigues matrix." << endl + << "Usage:" << endl + << "./coordinate_frame" << endl + << endl; +} + +/** + * @function main + */ +int main() +{ + help(); + + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + + /// Add line to represent (1,1,1) axis + viz::LineWidget 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::CubeWidget 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); + 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(0,0) += CV_PI * 0.01f; + rot_vec.at(0,1) += CV_PI * 0.01f; + rot_vec.at(0,2) += CV_PI * 0.01f; + + /// Shift on (1,1,1) + translation_phase += CV_PI * 0.01f; + translation = sin(translation_phase); + + Mat rot_mat; + Rodrigues(rot_vec, rot_mat); + + /// Construct pose + Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); + + myWindow.setWidgetPose("Cube Widget", pose); + + myWindow.spinOnce(1, true); + } + + return 0; +} From 5307339f8541391aa3930566a9826d54c115cd67 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sat, 7 Sep 2013 17:26:57 +0200 Subject: [PATCH 185/205] tutorial code for makeTransformToGlobal, makeCameraPose, minor fixes in widget_pose tutorial --- .../cpp/tutorial_code/viz/transformations.cpp | 86 +++++++++++++++++++ samples/cpp/tutorial_code/viz/widget_pose.cpp | 8 +- 2 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 samples/cpp/tutorial_code/viz/transformations.cpp diff --git a/samples/cpp/tutorial_code/viz/transformations.cpp b/samples/cpp/tutorial_code/viz/transformations.cpp new file mode 100644 index 000000000..e3e3d094a --- /dev/null +++ b/samples/cpp/tutorial_code/viz/transformations.cpp @@ -0,0 +1,86 @@ +/** + * @file transformations.cpp + * @brief Visualizing cloud in different positions, coordinate frames, camera frustums + * @author Ozan Cagri Tonkal + */ + +#include +#include + +using namespace cv; +using namespace std; + +/** + * @function help + * @brief Display instructions to use this tutorial program + */ +void help() +{ + cout + << "--------------------------------------------------------------------------" << endl + << "This program shows how to use makeTransformToGlobal() to compute required pose," + << "how to use makeCameraPose and Viz3d::setViewerPose. You can observe the scene " + << "from camera point of view (C) or global point of view (G)" << endl + << "Usage:" << endl + << "./coordinate_frame [ G | C ]" << endl + << endl; +} + +/** + * @function main + */ +int main(int argn, char **argv) +{ + help(); + + if (argn < 2) + { + cout << "Missing arguments." << endl; + return 1; + } + + bool camera_pov = (argv[1][0] == 'C'); + + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + + /// Let's assume camera has the following properties + Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f, 3.0f, 2.0f), cam_y_dir(-1.0,0.0,0.0); + /// We can get the pose of the cam using makeCameraPose + Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + /// We can get the transformation matrix from camera coordinate system to global using + /// - makeTransformToGlobal. We need the axes of the camera + Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); + + /// Create a cloud widget. + viz::SphereWidget sphere_widget(Point3f(0.0,0.0,0.0), 0.5, 10, viz::Color::red()); + + /// Pose of the widget in camera frame + Affine3f sphere_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); + /// Pose of the widget in global frame + Affine3f sphere_pose_global = transform * sphere_pose; + + /// Visualize camera frame + if (!camera_pov) + { + viz::CameraPositionWidget cpw(0.5); // Coordinate axes + viz::CameraPositionWidget cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + myWindow.showWidget("CPW", cpw, cam_pose); + myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); + } + + /// Visualize widget + myWindow.showWidget("sphere", sphere_widget, sphere_pose_global); + + /// Set the viewer pose to that of camera + if (camera_pov) + myWindow.setViewerPose(cam_pose); + + /// Start event loop. + myWindow.spin(); + + return 0; +} diff --git a/samples/cpp/tutorial_code/viz/widget_pose.cpp b/samples/cpp/tutorial_code/viz/widget_pose.cpp index 1689a9cc6..d83ac6b2e 100644 --- a/samples/cpp/tutorial_code/viz/widget_pose.cpp +++ b/samples/cpp/tutorial_code/viz/widget_pose.cpp @@ -1,6 +1,6 @@ /** - * @file creating_widgets.cpp - * @brief Creating custom widgets using VTK + * @file widget_pose.cpp + * @brief Setting pose of a widget * @author Ozan Cagri Tonkal */ @@ -20,9 +20,9 @@ void help() cout << "--------------------------------------------------------------------------" << endl << "This program shows how to visualize a cube rotated around (1,1,1) and shifted " - << "using Rodrigues matrix." << endl + << "using Rodrigues vector." << endl << "Usage:" << endl - << "./coordinate_frame" << endl + << "./widget_pose" << endl << endl; } From 2969ec0274aa3564b389a148b9410e0626f181b7 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sat, 7 Sep 2013 18:23:26 +0200 Subject: [PATCH 186/205] transformations tutorial rst --- .../viz/images/camera_view_point.png | Bin 0 -> 18439 bytes .../viz/images/global_view_point.png | Bin 0 -> 13767 bytes doc/tutorials/viz/images/red_triangle.png | Bin 0 -> 10489 bytes doc/tutorials/viz/transformations.rst | 202 + samples/cpp/tutorial_code/viz/bunny.ply | 5752 +++++++++++++++++ .../cpp/tutorial_code/viz/transformations.cpp | 38 +- 6 files changed, 5986 insertions(+), 6 deletions(-) create mode 100644 doc/tutorials/viz/images/camera_view_point.png create mode 100644 doc/tutorials/viz/images/global_view_point.png create mode 100644 doc/tutorials/viz/images/red_triangle.png create mode 100644 doc/tutorials/viz/transformations.rst create mode 100644 samples/cpp/tutorial_code/viz/bunny.ply diff --git a/doc/tutorials/viz/images/camera_view_point.png b/doc/tutorials/viz/images/camera_view_point.png new file mode 100644 index 0000000000000000000000000000000000000000..e2ac5b0f0de84aa88561e44b635c0b73fd68dab0 GIT binary patch literal 18439 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 literal 0 HcmV?d00001 diff --git a/doc/tutorials/viz/images/global_view_point.png b/doc/tutorials/viz/images/global_view_point.png new file mode 100644 index 0000000000000000000000000000000000000000..fc6de2c1a1fa36ad56ad6ffb679eb20d5bf77609 GIT binary patch literal 13767 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 QpoJpyQt?HJgi-MS0}6qlQ~&?~ literal 0 HcmV?d00001 diff --git a/doc/tutorials/viz/images/red_triangle.png b/doc/tutorials/viz/images/red_triangle.png new file mode 100644 index 0000000000000000000000000000000000000000..7da6ad0602a974e00695f9c0aa698c5dc474b2be GIT binary patch literal 10489 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 Y2MLWci`MvfP>e97x{g}mO`E6x2cG-67XSbN literal 0 HcmV?d00001 diff --git a/doc/tutorials/viz/transformations.rst b/doc/tutorials/viz/transformations.rst new file mode 100644 index 000000000..0639a0d34 --- /dev/null +++ b/doc/tutorials/viz/transformations.rst @@ -0,0 +1,202 @@ +.. _transformations: + +Transformations +*************** + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * How to use makeTransformToGlobal to compute pose + * How to use makeCameraPose and Viz3d::setViewerPose + * How to visualize camera position by axes and by viewing frustum + +Code +==== + +You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/transformations.cpp>`_. + +.. code-block:: cpp + + #include + #include + #include + + using namespace cv; + using namespace std; + + /** + * @function cvcloud_load + * @brief load bunny.ply + */ + Mat cvcloud_load() + { + Mat cloud(1, 1889, CV_32FC3); + ifstream ifs("bunny.ply"); + + string str; + for(size_t i = 0; i < 12; ++i) + getline(ifs, str); + + Point3f* data = cloud.ptr(); + float dummy1, dummy2; + for(size_t i = 0; i < 1889; ++i) + ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2; + + cloud *= 5.0f; + return cloud; + } + + /** + * @function main + */ + int main(int argn, char **argv) + { + if (argn < 2) + { + cout << "Usage: " << endl << "./transformations [ G | C ]" << endl; + return 1; + } + + bool camera_pov = (argv[1][0] == 'C'); + + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + + /// Let's assume camera has the following properties + Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); + + /// We can get the pose of the cam using makeCameraPose + Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + + /// We can get the transformation matrix from camera coordinate system to global using + /// - makeTransformToGlobal. We need the axes of the camera + Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); + + /// Create a cloud widget. + Mat bunny_cloud = cvcloud_load(); + viz::CloudWidget cloud_widget(bunny_cloud, viz::Color::green()); + + /// Pose of the widget in camera frame + Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); + /// Pose of the widget in global frame + Affine3f cloud_pose_global = transform * cloud_pose; + + /// Visualize camera frame + if (!camera_pov) + { + viz::CameraPositionWidget cpw(0.5); // Coordinate axes + viz::CameraPositionWidget cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + myWindow.showWidget("CPW", cpw, cam_pose); + myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); + } + + /// Visualize widget + myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); + + /// Set the viewer pose to that of camera + if (camera_pov) + myWindow.setViewerPose(cam_pose); + + /// Start event loop. + myWindow.spin(); + + return 0; + } + + +Explanation +=========== + +Here is the general structure of the program: + +* Create a visualization window. + +.. code-block:: cpp + + /// Create a window + viz::Viz3d myWindow("Transformations"); + +* Get camera pose from camera position, camera focal point and y direction. + +.. code-block:: cpp + + /// Let's assume camera has the following properties + Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); + + /// We can get the pose of the cam using makeCameraPose + Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + +* Obtain transform matrix knowing the axes of camera coordinate system. + +.. code-block:: cpp + + /// We can get the transformation matrix from camera coordinate system to global using + /// - makeTransformToGlobal. We need the axes of the camera + Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); + +* Create a cloud widget from bunny.ply file + +.. code-block:: cpp + + /// Create a cloud widget. + Mat bunny_cloud = cvcloud_load(); + viz::CloudWidget cloud_widget(bunny_cloud, viz::Color::green()); + +* Given the pose in camera coordinate system, estimate the global pose. + +.. code-block:: cpp + + /// Pose of the widget in camera frame + Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); + /// Pose of the widget in global frame + Affine3f cloud_pose_global = transform * cloud_pose; + +* If the view point is set to be global, visualize camera coordinate frame and viewing frustum. + +.. code-block:: cpp + + /// Visualize camera frame + if (!camera_pov) + { + viz::CameraPositionWidget cpw(0.5); // Coordinate axes + viz::CameraPositionWidget cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + myWindow.showWidget("CPW", cpw, cam_pose); + myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); + } + +* Visualize the cloud widget with the estimated global pose + +.. code-block:: cpp + + /// Visualize widget + myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); + +* If the view point is set to be camera's, set viewer pose to **cam_pose**. + +.. code-block:: cpp + + /// Set the viewer pose to that of camera + if (camera_pov) + myWindow.setViewerPose(cam_pose); + +Results +======= + +#. Here is the result from the camera point of view. + + .. image:: images/camera_view_point.png + :alt: Camera Viewpoint + :align: center + +#. Here is the result from global point of view. + + .. image:: images/global_view_point.png + :alt: Global Viewpoint + :align: center diff --git a/samples/cpp/tutorial_code/viz/bunny.ply b/samples/cpp/tutorial_code/viz/bunny.ply new file mode 100644 index 000000000..10ae64fc3 --- /dev/null +++ b/samples/cpp/tutorial_code/viz/bunny.ply @@ -0,0 +1,5752 @@ +ply +format ascii 1.0 +comment zipper output +element vertex 1889 +property float x +property float y +property float z +property float confidence +property float intensity +element face 3851 +property list uchar int vertex_indices +end_header +-0.0369122 0.127512 0.00276757 0.850855 0.5 +-0.0457707 0.130327 0.00306785 0.900159 0.5 +-0.0708847 0.149834 0.0388672 0.398443 0.5 +-0.00331557 0.130403 0.0212208 0.85268 0.5 +-0.0211979 0.1272 0.00915278 0.675938 0.5 +-0.0265255 0.12592 0.00874866 0.711533 0.5 +0.0339261 0.112038 0.0269672 0.652757 0.5 +0.0376485 0.110455 0.0145481 0.708171 0.5 +-0.0259368 0.111118 0.0379115 0.454541 0.437538 +0.027952 0.120939 0.0215377 0.533079 0.5 +-0.0628308 0.155987 -0.0150105 0.404517 0.5 +0.0390029 0.106711 0.0215202 0.535542 0.5 +0.0447976 0.0950477 0.00866471 0.579563 0.425995 +-0.0330636 0.173619 -0.0031267 0.365607 0.5 +-0.0808069 0.136243 0.0495014 0.499575 0.5 +-0.0705086 0.12445 0.0526685 0.564827 0.5 +0.00874873 0.131225 0.0145345 0.748371 0.5 +0.0401015 0.106711 0.00874166 0.680399 0.5 +0.0379483 0.100145 -0.00827134 0.600054 0.5 +-0.0906538 0.137201 0.0207305 0.824561 0.5 +-0.0841655 0.110667 0.0275273 0.690889 0.5 +-0.0705214 0.156214 0.0144536 0.807492 0.5 +-0.083872 0.15212 0.0282652 0.248168 0.41865 +0.00305028 0.12432 0.0332425 0.555044 0.354559 +0.00870828 0.124165 0.0330348 0.653433 0.5 +-0.0328896 0.12613 0.00300653 0.898771 0.5 +-0.0506302 0.143065 0.0150611 0.691477 0.5 +-0.0757863 0.13637 0.050172 0.566256 0.5 +-0.0027191 0.128962 0.0264678 0.271491 0.462815 +-0.0460961 0.125118 0.0263142 0.539149 0.5 +-0.0785104 0.0942728 -0.0109192 0.710999 0.5 +0.0216915 0.125373 0.0211452 0.530957 0.5 +-0.0888469 0.124305 0.00237041 0.635593 0.5 +0.040386 0.100825 -0.00303043 0.574857 0.5 +-0.0884145 0.117791 0.00268555 0.487167 0.430737 +-0.0319074 0.177421 -0.00491879 0.269231 0.447035 +-0.0765825 0.143224 0.0455148 0.414139 0.5 +-0.0209748 0.112544 0.0388613 0.482541 0.5 +-0.020836 0.179425 -0.0221622 0.341071 0.440034 +-0.0377039 0.167987 -0.0130391 0.396317 0.473039 +-0.0331765 0.12681 0.00839958 0.896274 0.5 +0.00893926 0.127114 0.0292916 0.350014 0.41288 +-0.044944 0.131083 0.0147963 0.599596 0.5 +-0.0266041 0.12515 0.00282384 0.73687 0.5 +0.0144285 0.12328 0.0319185 0.625269 0.5 +0.019244 0.122284 0.0308314 0.611204 0.34486 +-0.0390225 0.167317 0.00215527 0.413994 0.469929 +-0.08808 0.129976 0.00206377 0.625486 0.5 +-0.0537203 0.142608 0.0266058 0.696873 0.5 +0.043095 0.0980072 0.0191617 0.665192 0.5 +0.0432138 0.100117 0.00866473 0.691828 0.5 +0.0415448 0.0944954 0.0275695 0.671611 0.5 +-0.0578726 0.155337 0.0149245 0.394763 0.437313 +-0.0231577 0.157375 -0.0046304 0.136389 0.380194 +-0.0683123 0.145735 0.0420568 0.751812 0.5 +-0.0708351 0.142847 0.0451248 0.627973 0.5 +-0.070664 0.0642894 0.0209789 0.413051 0.5 +-0.0761519 0.130581 0.0525324 0.629117 0.5 +-0.0640036 0.161784 -0.0208118 0.449093 0.5 +-0.0706461 0.155711 0.00252406 0.855717 0.5 +-0.0924366 0.118434 0.0399838 0.673877 0.5 +-0.0635349 0.156052 0.0148814 0.798496 0.5 +0.0282675 0.118192 0.0274382 0.635485 0.5 +0.0392736 0.0938857 -0.00915453 0.585857 0.459742 +-0.0695973 0.164844 -0.0174846 0.548789 0.5 +-0.00892354 0.123904 0.0330319 0.602316 0.374044 +0.0269099 0.0942476 0.0444911 0.649753 0.5 +-0.0146258 0.162377 -0.0144398 0.338176 0.5 +-0.0450983 0.167072 0.00289327 0.449091 0.5 +-0.0761536 0.172742 -0.0384391 0.256591 0.4298 +-0.0858274 0.105458 0.00472318 0.523819 0.297125 +0.0370431 0.110443 0.0207229 0.52623 0.448558 +0.0321593 0.0994027 0.0380657 0.733041 0.5 +-0.075287 0.146433 0.0428582 0.424358 0.5 +-0.0395145 0.171107 0.000531747 0.452893 0.5 +-0.0839586 0.11215 0.00148754 0.436727 0.419097 +0.0446848 0.0883378 0.0216285 0.487783 0.481728 +0.0161783 0.127819 0.0220535 0.481793 0.5 +-0.00251635 0.0397232 0.0474087 0.280725 0.5 +0.00303163 0.0406968 0.0460422 0.331809 0.5 +-0.0143059 0.128197 0.00333856 0.693854 0.5 +-0.0526117 0.155596 0.0109972 0.561042 0.5 +-0.0332043 0.17776 -0.00906223 0.212789 0.5 +0.0394391 0.106654 0.00306577 0.522321 0.489889 +-0.0923799 0.1249 0.0327641 0.848517 0.5 +0.0454681 0.0882959 0.0146642 0.575503 0.5 +-0.0274495 0.179802 -0.00925837 0.258799 0.457369 +-0.072504 0.146297 0.0429682 0.549207 0.5 +-0.0579959 0.129793 0.0383118 0.658867 0.444043 +0.043117 0.0923689 0.0251649 0.622686 0.5 +-0.00865718 0.130323 0.0149721 0.633691 0.5 +-0.0141304 0.129188 0.0147431 0.547632 0.5 +-0.0707877 0.15583 0.00921954 0.739059 0.5 +-0.00952731 0.127041 0.0281475 0.375412 0.377874 +-0.0646289 0.153404 0.0329146 0.855321 0.5 +-0.0706939 0.15347 0.0328596 0.444959 0.455263 +0.0208126 0.118434 0.0336393 0.519282 0.5 +-0.0396566 0.173008 -0.00299705 0.274377 0.177706 +-0.0442176 0.170815 -0.00391429 0.245926 0.5 +-0.0582565 0.0395149 0.0457796 0.417977 0.459314 +-0.0523033 0.0401501 0.04623 0.454776 0.456044 +-0.0760211 0.161274 -0.0145891 0.267801 0.372187 +-0.0693983 0.163016 -0.0140293 0.403228 0.45768 +0.0399663 0.106491 0.014952 0.713602 0.5 +0.041536 0.0950084 -0.00475737 0.490139 0.464008 +-0.0470079 0.163779 0.00528295 0.432857 0.486946 +-0.0402546 0.161678 0.00298655 0.447592 0.5 +-0.0386569 0.0389805 0.0441153 0.509262 0.5 +-0.0704175 0.166991 -0.0216976 0.332592 0.447054 +-0.0254201 0.0886622 0.0503827 0.608282 0.5 +-0.0886334 0.137429 0.00876953 0.549009 0.5 +-0.014179 0.12627 0.0266417 0.420759 0.5 +-0.0360017 0.17408 -0.0118959 0.409753 0.289042 +-0.0886251 0.0937834 0.00823534 0.753697 0.5 +-0.0648672 0.155874 -0.00891497 0.595216 0.5 +-0.0704508 0.137752 -0.00774011 0.446131 0.5 +-0.0750154 0.166247 -0.0219558 0.263106 0.5 +0.0299465 0.114869 0.0300239 0.642356 0.5 +0.0398138 0.0998788 0.0273101 0.51725 0.5 +-0.015242 0.111698 0.0407424 0.605597 0.5 +-0.0700387 0.118219 0.0524379 0.585543 0.5 +0.0149973 0.112399 0.0386082 0.669811 0.5 +-0.036487 0.171225 0.000545037 0.438578 0.5 +-0.0641664 0.118551 -0.00968333 0.569796 0.5 +-0.071817 0.166979 -0.0463822 0.381568 0.451091 +-0.0913559 0.14534 0.0246937 0.648478 0.5 +0.00903703 0.112569 0.0396571 0.549283 0.408623 +0.0324674 0.0997396 -0.0141603 0.732658 0.5 +0.0417911 0.101845 0.00188609 0.547756 0.5 +0.00302992 0.112517 0.0415434 0.592572 0.5 +-0.0650368 0.148485 0.0382561 0.62562 0.5 +-0.0706519 0.13063 0.0502497 0.563116 0.5 +-0.0144471 0.128935 0.00903509 0.682121 0.5 +0.00292575 0.131541 0.00912318 0.795238 0.5 +-0.0625682 0.151125 0.035875 0.463512 0.5 +0.0349829 0.113328 0.0214487 0.620597 0.5 +0.021327 0.0385664 0.0392992 0.259499 0.426724 +0.0145125 0.093771 0.0501571 0.654705 0.5 +-0.00923752 0.112849 0.0413907 0.615633 0.5 +0.0415329 0.100906 0.0210277 0.662312 0.5 +0.0422859 0.101486 0.0146614 0.569693 0.490777 +-0.0773783 0.112839 -0.00448759 0.505277 0.5 +-0.078035 0.137641 -0.00517379 0.466714 0.5 +0.00873437 0.106347 -0.0202193 0.792948 0.5 +0.0090324 0.13035 0.0211569 0.465873 0.5 +0.00301322 0.130902 0.0206741 0.592486 0.5 +-0.00286342 0.13115 0.0147367 0.587804 0.5 +-0.0391578 0.12569 0.0207996 0.438744 0.464814 +-0.0205725 0.123523 0.0265579 0.445477 0.415699 +-0.0644194 0.155634 0.00928477 0.611624 0.331941 +-0.0463385 0.131411 0.0207671 0.674928 0.5 +-0.0532034 0.0439067 0.044658 0.417403 0.440199 +-0.00297651 0.131046 0.00884967 0.738924 0.5 +-0.089664 0.137755 0.0263925 0.80362 0.5 +-0.00888731 0.124273 -0.00880284 0.767738 0.284429 +-0.0460971 0.0385107 0.0446891 0.654962 0.5 +-0.0649255 0.178874 -0.0579325 0.245129 0.411885 +-0.0329347 0.124601 0.0211235 0.32811 0.5 +-0.0831301 0.149901 0.0334123 0.331963 0.314683 +-0.0895652 0.093948 0.0149303 0.603378 0.5 +-0.0328901 0.124518 -0.00282055 0.63839 0.5 +-0.0845271 0.106161 0.00204328 0.338681 0.43162 +-0.0469341 0.155816 0.00872921 0.470367 0.484595 +0.0206202 0.123943 0.0267275 0.477255 0.5 +-0.026256 0.117499 0.0321672 0.543293 0.5 +-0.021392 0.118632 0.0336445 0.468887 0.429556 +-0.0195069 0.116132 0.0368525 0.534732 0.411301 +-0.0761618 0.118382 0.0520923 0.490413 0.5 +0.00889281 0.0395765 0.0451727 0.476347 0.38769 +-0.0534736 0.159548 0.00753828 0.476667 0.5 +-0.0469464 0.161226 0.00680216 0.495992 0.483766 +-0.0574886 0.154862 0.0204748 0.677314 0.5 +0.0317199 0.117635 0.0202007 0.579556 0.5 +0.0378683 0.105514 -0.00259159 0.588286 0.5 +-0.0811847 0.137693 -0.00253994 0.641736 0.5 +-0.0764348 0.124515 0.0528345 0.65366 0.5 +0.0343816 0.106104 -0.00900254 0.534403 0.5 +0.0457922 0.088316 0.00867097 0.586292 0.439394 +-0.0703288 0.0944195 -0.0159143 0.511499 0.5 +-0.0756048 0.0937947 -0.0135536 0.429902 0.5 +-0.058657 0.156369 0.0093256 0.31374 0.5 +-0.0637335 0.153848 0.00222718 0.478676 0.5 +-0.0777278 0.0960024 0.0363437 0.678588 0.5 +-0.0868519 0.136556 0.00309926 0.517441 0.5 +-0.0455299 0.0432404 0.0432162 0.712662 0.5 +-0.0402011 0.045749 0.0408051 0.669165 0.320516 +-0.0654123 0.160403 -0.0149066 0.335302 0.5 +-0.0318898 0.0387174 0.0510004 0.553401 0.5 +-0.0267997 0.0453977 0.0509311 0.501112 0.5 +-0.0271043 0.0396972 0.0535379 0.487956 0.5 +-0.0215575 0.0460868 0.0517209 0.709553 0.5 +-0.0143078 0.0445295 0.0504368 0.575852 0.5 +-0.00981594 0.043264 0.0493162 0.448927 0.393067 +-0.00348436 0.044054 0.0472086 0.598081 0.5 +0.009577 0.0458139 0.0465877 0.519814 0.433928 +0.02048 0.111086 0.0379569 0.681163 0.5 +-0.0141831 0.128547 0.0200007 0.293349 0.5 +-0.0526702 0.144108 0.0210347 0.639643 0.5 +-0.0634838 0.17384 -0.0527131 0.549906 0.5 +-0.0366553 0.171999 -0.0125745 0.436075 0.5 +-0.0525548 0.131228 0.0328277 0.727547 0.5 +-0.0659567 0.132023 0.0442925 0.724494 0.5 +-0.0921726 0.11832 0.0267606 0.794672 0.5 +0.0452792 0.0882737 0.00268175 0.507794 0.5 +-0.00305651 0.112889 0.0417789 0.635396 0.5 +-0.0451955 0.161396 -0.00871567 0.424682 0.5 +-0.0402914 0.160933 -0.0115368 0.411895 0.405943 +-0.0521414 0.0701165 0.0389584 0.682177 0.456916 +-0.0383315 0.093604 -0.0232581 0.72469 0.5 +-0.0690556 0.137374 0.046352 0.61723 0.5 +-0.0695996 0.167401 -0.0516299 0.518552 0.5 +-0.00246047 0.124102 0.0337609 0.444043 0.5 +-0.0398624 0.128204 0.00299348 0.864483 0.5 +-0.0753331 0.149032 0.0395625 0.432149 0.5 +-0.0701432 0.160618 -0.00917801 0.464361 0.5 +-0.0589378 0.0440425 0.0434222 0.437887 0.447715 +-0.0207164 0.126445 0.00312493 0.710427 0.5 +-0.00850666 0.0467286 0.0481052 0.613173 0.5 +0.00300323 0.0450308 0.0469911 0.464978 0.5 +-0.0802174 0.148665 0.0379438 0.47939 0.5 +-0.0819961 0.130698 0.0513437 0.54405 0.5 +0.00273088 0.106333 -0.0209927 0.733954 0.5 +-0.0757273 0.0885687 -0.0138399 0.397424 0.5 +-0.0698477 0.0882875 -0.0167823 0.420617 0.5 +-0.0668508 0.159243 -0.0102161 0.42216 0.440727 +-0.0226988 0.0885773 0.0536309 0.546444 0.5 +-0.00281419 0.0990077 0.0505614 0.455087 0.5 +0.0452902 0.0696213 0.0253974 0.33948 0.5 +-0.0525629 0.0472823 0.040482 0.279548 0.5 +-0.046959 0.0466581 0.0408127 0.43714 0.5 +-0.0691348 0.156682 -0.00276369 0.629099 0.5 +-0.0897599 0.150073 0.0220744 0.276354 0.5 +-0.0702883 0.155637 0.0263654 0.47565 0.441038 +-0.0765031 0.154893 0.0266005 0.799832 0.5 +-0.00804843 0.0987379 0.0505998 0.327523 0.438474 +0.0300791 0.11567 -0.00430465 0.66246 0.5 +-0.0923054 0.117757 0.0334441 0.476916 0.5 +-0.0331192 0.0449511 0.0462474 0.432059 0.466683 +-0.0337794 0.113308 0.034612 0.683562 0.5 +-0.0521291 0.113769 0.0349566 0.515399 0.5 +0.0437636 0.0825382 -0.0027974 0.568535 0.5 +-0.0202819 0.126016 0.0210507 0.374818 0.437592 +0.0327872 0.043925 0.0295904 0.650152 0.5 +-0.0453372 0.155266 -0.0075525 0.386286 0.5 +-0.0284609 0.173987 -0.0175958 0.379432 0.418735 +0.0268448 0.0881755 -0.0223077 0.715629 0.5 +-0.0308231 0.0923023 -0.0246377 0.474586 0.431409 +-0.0899732 0.149975 0.0141115 0.257143 0.5 +0.0381804 0.105121 0.0266947 0.534482 0.490368 +0.00842001 0.12907 0.0258154 0.374593 0.448613 +-0.0266549 0.0942999 -0.0265555 0.294426 0.332222 +-0.0279896 0.0475815 0.0485532 0.381268 0.5 +-0.0150037 0.048073 0.0483203 0.576068 0.5 +-0.00298993 0.0473817 0.0491102 0.446744 0.431743 +0.00376754 0.0477551 0.0502037 0.495901 0.44823 +0.00748504 0.0473851 0.0493363 0.494952 0.5 +-0.0581651 0.149751 0.032858 0.470966 0.5 +-0.0720688 0.136456 0.0490662 0.625357 0.5 +-0.0810638 0.0939541 -0.0082617 0.685573 0.5 +0.0380863 0.0458646 0.0307423 0.807573 0.5 +-0.0253234 0.182998 -0.0108168 0.245054 0.5 +-0.0230508 0.183235 -0.0110157 0.246322 0.458572 +0.00323317 0.129146 0.0263855 0.347796 0.441746 +-0.0626125 0.149788 -0.00343342 0.691705 0.5 +-0.0591471 0.0466998 0.0395843 0.0883466 0.213805 +-0.0353862 0.0471292 0.0414241 0.656538 0.5 +-0.0194948 0.0486404 0.0485565 0.373069 0.5 +-0.00849455 0.0521633 0.0517688 0.61481 0.5 +-0.00296485 0.051429 0.0527827 0.53012 0.5 +0.00279019 0.0517664 0.0528352 0.560812 0.423049 +0.00904034 0.0517165 0.051222 0.558244 0.5 +0.0443839 0.0943042 0.00268377 0.582116 0.455816 +-0.0886145 0.111113 0.0148415 0.604102 0.5 +-0.0885219 0.144027 0.0329221 0.623335 0.5 +0.0440719 0.0937787 0.0206165 0.493368 0.454688 +0.0436531 0.0980341 0.0146596 0.668233 0.5 +-0.0650976 0.153799 -0.00285808 0.715743 0.5 +-0.0517297 0.0490759 0.0371355 0 0 +-0.0331222 0.0518259 0.0385377 0.676102 0.5 +-0.0377352 0.127448 0.0152358 0.612182 0.5 +-0.00906608 0.100701 0.0460122 0.338462 0.5 +-0.0410683 0.128416 0.0134054 0.417331 0.5 +-0.0712056 0.158724 -0.00521868 0.246338 0.5 +-0.0266313 0.0501544 0.044695 0.182016 0.5 +-0.0211065 0.0519946 0.0455753 0.195646 0.404388 +-0.0168667 0.0505241 0.0476889 0.520032 0.5 +-0.0147601 0.0527687 0.050103 0.451613 0.5 +-0.0626395 0.149972 -0.00897733 0.363787 0.461156 +-0.090861 0.124732 0.00627835 0.587249 0.5 +-0.0255786 0.0923499 -0.0315595 0.294527 0.5 +-0.0709738 0.172947 -0.052768 0.460427 0.5 +-0.0588974 0.143232 -0.00327646 0.48145 0.5 +-0.0943643 0.12436 0.0216467 0.570519 0.5 +0.0337044 0.112449 -0.00269877 0.532211 0.5 +-0.0515051 0.136557 0.0263185 0.72719 0.5 +-0.00886593 0.121199 0.0360577 0.614897 0.5 +-0.061729 0.155665 -0.0259512 0.690546 0.5 +-0.0862637 0.10567 0.0206042 0.519516 0.5 +-0.0895584 0.138606 0.032689 0.685876 0.5 +-0.0268168 0.123904 0.0208113 0.428255 0.5 +0.0341937 0.0515433 0.033081 0.609925 0.5 +0.0401268 0.0512743 0.0322702 0.669803 0.5 +0.0449306 0.0526595 0.0319582 0.655209 0.5 +-0.0405348 0.117168 0.0319438 0.657986 0.5 +-0.0636902 0.155546 -0.0390642 0.523327 0.5 +0.0278663 0.100401 0.0410064 0.689793 0.5 +-0.0275828 0.179275 -0.0157605 0.314049 0.5 +-0.0758871 0.0942302 0.0383961 0.647987 0.457049 +0.0138371 0.129201 0.0203961 0.412341 0.5 +-0.0152723 0.0998429 0.0451638 0.271215 0.427554 +-0.00916763 0.129718 0.0206646 0.438679 0.430152 +-0.0512444 0.0516901 0.0334801 0.192432 0.5 +-0.0461563 0.0523184 0.0379981 0.311543 0.5 +-0.0410001 0.05272 0.0393793 0.629588 0.477809 +-0.0270993 0.0526642 0.0393104 0.155274 0.5 +0.0434924 0.0931097 -0.00154028 0.576953 0.480183 +-0.0823819 0.112683 0.045427 0.438131 0.5 +-0.092066 0.118055 0.00909937 0.325678 0.5 +-0.00448884 0.121713 0.0362976 0.591545 0.5 +0.0147346 0.129423 0.0143146 0.840212 0.5 +-0.0158113 0.161888 -0.00973584 0.202865 0.5 +-0.0778838 0.149704 -0.00337488 0.403345 0.5 +-0.0865357 0.12477 -0.00166991 0.677311 0.5 +0.0153656 0.126058 0.0275381 0.479299 0.429147 +-0.0388913 0.123761 0.0249778 0.514489 0.5 +-0.0390351 0.121238 0.0283673 0.510424 0.470651 +-0.0324963 0.120237 0.0283344 0.568849 0.348087 +-0.0149052 0.12311 0.0316417 0.446842 0.5 +-0.0582873 0.117688 0.0386719 0.634635 0.5 +-0.0626536 0.161861 -0.0264031 0.685413 0.5 +-0.0818147 0.141639 0.0444825 0.392929 0.5 +0.0350734 0.100071 0.0345975 0.716199 0.5 +0.0311856 0.11215 0.0310216 0.689434 0.5 +-0.0335778 0.11743 0.031458 0.525408 0.5 +-0.059637 0.153475 0.031348 0.93076 0.5 +-0.0481256 0.0536625 0.0362191 0.58186 0.5 +-0.059026 0.156388 0.00269852 0.133166 0.5 +-0.0211187 0.0578754 0.0461125 0.660553 0.5 +-0.082738 0.124721 0.050554 0.665202 0.5 +-0.0466997 0.11363 0.0348133 0.568902 0.5 +-0.0107262 0.179662 -0.0277472 0.400699 0.458536 +0.0347725 0.0894441 -0.0170339 0.702331 0.5 +-0.0891825 0.100351 0.0148945 0.574286 0.477791 +0.0257275 0.122894 0.0207337 0.498278 0.5 +-0.0883949 0.100277 0.00841226 0.477822 0.5 +-0.0649858 0.155518 0.0263367 0.864791 0.5 +-0.0768402 0.154073 0.00257877 0.57436 0.5 +-0.0576877 0.154146 0.0262123 0.402162 0.5 +-0.0266966 0.125729 0.0145923 0.393422 0.5 +-0.076376 0.155782 0.0208875 0.505065 0.5 +-0.0763295 0.167188 -0.039594 0.405226 0.426366 +-0.0771877 0.100229 -0.0103313 0.528684 0.5 +-0.0153681 0.0590839 0.0519909 0.652683 0.5 +-0.010206 0.0576345 0.0535443 0.781548 0.413019 +-0.00350044 0.0578672 0.0543757 0.774384 0.5 +0.00300818 0.0568916 0.0538692 0.704357 0.5 +0.0088308 0.0580497 0.0529859 0.692645 0.5 +0.0410915 0.0820775 -0.00893411 0.500391 0.430286 +0.0395449 0.0576373 0.0318985 0.612032 0.4505 +-0.0762443 0.139336 0.0484763 0.588653 0.42756 +-0.0324306 0.120379 -0.00955344 0.656019 0.5 +-0.0194451 0.0881559 0.0557639 0.449983 0.473992 +-0.074787 0.159471 -0.00898201 0.281303 0.5 +-0.0639935 0.15611 0.0210031 0.687157 0.5 +-0.0762438 0.153101 0.0322442 0.323875 0.45561 +-0.00876679 0.128727 0.025102 0.735708 0.5 +0.0282216 0.112237 -0.00983067 0.567922 0.385391 +-0.0451341 0.0593225 0.0387559 0.511245 0.5 +-0.0405005 0.0579499 0.040202 0.540369 0.5 +-0.033993 0.0584028 0.038704 0.646744 0.5 +-0.0272756 0.0585468 0.0382285 0.571263 0.5 +-0.0248608 0.122913 0.0245429 0.379391 0.5 +-0.0825276 0.154355 0.0206132 0.385494 0.444119 +-0.00884271 0.129403 0.00305159 0.702319 0.5 +0.0207587 0.126654 0.0147646 0.624434 0.5 +-0.0394868 0.173351 -0.00839443 0.199648 0.251821 +-0.028421 0.114019 0.0347746 0.603313 0.5 +-0.0193575 0.122009 0.0306737 0.55532 0.5 +-0.0691626 0.161675 -0.0514614 0.38665 0.5 +-0.0516736 0.15006 0.0148119 0.716684 0.5 +-0.0156325 0.120151 0.0349054 0.470635 0.336572 +0.0467454 0.0582319 0.0314404 0.576429 0.5 +-0.0770165 0.0685425 0.0147863 0.703257 0.5 +-0.00967101 0.173225 -0.0264945 0.379771 0.5 +-0.0213141 0.184813 -0.0151112 0.186313 0.403961 +-0.0766524 0.0882188 0.0382876 0.650646 0.5 +-0.0540219 0.0521463 0.0110698 0.270787 0.5 +-0.0219451 0.126821 0.0155536 0.534695 0.5 +-0.0820391 0.153392 0.0264506 0.292051 0.4047 +-0.0213183 0.124468 -0.00290836 0.782181 0.5 +-0.0268364 0.123465 -0.00321538 0.727949 0.5 +-0.0312035 0.177796 -0.0133521 0.371348 0.5 +-0.00749945 0.0598042 0.0553302 0.778631 0.5 +-0.00108951 0.0601245 0.0554892 0.776353 0.5 +0.00280202 0.0599746 0.0555283 0.768603 0.5 +-0.051797 0.118119 0.033678 0.677092 0.438456 +0.00302464 0.131618 0.0149353 0.692956 0.5 +0.0446005 0.0942619 0.0151198 0.554026 0.5 +-0.0880636 0.111855 0.00852285 0.304511 0.3924 +-0.0704321 0.144096 -0.0148369 0.130446 0.5 +-0.0820967 0.0943634 0.0322765 0.629357 0.5 +-0.0269642 0.120812 0.0275676 0.345323 0.386314 +-0.0540164 0.149968 0.0253393 0.49489 0.5 +-0.0800337 0.0995053 -0.00770139 0.499264 0.5 +0.00922138 0.12038 0.0360924 0.562107 0.5 +0.00286056 0.117968 0.0387331 0.649494 0.5 +-0.0936229 0.118494 0.0206524 0.664933 0.5 +-0.0409923 0.113229 0.035109 0.667726 0.5 +-0.0822185 0.154488 0.0146661 0.500539 0.5 +-0.0625956 0.155202 -0.0329876 0.814083 0.5 +-0.0462511 0.124621 -0.00898124 0.590842 0.5 +-0.0220336 0.160676 -0.00426008 0.309766 0.47069 +-0.065621 0.172767 -0.0466049 0.613718 0.5 +-0.0762614 0.155884 0.0148687 0.717415 0.5 +-0.0644988 0.149044 -0.0265159 0.690046 0.5 +-0.0581979 0.0593456 0.0210895 0.079935 0 +-0.0335439 0.122618 0.0254024 0.514037 0.5 +-0.0826578 0.153434 0.00921403 0.601617 0.5 +-0.049999 0.132417 0.0286961 0.650903 0.5 +0.0088217 0.131096 0.00864908 0.834131 0.5 +-0.0154842 0.0644282 0.0533754 0.608033 0.445048 +-0.00871951 0.065015 0.0556827 0.650491 0.470895 +-0.00324815 0.0640003 0.0562816 0.762387 0.5 +0.00292601 0.0643094 0.0563956 0.748671 0.5 +0.00738462 0.0651614 0.0553402 0.488299 0.46872 +-0.0143174 0.116971 0.037836 0.441459 0.5 +-0.00299223 0.118083 0.0390751 0.65526 0.5 +-0.00864301 0.117816 0.0385662 0.681198 0.5 +-0.0532884 0.0571719 0.0206631 0.106703 0 +-0.0882588 0.100387 0.0210097 0.535268 0.5 +-0.0324377 0.099703 -0.0227313 0.620611 0.5 +0.0425072 0.0603725 0.0302275 0.744481 0.5 +0.0523383 0.0580401 0.0290457 0.405493 0.41666 +0.0413612 0.0877503 -0.00929235 0.635782 0.5 +-0.0581547 0.0620148 0.0270981 0.448705 0.5 +-0.0530328 0.0590503 0.0266933 0.136202 0.5 +-0.0477227 0.135526 0.0148654 0.740469 0.5 +0.00323512 0.0983053 0.0504424 0.395048 0.366076 +0.0150627 0.119642 0.034806 0.696033 0.374342 +-0.0453373 0.0643061 0.0391142 0.587502 0.5 +-0.0394097 0.0644278 0.0414133 0.715885 0.5 +-0.033068 0.0642666 0.0396407 0.650585 0.5 +-0.0270237 0.0644489 0.0395335 0.617817 0.5 +-0.0881604 0.149479 0.0268507 0.265855 0.5 +-0.0640727 0.143434 -0.00894036 0.668887 0.5 +0.00286033 0.121151 0.036139 0.623932 0.5 +-0.0827306 0.138152 0.0466993 0.412428 0.5 +-0.00261511 0.127006 0.030132 0.335862 0.5 +0.0355841 0.108498 -0.00452523 0.461807 0.466834 +0.0219203 0.114136 0.0356941 0.554683 0.5 +-0.0379555 0.161954 -0.0128021 0.499753 0.5 +-0.0526362 0.0643632 0.0340621 0.277414 0.5 +0.025874 0.123374 0.0143811 0.506732 0.5 +-0.0451406 0.131184 0.00901599 0.493237 0.5 +-0.075778 0.155361 -0.00310678 0.708579 0.5 +-0.0739145 0.156437 -0.0274945 0.645327 0.5 +-0.0833056 0.100778 -0.00354288 0.490806 0.397415 +-0.0767099 0.173942 -0.0452732 0.259897 0.5 +0.00846106 0.116985 0.038033 0.66824 0.5 +-0.0200899 0.184788 -0.020546 0.237973 0.106197 +-0.046571 0.120413 0.0285524 0.752764 0.5 +-0.0515313 0.123718 -0.0088569 0.538005 0.5 +0.0212116 0.105804 -0.0171101 0.576137 0.468722 +-0.0938613 0.124487 0.0151416 0.737559 0.5 +0.0414591 0.064577 0.0290352 0.617794 0.5 +0.0466725 0.0643471 0.0285539 0.486488 0.5 +0.0526423 0.0634018 0.0283831 0.501229 0.5 +-0.0468141 0.168322 -0.00285433 0.371444 0.5 +-0.0869152 0.0944156 0.00293118 0.494536 0.346642 +-0.0773713 0.161559 -0.0267238 0.476378 0.5 +-0.0396095 0.126677 -0.00334699 0.853498 0.5 +-0.0271315 0.0764239 0.0455715 0.693464 0.5 +-0.0587953 0.107012 -0.0177177 0.484023 0.5 +-0.0748314 0.11156 -0.00720996 0.44421 0.5 +-0.0642623 0.0888181 -0.018733 0.676741 0.5 +-0.0325172 0.0881157 -0.0255424 0.370176 0.330832 +0.00325654 0.0700086 0.0561047 0.731659 0.5 +0.0103151 0.0636713 0.0537558 0.477793 0.458716 +0.0432701 0.0979967 0.00267804 0.544182 0.465461 +-0.0708223 0.156244 0.021207 0.768676 0.5 +-0.0584176 0.0702277 0.0384322 0.673529 0.5 +-0.0703207 0.112305 -0.00963846 0.530989 0.5 +-0.0581653 0.0881983 -0.0208369 0.619673 0.5 +-0.0443038 0.0877156 -0.0218942 0.693083 0.5 +-0.0488091 0.0660127 0.0373959 0.829801 0.5 +0.00269411 0.126911 0.030114 0.419275 0.5 +0.0239692 0.12105 0.0288706 0.523768 0.5 +-0.0469203 0.117468 0.0314407 0.649888 0.5 +-0.091552 0.143361 0.0201623 0.515231 0.5 +-0.0907563 0.143859 0.0263089 0.504684 0.469425 +-0.0495713 0.144022 0.00976642 0.636632 0.45621 +-0.0770934 0.15583 -0.0147903 0.519503 0.5 +-0.0868322 0.105634 0.00887573 0.731519 0.5 +-0.082848 0.131648 -0.00299747 0.386393 0.5 +-0.0384249 0.106407 -0.0201393 0.79815 0.5 +-0.0823953 0.118841 -0.00336022 0.540306 0.5 +-0.0102333 0.0876697 -0.0375101 0.564234 0.5 +-0.00789361 0.089842 -0.0363492 0.755212 0.5 +-0.0579097 0.111769 -0.0161856 0.463258 0.5 +0.0140074 0.105793 -0.0193841 0.554632 0.5 +-0.00328561 0.105435 -0.0225198 0.740261 0.5 +-0.0409613 0.070972 0.0419904 0.795206 0.5 +-0.033501 0.0710512 0.0409793 0.706864 0.5 +-0.0272732 0.0701361 0.0410332 0.726443 0.5 +-0.0161963 0.127121 0.0228897 0.305628 0.5 +-0.0190644 0.127936 0.0133818 0.519435 0.5 +-0.0149926 0.0694778 0.0545159 0.595577 0.5 +-0.00932719 0.0707313 0.0562936 0.785998 0.5 +-0.002994 0.0710941 0.0575426 0.779773 0.5 +0.00838831 0.0714267 0.0556585 0.671976 0.5 +0.0102531 0.0693533 0.0547665 0.525573 0.5 +-0.0323939 0.153399 -0.00240332 0.209483 0.5 +0.0435981 0.0881514 0.0254203 0.603121 0.478265 +-0.0586529 0.124882 -0.00781093 0.700525 0.5 +-0.0204287 0.107045 -0.022046 0.723165 0.5 +-0.0382961 0.0879422 -0.0229335 0.629507 0.5 +-0.081573 0.113394 -0.00173083 0.508624 0.426711 +-0.0380811 0.154778 -0.00889149 0.748063 0.5 +-0.00212588 0.0889926 -0.0354677 0.782073 0.5 +0.00904065 0.100193 -0.0222794 0.54652 0.5 +-0.0467068 0.0700493 0.0405769 0.710023 0.5 +-0.0779974 0.151244 0.0352264 0.347296 0.5 +0.0149019 0.116126 0.0367849 0.635361 0.5 +-0.07603 0.106301 -0.0087688 0.520423 0.5 +-0.0885261 0.137839 0.0393964 0.651389 0.5 +-0.0703112 0.131278 -0.00857724 0.737784 0.5 +0.0419377 0.0703605 0.0288832 0.54196 0.5 +0.0514194 0.0684326 0.0256968 0.512602 0.5 +-0.0922548 0.124813 0.0393757 0.806636 0.5 +0.0135035 0.128105 0.0250558 0.487288 0.424656 +-0.0704618 0.125421 -0.00881334 0.801453 0.5 +-0.0703931 0.118731 -0.00840961 0.381625 0.5 +-0.0719685 0.106305 -0.0114493 0.499561 0.5 +-0.0646972 0.161498 -0.0573125 0.41682 0.5 +0.0463693 0.0715128 0.0216754 0.461473 0.448797 +-0.0538246 0.153497 0.0152346 0.602795 0.402362 +-0.0142869 0.0724666 0.0554243 0.617853 0.5 +-0.0394057 0.118512 -0.01336 0.602235 0.5 +-0.0280509 0.0880065 -0.0330858 0.33771 0.5 +-0.00957701 0.168254 -0.0212321 0.359593 0.5 +-0.0445856 0.167324 -0.00782662 0.413138 0.327414 +-0.0513101 0.161594 -0.00355965 0.292939 0.5 +-0.0702356 0.179304 -0.0569867 0.253404 0.5 +-0.0644695 0.168402 -0.0398946 0.676128 0.5 +-0.0089459 0.130139 0.00911776 0.703889 0.5 +0.00219503 0.0880369 -0.0342201 0.75972 0.5 +-0.0268891 0.16726 -0.0174204 0.847505 0.5 +-0.0525985 0.155054 -0.00368706 0.37123 0.419006 +-0.0761618 0.131736 -0.00696723 0.42394 0.44361 +-0.0759576 0.07099 0.0265672 0.757943 0.5 +-0.00875341 0.10588 -0.02285 0.71177 0.5 +-0.0519242 0.1493 -0.00277595 0.483301 0.5 +-0.016371 0.18465 -0.0214272 0.271878 0.5 +-0.020548 0.0705632 0.0520411 0.601639 0.5 +-0.0813371 0.120073 0.049533 0.662828 0.5 +-0.0625087 0.149934 -0.0150319 0.415531 0.480025 +-0.0831098 0.10651 0.0273461 0.515033 0.5 +-0.011119 0.163582 -0.018751 0.17813 0.5 +-0.00291057 0.101147 0.0456419 0.307462 0.5 +-0.0635467 0.0660523 0.0318653 0.49936 0.45677 +-0.0511979 0.0873878 -0.0217212 0.75515 0.5 +-0.0530335 0.0740367 0.0417219 0.727079 0.5 +-0.0465007 0.0756701 0.0421325 0.696934 0.5 +-0.022314 0.0760359 0.0530306 0.607912 0.5 +-0.0151351 0.0764056 0.0563566 0.616605 0.5 +-0.00900601 0.0766621 0.0575852 0.791265 0.5 +-0.00299732 0.0767339 0.0584651 0.678647 0.450838 +0.00347424 0.0769755 0.0565905 0.523043 0.5 +0.00860763 0.0767538 0.0557293 0.612782 0.5 +-0.0271239 0.156216 -0.00302734 0.139755 0.329034 +-0.0633091 0.16738 -0.0580906 0.358909 0.45373 +-0.0873943 0.144225 0.00902371 0.583528 0.5 +-0.0626891 0.162297 -0.0470925 0.70746 0.5 +0.0370111 0.110397 0.00265294 0.516602 0.481774 +-0.0744006 0.144062 -0.00864565 0.417075 0.5 +-0.0244124 0.183841 -0.0135068 0.166659 0.5 +-0.0803381 0.0715473 0.0150483 0.5669 0.5 +-0.0644528 0.0761561 0.040638 0.610448 0.476331 +-0.0588413 0.0753794 0.0421022 0.634349 0.5 +-0.0524294 0.077372 0.0433357 0.774603 0.5 +-0.0484981 0.0769334 0.043281 0.674446 0.5 +-0.0414954 0.0773856 0.0429005 0.752035 0.5 +-0.0395008 0.0754808 0.0425134 0.72256 0.5 +-0.033488 0.0764759 0.0414605 0.748994 0.5 +-0.0627838 0.162163 -0.0530538 0.691143 0.5 +0.0381456 0.0881056 -0.0138675 0.676152 0.5 +-0.0642837 0.0396418 0.039624 0.532543 0.5 +-0.0526672 0.121335 -0.010917 0.523608 0.5 +-0.0738104 0.162942 -0.037093 0.458525 0.324439 +-0.0490869 0.13938 0.00889895 0.657159 0.5 +-0.0495771 0.166027 -0.00171113 0.322064 0.5 +-0.0709736 0.161609 -0.0450808 0.365011 0.420984 +0.0251847 0.12195 0.0254854 0.524179 0.5 +-0.0193615 0.0781018 0.0558163 0.595703 0.4544 +-0.0265458 0.120645 -0.00911332 0.52669 0.5 +-0.061796 0.155741 -0.0207923 0.443336 0.5 +-0.082476 0.110295 0.0324103 0.745977 0.5 +-0.0691674 0.156314 -0.050857 0.360984 0.5 +-0.0622848 0.16236 -0.0396288 0.427869 0.464762 +-0.088248 0.113803 0.0264606 0.595923 0.5 +-0.0575392 0.0787026 0.0436363 0.801201 0.5 +-0.0298439 0.0782596 0.0421168 0.771067 0.5 +-0.0677617 0.0876701 0.0434928 0.59211 0.5 +-0.0921939 0.131884 0.015227 0.781723 0.5 +-0.0878987 0.111742 0.0209206 0.698028 0.5 +-0.049353 0.139298 0.0147955 0.761861 0.5 +-0.0327071 0.173321 -0.0149209 0.384317 0.5 +-0.0866298 0.152851 0.0149144 0.267781 0.5 +-0.0779646 0.100025 0.035185 0.697079 0.5 +-0.0935537 0.118404 0.0151524 0.667612 0.5 +-0.084908 0.10801 0.0228537 0.694681 0.5 +-0.0210677 0.0821213 0.0562096 0.557699 0.5 +-0.0149957 0.082187 0.0572635 0.665194 0.5 +-0.00899671 0.0822178 0.0576875 0.71377 0.5 +-0.00299966 0.0822055 0.0574653 0.668024 0.472979 +0.0034748 0.0817533 0.0567544 0.69456 0.5 +0.00824833 0.082992 0.0556315 0.615627 0.5 +0.0102414 0.0812949 0.0546523 0.424956 0.485927 +-0.0398496 0.123966 -0.00878898 0.60318 0.5 +-0.092257 0.124769 0.00902091 0.309094 0.468872 +-0.0436728 0.126191 0.0209533 0.472028 0.413108 +-0.0820425 0.105873 -0.00271871 0.341089 0.347157 +-0.0663016 0.0807623 0.0424437 0.632223 0.5 +-0.0639939 0.0836688 0.0439754 0.778832 0.5 +-0.058539 0.0825906 0.0439671 0.770991 0.5 +-0.0521209 0.0822523 0.0446262 0.782751 0.5 +-0.0467559 0.0828569 0.0439458 0.699516 0.399968 +-0.0424962 0.0810729 0.0423266 0.617938 0.5 +-0.0404903 0.0830123 0.0430984 0.712874 0.5 +-0.0365108 0.0825773 0.0434355 0.675696 0.5 +-0.032204 0.0824171 0.0421121 0.529763 0.5 +-0.0864005 0.152981 0.0204492 0.250247 0.416029 +-0.0235661 0.115415 0.0353667 0.518805 0.471584 +-0.0764871 0.111685 0.0461598 0.498936 0.5 +-0.0763895 0.14977 -0.00829972 0.604451 0.5 +-0.0754801 0.161855 -0.0327796 0.39691 0.5 +-0.0285733 0.0828247 0.0462702 0.636794 0.5 +-0.0862819 0.100797 0.0028483 0.65379 0.5 +0.021088 0.08242 0.0504086 0.491924 0.475524 +-0.0801892 0.143128 -0.00230055 0.641961 0.5 +0.00844098 0.124407 -0.00878569 0.555015 0.5 +0.0147552 0.0825883 0.0529115 0.480476 0.5 +-0.061995 0.161169 -0.032654 0.499509 0.5 +-0.0807571 0.1525 0.0307996 0.295115 0.454522 +-0.00295953 0.130272 0.00279699 0.742188 0.5 +-0.0153619 0.0884791 0.0565599 0.818561 0.5 +-0.00899729 0.0878977 0.0570287 0.818958 0.5 +-0.00299611 0.0880658 0.0568489 0.695384 0.5 +0.00301457 0.0885291 0.0562756 0.81087 0.5 +0.00834267 0.0873808 0.0555541 0.577038 0.479545 +-0.00897481 0.0941651 -0.0338408 0.678465 0.5 +0.0314278 0.11673 0.0250113 0.597807 0.5 +-0.0760602 0.155337 0.0093949 0.68566 0.5 +0.0257808 0.116776 -0.00728909 0.54747 0.36626 +-0.0646577 0.0882843 0.0447113 0.69894 0.5 +-0.058996 0.0882997 0.0449149 0.778337 0.5 +-0.0529958 0.0883132 0.0451395 0.696869 0.45083 +-0.0465421 0.0881579 0.0443187 0.605881 0.5 +-0.0404961 0.0876863 0.0430941 0.556958 0.5 +-0.0331792 0.0885648 0.04366 0.668172 0.5 +-0.0280482 0.0879652 0.046363 0.699915 0.5 +0.0150626 0.0881784 0.0517745 0.702815 0.5 +0.0205955 0.087113 0.0492325 0.678548 0.5 +-0.0702712 0.0823874 0.0409431 0.628092 0.5 +-0.0296926 0.0896882 -0.0286839 0.317989 0.390463 +-0.0236137 0.179242 -0.0115629 0.264741 0.5 +-0.0809391 0.100029 0.0323433 0.683272 0.5 +-0.0928336 0.130683 0.0207107 0.62518 0.472282 +-0.0761771 0.156201 -0.0204165 0.612769 0.5 +0.0146577 0.129396 0.00843576 0.595962 0.5 +0.0104845 0.089766 0.0542005 0.46622 0.5 +-0.072579 0.161253 -0.0389447 0.482103 0.5 +-0.0322741 0.110391 -0.0184574 0.809584 0.5 +-0.0550172 0.150108 0.027792 0.412797 0.5 +-0.071635 0.0883254 0.0414652 0.604622 0.463567 +-0.0424904 0.0895336 0.0426086 0.959715 0.5 +0.0207945 0.0897491 0.0484315 0.669841 0.5 +0.0273189 0.118845 -0.00265658 0.615055 0.5 +0.0285218 0.121112 0.0162366 0.593248 0.434231 +-0.00899735 0.0930598 0.0559298 0.639163 0.5 +-0.00291176 0.118727 -0.0144021 0.826286 0.5 +-0.0885191 0.113233 0.0327948 0.447552 0.461926 +-0.0713744 0.0938304 0.0415269 0.544171 0.444972 +-0.0641029 0.0935514 0.0439488 0.597795 0.395518 +-0.0584965 0.0944146 0.0446213 0.678752 0.5 +-0.0515853 0.0939836 0.0442383 0.634435 0.477778 +-0.0465591 0.0937901 0.0436103 0.714507 0.5 +-0.0414914 0.0942416 0.0425268 0.490492 0.46307 +-0.0377723 0.0933327 0.0434889 0.620752 0.5 +-0.0332864 0.0945766 0.0443868 0.723538 0.5 +-0.0263807 0.094318 0.0450568 0.620324 0.5 +-0.0141606 0.0929618 0.0553898 0.503825 0.5 +-0.00319641 0.0930898 0.0557853 0.624082 0.5 +0.00150357 0.0931879 0.0551544 0.492015 0.5 +0.00367616 0.0950752 0.0535295 0.508462 0.5 +0.00915739 0.0941794 0.0519212 0.597357 0.452723 +0.0216553 0.0937794 0.0473202 0.671835 0.5 +-0.0702968 0.174481 -0.045888 0.43732 0.455145 +-0.0305889 0.168899 -0.00702359 0.59106 0.5 +-0.0528191 0.162649 0.00296711 0.343566 0.5 +-0.0890968 0.0940104 0.0208024 0.539357 0.478012 +-0.0626249 0.173112 -0.0586131 0.353011 0.447085 +-0.0443835 0.105923 -0.0201903 0.683228 0.5 +-0.0664958 0.0951776 0.0424531 0.672396 0.5 +-0.0324384 0.126415 0.0146752 0.445893 0.463327 +-0.0152469 0.0961657 0.0518098 0.323594 0.5 +-0.0097537 0.0960506 0.0535818 0.446732 0.426556 +-0.00304601 0.0963367 0.0537791 0.579525 0.5 +0.01642 0.0957081 0.0480381 0.687032 0.5 +-0.0876548 0.105191 0.0148253 0.774556 0.5 +-0.0699417 0.0763232 0.0381496 0.596573 0.5 +0.0358078 0.0958594 -0.0120328 0.738943 0.5 +0.0374966 0.100154 0.031249 0.720944 0.5 +-0.0530195 0.150059 0.0207323 0.696139 0.5 +-0.0905911 0.131765 0.0328667 0.816274 0.5 +-0.0709717 0.147309 -0.0268389 0.224341 0.389051 +-0.0443321 0.0935075 -0.0222668 0.709831 0.5 +-0.0400911 0.128618 0.00909496 0.81345 0.5 +-0.0710054 0.100275 0.0398128 0.481571 0.5 +-0.0653063 0.100124 0.0417262 0.670525 0.470095 +-0.0589969 0.0980495 0.0430328 0.779482 0.5 +-0.0529938 0.0980631 0.0432952 0.836255 0.5 +-0.0469951 0.0980659 0.043235 0.637806 0.5 +-0.0408476 0.100401 0.0414668 0.648927 0.395789 +-0.0323344 0.0988071 0.0435216 0.652032 0.5 +-0.0259464 0.0998425 0.0438947 0.737424 0.5 +-0.0212066 0.0999849 0.0444194 0.576924 0.5 +0.00749586 0.09835 0.0488255 0.46146 0.5 +0.0090271 0.101109 0.0469975 0.470012 0.5 +0.0153076 0.100008 0.0472449 0.600016 0.5 +0.0208175 0.100067 0.0453866 0.595024 0.46889 +-0.0648326 0.131509 -0.00838673 0.790869 0.5 +-0.0740297 0.150832 -0.0323367 0.406089 0.5 +-0.0932444 0.124885 0.026841 0.802537 0.5 +-0.0633239 0.169093 -0.0610358 0.362406 0.5 +-0.0771158 0.162488 -0.0202679 0.465605 0.5 +-0.0585669 0.0647555 0.0323611 0.494963 0.328305 +0.0377689 0.110383 0.00969065 0.710008 0.5 +-0.0503559 0.0935892 -0.0218956 0.807094 0.5 +-0.0589961 0.101543 0.042437 0.529374 0.5 +-0.0516647 0.101981 0.0417488 0.647378 0.5 +-0.0469248 0.101325 0.0421166 0.608323 0.5 +-0.0352173 0.101965 0.0413638 0.751982 0.5 +0.00285015 0.100935 0.0464433 0.395489 0.5 +-0.075479 0.150312 -0.0143808 0.730394 0.5 +-0.078936 0.108126 -0.00525459 0.540251 0.381971 +-0.0251472 0.168981 -0.0187156 0.757996 0.5 +-0.071457 0.113692 0.0499983 0.429195 0.5 +-0.0747771 0.0997536 0.0377868 0.551123 0.5 +-0.0902919 0.137212 0.0146286 0.495279 0.5 +-0.0264568 0.105883 0.0411765 0.58994 0.471484 +-0.0209966 0.1044 0.0429589 0.797197 0.5 +-0.0145208 0.105597 0.0430511 0.780555 0.5 +-0.00899316 0.10622 0.0435541 0.510194 0.5 +-0.00289533 0.105882 0.0438861 0.384284 0.5 +0.00245231 0.105621 0.0429868 0.332307 0.5 +0.00945613 0.104903 0.0439002 0.435482 0.5 +0.0149913 0.104769 0.0443348 0.548532 0.5 +-0.0772186 0.106139 0.0350601 0.430274 0.367589 +-0.0708601 0.106945 0.0381598 0.402417 0.5 +-0.0652985 0.106577 0.0390805 0.558067 0.398761 +-0.0583896 0.105623 0.0405326 0.594554 0.5 +-0.0529341 0.106445 0.0398435 0.644542 0.398207 +-0.0461638 0.105797 0.0404843 0.759883 0.5 +-0.0400204 0.106789 0.0388993 0.653599 0.5 +-0.03311 0.106322 0.0394461 0.532024 0.5 +0.0193026 0.10477 0.0431964 0.486674 0.480281 +-0.0501412 0.13774 0.00286739 0.569746 0.5 +0.0266104 0.105911 0.0384052 0.650339 0.5 +0.0438719 0.088439 -0.0031027 0.506353 0.478726 +-0.0590381 0.113203 0.0362299 0.87726 0.5 +-0.021499 0.107851 0.0414162 0.584043 0.5 +-0.0164951 0.107881 0.0420289 0.633836 0.5 +0.00450524 0.107918 0.0419336 0.79888 0.5 +0.00856234 0.108229 0.0410531 0.820786 0.5 +0.0149994 0.10779 0.0412845 0.598409 0.5 +0.0213049 0.106041 0.0409433 0.561561 0.479574 +-0.0336665 0.167843 -0.00338268 0.478764 0.5 +-0.0587789 0.131705 -0.00671001 0.673026 0.5 +-0.0443517 0.100306 -0.0215281 0.825942 0.5 +-0.0147306 0.179604 -0.0266222 0.40888 0.5 +0.0159582 0.108177 -0.0177822 0.564672 0.468958 +-0.0638447 0.138119 -0.00733006 0.633194 0.5 +-0.0330953 0.167861 -0.0155539 0.527374 0.428366 +-0.0643684 0.125359 -0.00876153 0.813046 0.5 +-0.032583 0.161992 -0.0142418 0.852313 0.5 +-0.068568 0.110392 0.0392194 0.353622 0.364353 +-0.0643494 0.112195 0.0388907 0.34696 0.5 +-0.0593722 0.112082 0.0373875 0.588374 0.5 +-0.0529986 0.110472 0.0373551 0.513233 0.408461 +-0.0468613 0.11028 0.0378862 0.569336 0.5 +-0.040984 0.110496 0.0370883 0.553647 0.5 +-0.0320055 0.110468 0.0370438 0.565129 0.5 +-0.0074871 0.110717 0.042649 0.617568 0.5 +-0.00449218 0.110714 0.0426582 0.621679 0.5 +0.0250033 0.110611 0.0368459 0.631257 0.5 +0.025919 0.0995286 -0.0189206 0.684181 0.5 +-0.06973 0.112153 0.0457184 0.746569 0.5 +-0.045604 0.148834 -0.00329924 0.521986 0.5 +-0.0653006 0.0947889 -0.0177657 0.582853 0.5 +-0.0906677 0.13318 0.0277848 0.773217 0.5 +-0.0331508 0.094474 -0.0237799 0.742 0.5 +-0.0575764 0.0941613 -0.0208023 0.703326 0.5 +-0.0200586 0.0397198 0.0532237 0.447203 0.5 +-0.0203685 0.0352888 0.051184 0.291685 0.457265 +-0.0764163 0.125947 -0.00745144 0.524375 0.5 +-0.0205906 0.167551 -0.0139677 0.809186 0.5 +0.025858 0.116851 0.0315289 0.660225 0.5 +-0.0139279 0.167191 -0.021044 0.669958 0.5 +-0.0587481 0.149802 -0.00133886 0.562881 0.5 +0.0144191 0.0395247 0.0443396 0.266796 0.5 +0.0332953 0.105473 0.0329627 0.721815 0.5 +-0.0647461 0.114313 -0.0115219 0.592211 0.5 +-0.0520818 0.0353771 0.0449331 0.341981 0.5 +-0.015004 0.0392095 0.0513548 0.312679 0.5 +-0.0094925 0.0384962 0.049554 0.302651 0.5 +-0.0638496 0.117631 0.0454477 0.559641 0.5 +-0.0573025 0.136864 0.033162 0.554568 0.5 +0.0189101 0.0400942 0.0428502 0.270107 0.5 +-0.0508192 0.124393 0.0332635 0.581555 0.5 +-0.0182623 0.180885 -0.017743 0.594618 0.5 +-0.0651271 0.150343 -0.0325707 0.505808 0.5 +0.0332966 0.0936886 0.0400216 0.637373 0.5 +-0.0463011 0.149493 0.00833001 0.611316 0.5 +0.00260773 0.0354887 0.0450013 0.261253 0.345588 +-0.0780807 0.10971 0.0423535 0.916894 0.5 +-0.0542262 0.124756 0.0369858 0.64506 0.5 +-0.0402584 0.0361447 0.0436625 0.193197 0.5 +-0.00317483 0.0942874 -0.0331049 0.71511 0.325502 +-0.0151032 0.179716 -0.0207621 0.731902 0.5 +0.026141 0.0403246 0.0327265 0.294647 0.339561 +-0.0640247 0.111376 -0.0136272 0.608847 0.5 +0.027817 0.112309 0.0339118 0.692282 0.5 +-0.0586332 0.142774 0.0334953 0.761767 0.5 +-0.0146622 0.167501 -0.0154455 0.61604 0.5 +-0.0270893 0.167298 -0.00866399 0.642638 0.5 +0.0152056 0.045813 0.0442638 0.487785 0.5 +0.0190988 0.0442996 0.0429 0.362689 0.463942 +0.0215694 0.0456112 0.041209 0.479281 0.5 +0.0257452 0.0459137 0.0381185 0.444171 0.5 +0.0387365 0.0944447 0.0327088 0.718127 0.5 +0.0287308 0.0456722 0.0347466 0.335561 0.431941 +-0.0151805 0.173809 -0.0213305 0.730436 0.5 +-0.0658903 0.118253 0.0498126 0.307185 0.5 +-0.0628345 0.093206 -0.0188544 0.659442 0.5 +-0.0643065 0.142451 0.0394123 0.621016 0.5 +-0.040079 0.150283 0.00280951 0.491474 0.5 +-0.026851 0.173268 -0.00983852 0.620534 0.5 +-0.0207913 0.173767 -0.0147826 0.653794 0.5 +-0.0582334 0.124238 0.0403406 0.70004 0.5 +-0.0683337 0.131545 0.0479709 0.732904 0.5 +-0.0693547 0.10637 -0.012803 0.472443 0.5 +-0.0428668 0.157627 0.0050419 0.670804 0.5 +-0.0476449 0.130368 0.0258834 0.623828 0.5 +0.0379451 0.0817167 -0.0141547 0.644934 0.5 +0.0312298 0.0470286 0.0324465 0.426433 0.5 +-0.0662284 0.138149 0.042896 0.72515 0.5 +-0.0644094 0.105575 -0.0158634 0.566501 0.5 +0.0411271 0.0443713 0.0285474 0.466284 0.5 +-0.0830031 0.0762361 0.0150296 0.67606 0.5 +-0.0660167 0.123488 0.0501643 0.718404 0.5 +-0.0416352 0.155329 0.00636435 0.466436 0.5 +-0.0388456 0.155994 0.00477206 0.438555 0.402124 +-0.0551732 0.116538 0.0359195 0.457649 0.5 +-0.0600069 0.134082 0.0369434 0.682472 0.5 +0.0452816 0.0453284 0.0263124 0.471094 0.5 +0.0513161 0.0463154 0.0204963 0.342211 0.398387 +-0.0106687 0.172847 -0.0215627 0.69267 0.5 +-0.0147735 0.18419 -0.0259341 0.309641 0.5 +0.0301064 0.106776 0.0358091 0.72383 0.5 +-0.063709 0.125122 0.0457451 0.712215 0.420475 +0.0473431 0.0499217 0.0295077 0.554948 0.5 +0.0497106 0.0482066 0.0259506 0.48379 0.5 +0.0518484 0.0518415 0.0267161 0.416499 0.5 +-0.0162732 0.172938 -0.0174582 0.719256 0.5 +0.0355097 0.107304 0.0291151 0.718782 0.5 +-0.0552656 0.143077 0.0300537 0.622521 0.5 +-0.0637191 0.136482 0.0388176 0.603354 0.5 +-0.0199086 0.161072 -0.00863325 0.350317 0.5 +-0.0209172 0.179282 -0.0148523 0.455842 0.5 +0.014511 0.0513519 0.0474271 0.589102 0.5 +-0.0610259 0.126912 0.0416133 0.698375 0.5 +0.0539905 0.0494141 0.0219114 0.418448 0.5 +0.00925922 0.118865 -0.0148674 0.54369 0.457314 +-0.0268384 0.162091 -0.00836699 0.546076 0.486591 +-0.0367024 0.163198 -0.00107067 0.680811 0.5 +-0.0336432 0.155948 0.00188963 0.445666 0.44081 +-0.0280966 0.159587 0.000483069 0.431301 0.5 +-0.026491 0.16163 -0.00321758 0.537982 0.323001 +0.0206613 0.0528733 0.0451655 0.647628 0.324331 +0.0231576 0.0513069 0.0414753 0.507052 0.5 +0.0266044 0.0526516 0.039853 0.635463 0.446542 +0.0309772 0.0527823 0.0371348 0.671735 0.5 +0.0239371 0.103424 0.0418106 0.654526 0.5 +0.0568895 0.0527484 0.0209204 0.474964 0.5 +-0.0664209 0.11329 0.0441331 0.212624 0.5 +-0.0326789 0.162384 -0.00243762 0.543585 0.5 +0.0145199 0.0932586 -0.026363 0.546403 0.5 +-0.0543983 0.119186 0.0365781 0.502204 0.44785 +-0.0564272 0.132376 0.0357966 0.720059 0.5 +-0.0501636 0.142911 0.00230897 0.376445 0.5 +-0.043714 0.147707 0.0038501 0.245798 0.5 +-0.0291346 0.177171 -0.00534178 0.371295 0.5 +0.0357304 0.100363 -0.0111604 0.61591 0.5 +0.0133943 0.0541536 0.0499521 0.532724 0.5 +0.0551089 0.0545007 0.0253961 0.545646 0.5 +0.0291033 0.0572886 0.0407089 0.633826 0.5 +0.0585723 0.0583402 0.0214893 0.549998 0.477428 +-0.0740322 0.0656952 0.0144875 0.594594 0.5 +-0.0749844 0.179305 -0.0518221 0.216638 0.5 +0.0145778 0.0585769 0.0501691 0.387785 0.5 +0.0214876 0.058332 0.0470549 0.596242 0.5 +0.0259507 0.0590004 0.0437762 0.663038 0.5 +0.032833 0.0585633 0.0387158 0.630786 0.5 +0.0358218 0.0578374 0.0350365 0.591179 0.5 +0.0360585 0.0951301 0.0364902 0.726421 0.5 +-0.0886806 0.118283 0.0459142 0.444358 0.5 +0.0562736 0.0586365 0.0253398 0.57284 0.5 +0.0303311 0.0951295 0.0419589 0.717458 0.5 +-0.0222315 0.167389 -0.0110472 0.688671 0.5 +-0.0543257 0.136577 0.0307959 0.688078 0.5 +-0.0500074 0.150447 0.0117579 0.563476 0.5 +-0.0616289 0.137406 0.0354744 0.592141 0.5 +-0.0319367 0.159507 0.00191749 0.44862 0.5 +-0.0634458 0.132148 0.0406867 0.731705 0.5 +0.0368678 0.0921989 0.0367449 0.708135 0.5 +-0.0728433 0.156137 -0.0339112 0.713518 0.5 +0.0389872 0.0640689 0.0330299 0.521361 0.5 +-0.0636611 0.1488 -0.0205996 0.618447 0.5 +0.0153938 0.0648444 0.0513036 0.554385 0.463079 +0.0213958 0.0645506 0.0473078 0.414803 0.412252 +0.0265105 0.0649235 0.0439721 0.611901 0.5 +0.0302364 0.0650657 0.0415975 0.600683 0.487653 +0.0331295 0.0642221 0.0397381 0.500385 0.490901 +0.0367885 0.065027 0.0366867 0.593561 0.5 +0.0563131 0.0650782 0.0252208 0.639437 0.5 +0.0591364 0.0644742 0.0211357 0.550839 0.448044 +-0.0110683 0.167098 -0.0167807 0.360187 0.5 +-0.0605202 0.146205 0.0366666 0.591479 0.5 +0.0194528 0.0665736 0.0491642 0.603282 0.5 +-0.0286777 0.158132 0.000508817 0.402765 0.431383 +0.0253025 0.0989569 0.0434277 0.623394 0.5 +-0.0349979 0.152158 8.20736e-05 0.217633 0.5 +0.014665 0.070627 0.0528306 0.52613 0.5 +0.0202908 0.071041 0.0498828 0.634288 0.435356 +0.0230702 0.0702991 0.0473835 0.571849 0.5 +0.0263693 0.0706238 0.0441789 0.622852 0.474797 +0.0328306 0.0707606 0.0401362 0.612279 0.409693 +0.0368832 0.070672 0.0365953 0.662199 0.5 +0.0398878 0.0705632 0.0325808 0.656566 0.5 +0.0579544 0.0694794 0.0198345 0.6125 0.5 +-0.0641704 0.063724 0.0268682 0.425507 0.418571 +-0.0919499 0.114216 0.0149265 0.530043 0.5 +0.0351624 0.0819076 -0.0172502 0.760295 0.5 +-0.0862408 0.119271 -0.00117534 0.455279 0.5 +-0.0294401 0.174958 -0.00579982 0.562984 0.5 +-0.0175288 0.165418 -0.0114925 0.675539 0.5 +-0.0617869 0.117789 0.0409144 0.40334 0.5 +0.0301891 0.0723658 0.0418804 0.606777 0.5 +-0.0822099 0.149486 0.00288044 0.385889 0.468811 +-0.0760271 0.175704 -0.0506937 0.340571 0.5 +-0.0652343 0.0614738 0.0211346 0.414933 0.425841 +-0.0266574 0.110394 -0.019007 0.783101 0.5 +-0.0813538 0.0779161 0.0268055 0.756683 0.5 +0.021417 0.118723 -0.00893569 0.549 0.5 +0.0149346 0.0759297 0.0536191 0.48671 0.476705 +0.0209886 0.0761609 0.0506055 0.575091 0.5 +0.0268396 0.0762089 0.0459193 0.572664 0.5 +0.0336785 0.0760737 0.0405166 0.630563 0.5 +0.0373422 0.0760306 0.0366776 0.505468 0.5 +0.0400324 0.0763062 0.0328345 0.645662 0.5 +0.0419048 0.076876 0.0296092 0.673034 0.5 +0.0438094 0.0763805 0.0258638 0.624347 0.5 +-0.0452412 0.118472 -0.0142046 0.833781 0.5 +0.0456773 0.0768089 0.0208187 0.458504 0.467907 +-0.050165 0.137714 0.0207618 0.606401 0.481088 +-0.00327054 0.111563 -0.0203549 0.551699 0.482404 +-0.0483236 0.145111 0.00757835 0.59165 0.5 +0.0310833 0.0775315 0.0432282 0.624343 0.5 +-0.046855 0.145222 0.00288431 0.195425 0.432502 +-0.0141716 0.10541 -0.0225802 0.672132 0.5 +0.0470348 0.0753979 0.0148736 0.455861 0.5 +-0.0611433 0.140542 0.0356184 0.646306 0.5 +0.0272779 0.0823714 0.0459243 0.61663 0.478488 +0.0309212 0.08255 0.0430252 0.611382 0.5 +0.0343037 0.0825412 0.0402907 0.613309 0.465282 +0.0370354 0.0824663 0.0369099 0.642585 0.5 +-0.0799946 0.147989 -0.000835337 0.484293 0.5 +-0.0774435 0.0690153 0.00961977 0.704234 0.277826 +0.0404363 0.0826995 0.0326021 0.686672 0.5 +0.0417479 0.0827335 0.0302524 0.63553 0.5 +0.0436887 0.0825508 0.0263844 0.61829 0.5 +0.0454407 0.0825465 0.0207137 0.601475 0.480065 +-0.0822812 0.116295 0.0482855 0.66926 0.5 +-0.0844726 0.0947391 -0.00345192 0.592061 0.5 +-0.020271 0.168003 -0.0193935 0.821267 0.5 +-0.0742716 0.0668501 0.0190414 0.706894 0.5 +0.026747 0.0882417 0.0458314 0.539865 0.389736 +0.0308722 0.0882572 0.0430146 0.948814 0.5 +0.0344922 0.0883047 0.0403697 0.638338 0.5 +0.0372481 0.0881263 0.0366393 0.643327 0.5 +0.039927 0.088094 0.0326668 0.711283 0.5 +0.0419027 0.0877782 0.0290815 0.667656 0.5 +0.00264738 0.112302 -0.019871 0.766242 0.5 +-0.0703315 0.1455 -0.0205576 0.136819 0.239158 +-0.0749446 0.137879 -0.00653312 0.459033 0.397283 +-0.0266967 0.114299 -0.0159903 0.856895 0.5 +-0.0869924 0.113518 0.00410409 0.344807 0.5 +-0.0142186 0.174013 -0.0259807 0.439072 0.5 +-0.0221564 0.157852 -0.00861651 0.254248 0.5 +-0.011587 0.164129 -0.0163045 0.228563 0.367524 +-0.00997381 0.169338 -0.0247765 0.42189 0.5 +-0.082875 0.143405 0.00186692 0.494272 0.5 +0.0203757 0.0354405 -0.00287175 0 0 +0.0191274 0.0363337 -0.00917714 0.174536 0.5 +0.0184456 0.036388 -0.013479 0.173751 0.5 +0.0149535 0.0347732 -0.0154937 0.144529 0.253209 +0.0221204 0.0372026 0.0342324 0.156956 0.287305 +0.039271 0.0382866 0.00854708 0.245023 0.5 +0.0397549 0.0398545 0.002614 0.276002 0.5 +0.0221892 0.0380614 -0.00446361 0.173629 0.5 +0.0179901 0.0369066 -0.0161835 0.336518 0.5 +0.0154148 0.0392444 -0.0212861 0.367832 0.5 +0.0208023 0.100118 -0.0213392 0.648293 0.46589 +0.0446004 0.0409064 0.00927401 0.208963 0.5 +0.0435625 0.0411355 0.00427044 0.357471 0.452104 +0.0381381 0.0411139 -0.00147908 0.514406 0.5 +-0.0478807 0.135207 0.00885778 0.482359 0.5 +0.0217274 0.0404287 -0.00964433 0.311593 0.5 +0.0206744 0.0405956 -0.0144437 0.473825 0.5 +0.0192578 0.0411681 -0.0195074 0.414351 0.5 +-0.0885736 0.112913 0.0395856 0.488806 0.5 +-0.026793 0.106457 -0.0218501 0.617481 0.5 +0.0481487 0.0428585 0.0145594 0.265572 0.5 +0.0521212 0.0461655 0.0089655 0.199267 0.5 +0.0480438 0.0430647 0.00724585 0.412258 0.5 +0.0460936 0.0434131 0.00284357 0.566688 0.5 +0.0285003 0.100485 -0.0168103 0.728425 0.5 +0.0269462 0.0395833 -0.00334578 0.464947 0.5 +-0.0907856 0.117838 0.00647331 0.421552 0.5 +-0.062721 0.167567 -0.0470628 0.645866 0.5 +-0.0799532 0.106813 0.0316838 0.420249 0.5 +0.0527437 0.0462125 0.0139554 0.286197 0.5 +0.0504533 0.0466263 0.00264513 0.57721 0.5 +-0.0322581 0.117324 -0.0133273 0.811815 0.5 +0.0272475 0.0455966 -0.00927071 0.533119 0.5 +-0.0146455 0.0942084 -0.0337341 0.520871 0.5 +-0.0411545 0.16722 -0.010818 0.48116 0.5 +-0.0721385 0.156112 -0.0384102 0.511983 0.468875 +0.0456803 0.0474217 -0.00311192 0.412576 0.5 +0.0239407 0.0433254 -0.00969837 0.651864 0.5 +0.021084 0.0462585 -0.0205303 0.476548 0.5 +-0.0348527 0.0351549 -0.0307351 0.16856 0.5 +-0.0699867 0.0663066 0.0259153 0.590849 0.43032 +-0.0747071 0.149891 -0.0201453 0.5851 0.5 +-0.0845448 0.13725 0.000743181 0.580039 0.5 +0.0549514 0.0484178 0.0163982 0.295573 0.5 +0.0264565 0.0466261 -0.0141039 0.515417 0.5 +0.0225276 0.0444655 -0.0157683 0.505631 0.5 +0.0330538 0.0938135 -0.0160538 0.699679 0.5 +0.0526476 0.0694992 0.00297306 0.629664 0.372945 +0.0528544 0.0581339 -0.00277966 0.592036 0.5 +-0.0571464 0.0671799 0.0361705 0.503626 0.472266 +-0.0651544 0.157167 -0.0515491 0.708429 0.5 +-0.0493189 0.133682 0.00119868 0.355836 0.438333 +-0.032962 0.10595 -0.0206729 0.810434 0.5 +-0.0649538 0.155656 -0.045631 0.820472 0.5 +-0.0390456 0.150445 -0.00354536 0.204281 0.5 +0.0574365 0.051618 0.0145183 0.351624 0.5 +0.0574129 0.0522531 0.00903377 0.511629 0.5 +0.0536112 0.0500965 0.00204174 0.768402 0.5 +0.0512204 0.0520121 -0.00218354 0.534755 0.5 +0.0471226 0.0515811 -0.00481298 0.434179 0.5 +0.033443 0.047576 -0.0063817 0.557462 0.465257 +0.00280933 0.118297 -0.0158208 0.570337 0.473222 +-0.0147841 0.10125 -0.0238408 0.771507 0.5 +-0.0620037 0.167422 -0.0527165 0.538383 0.466596 +0.0559147 0.0528382 0.00339683 0.824166 0.5 +0.0334801 0.0518506 -0.00825293 0.591066 0.5 +0.0287814 0.0501171 -0.0157926 0.574224 0.5 +0.0256197 0.0485542 -0.0190548 0.421586 0.5 +-0.00863537 0.118406 -0.0146114 0.827086 0.5 +-0.0148322 0.117675 -0.014701 0.559736 0.5 +-0.0615138 0.145712 -0.00481276 0.466074 0.5 +0.0232531 0.12083 -0.00456186 0.617393 0.5 +-0.0401535 0.0342718 -0.0275149 0.0979878 0.5 +0.0302657 0.0496868 -0.0107289 0.647285 0.5 +0.0320066 0.111334 -0.00737407 0.536101 0.5 +-0.0211003 0.120417 -0.0102482 0.732965 0.5 +-0.0204991 0.117125 -0.0140803 0.767014 0.5 +-0.00910263 0.0383602 -0.025776 0.274297 0.5 +-0.0525144 0.11229 -0.0171034 0.442719 0.484227 +0.0202353 0.123713 -0.00247094 0.59012 0.5 +-0.0701749 0.0347541 -0.0017891 0.135623 0.5 +-0.00340266 0.114844 -0.0176928 0.826111 0.5 +0.0310248 0.053713 -0.0140522 0.572913 0.5 +0.0268191 0.0528482 -0.020339 0.412387 0.455219 +-0.0147458 0.120673 -0.0105853 0.653192 0.5 +0.0270905 0.106214 -0.0146756 0.603346 0.5 +0.0465541 0.0697991 0.00228503 0.590477 0.5 +-0.00300122 0.100676 -0.0235814 0.77298 0.5 +-0.0755874 0.076212 0.033468 0.651011 0.5 +0.059738 0.0572998 0.0151736 0.624329 0.5 +0.0595394 0.0578717 0.00861672 0.650231 0.5 +0.0572091 0.0580526 0.00253507 0.577167 0.5 +-0.0142907 0.123147 -0.00746744 0.689207 0.5 +0.0211831 0.112303 -0.0140834 0.636933 0.5 +0.0347455 0.0565046 -0.010714 0.517615 0.5 +0.0249138 0.0825163 -0.0245877 0.759593 0.5 +-0.0382227 0.114521 -0.016178 0.845616 0.5 +-0.0819485 0.0761672 0.0208322 0.76776 0.5 +-0.0269557 0.0392251 -0.0293943 0.537642 0.5 +0.0377037 0.0593401 -0.00852013 0.537798 0.5 +0.0330295 0.0586306 -0.014729 0.60439 0.5 +0.0218121 0.0515865 -0.0236492 0.56032 0.5 +-0.0204953 0.0935908 -0.0331675 0.485557 0.5 +-0.0872217 0.113521 0.0440666 0.448078 0.427651 +-0.0271537 0.0351608 0.0509267 0.96808 0.5 +-0.0503825 0.106302 -0.0194598 0.649024 0.5 +0.0266611 0.0585067 -0.0219134 0.622435 0.5 +0.00975018 0.0945932 -0.0280451 0.504262 0.457756 +-0.0205524 0.122391 -0.00754739 0.498583 0.5 +-0.0668021 0.0909191 -0.0174744 0.566525 0.5 +-0.0856155 0.0942099 -0.00109094 0.420789 0.436678 +-0.0915274 0.11444 0.0204492 0.759207 0.5 +-0.0909048 0.131701 0.00809159 0.558083 0.5 +0.0404851 0.0578886 -0.0051698 0.425865 0.437223 +0.0295964 0.0580473 -0.0178274 0.608291 0.460655 +0.0266986 0.0941359 -0.0205949 0.662934 0.5 +-0.0677104 0.172869 -0.0572602 0.695141 0.5 +0.0142001 0.118043 -0.013917 0.45799 0.403894 +-0.0698171 0.0699687 0.0326375 0.529959 0.5 +0.0607097 0.0648802 0.0151632 0.434757 0.451533 +0.0609346 0.0630505 0.0131585 0.526971 0.5 +0.0602205 0.0643718 0.00864139 0.443146 0.456896 +0.0574055 0.0638877 0.00271573 0.413274 0.5 +-0.0797793 0.103858 -0.00660016 0.553637 0.5 +-0.0563867 0.137359 -0.00421998 0.659682 0.5 +0.0344512 0.0638263 -0.0152012 0.581486 0.5 +0.0307139 0.0605317 -0.0184589 0.617611 0.449874 +0.0185684 0.121789 -0.00725624 0.61441 0.349043 +-0.0456617 0.112414 -0.0169658 0.70381 0.5 +0.0456177 0.0644845 -0.00162168 0.572144 0.5 +-0.0584268 0.0349015 0.0441202 0.767369 0.5 +-0.0747982 0.0723674 0.0308514 0.656357 0.5 +-0.0699373 0.0621854 0.0151778 0.587415 0.5 +-0.052889 0.136519 -0.00170821 0.593683 0.5 +0.0410205 0.0644886 -0.00476733 0.363401 0.5 +0.0388712 0.0646166 -0.00976797 0.384344 0.5 +0.0514871 0.0637279 -0.00174794 0.518067 0.5 +-0.0787297 0.0744551 0.0267421 0.809934 0.5 +-0.0850281 0.144269 0.00618082 0.578063 0.5 +0.0313094 0.064487 -0.0188936 0.672704 0.5 +0.0267274 0.0646171 -0.0220842 0.752591 0.5 +0.0318737 0.0877439 -0.0192705 0.740422 0.5 +-0.0772455 0.143995 -0.00470939 0.452269 0.5 +0.0132576 0.110443 -0.0183541 0.539267 0.5 +-0.00289343 0.124723 -0.00863032 0.516883 0.5 +-0.0342868 0.038582 0.0485461 0.546061 0.5 +0.0200397 0.0876233 -0.0261205 0.735721 0.5 +0.0585453 0.0705354 0.0146976 0.608535 0.5 +0.0581405 0.0699819 0.00856199 0.483528 0.5 +0.056099 0.069436 0.00424359 0.385578 0.5 +0.0370479 0.0665186 -0.0132637 0.645736 0.5 +-0.062561 0.172971 -0.0616721 0.43069 0.5 +-0.0702718 0.15494 -0.0455472 0.29179 0.457421 +-0.0916259 0.130499 0.00930481 0.432982 0.472725 +-0.070021 0.148229 -0.0328231 0.322588 0.195946 +-0.0721274 0.0680183 0.0267753 0.656727 0.5 +-0.0745337 0.15067 -0.0264303 0.331486 0.5 +0.0431087 0.0713461 -0.002764 0.390428 0.45538 +0.0421659 0.0692525 -0.00466106 0.55545 0.5 +0.0345404 0.0699378 -0.0160391 0.727409 0.5 +-0.0342368 0.122912 -0.00708584 0.432969 0.5 +0.0401518 0.070932 -0.00951127 0.706551 0.5 +0.0370706 0.0707408 -0.013301 0.722628 0.5 +0.0310856 0.0702175 -0.0192905 0.761897 0.5 +0.0283004 0.0705453 -0.0222447 0.701199 0.5 +-0.00859023 0.101699 -0.0237897 0.731824 0.5 +-0.0328234 0.0400139 -0.029875 0.413461 0.5 +-0.0830588 0.11047 0.0397334 0.931001 0.5 +0.0142724 0.123237 -0.00806485 0.479991 0.484444 +-0.0760443 0.108637 0.0389078 0.769887 0.5 +-0.0732762 0.154939 -0.0321392 0.640327 0.5 +0.0160324 0.0889232 -0.0282477 0.595959 0.5 +-0.0901677 0.131361 0.0394374 0.633972 0.457764 +0.0455828 0.0768365 0.00270178 0.323813 0.5 +-0.0516717 0.0553965 0.014906 0.168077 0.5 +-0.0376545 0.121002 -0.0109724 0.599451 0.451266 +0.0466318 0.0762885 0.00910629 0.334003 0.5 +0.0437303 0.0769241 -0.00295564 0.541016 0.5 +0.0405043 0.0766784 -0.0084913 0.540094 0.5 +0.0369463 0.0762836 -0.0128837 0.716695 0.5 +0.0349351 0.0766648 -0.0155944 0.687304 0.5 +0.0319237 0.0763904 -0.0194186 0.722365 0.5 +0.0285208 0.0758075 -0.0225233 0.729644 0.5 +-0.0646857 0.068809 0.0348219 0.518098 0.396839 +-0.00335573 0.0986136 -0.0269283 0.762285 0.5 +-0.0383606 0.100112 -0.0217661 0.633523 0.5 +-0.0705433 0.149897 -0.0387319 0.143598 0.5 +-0.0247871 0.179215 -0.0188356 0.466421 0.5 +0.00339058 0.0937023 -0.0318365 0.697748 0.5 +-0.09099 0.142689 0.0226645 0.743514 0.5 +-0.0851088 0.102115 0.000391121 0.420019 0.403283 +0.00299202 0.124707 -0.00864775 0.631346 0.5 +-0.0649459 0.167336 -0.0329944 0.692397 0.5 +0.045975 0.0827243 0.0146716 0.494123 0.463874 +0.0461931 0.0827376 0.00867911 0.540283 0.443947 +0.0453461 0.0826602 0.00269811 0.520808 0.5 +0.032594 0.082231 -0.0190597 0.700575 0.5 +-0.0707752 0.142011 -0.00901143 0.440829 0.5 +-0.0396694 0.045239 -0.0210351 0.371561 0.5 +-0.0736488 0.145787 -0.0131048 0.298566 0.5 +-0.0661855 0.1779 -0.0529018 0.456268 0.5 +-0.0698006 0.179227 -0.0517285 0.330383 0.5 +-0.0719677 0.177848 -0.0474604 0.498199 0.393806 +-0.0131817 0.0974247 0.0509808 0.29677 0.5 +-0.0760529 0.177651 -0.0471457 0.200482 0.341482 +-0.0875274 0.149451 0.00937476 0.260452 0.5 +-0.0847504 0.149536 0.00652369 0.220089 0.5 +-0.0853843 0.0980412 -0.000554198 0.453316 0.5 +-0.070162 0.172945 -0.0393132 0.377002 0.42015 +-0.0669053 0.17136 -0.0404187 0.587367 0.5 +-0.0915765 0.114644 0.0108349 0.335405 0.476851 +0.0311175 0.116345 -0.00142056 0.524001 0.485056 +-0.09039 0.144074 0.0142555 0.571623 0.5 +0.0533752 0.0724173 0.00805773 0.504643 0.5 +0.0348115 0.113636 0.00289967 0.517745 0.5 +0.0321047 0.117128 0.00373672 0.512637 0.481334 +-0.0558554 0.16013 0.00226313 0.176407 0.35978 +0.0284127 0.12005 0.00266093 0.800124 0.5 +-0.0693417 0.151526 -0.0443255 0.162625 0.220555 +0.0509143 0.0733396 0.0112131 0.81315 0.5 +0.0485286 0.0726358 0.00856732 0.779683 0.5 +0.0251471 0.122517 0.00254898 0.804299 0.5 +-0.0684168 0.170157 -0.0319531 0.535557 0.5 +-0.071028 0.171274 -0.0325886 0.712016 0.5 +-0.0765634 0.155757 -0.00874762 0.256295 0.5 +0.0525206 0.0734678 0.0148876 0.468908 0.45355 +0.035521 0.113454 0.00908801 0.654915 0.5 +0.0208324 0.125627 0.00327965 0.76886 0.5 +-0.0476722 0.134348 0.0194434 0.579216 0.488505 +-0.0746083 0.171229 -0.0326516 0.439107 0.422901 +0.0322027 0.117616 0.0093642 0.646061 0.5 +0.0162523 0.127588 0.00132734 0.679655 0.445027 +-0.0914669 0.142805 0.0167223 0.344959 0.5 +0.0290775 0.120474 0.00686894 0.798143 0.5 +0.0135909 0.12914 0.00336546 0.632038 0.474565 +-0.0861635 0.100458 0.025719 0.514874 0.431291 +-0.0653051 0.165945 -0.0269849 0.665887 0.5 +-0.0698492 0.16889 -0.0268648 0.536219 0.5 +-0.07827 0.167473 -0.032496 0.259817 0.452429 +0.0215557 0.0945234 -0.0226594 0.630702 0.48336 +0.0260612 0.123082 0.00873766 0.803075 0.5 +0.00920342 0.130081 0.00248247 0.641161 0.5 +-0.0709934 0.170517 -0.0295248 0.566905 0.409383 +-0.0760202 0.167938 -0.0272636 0.242234 0.5 +0.0525229 0.0716654 0.0211203 0.349876 0.431389 +0.0207167 0.126566 0.00922145 0.763786 0.5 +-0.0746025 0.0998033 -0.0126456 0.503102 0.5 +-0.0864333 0.0890874 0.0257055 0.752441 0.5 +0.0354941 0.113435 0.0150848 0.708057 0.5 +0.0320737 0.117698 0.0146262 0.694886 0.5 +0.00294754 0.130714 0.00292443 0.849802 0.5 +-0.0256391 0.0823957 0.0519489 0.764034 0.5 +-0.0666258 0.165416 -0.0221631 0.534987 0.5 +-0.0804177 0.153092 0.00488677 0.321879 0.39417 +-0.0645623 0.0350017 0.0151892 0.352362 0.5 +-0.0627936 0.0352479 0.02012 0.616295 0.5 +-0.0642932 0.0349381 0.0264604 0.161121 0.384305 +-0.0642421 0.0397497 0.0267659 0.206373 0.5 +-0.0652419 0.0352202 0.0324357 0.167045 0.5 +-0.06432 0.0352261 0.0387914 0.349097 0.5 +-0.0869014 0.0944088 0.0260869 0.722262 0.5 +-0.026376 0.100403 -0.0237519 0.527518 0.47737 +-0.0704394 0.0348288 0.00888692 0.228898 0.5 +-0.0696375 0.039673 0.0091864 0.30841 0.5 +-0.0678064 0.035728 0.013362 0.509091 0.5 +-0.0778433 0.0819732 0.0354617 0.774608 0.5 +-0.0809318 0.0827942 0.0325 0.767831 0.5 +-0.0712316 0.038974 0.00275642 0.155719 0.237906 +-0.0616101 0.0379618 0.0219344 0 0 +-0.0653778 0.0407054 0.0323415 0.379158 0.5 +-0.0612949 0.040108 0.0438783 0.388361 0.5 +-0.0748891 0.0826916 0.0381154 0.772848 0.5 +-0.0841641 0.133769 0.0486564 0.546232 0.467433 +-0.0849106 0.0945271 0.0290479 0.754258 0.5 +-0.082994 0.144712 0.0404065 0.382972 0.420138 +-0.0265479 0.117619 -0.0132781 0.755106 0.5 +-0.0679678 0.0383221 0.0123903 0.271535 0.306541 +-0.0639259 0.0401146 0.0151101 0.258252 0.450399 +-0.0588527 0.0407802 0.0202136 0.51937 0.5 +-0.0869621 0.135589 0.0440584 0.520567 0.5 +-0.038827 0.0398484 0.042564 0.570175 0.5 +-0.0253238 0.0773437 0.0501603 0.646885 0.5 +0.00864855 0.111878 -0.0192252 0.821439 0.5 +-0.0625014 0.04424 0.0388616 0.455153 0.47063 +-0.088493 0.125258 0.0461673 0.674925 0.5 +0.0150785 0.10107 -0.0220372 0.749486 0.5 +-0.0810533 0.0876325 0.0334622 0.750019 0.5 +-0.0636602 0.0439221 0.0322355 0.437404 0.5 +-0.0823757 0.12585 -0.00459555 0.376136 0.464207 +-0.0374554 0.042873 0.0429512 0.492581 0.5 +-0.031328 0.0432863 0.0501185 0.483275 0.5 +-0.0841802 0.0875016 0.0285815 0.671149 0.464325 +-0.0690099 0.0427216 0.00298087 0.372436 0.5 +-0.0690323 0.0427133 0.00739115 0.277083 0.5 +-0.0642007 0.0449178 0.00895163 0.562755 0.5 +-0.0630005 0.0427497 0.0133004 0.520064 0.348086 +-0.0580777 0.0444032 0.0143596 0.493924 0.5 +-0.087476 0.130712 0.0458544 0.531379 0.477045 +-0.0837712 0.0999337 0.029339 0.668895 0.5 +-0.083719 0.0822846 0.0270932 0.660348 0.5 +-0.0209183 0.0934772 0.0512134 0.479975 0.5 +-0.0868983 0.142651 0.0383505 0.486766 0.469754 +-0.0588984 0.0467651 0.00989959 0.460736 0.319245 +-0.0529144 0.0464475 0.0158024 0.381525 0.5 +-0.0881654 0.0882094 0.0209192 0.624947 0.5 +-0.0494075 0.165901 0.000731671 0.369742 0.391777 +-0.0586114 0.0473978 0.0337061 0.152377 0.410418 +-0.05614 0.0517476 0.00835186 0.396733 0.5 +-0.0865231 0.148073 0.0321271 0.367072 0.452379 +-0.0308497 0.0493297 0.0429654 0.330168 0.454747 +-0.0769102 0.114994 0.0501188 0.653806 0.5 +-0.0209065 0.0959579 0.0474195 0.622864 0.5 +-0.0509947 0.0509637 0.0150799 0.759028 0.5 +0.00842415 0.0889657 -0.0320537 0.627702 0.5 +-0.0240561 0.0544386 0.0416973 0.433194 0.5 +-0.0510392 0.0524223 0.0203213 0.262945 0.5 +-0.0526208 0.0518271 0.027021 0.695325 0.5 +-0.0504022 0.0591186 0.0326891 0.768296 0.5 +-0.0478821 0.0590694 0.0363134 0.800191 0.5 +-0.0239128 0.0586553 0.0421308 0.768223 0.5 +-0.0759314 0.119228 -0.00697007 0.568703 0.5 +-0.0183181 0.0604564 0.0506182 0.70539 0.5 +-0.0298441 0.0972531 -0.0235715 0.830462 0.5 +-0.0241926 0.0628773 0.0422936 0.709715 0.5 +-0.0223998 0.06467 0.045979 0.606456 0.5 +-0.0192899 0.0641483 0.0503928 0.754401 0.5 +-0.0260109 0.172925 -0.0191453 0.51739 0.5 +-0.0265331 0.161574 -0.0144318 0.84044 0.5 +-0.0558556 0.15572 -0.00121016 0.41523 0.5 +-0.0599028 0.136466 -0.0064456 0.660892 0.5 +-0.063538 0.071665 0.0379463 0.556494 0.5 +-0.0200417 0.0869862 -0.0378876 0.500126 0.449734 +-0.0557176 0.105745 -0.0186241 0.707273 0.5 +-0.0530691 0.143914 -0.00100898 0.728895 0.5 +-0.0256688 0.0704637 0.0438935 0.717372 0.393932 +-0.0235577 0.0693774 0.0470203 0.657726 0.5 +-0.0525759 0.127247 -0.00521525 0.567734 0.5 +-0.0787859 0.131858 -0.00545913 0.44224 0.460808 +-0.0580212 0.120088 -0.0102747 0.564344 0.455328 +-0.0396294 0.110441 -0.0186258 0.62346 0.5 +-0.0210282 0.173113 -0.0214922 0.42389 0.352327 +-0.0547593 0.0563289 0.0107147 0.179388 0.5 +-0.0435534 0.0345758 -0.024752 0.176398 0.205782 +-0.0449833 0.0346921 -0.0207483 0.159962 0.261208 +-0.0443576 0.0390403 -0.0217491 0.178142 0.5 +-0.0462855 0.0345037 -0.0153112 0.189574 0.5 +-0.046619 0.0396457 -0.0141457 0.194812 0.5 +-0.00904923 0.0343826 -0.0246429 0.15305 0.5 +0.00311748 0.100303 -0.0227929 0.684313 0.5 +-0.0690809 0.0392217 -0.00181724 0.169982 0.409113 +-0.0920289 0.131041 0.0262349 0.856795 0.5 +-0.043414 0.0372487 -0.0253064 0.219927 0.5 +0.0280974 0.0818294 -0.0220931 0.752623 0.5 +-0.067702 0.169446 -0.0560134 0.487347 0.455218 +-0.0915377 0.129674 0.0312365 0.601516 0.48259 +-0.0663086 0.0411162 -0.00443149 0.346306 0.5 +-0.0731255 0.151935 -0.0368879 0.40925 0.5 +-0.0390145 0.0394889 -0.027598 0.3765 0.5 +-0.0637372 0.0437827 -0.00264533 0.37233 0.5 +-0.0605427 0.0425565 0.0246975 0.23689 0.5 +-0.0857603 0.130763 -0.000714461 0.66754 0.5 +-0.0520472 0.0403573 -0.0107411 0.62257 0.5 +-0.0568522 0.0434504 0.0224413 0.404188 0.5 +-0.043239 0.0429342 -0.0193166 0.339314 0.38382 +-0.0438787 0.0441322 -0.0144222 0.427488 0.468839 +-0.0457505 0.046486 -0.0105694 0.340556 0.5 +-0.0645938 0.0456897 0.00313082 0.3549 0.5 +-0.0525978 0.0464843 0.0207116 0.3335 0.5 +-0.0572578 0.0459489 0.026887 0.439332 0.5 +-0.0618962 0.0443648 0.0286813 0.302557 0.45843 +-0.0331467 0.0453179 -0.0267282 0.481653 0.5 +-0.0377669 0.0443547 -0.0252099 0.392631 0.5 +-0.0320922 0.114425 -0.0162304 0.853943 0.5 +-0.0578027 0.0470669 -0.0032674 0.530144 0.5 +-0.0914954 0.147994 0.0205137 0.478387 0.480384 +-0.0400067 0.0471536 -0.0151042 0.224844 0.33752 +0.00454895 0.121869 -0.0124797 0.622385 0.5 +0.0151282 0.112708 -0.0165496 0.634759 0.463552 +-0.0525787 0.0463291 -0.00775444 0.598118 0.5 +-0.0599276 0.0475112 0.00267117 0.286734 0.429608 +-0.0726458 0.147126 -0.0218625 0.235551 0.5 +-0.0740924 0.168686 -0.0440312 0.451963 0.347747 +-0.057494 0.0515426 0.00319413 0.311918 0.5 +-0.0536918 0.0483048 0.0264945 0.447469 0.5 +-0.0147156 0.114453 -0.0172255 0.634887 0.5 +-0.0335191 0.0480424 -0.021246 0.299501 0.5 +0.019461 0.0924333 -0.0244344 0.636237 0.5 +0.0169402 0.0952065 -0.0238278 0.793707 0.5 +0.0201047 0.104156 -0.0188197 0.859301 0.5 +-0.0319642 0.0516657 -0.0152509 0.265727 0.5 +-0.0368448 0.0488256 -0.0131071 0.109826 0.5 +-0.0391265 0.0518909 -0.0109467 0.555432 0.5 +-0.00892221 0.111576 -0.0202733 0.785262 0.5 +-0.0515659 0.0515158 -0.00751393 0.527245 0.5 +-0.0557028 0.05294 -0.00268598 0.514955 0.5 +-0.0293421 0.0526398 -0.0213991 0.356317 0.5 +-0.0314453 0.0496351 -0.0193539 0.306544 0.5 +0.0322381 0.10409 -0.0128482 0.653044 0.5 +-0.0261025 0.0525801 -0.0264669 0.366688 0.5 +-0.0583031 0.116733 -0.0130038 0.568329 0.5 +-0.014851 0.111599 -0.0191484 0.630253 0.463696 +-0.0521348 0.118189 -0.0137451 0.464136 0.474515 +-0.0517493 0.0582798 -0.00896954 0.683087 0.5 +-0.0561982 0.0582462 -0.00310645 0.618759 0.5 +-0.0587989 0.0586119 0.00276734 0.328771 0.427166 +-0.0585564 0.0578416 0.00857596 0.293131 0.5 +0.019026 0.11614 -0.0131686 0.497701 0.5 +-0.0211893 0.111662 -0.0190883 0.650648 0.5 +-0.0239176 0.0561149 -0.030057 0.484351 0.5 +-0.0272603 0.058548 -0.027478 0.457773 0.5 +-0.0295766 0.0582799 -0.0217551 0.550969 0.5 +-0.0320928 0.0589382 -0.0147618 0.534177 0.453646 +0.0073938 0.121789 -0.0126555 0.654152 0.5 +-0.0251946 0.0595227 -0.0308632 0.509396 0.5 +-0.0307167 0.06013 -0.0194181 0.549851 0.422118 +-0.0650113 0.0632174 -0.00293095 0.168435 0.5 +-0.0696479 0.065751 -0.00198101 0.165663 0.5 +-0.0699926 0.0635013 0.00374106 0.275779 0.5 +-0.0799435 0.0724812 0.0191514 0.599916 0.5 +-0.0676844 0.160922 -0.0559942 0.35716 0.5 +-0.0215435 0.0636559 -0.0350431 0.45692 0.5 +-0.0258325 0.0648252 -0.0322087 0.452259 0.5 +-0.028982 0.0636438 -0.0274997 0.410415 0.5 +-0.0304226 0.0629368 -0.0224261 0.908229 0.5 +-0.0319042 0.0651819 -0.0201942 0.518875 0.434998 +-0.0332741 0.0636337 -0.0160032 0.40837 0.447765 +-0.0205547 0.034111 -0.026401 0.174612 0.215481 +-0.0743367 0.0658286 0.00833126 0.649876 0.5 +0.016103 0.120745 -0.0103843 0.509865 0.5 +-0.0770212 0.0700544 0.00316631 0.305775 0.384345 +-0.0748219 0.06693 0.00451345 0.433069 0.463791 +-0.0306317 0.0657524 -0.025453 0.517895 0.5 +-0.0711433 0.0687078 -0.00390291 0.256016 0.135401 +-0.0762625 0.0716316 -0.00295918 0.293636 0.296358 +-0.0802204 0.0713935 0.00991267 0.507181 0.5 +-0.0913413 0.148143 0.0161458 0.474933 0.5 +-0.0273736 0.0700052 -0.0335323 0.445714 0.5 +-0.0300274 0.0692073 -0.0289677 0.511122 0.5 +-0.0316277 0.0711218 -0.0266514 0.502235 0.5 +-0.0330629 0.0699765 -0.0212743 0.929225 0.5 +-0.0353642 0.0705896 -0.0177097 0.263666 0.5 +-0.0587004 0.0391044 -0.0090027 0.295521 0.5 +-0.0697696 0.0703857 -0.00808666 0.238472 0.5 +-0.0804832 0.0726462 0.00472466 0.630221 0.5 +0.0151616 0.126104 -0.00266395 0.542796 0.5 +-0.0745721 0.072883 -0.00757069 0.303203 0.5 +-0.0823908 0.076277 0.00270117 0.615888 0.5 +-0.0912831 0.133698 0.0142161 0.68945 0.5 +0.00371049 0.0968817 -0.0280931 0.670854 0.5 +-0.0761392 0.0766258 -0.00859487 0.260107 0.5 +-0.0784749 0.0748827 -0.00523624 0.238143 0.440892 +-0.0806781 0.0771902 -0.00290803 0.36458 0.43512 +-0.0834622 0.0765209 0.00927112 0.562933 0.5 +0.00983826 0.11402 -0.0178612 0.519736 0.475688 +0.00210649 0.0981565 -0.0261244 0.689185 0.5 +-0.0285085 0.0757575 -0.0348118 0.64535 0.304239 +-0.0330874 0.0761249 -0.0270661 0.564742 0.5 +-0.0346568 0.0757906 -0.0215029 0.930953 0.5 +0.0231104 0.0892807 -0.0240236 0.697809 0.45449 +-0.0312132 0.0771357 -0.0320416 0.687582 0.5 +-0.0700425 0.0763633 -0.0141464 0.485274 0.5 +-0.0861137 0.0814707 0.00908143 0.590509 0.5 +-0.086319 0.08152 0.0149936 0.698173 0.5 +-0.0208042 0.0963182 -0.0270563 0.75553 0.5 +-0.0211078 0.114391 -0.0171285 0.793027 0.5 +-0.0746162 0.0828529 -0.0139325 0.683447 0.5 +-0.077295 0.081216 -0.0100568 0.47673 0.5 +-0.0800127 0.0821605 -0.00722237 0.637376 0.5 +-0.0826334 0.0820868 -0.00324616 0.569954 0.5 +-0.0844667 0.0817669 0.00249573 0.601403 0.5 +-0.0860445 0.0832591 0.0203255 0.630527 0.5 +-0.084816 0.0816746 0.0219849 0.638209 0.5 +0.0545549 0.0661692 0.000765649 0.628404 0.43579 +-0.0331604 0.0828369 -0.0270493 0.417784 0.5 +-0.0358028 0.0829047 -0.0227723 0.112354 0 +-0.0861942 0.0842505 0.00298565 0.418742 0.5 +-0.0287072 0.0827267 -0.0349537 0.48086 0.471486 +-0.0311601 0.0822387 -0.0315627 0.627475 0.5 +-0.085403 0.141865 0.00516647 0.463398 0.5 +-0.0785169 0.0885628 -0.0107607 0.69884 0.5 +-0.0807046 0.0887676 -0.00826584 0.689404 0.5 +-0.0843972 0.0878743 -0.00349923 0.402052 0.5 +-0.0855708 0.0882073 -0.00109946 0.425364 0.422235 +-0.0876157 0.0881286 0.00369184 0.414972 0.435161 +-0.0885339 0.0876942 0.00897158 0.630733 0.5 +-0.0885791 0.0877213 0.0149616 0.665472 0.5 +-0.0643854 0.0348576 -0.00775085 0.279509 0.5 +-0.0512932 0.034227 -0.0129013 0.159841 0.5 +-0.0266839 0.0458556 -0.027274 0.610127 0.5 +-0.0146368 0.0981541 -0.0264318 0.44201 0.5 +-0.0213468 0.10077 -0.0239588 0.58675 0.5 +0.020932 0.0825954 -0.0267347 0.750174 0.5 +0.00759225 0.0928541 -0.0309237 0.580726 0.5 +-0.0144478 0.0879274 -0.0380297 0.689122 0.5 +-0.00859724 0.11451 -0.0173132 0.77831 0.5 +0.0264818 0.109935 -0.0126182 0.652634 0.5 +-0.0145855 0.0385179 -0.0267991 0.230538 0.5 +-0.0330054 0.0337044 -0.0272991 0.262513 0.5 +-0.0267872 0.0340475 -0.0271901 0.244173 0 +-0.00849157 0.0985859 -0.0270535 0.53889 0.411612 +-0.0110954 0.120824 -0.0120135 0.770076 0.5 +0.0367379 0.0925992 -0.0129888 0.684003 0.5 +-0.0571635 0.0435755 -0.00717607 0.581004 0.404197 +-0.0193328 0.0979251 -0.024792 0.661276 0.5 +-0.0203798 0.0385467 -0.0283088 0.392689 0.5 +-0.0587681 0.0337133 -0.00871891 0.1361 0.5 +-0.0517919 0.100655 -0.0213258 0.798237 0.5 +0.00702627 0.0978418 -0.0246055 0.732067 0.326346 +-0.0148892 0.126068 -0.00252126 0.467449 0.5 +0.0307578 0.092446 -0.0188519 0.704525 0.5 +0.0211049 0.0578126 -0.0266116 0.685576 0.5 +-0.0169237 0.0970481 -0.0278718 0.775366 0.5 +0.0460004 0.0581866 -0.00508589 0.612698 0.5 +-0.00944331 0.0822271 -0.0381067 0.670336 0.467319 +-0.0635881 0.0392124 -0.00717766 0.572252 0.5 +0.00864227 0.0386371 -0.0233053 0.540697 0.5 +0.0252935 0.0769557 -0.0248407 0.75695 0.5 +-0.0229653 0.0895159 -0.036199 0.454072 0.467569 +-0.0523791 0.0341193 -0.00994653 0.132813 0.5 +0.0211693 0.0643935 -0.0268578 0.690366 0.5 +-0.0515867 0.13164 -0.0028092 0.545448 0.5 +-0.0149669 0.0345529 -0.0254273 0.17846 0.5 +-0.0161167 0.127288 0.00169291 0.694465 0.5 +-0.0469232 0.128515 -0.00163965 0.389857 0.5 +-0.00961381 0.127158 -0.00378809 0.714685 0.5 +-0.0074566 0.128562 -0.00130751 0.72817 0.5 +-0.00304493 0.128909 -0.00174857 0.778769 0.5 +0.0028379 0.129022 -0.00194723 0.574275 0.5 +0.00903363 0.128674 -0.00165013 0.617309 0.5 +-0.0561607 0.131588 -0.00571429 0.687735 0.5 +-0.0457551 0.127167 -0.00484962 0.645893 0.5 +-0.00304746 0.127678 -0.00456004 0.562309 0.5 +0.00303811 0.12768 -0.00442 0.624596 0.5 +0.0101526 0.126812 -0.00466464 0.64326 0.5 +-0.0553259 0.126836 -0.00601308 0.517644 0.5 +0.00799473 0.034846 -0.0206913 0.278473 0.5 +0.0027179 0.0342191 -0.0204737 0.322372 0.5 +-0.00295804 0.0342418 -0.0216222 0.194059 0.5 +0.0134674 0.0353221 -0.0196961 0.466171 0.5 +0.00440963 0.0383063 -0.0240776 0.3469 0.5 +0.00140752 0.0383474 -0.0246147 0.361099 0.5 +-0.00309177 0.0383877 -0.0251866 0.314174 0.5 +-0.0575023 0.100661 -0.0195211 0.459895 0.452391 +-0.0485739 0.15316 -0.00547278 0.691758 0.5 +-0.0646573 0.0334831 -0.00296009 0.187639 0.5 +-0.0640796 0.100426 -0.0173936 0.44544 0.466101 +-0.0704415 0.100139 -0.0146037 0.499781 0.478548 +-0.0326376 0.155806 -0.00949884 0.828995 0.5 +0.0336094 0.0373624 0.00273412 0.290019 0.5 +0.0320943 0.0397885 -0.00195136 0.323719 0.5 +0.0158502 0.0449602 -0.0237212 0.910511 0.5 +0.00889467 0.0426449 -0.0242659 0.891863 0.5 +0.00312499 0.0452721 -0.026588 0.665265 0.460024 +-0.00298345 0.044686 -0.0272222 0.905955 0.5 +-0.00912346 0.0448524 -0.0280671 0.895801 0.5 +-0.0145351 0.0443266 -0.0277771 0.887903 0.5 +-0.0209223 0.0460913 -0.0281918 0.705844 0.5 +0.034052 0.0448434 -0.00540113 0.626363 0.5 +-0.0312646 0.158257 -0.01223 0.732334 0.5 +0.0401509 0.0448981 -0.00354586 0.446696 0.5 +0.0143253 0.0473484 -0.0251513 0.546545 0.456757 +0.00937888 0.0466526 -0.0261685 0.907397 0.5 +-0.0766531 0.0695423 0.0207982 0.774152 0.5 +0.0087246 0.0517916 -0.0291615 0.840924 0.5 +0.00299372 0.0506927 -0.0298557 0.901259 0.5 +-0.00164566 0.0489436 -0.0304144 0.872257 0.5 +-0.00321397 0.0522596 -0.0314075 0.634884 0.475184 +-0.00915341 0.0509217 -0.0318681 0.650022 0.5 +-0.0146018 0.0513752 -0.0319045 0.891033 0.5 +-0.0161558 0.0488543 -0.0303763 0.808351 0.5 +-0.0205843 0.0508011 -0.0296435 0.813106 0.5 +0.0405252 0.0518855 -0.00654453 0.65569 0.5 +0.0149309 0.0520772 -0.0273859 0.655547 0.5 +0.041884 0.0490868 -0.00604367 0.898378 0.5 +0.019962 0.0529908 -0.0261219 0.592286 0.5 +-0.0198501 0.0534234 -0.0312267 0.768335 0.5 +-0.0336273 0.0527187 -0.0106243 0.102172 0.5 +-0.0461112 0.0529158 -0.0101664 0.636429 0.372142 +-0.0204 0.161875 -0.014658 0.822907 0.5 +0.0449924 0.0530898 -0.00614891 0.575737 0.5 +0.00733679 0.0546532 -0.0305038 0.688621 0.5 +0.00283568 0.0546532 -0.0307468 0.611749 0.5 +-0.00302245 0.0577 -0.0331477 0.67582 0.5 +-0.00914668 0.0576676 -0.0341165 0.698389 0.5 +-0.01517 0.058199 -0.0349877 0.856637 0.5 +-0.0202707 0.0581031 -0.0333681 0.552506 0.5 +0.0140844 0.057965 -0.028983 0.564173 0.483714 +0.0103301 0.0588553 -0.0299472 0.602031 0.489059 +0.00732823 0.0588898 -0.0306117 0.710141 0.5 +0.0027369 0.0590151 -0.0321928 0.690932 0.5 +-0.0337187 0.0579742 -0.0115824 0.143826 0.5 +-0.0390711 0.0582467 -0.0115033 0.780735 0.5 +-0.0460474 0.0579124 -0.0115174 0.472305 0.5 +-0.00961439 0.0642168 -0.0358564 0.670518 0.457134 +-0.044157 0.0599825 -0.0123877 0.830365 0.5 +0.015251 0.0645803 -0.029567 0.626368 0.396114 +0.00839294 0.0649214 -0.0316957 0.79033 0.385997 +0.00325858 0.0643529 -0.0332439 0.728322 0.418376 +-0.00361257 0.0645861 -0.034907 0.670644 0.5 +-0.0144709 0.065006 -0.0371603 0.712311 0.5 +-0.0366623 0.060679 -0.0122791 0.525705 0.5 +-0.0526404 0.0636402 -0.0101297 0.452904 0.5 +-0.0381866 0.0648919 -0.0142073 0.543504 0.5 +-0.0452495 0.0647856 -0.0139819 0.883769 0.5 +-0.0599262 0.0622966 -0.00429285 0.195385 0.344922 +-0.0778641 0.117463 -0.00576778 0.523105 0.5 +-0.0187447 0.0664151 -0.0374779 0.820087 0.5 +-0.0577616 0.0644884 -0.00779097 0.472929 0.5 +-0.0625778 0.0655353 -0.00741131 0.379588 0.453283 +0.0251088 0.0710945 -0.0248604 0.704567 0.5 +0.021457 0.0702729 -0.0273415 0.740248 0.5 +0.0166747 0.0701586 -0.0297203 0.658948 0.5 +0.0132745 0.0702643 -0.0312074 0.651019 0.5 +0.00867525 0.0703509 -0.0324278 0.818076 0.5 +0.00229643 0.0708694 -0.0343123 0.73028 0.5 +-0.0030646 0.070381 -0.0353565 0.764349 0.5 +-0.00773679 0.0691749 -0.0362051 0.757441 0.5 +-0.0101988 0.0715122 -0.0373778 0.76291 0.5 +-0.0147454 0.0704429 -0.0382943 0.581028 0.470136 +-0.0203984 0.0706516 -0.038158 0.645161 0.5 +-0.0240967 0.0693418 -0.0362521 0.4533 0.5 +-0.0605175 0.0673597 -0.0108259 0.635082 0.5 +-0.0387293 0.0706355 -0.0168457 0.666323 0.5 +-0.0451347 0.0705064 -0.0164504 0.875899 0.5 +-0.0523435 0.0697862 -0.0145984 0.401473 0.5 +-0.0591515 0.0702891 -0.0147203 0.639534 0.5 +-0.0652515 0.0688492 -0.00993982 0.422384 0.422462 +-0.0247614 0.0719777 -0.0368317 0.497524 0.5 +-0.0637884 0.0712697 -0.0138535 0.437166 0.5 +0.0211454 0.0769268 -0.0268772 0.737516 0.5 +0.0162128 0.0765268 -0.0293784 0.712202 0.5 +0.0133247 0.0760196 -0.0306715 0.679361 0.5 +0.00907695 0.076038 -0.0330382 0.719764 0.5 +0.00245085 0.0760857 -0.0351615 0.721395 0.5 +-0.00176321 0.0762288 -0.0360688 0.799862 0.5 +-0.00476487 0.076286 -0.0369742 0.814155 0.377247 +-0.00962992 0.0765936 -0.0378651 0.627364 0.487104 +-0.0144481 0.0764118 -0.0385775 0.832444 0.5 +-0.021453 0.0763574 -0.038668 0.751656 0.5 +-0.024977 0.0762484 -0.0374518 0.39297 0.457854 +-0.0377453 0.0766164 -0.0189124 0.273711 0.5 +-0.0397395 0.0746623 -0.0180255 0.973337 0.5 +-0.0437423 0.0765905 -0.0187922 0.595439 0.440211 +-0.0466377 0.0744845 -0.0173668 0.538698 0.468502 +-0.0518623 0.0745812 -0.0175084 0.855826 0.5 +-0.0589866 0.0745368 -0.01766 0.879682 0.5 +-0.0644081 0.0756279 -0.0167529 0.562234 0.481782 +-0.0721295 0.0740256 -0.0105719 0.341576 0.432723 +-0.0615233 0.0354132 0.043881 0.499903 0.5 +-0.0524971 0.0769872 -0.0189536 0.873913 0.5 +-0.0587482 0.0767445 -0.0187462 0.882838 0.5 +0.013102 0.0809953 -0.0307917 0.69611 0.5 +0.00892296 0.0820652 -0.0325478 0.700162 0.5 +0.0022917 0.0820297 -0.0349279 0.829579 0.5 +-0.00177837 0.0804805 -0.0364471 0.647084 0.379833 +-0.00379684 0.0824193 -0.037328 0.824332 0.5 +-0.0142988 0.0820384 -0.0390211 0.832022 0.373406 +-0.0207708 0.0823862 -0.0387335 0.805306 0.5 +-0.0248089 0.0818968 -0.0377031 0.470046 0.439483 +-0.0735819 0.0777026 -0.0122023 0.445372 0.5 +0.015425 0.0831288 -0.0295207 0.735694 0.5 +-0.0383994 0.0817919 -0.0209596 0.290803 0.5 +-0.0451184 0.0815526 -0.020434 0.548777 0.45056 +-0.051814 0.0818472 -0.0211348 0.886135 0.5 +-0.0583689 0.0812724 -0.0202975 0.847354 0.5 +-0.063949 0.082768 -0.0188935 0.606874 0.5 +-0.0662709 0.080065 -0.0177832 0.593549 0.449354 +-0.0695594 0.0830593 -0.0170582 0.4495 0.5 +-0.00481814 0.086841 -0.0367951 0.827149 0.5 +-0.0248206 0.0867524 -0.0367639 0.487957 0.5 +0.0132046 0.0871602 -0.0305473 0.663835 0.5 +-0.0360837 0.0867076 -0.023791 0.366486 0.5 +-0.00877843 0.0340556 -0.0204927 0 0 +-0.0207128 0.0342382 -0.0208728 0.319674 0.5 +-0.0147915 0.0341096 -0.0207616 0.312592 0.5 +-0.0265767 0.0342963 -0.0210989 0.482378 0.5 +0.00282685 0.0351053 -0.0158136 0.508357 0.5 +0.00885967 0.034471 -0.0147487 0.490133 0.5 +-0.0390848 0.0337228 -0.0202617 0.628543 0.5 +-0.0326656 0.0345334 -0.0201874 0.788348 0.5 +-0.00224535 0.0351539 -0.0166234 0.756398 0.5 +-0.0149096 0.0357313 -0.0180956 0.933106 0.5 +-0.0114808 0.0353662 -0.0177045 0.933613 0.5 +-0.00921575 0.0380183 -0.0149732 0.909294 0.5 +-0.00282494 0.0382292 -0.0140636 0.920543 0.5 +0.00285919 0.0377324 -0.0134715 0.965028 0.5 +0.0159109 0.0347098 -0.00882204 0.420938 0.5 +-0.0306839 0.036693 -0.0184598 0.875112 0.5 +-0.0265216 0.0367471 -0.0188177 0.84266 0.5 +-0.0218341 0.0369718 -0.0184303 0.873319 0.5 +-0.0203027 0.0382765 -0.0152577 0.887215 0.5 +-0.0152596 0.0382328 -0.0156428 0.873575 0.5 +0.00738356 0.0366172 -0.0125003 0.962688 0.5 +0.00992361 0.0351979 -0.00924624 0.9642 0.5 +0.00702596 0.0378387 -0.00879015 0.927286 0.5 +-0.0396958 0.0342843 -0.014578 0.76643 0.5 +-0.0329517 0.0382154 -0.014678 0.654319 0.5 +-0.0263862 0.0385778 -0.0153644 0.924592 0.5 +0.00320835 0.0389424 -0.00953857 0.945732 0.5 +-0.0364387 0.0357946 -0.0155844 0.543249 0.5 +-0.00301526 0.0391061 -0.00886496 0.816802 0.5 +0.00831664 0.0348156 -0.00321961 0.671683 0.5 +0.0145039 0.0343685 -0.0028433 0.748562 0.5 +-0.0365752 0.0370276 -0.0136534 0.498247 0.5 +-0.0146234 0.0388055 -0.00887465 0.759701 0.5 +-0.00886749 0.0389394 -0.00890173 0.761944 0.5 +-0.0451032 0.0336721 -0.00848668 0.772585 0.5 +-0.040313 0.0350801 -0.00861758 0.462745 0.5 +-0.0206235 0.0386 -0.00878063 0.747754 0.5 +0.00267879 0.038424 -0.00319748 0.448355 0.5 +0.015044 0.0350517 0.00289039 0.579133 0.5 +0.0201479 0.0347806 0.00348327 0.403273 0.5 +0.027119 0.0353514 0.00366834 0.0909279 0.5 +0.0280785 0.0365531 0.000826759 0 0 +-0.0376066 0.0375692 -0.00942418 0.22755 0.5 +-0.0332748 0.0384549 -0.00855692 0.752109 0.5 +-0.0264541 0.0384497 -0.00886193 0.729343 0.5 +-0.00299262 0.0389582 -0.00292437 0.746846 0.5 +0.00451408 0.0356078 -0.00103635 0.413486 0.5 +0.00881079 0.0350428 0.00356828 0.588251 0.5 +0.0314184 0.0360255 0.00457907 0.187967 0.5 +-0.00888202 0.0387884 -0.00299409 0.73859 0.5 +0.00271787 0.0349091 0.00339755 0.645421 0.5 +-0.041199 0.0341471 -0.00327644 0 0 +-0.0205479 0.0384259 -0.00283766 0.741413 0.5 +-0.0146618 0.0385908 -0.00288739 0.718901 0.5 +0.00103528 0.0375917 0.000952222 0.441385 0.5 +0.0215747 0.0354906 0.0086194 0.395945 0.5 +0.0264794 0.0346514 0.00870654 0.414057 0.5 +0.0322391 0.0355412 0.00882378 0.515667 0.5 +-0.0521057 0.0334794 -0.00318207 0.614129 0.5 +-0.0455078 0.0336572 -0.00225818 0.757211 0.5 +-0.0334104 0.0383259 -0.00292317 0.611245 0.5 +-0.0265122 0.0383343 -0.00296504 0.763748 0.5 +-0.00224847 0.0383354 0.00320971 0.728422 0.5 +-0.0589386 0.0334143 -0.00291301 0.444064 0.5 +-0.00874044 0.0385976 0.00291227 0.735039 0.5 +0.00273457 0.0342734 0.0088248 0.796819 0.5 +0.00621941 0.0351341 0.00654928 0 0 +-0.080018 0.109279 0.0373655 0.503151 0.426569 +-0.0393178 0.0336443 0.00354096 0.266658 0.5 +-0.0213111 0.0382973 0.00334866 0.753895 0.5 +-0.0146196 0.0384265 0.00290922 0.762157 0.5 +-0.00353554 0.0379644 0.00874752 0.658939 0.5 +0.0276681 0.0349662 0.0149532 0.360666 0.5 +0.03282 0.0359255 0.0147037 0.719837 0.5 +0.0389763 0.0383079 0.0145025 0.635106 0.5 +-0.0523961 0.0335249 0.00326874 0.742717 0.5 +-0.0462346 0.0335696 0.00267776 0.743661 0.5 +-0.0277984 0.0382296 0.00286126 0.456211 0.5 +-0.000947006 0.0357374 0.0103469 0.779853 0.5 +0.0222276 0.0358262 0.0160256 0.180494 0.5 +0.0448051 0.0411192 0.0150961 0.294679 0.5 +-0.0581064 0.033504 0.00272997 0.775526 0.5 +-0.0352323 0.0337248 0.00491425 0.152905 0 +-0.0312985 0.0381858 0.00167702 0 0 +-0.0088641 0.03847 0.00876261 0.73345 0.5 +0.0028919 0.0342894 0.0147059 0.676527 0.5 +-0.0703332 0.0340583 0.00286723 0.639535 0.5 +-0.0648245 0.0334924 0.00301734 0.793089 0.5 +-0.0387963 0.034763 0.00935652 0.458758 0.5 +-0.0332327 0.0337932 0.00943608 0.151116 0.5 +-0.0203456 0.0382265 0.00836296 0.759992 0.5 +-0.0152156 0.0383161 0.00935801 0.755179 0.5 +-0.000385714 0.0351459 0.0134171 0.848157 0.5 +0.00663645 0.0342324 0.0159688 0 0 +0.0268074 0.0356469 0.0204126 0.619176 0.5 +0.0309391 0.0362152 0.0189937 0.762661 0.5 +0.0334119 0.0376179 0.0210082 0.70177 0.5 +-0.0515734 0.0338904 0.00817232 0.493124 0.5 +-0.0454999 0.0352808 0.00804865 0.53914 0.5 +-0.0263229 0.0380313 0.00871732 0.143858 0.5 +-0.0031858 0.0377098 0.014513 0.797449 0.5 +0.0211051 0.0351552 0.0207004 0.432057 0.5 +0.0391983 0.0395969 0.0205879 0.670001 0.5 +0.0441778 0.0418755 0.0204802 0.609797 0.5 +-0.0580282 0.0335624 0.00918162 0.776077 0.5 +-0.00922404 0.0383488 0.0150261 0.754001 0.5 +0.00313746 0.0352426 0.0204176 0.692001 0.5 +0.00877508 0.0346179 0.020856 0.290121 0.5 +0.0468489 0.0434226 0.0210936 0.239557 0.5 +-0.0648031 0.0337402 0.00884817 0.802283 0.5 +-0.0338156 0.0345063 0.0150293 0.572312 0.5 +-0.0149173 0.0382498 0.0147214 0.753708 0.5 +0.0146344 0.0345628 0.0222588 0.157065 0.5 +-0.0365655 0.0357926 0.0130139 0.391807 0.5 +-0.0262153 0.0376693 0.0148666 0.146481 0.5 +-0.0205165 0.0381248 0.0146779 0.715632 0.5 +-0.00229335 0.0382456 0.020565 0.923102 0.5 +0.014723 0.0347707 0.0263935 0.310145 0.5 +0.0210245 0.0353476 0.0265418 0.313898 0.5 +0.0250756 0.0364517 0.0246847 0.678097 0.5 +0.0273584 0.0381522 0.0267127 0.778478 0.5 +0.0321164 0.0401984 0.026762 0.778536 0.5 +-0.053829 0.0335431 0.0139547 0.458851 0.5 +0.00114114 0.037661 0.0223414 0.978558 0.5 +0.00915473 0.0353589 0.0262457 0.701449 0.5 +0.0380552 0.0412819 0.02589 0.374179 0.417844 +-0.0588034 0.0336951 0.0146283 0.798139 0.5 +-0.0339319 0.0346253 0.0202274 0.513983 0.5 +-0.0152545 0.0382629 0.0204704 0.75125 0.5 +-0.00888844 0.0384087 0.0207206 0.746481 0.5 +0.00307272 0.0384964 0.0264151 0.996029 0.5 +-0.0261643 0.0378491 0.0205422 0.603577 0.5 +-0.0205429 0.0381473 0.0213758 0.772551 0.5 +-0.0538188 0.0335608 0.0210581 0 0 +-0.00301594 0.03875 0.0263901 0.805634 0.5 +0.00756209 0.0380712 0.0285007 0.978659 0.5 +0.0143741 0.0348327 0.0331833 0.915728 0.5 +0.0198279 0.03555 0.0321213 0.749506 0.5 +0.0236875 0.0373106 0.0299772 0.517201 0.5 +-0.0588476 0.033906 0.020465 0.657735 0.5 +-0.00882687 0.0386047 0.0265705 0.756827 0.5 +0.00847025 0.0383344 0.0315598 0.739987 0.5 +0.0108958 0.035647 0.0330663 0.649316 0.5 +-0.0366651 0.0353042 0.023032 0.153172 0.5 +-0.0340084 0.0344659 0.0266224 0.263742 0.5 +-0.0270447 0.0379104 0.0270529 0.074682 0.5 +-0.0210471 0.0383013 0.026282 0.782021 0.5 +-0.0147317 0.0384888 0.0265233 0.791552 0.5 +-0.0712786 0.0733348 0.0355839 0.683322 0.427231 +-0.0388887 0.0346255 0.0265538 0.109729 0 +0.00290004 0.0393205 0.032168 0.626516 0.5 +0.0155389 0.0350901 0.0393977 0.759188 0.5 +0.0195159 0.0358111 0.0367948 0.405286 0.5 +-0.0589139 0.0341314 0.0264586 0.808252 0.5 +-0.052234 0.0340737 0.0268887 0.497915 0.5 +-0.0447866 0.0339274 0.0274346 0.154159 0.5 +-0.0310127 0.0369382 0.02848 0.240675 0.5 +-0.00908756 0.0390146 0.0330901 0.79352 0.5 +-0.00293287 0.039209 0.03365 0.804769 0.5 +0.00861952 0.0346654 0.0391536 0.125418 0.5 +-0.0149144 0.0388312 0.0324344 0.795183 0.5 +0.00392423 0.0347398 0.0399064 0.146347 0.5 +-0.0657827 0.0618455 0.00187562 0.442355 0.5 +-0.0640051 0.0606097 0.00361345 0.333039 0.5 +-0.0455164 0.0345095 0.0326748 0.510388 0.5 +-0.0385699 0.0344168 0.033204 0.485482 0.5 +-0.0342024 0.0351611 0.0325685 0.248514 0.5 +-0.0270303 0.0384799 0.0326469 0.783767 0.5 +-0.0209433 0.0387397 0.0332273 0.806699 0.5 +-0.0520994 0.0344582 0.0326775 0.466807 0.5 +-0.0313489 0.0377268 0.0321213 0.178238 0.5 +-0.00219023 0.0348305 0.0410082 0.139343 0 +0.00818206 0.0355366 0.0443043 0.642932 0.5 +0.014947 0.0361331 0.0431407 0.796588 0.5 +-0.0642564 0.0597236 0.0092932 0.716255 0.5 +-0.0584732 0.0343588 0.0331559 0.775713 0.5 +-0.0145859 0.0393004 0.0380317 0.483641 0.5 +-0.00937548 0.0394517 0.037871 0.328321 0.5 +-0.0588297 0.0579582 0.0145443 0 0 +-0.038732 0.0346956 0.0400227 0.628019 0.5 +-0.0331487 0.034492 0.0390527 0.154826 0.5 +-0.0201914 0.0391628 0.0381696 0.483919 0.5 +-0.00878985 0.0348233 0.0452949 0.139305 0.5 +-0.0031441 0.0351515 0.045825 0.295611 0.5 +-0.0701619 0.0622789 0.00863964 0.42197 0.408074 +-0.0451191 0.034688 0.0396457 0.766116 0.5 +-0.0256628 0.0389081 0.0373249 0 0 +-0.0146115 0.0348173 0.0458198 0.143796 0.5 +-0.0636462 0.0593677 0.014889 0.807508 0.5 +-0.0531671 0.0345191 0.0391729 0.74918 0.5 +-0.0595372 0.034497 0.0397515 0.783724 0.5 +-0.0329555 0.0349777 0.045552 0.474674 0.5 +-0.0262436 0.034809 0.0452831 0.162616 0.5 +-0.0215554 0.0348112 0.0459347 0.152356 0 +-0.0633407 0.0601272 0.0190813 0.939061 0.5 +-0.0471 0.0351015 0.0434178 0.627709 0.5 +-0.0120723 0.0353434 0.0494553 0.877126 0.5 +-0.016313 0.0351836 0.0504037 0.67915 0.5 +-0.0483699 0.146034 -0.00115148 0.583019 0.5 +-0.0264335 0.156562 -0.00835956 0.469485 0.437523 +-0.065003 0.144791 -0.0142909 0.400803 0.470167 +-0.066228 0.151547 -0.0394609 0.538048 0.5 +-0.0663323 0.145309 -0.018858 0.764025 0.5 +-0.0412403 0.152108 -0.00674014 0.633348 0.5 +3 4 132 80 +3 80 132 544 +3 373 80 544 +3 387 299 241 +3 859 1475 1474 +3 371 299 401 +3 401 326 333 +3 347 673 402 +3 1187 1354 386 +3 1221 457 69 +3 186 224 114 +3 1250 1256 116 +3 164 333 376 +3 19 488 1245 +3 749 19 1245 +3 667 19 749 +3 1040 412 543 +3 1359 1358 1500 +3 216 4 80 +3 152 544 146 +3 4 387 505 +3 543 1235 1205 +3 610 604 297 +3 250 801 1274 +3 504 148 111 +3 387 348 299 +3 401 333 164 +3 1484 1483 1110 +3 91 196 310 +3 90 91 310 +3 952 406 609 +3 1244 1247 1240 +3 93 327 65 +3 373 544 152 +3 373 152 644 +3 1321 158 22 +3 401 416 326 +3 644 152 1263 +3 276 59 181 +3 294 853 150 +3 308 249 529 +3 406 1124 604 +3 609 406 463 +3 146 3 145 +3 90 310 3 +3 58 186 10 +3 575 261 384 +3 25 40 43 +3 379 535 713 +3 348 704 157 +3 388 443 22 +3 396 146 145 +3 152 133 1263 +3 1830 1829 1812 +3 214 114 224 +3 157 147 324 +3 1335 430 1274 +3 282 230 214 +3 92 346 652 +3 1151 1012 1491 +3 571 1151 1491 +3 571 1491 183 +3 310 196 111 +3 91 4 505 +3 1250 116 108 +3 110 183 47 +3 1209 854 953 +3 132 4 91 +3 111 148 327 +3 93 111 327 +3 110 571 183 +3 713 171 402 +3 294 920 200 +3 81 180 52 +3 525 731 784 +3 347 256 673 +3 175 57 220 +3 338 175 220 +3 27 14 220 +3 57 27 220 +3 359 446 27 +3 359 36 446 +3 145 28 262 +3 133 16 419 +3 1447 576 1465 +3 1885 287 444 +3 133 396 16 +3 598 543 1205 +3 447 93 65 +3 73 213 36 +3 1236 1255 1250 +3 1235 1236 1250 +3 115 782 731 +3 28 93 447 +3 525 548 115 +3 299 416 401 +3 667 603 463 +3 292 667 463 +3 492 70 637 +3 133 146 396 +3 1166 1125 619 +3 1151 1219 959 +3 821 304 409 +3 1486 1487 1684 +3 15 175 167 +3 120 15 167 +3 15 131 57 +3 175 15 57 +3 57 131 27 +3 257 209 359 +3 27 257 359 +3 209 55 36 +3 359 209 36 +3 55 87 73 +3 36 55 73 +3 101 108 735 +3 108 101 64 +3 310 365 3 +3 576 859 1465 +3 262 28 447 +3 102 64 101 +3 544 91 90 +3 262 447 485 +3 485 447 211 +3 1443 1440 1442 +3 697 457 1221 +3 1008 383 1011 +3 451 435 1330 +3 129 405 426 +3 70 75 161 +3 648 693 692 +3 204 129 426 +3 812 481 123 +3 406 292 463 +3 878 1591 1009 +3 478 128 50 +3 900 979 977 +3 490 900 977 +3 241 299 371 +3 1164 701 734 +3 683 703 682 +3 719 718 682 +3 703 719 682 +3 760 759 718 +3 719 760 718 +3 137 729 728 +3 54 130 2 +3 302 358 301 +3 566 567 614 +3 1069 1103 1068 +3 1186 1190 1208 +3 4 348 387 +3 277 311 228 +3 707 226 706 +3 355 394 393 +3 773 129 755 +3 646 647 679 +3 356 355 269 +3 270 356 269 +3 424 394 356 +3 623 654 602 +3 654 683 602 +3 193 217 192 +3 1677 1676 1662 +3 1018 1019 1025 +3 597 1231 1165 +3 490 26 605 +3 299 157 416 +3 504 241 148 +3 84 528 714 +3 1247 669 1240 +3 683 719 703 +3 1886 1231 1066 +3 79 168 218 +3 211 318 426 +3 165 377 148 +3 91 505 387 +3 577 623 622 +3 692 693 707 +3 255 254 218 +3 194 270 255 +3 695 137 728 +3 1475 1498 1474 +3 67 808 1010 +3 1190 240 1208 +3 242 259 300 +3 476 509 567 +3 743 755 558 +3 1025 1024 1018 +3 194 255 218 +3 270 269 254 +3 203 271 12 +3 603 667 749 +3 1379 1395 1392 +3 783 546 1340 +3 578 600 577 +3 624 623 577 +3 600 624 577 +3 655 654 623 +3 684 683 654 +3 655 684 654 +3 720 719 683 +3 684 720 683 +3 720 739 719 +3 761 760 719 +3 739 761 719 +3 218 254 253 +3 694 695 437 +3 255 270 254 +3 1202 488 19 +3 412 1222 543 +3 60 528 84 +3 1352 494 702 +3 624 655 623 +3 1361 221 143 +3 755 129 204 +3 132 91 544 +3 543 1221 1235 +3 216 5 4 +3 1221 1236 1235 +3 754 755 204 +3 1169 732 715 +3 756 755 743 +3 1036 1035 1024 +3 728 756 743 +3 476 567 508 +3 4 5 348 +3 244 1339 546 +3 405 445 211 +3 254 269 268 +3 253 254 268 +3 381 358 302 +3 346 92 59 +3 517 450 1560 +3 1618 1333 141 +3 1498 1497 1474 +3 1231 597 1165 +3 228 264 215 +3 100 151 99 +3 151 215 99 +3 151 228 215 +3 1864 827 1870 +3 561 578 480 +3 207 561 480 +3 579 600 578 +3 561 579 578 +3 600 625 624 +3 656 655 624 +3 625 656 624 +3 685 684 655 +3 656 685 655 +3 685 721 720 +3 684 685 720 +3 721 740 739 +3 720 721 739 +3 739 740 761 +3 762 789 788 +3 761 762 788 +3 789 239 770 +3 788 789 770 +3 328 770 239 +3 423 424 476 +3 121 195 522 +3 423 476 422 +3 381 431 358 +3 148 371 401 +3 579 625 600 +3 465 464 431 +3 381 465 431 +3 464 465 227 +3 248 11 71 +3 548 142 1005 +3 740 762 761 +3 767 900 490 +3 728 743 437 +3 776 195 121 +3 1177 1176 1153 +3 1043 1034 1035 +3 137 708 729 +3 91 387 196 +3 1721 1729 1703 +3 728 729 756 +3 727 728 437 +3 196 387 241 +3 404 458 522 +3 355 354 268 +3 647 648 692 +3 979 846 901 +3 241 371 148 +3 142 1155 574 +3 269 355 268 +3 358 301 300 +3 301 358 300 +3 753 754 793 +3 184 229 228 +3 229 277 228 +3 312 311 277 +3 1845 1853 1831 +3 1523 1532 1153 +3 580 579 561 +3 1276 1280 1771 +3 580 626 625 +3 579 580 625 +3 626 657 656 +3 625 626 656 +3 656 657 685 +3 722 721 685 +3 741 740 721 +3 722 741 721 +3 740 763 762 +3 790 789 762 +3 763 790 762 +3 790 339 239 +3 789 790 239 +3 377 165 327 +3 476 508 422 +3 259 301 300 +3 162 170 169 +3 81 162 169 +3 580 561 562 +3 657 686 685 +3 229 312 277 +3 28 365 93 +3 1263 419 1254 +3 396 145 144 +3 685 686 722 +3 741 763 740 +3 133 152 146 +3 1263 133 419 +3 207 520 562 +3 520 562 580 +3 562 520 580 +3 562 626 580 +3 239 339 487 +3 597 1063 1066 +3 3 365 28 +3 649 648 615 +3 108 64 116 +3 571 1225 1218 +3 184 185 229 +3 313 312 229 +3 185 313 229 +3 439 501 520 +3 501 581 562 +3 520 501 562 +3 627 626 562 +3 581 627 562 +3 627 628 626 +3 658 657 626 +3 628 658 626 +3 658 675 657 +3 687 686 657 +3 675 687 657 +3 723 722 686 +3 687 723 686 +3 722 723 741 +3 741 723 763 +3 764 791 790 +3 763 764 790 +3 791 407 339 +3 790 791 339 +3 407 303 339 +3 303 487 339 +3 303 460 487 +3 303 325 460 +3 170 106 105 +3 105 106 68 +3 439 440 501 +3 723 764 763 +3 1 1027 453 +3 1067 511 942 +3 775 121 774 +3 1281 1270 1291 +3 368 440 439 +3 367 368 439 +3 582 581 501 +3 628 627 581 +3 658 688 687 +3 675 658 687 +3 1733 1562 1561 +3 757 775 756 +3 74 68 46 +3 398 1223 317 +3 631 607 231 +3 1465 859 1474 +3 1775 1784 1754 +3 204 138 793 +3 74 122 97 +3 584 533 570 +3 278 313 185 +3 265 278 185 +3 369 368 313 +3 278 369 313 +3 369 440 368 +3 502 501 440 +3 583 582 501 +3 502 583 501 +3 583 581 582 +3 629 628 581 +3 583 629 581 +3 629 659 658 +3 628 629 658 +3 658 659 688 +3 724 723 687 +3 688 724 687 +3 724 742 723 +3 742 765 764 +3 723 742 764 +3 764 238 791 +3 791 238 407 +3 407 238 303 +3 238 333 303 +3 333 325 303 +3 614 615 647 +3 46 122 74 +3 606 199 112 +3 441 440 369 +3 83 173 573 +3 775 776 121 +3 846 979 901 +3 441 502 440 +3 659 689 688 +3 84 714 1367 +3 535 52 171 +3 551 798 1883 +3 630 629 583 +3 629 630 659 +3 689 724 688 +3 792 238 764 +3 765 792 764 +3 1207 1208 177 +3 195 96 522 +3 122 13 97 +3 344 492 637 +3 1025 1036 1024 +3 775 774 756 +3 1012 1151 959 +3 1270 1372 1291 +3 145 3 28 +3 649 670 695 +3 517 1888 243 +3 444 399 1885 +3 370 369 278 +3 724 765 742 +3 376 333 238 +3 1372 1375 1291 +3 1060 1161 1162 +3 16 396 144 +3 369 442 441 +3 583 601 630 +3 690 689 659 +3 318 295 427 +3 138 204 427 +3 693 694 707 +3 310 111 365 +3 365 111 93 +3 636 660 659 +3 567 566 508 +3 426 405 211 +3 121 126 774 +3 471 601 583 +3 251 237 188 +3 1303 188 237 +3 278 314 370 +3 370 442 369 +3 442 503 502 +3 441 442 502 +3 503 471 583 +3 502 503 583 +3 858 302 259 +3 16 144 319 +3 660 690 659 +3 690 725 724 +3 689 690 724 +3 750 765 724 +3 725 750 724 +3 8 792 765 +3 750 8 765 +3 376 238 792 +3 8 376 792 +3 164 376 238 +3 376 164 238 +3 1381 1380 1375 +3 1135 1134 1103 +3 1104 1135 1103 +3 794 204 793 +3 447 65 211 +3 442 1347 503 +3 249 262 485 +3 1036 1043 1035 +3 522 96 438 +3 204 426 427 +3 188 283 251 +3 1235 1250 1205 +3 485 262 23 +3 597 1066 1165 +3 144 308 319 +3 1027 767 589 +3 648 649 694 +3 567 615 614 +3 821 409 304 +3 63 711 903 +3 8 164 376 +3 12 478 50 +3 171 347 402 +3 284 1327 314 +3 1447 1465 1459 +3 1456 1447 1459 +3 1329 1328 1380 +3 755 756 773 +3 756 774 773 +3 193 218 253 +3 648 694 693 +3 168 194 218 +3 190 188 189 +3 284 283 188 +3 190 284 188 +3 283 284 314 +3 262 485 23 +3 108 116 64 +3 751 750 725 +3 726 751 725 +3 751 771 750 +3 37 8 750 +3 771 37 750 +3 632 164 8 +3 569 53 411 +3 511 1560 1884 +3 386 1354 1320 +3 165 632 8 +3 37 165 8 +3 165 164 632 +3 662 661 638 +3 354 393 422 +3 401 165 148 +3 979 1883 798 +3 144 145 262 +3 413 408 349 +3 16 319 669 +3 318 211 295 +3 156 1213 198 +3 1153 1152 1119 +3 1225 1448 247 +3 190 266 284 +3 419 669 1247 +3 479 233 232 +3 166 165 37 +3 709 492 344 +3 567 568 615 +3 107 827 1864 +3 695 727 437 +3 485 211 23 +3 1254 419 1247 +3 419 16 669 +3 1884 1591 1009 +3 249 485 24 +3 41 249 24 +3 1103 1134 1133 +3 272 398 492 +3 754 204 794 +3 1498 159 113 +3 24 485 23 +3 1102 1103 1133 +3 308 144 249 +3 164 165 401 +3 692 707 706 +3 509 568 567 +3 191 252 190 +3 190 252 266 +3 252 285 284 +3 266 252 284 +3 285 286 284 +3 284 286 337 +3 144 262 249 +3 536 564 563 +3 563 564 593 +3 564 612 611 +3 593 564 611 +3 645 361 611 +3 612 645 611 +3 645 691 1313 +3 309 752 751 +3 726 309 751 +3 752 772 771 +3 751 752 771 +3 119 37 771 +3 772 119 771 +3 425 166 37 +3 119 425 37 +3 380 165 166 +3 425 380 166 +3 128 83 17 +3 50 128 17 +3 729 757 756 +3 394 423 422 +3 589 767 490 +3 424 509 476 +3 1374 1359 1531 +3 408 372 349 +3 679 692 706 +3 855 242 300 +3 766 757 730 +3 354 355 393 +3 79 218 193 +3 129 126 405 +3 126 458 405 +3 647 692 679 +3 757 766 775 +3 766 776 775 +3 1699 1014 1013 +3 393 394 422 +3 252 286 285 +3 752 119 772 +3 425 327 380 +3 696 730 729 +3 708 696 729 +3 649 695 694 +3 78 79 193 +3 1497 1498 113 +3 901 979 798 +3 404 24 445 +3 24 23 445 +3 776 795 195 +3 1340 1591 1884 +3 1035 1034 1024 +3 177 203 12 +3 380 327 425 +3 510 509 424 +3 477 510 424 +3 458 404 405 +3 192 217 252 +3 191 192 252 +3 217 267 286 +3 252 217 286 +3 286 267 352 +3 353 421 420 +3 352 353 420 +3 421 507 506 +3 506 507 536 +3 507 565 564 +3 536 507 564 +3 565 613 612 +3 564 565 612 +3 646 645 612 +3 613 646 612 +3 646 679 691 +3 645 646 691 +3 706 705 691 +3 679 706 691 +3 753 309 280 +3 138 119 752 +3 753 138 752 +3 427 425 119 +3 138 427 119 +3 295 380 425 +3 427 295 425 +3 65 327 380 +3 295 65 380 +3 769 104 315 +3 426 318 427 +3 568 616 615 +3 695 728 727 +3 404 445 405 +3 1635 1653 1453 +3 271 478 12 +3 839 136 830 +3 615 648 647 +3 311 277 228 +3 749 1245 1225 +3 353 392 421 +3 793 138 753 +3 315 104 33 +3 432 466 465 +3 381 432 465 +3 465 466 527 +3 1170 1190 1099 +3 754 794 793 +3 558 754 280 +3 193 253 217 +3 253 268 267 +3 217 253 267 +3 268 354 353 +3 267 268 353 +3 354 392 353 +3 422 421 392 +3 354 422 392 +3 422 508 507 +3 421 422 507 +3 508 566 565 +3 507 508 565 +3 614 613 565 +3 566 614 565 +3 614 647 646 +3 613 614 646 +3 168 810 194 +3 886 940 923 +3 946 945 930 +3 929 939 944 +3 940 569 887 +3 661 649 616 +3 320 919 878 +3 227 526 464 +3 882 873 866 +3 552 384 820 +3 464 927 358 +3 917 432 905 +3 879 829 820 +3 194 836 880 +3 935 466 432 +3 917 935 432 +3 1038 1725 1013 +3 1378 1391 1406 +3 173 448 293 +3 477 943 510 +3 616 568 617 +3 1405 550 980 +3 665 86 847 +3 891 906 912 +3 845 130 54 +3 999 925 822 +3 1885 928 555 +3 904 910 270 +3 315 33 478 +3 1033 1034 1042 +3 490 921 26 +3 850 257 131 +3 1070 1077 1034 +3 843 860 15 +3 120 843 15 +3 850 209 257 +3 914 913 300 +3 880 911 910 +3 641 661 616 +3 843 120 797 +3 860 870 15 +3 870 131 15 +3 870 850 131 +3 894 873 882 +3 811 248 875 +3 974 981 992 +3 850 201 131 +3 131 201 850 +3 850 201 209 +3 907 917 905 +3 694 437 226 +3 895 843 797 +3 870 860 843 +3 816 870 843 +3 870 201 850 +3 913 933 932 +3 968 969 986 +3 840 118 712 +3 816 843 895 +3 201 856 209 +3 856 845 55 +3 209 856 55 +3 931 930 911 +3 228 151 184 +3 1340 884 1884 +3 553 506 536 +3 539 867 842 +3 870 924 201 +3 977 823 490 +3 868 829 780 +3 999 1000 925 +3 198 701 156 +3 787 816 895 +3 924 877 856 +3 201 924 856 +3 877 845 856 +3 66 305 941 +3 769 203 1208 +3 848 847 919 +3 880 889 911 +3 1027 589 605 +3 957 816 787 +3 849 870 816 +3 957 849 816 +3 414 821 409 +3 1887 1004 928 +3 569 888 887 +3 459 384 552 +3 891 889 890 +3 839 892 891 +3 1080 1057 1051 +3 957 328 816 +3 328 957 816 +3 849 881 870 +3 881 849 870 +3 870 849 924 +3 481 531 123 +3 777 835 698 +3 891 892 906 +3 912 911 889 +3 891 912 889 +3 546 1339 746 +3 328 849 957 +3 849 88 924 +3 1043 1070 1034 +3 777 122 46 +3 477 929 943 +3 617 641 616 +3 822 915 72 +3 915 331 72 +3 834 806 956 +3 788 957 787 +3 770 788 787 +3 788 328 957 +3 864 877 924 +3 833 938 130 +3 845 833 130 +3 938 256 130 +3 1005 142 574 +3 661 676 137 +3 730 305 776 +3 1186 1208 1207 +3 1189 1186 1207 +3 798 1888 1067 +3 864 924 88 +3 864 922 877 +3 982 845 877 +3 922 982 877 +3 982 833 845 +3 894 905 873 +3 879 665 86 +3 879 665 847 +3 817 922 864 +3 833 982 922 +3 817 833 922 +3 894 907 905 +3 1562 1561 1038 +3 305 893 776 +3 899 864 88 +3 1071 1049 1072 +3 788 770 328 +3 776 768 795 +3 835 919 847 +3 817 864 899 +3 833 256 938 +3 1177 1195 1176 +3 1276 1771 1275 +3 155 100 813 +3 832 96 449 +3 879 384 665 +3 879 86 665 +3 834 956 320 +3 863 898 328 +3 826 849 328 +3 898 826 328 +3 849 826 88 +3 826 899 88 +3 1346 1883 900 +3 930 945 944 +3 939 930 944 +3 810 818 836 +3 838 836 837 +3 1077 1069 1034 +3 891 890 838 +3 1473 1680 1679 +3 44 24 438 +3 899 200 817 +3 1374 1391 1378 +3 466 935 527 +3 66 941 730 +3 913 906 912 +3 956 919 320 +3 662 676 661 +3 239 395 863 +3 395 898 863 +3 819 826 898 +3 826 200 899 +3 35 86 82 +3 880 270 194 +3 935 950 527 +3 670 661 695 +3 134 256 94 +3 818 837 836 +3 848 879 847 +3 395 819 898 +3 826 819 200 +3 200 920 817 +3 920 876 833 +3 817 920 833 +3 833 876 256 +3 1034 1069 1068 +3 932 933 947 +3 997 676 662 +3 836 889 880 +3 757 729 730 +3 956 806 919 +3 603 749 1460 +3 876 48 256 +3 827 107 155 +3 107 184 155 +3 830 855 841 +3 1042 1034 1068 +3 832 449 795 +3 997 662 638 +3 384 261 665 +3 997 696 676 +3 294 48 876 +3 920 294 876 +3 925 915 822 +3 1199 1231 1886 +3 941 305 730 +3 200 418 294 +3 569 940 886 +3 100 155 184 +3 840 712 331 +3 921 379 26 +3 1016 1014 1699 +3 776 766 730 +3 983 997 638 +3 676 696 137 +3 487 395 239 +3 487 819 395 +3 569 886 511 +3 940 887 923 +3 986 1000 985 +3 1125 110 47 +3 947 968 958 +3 842 874 834 +3 822 918 66 +3 985 999 998 +3 984 985 998 +3 999 822 998 +3 983 984 997 +3 984 998 997 +3 819 418 200 +3 177 85 1206 +3 12 275 397 +3 1231 1165 1066 +3 240 769 1208 +3 1000 999 985 +3 943 965 568 +3 906 913 932 +3 300 913 892 +3 997 998 66 +3 998 822 66 +3 478 33 128 +3 570 701 1076 +3 305 72 768 +3 72 811 768 +3 878 884 411 +3 878 835 884 +3 930 939 929 +3 968 978 967 +3 958 968 967 +3 946 958 967 +3 819 853 418 +3 510 943 509 +3 509 943 568 +3 151 100 184 +3 978 984 983 +3 967 978 983 +3 474 1122 799 +3 932 931 912 +3 487 460 819 +3 460 29 819 +3 819 29 853 +3 340 867 383 +3 1134 1135 1161 +3 947 946 931 +3 1411 1501 1408 +3 300 892 855 +3 356 910 929 +3 136 838 837 +3 1259 351 523 +3 887 896 923 +3 260 86 665 +3 774 129 773 +3 872 873 871 +3 906 932 912 +3 661 137 695 +3 511 886 942 +3 985 984 978 +3 968 985 978 +3 818 136 837 +3 1559 851 857 +3 872 871 865 +3 1222 1221 543 +3 548 1005 115 +3 430 1198 1065 +3 768 811 832 +3 945 967 944 +3 1132 1134 1160 +3 1019 1036 1025 +3 1134 1161 1160 +3 615 616 649 +3 1560 884 1884 +3 884 835 888 +3 214 230 114 +3 811 332 832 +3 878 411 53 +3 848 842 879 +3 842 829 879 +3 48 673 256 +3 869 811 768 +3 912 931 911 +3 935 936 950 +3 871 302 381 +3 972 991 971 +3 708 137 696 +3 1225 571 110 +3 847 955 13 +3 803 190 189 +3 865 871 858 +3 986 985 968 +3 929 944 943 +3 227 972 526 +3 888 835 896 +3 1001 1002 840 +3 1830 1841 1829 +3 50 140 275 +3 394 424 423 +3 411 884 888 +3 936 935 917 +3 907 936 917 +3 835 847 698 +3 811 6 332 +3 842 867 829 +3 1161 1060 1226 +3 1885 399 1887 +3 808 834 995 +3 1659 1658 1638 +3 65 295 211 +3 918 822 305 +3 302 871 381 +3 847 86 955 +3 1001 840 925 +3 1010 937 834 +3 1208 203 177 +3 1135 1162 1161 +3 921 81 379 +3 271 315 478 +3 948 969 947 +3 464 526 927 +3 834 848 806 +3 409 296 414 +3 302 873 432 +3 885 896 777 +3 841 892 839 +3 811 875 6 +3 1077 1104 1069 +3 1104 1103 1069 +3 68 106 46 +3 823 921 490 +3 162 81 921 +3 823 162 921 +3 989 1001 1000 +3 986 989 1000 +3 1000 1001 925 +3 888 896 887 +3 929 477 356 +3 974 972 534 +3 87 2 213 +3 915 840 331 +3 970 969 948 +3 965 641 568 +3 1207 177 1206 +3 1726 1725 1038 +3 1002 51 840 +3 814 191 803 +3 191 190 803 +3 855 892 841 +3 302 432 381 +3 173 293 573 +3 880 904 270 +3 871 873 302 +3 358 914 300 +3 239 863 328 +3 910 911 929 +3 331 712 811 +3 438 24 404 +3 892 913 906 +3 991 1002 990 +3 128 33 83 +3 810 836 194 +3 788 770 787 +3 814 803 804 +3 774 126 129 +3 242 855 830 +3 981 1189 1206 +3 927 934 914 +3 847 13 777 +3 301 358 300 +3 822 72 305 +3 641 617 568 +3 839 838 136 +3 904 880 910 +3 1850 1864 1870 +3 118 248 811 +3 949 970 948 +3 970 989 986 +3 1328 1325 1316 +3 358 927 914 +3 867 340 829 +3 943 944 966 +3 1100 221 1361 +3 530 805 525 +3 327 148 377 +3 1259 179 351 +3 1029 1028 1014 +3 969 968 947 +3 970 986 969 +3 832 795 768 +3 888 569 411 +3 342 344 113 +3 458 126 121 +3 943 966 965 +3 979 901 823 +3 823 861 162 +3 701 198 1076 +3 966 638 641 +3 769 315 271 +3 760 761 787 +3 965 966 641 +3 927 949 934 +3 949 948 934 +3 558 755 754 +3 919 835 878 +3 270 910 356 +3 852 162 861 +3 106 170 162 +3 852 106 162 +3 947 958 946 +3 815 192 191 +3 814 815 191 +3 820 384 879 +3 305 768 893 +3 698 847 777 +3 829 340 780 +3 534 972 227 +3 121 522 458 +3 1071 1077 1070 +3 846 823 901 +3 846 861 823 +3 918 305 66 +3 893 768 776 +3 1190 1186 1099 +3 67 1010 937 +3 925 840 915 +3 862 861 846 +3 862 852 861 +3 835 777 896 +3 946 945 944 +3 862 106 852 +3 1885 1887 928 +3 464 358 431 +3 526 949 927 +3 946 944 945 +3 890 889 838 +3 66 696 997 +3 1019 1561 1026 +3 1375 1380 1291 +3 1071 1061 1077 +3 712 118 811 +3 806 848 919 +3 971 990 970 +3 661 670 649 +3 971 970 949 +3 749 1225 110 +3 122 777 13 +3 35 13 955 +3 734 701 1164 +3 795 449 195 +3 874 842 848 +3 990 1002 989 +3 977 979 823 +3 526 971 949 +3 78 193 192 +3 815 78 192 +3 990 989 970 +3 834 539 842 +3 839 891 838 +3 1146 767 1064 +3 1002 1001 989 +3 840 51 118 +3 886 862 846 +3 280 754 753 +3 811 869 768 +3 906 913 912 +3 967 966 944 +3 931 946 930 +3 829 552 820 +3 886 106 862 +3 885 46 106 +3 1061 1104 1077 +3 320 67 834 +3 905 432 873 +3 874 848 834 +3 911 930 929 +3 1026 1572 1019 +3 972 974 992 +3 934 933 913 +3 914 934 913 +3 923 106 886 +3 777 46 885 +3 355 356 394 +3 449 96 195 +3 66 730 696 +3 807 96 832 +3 72 331 811 +3 896 106 923 +3 896 885 106 +3 1071 1070 1043 +3 932 947 931 +3 1049 1071 1043 +3 450 39 785 +3 946 967 945 +3 836 838 889 +3 787 761 788 +3 967 983 638 +3 966 967 638 +3 991 990 971 +3 597 1165 1231 +3 937 539 834 +3 934 948 947 +3 933 934 947 +3 886 846 942 +3 972 971 526 +3 1737 1762 1746 +3 1841 1851 1829 +3 417 1219 1218 +3 1166 110 1125 +3 159 342 113 +3 1065 1032 1274 +3 430 1065 1274 +3 1307 1320 1395 +3 767 1027 1 +3 846 798 1067 +3 735 1256 469 +3 1829 1850 1834 +3 398 317 1039 +3 288 32 34 +3 1051 1057 1058 +3 515 1684 1674 +3 1080 1079 1057 +3 1051 1058 1029 +3 1039 288 34 +3 1561 1726 1038 +3 1379 1307 1395 +3 304 642 409 +3 1396 1380 1381 +3 1030 1051 1029 +3 1219 1218 959 +3 598 1205 642 +3 1604 1615 1613 +3 1209 953 1193 +3 389 1521 1121 +3 398 75 70 +3 1314 273 524 +3 1022 1030 1021 +3 1022 1021 1016 +3 1030 1029 1021 +3 598 642 304 +3 528 1185 714 +3 1194 1209 1193 +3 177 12 397 +3 878 67 320 +3 1057 1045 1028 +3 1096 1095 1079 +3 1296 264 1319 +3 101 491 1237 +3 834 808 67 +3 1312 1484 1110 +3 963 1312 1110 +3 113 344 637 +3 1497 113 1496 +3 1119 1127 1113 +3 1312 1483 1484 +3 1799 1816 1812 +3 1079 1095 1057 +3 854 357 1191 +3 399 444 1210 +3 539 1011 383 +3 246 250 664 +3 1028 1038 1020 +3 1058 1057 1029 +3 311 1329 1396 +3 1260 1483 1312 +3 1187 1328 428 +3 1851 1864 1850 +3 317 609 619 +3 609 463 619 +3 1223 952 317 +3 603 1166 619 +3 1003 976 1094 +3 1248 556 297 +3 287 1885 555 +3 1138 1172 1163 +3 297 556 610 +3 1591 878 1009 +3 463 603 619 +3 749 110 1166 +3 1157 680 1081 +3 1886 304 409 +3 436 1027 605 +3 1015 1029 1014 +3 556 20 610 +3 20 604 610 +3 1099 1186 1189 +3 20 599 604 +3 1209 854 953 +3 1360 1550 1685 +3 492 398 70 +3 1172 1193 1192 +3 1175 1172 1192 +3 733 292 406 +3 202 733 406 +3 1010 834 67 +3 468 113 637 +3 154 1157 1081 +3 1172 1175 1163 +3 1193 854 1192 +3 953 854 1193 +3 1055 174 493 +3 1502 650 1046 +3 236 60 84 +3 1195 1194 1176 +3 85 177 397 +3 1163 1175 1148 +3 585 433 357 +3 1050 1045 1028 +3 1138 1148 1112 +3 1603 1402 1589 +3 1174 1192 1191 +3 1170 1174 1190 +3 1416 1417 1617 +3 398 1039 34 +3 75 398 1007 +3 1095 1107 1078 +3 1133 1134 1132 +3 1528 1022 1551 +3 1066 598 304 +3 292 733 667 +3 63 903 18 +3 619 1125 288 +3 1357 1355 1356 +3 733 1363 667 +3 470 1 212 +3 1017 830 136 +3 1119 1113 1095 +3 1387 231 247 +3 1107 1112 1078 +3 113 468 1496 +3 1028 1045 1050 +3 1014 1028 1013 +3 808 1011 539 +3 830 841 839 +3 12 50 275 +3 1344 1530 1115 +3 1363 153 19 +3 667 1363 19 +3 1103 1102 1068 +3 952 609 317 +3 1175 1174 1148 +3 1031 236 681 +3 595 10 555 +3 1119 1114 1587 +3 1114 1119 1096 +3 709 272 492 +3 451 736 434 +3 1174 1175 1192 +3 1380 1328 1316 +3 928 595 555 +3 153 489 1202 +3 572 598 1066 +3 19 153 1202 +3 1737 1746 1721 +3 1418 1417 1395 +3 1148 1147 1126 +3 488 1387 1448 +3 1245 488 1448 +3 1040 543 598 +3 572 1040 598 +3 1021 1029 1015 +3 1654 1653 1635 +3 329 58 595 +3 489 125 488 +3 1163 1148 1138 +3 1534 1687 1439 +3 342 709 344 +3 1112 1148 1126 +3 1202 489 488 +3 125 231 1387 +3 488 125 1387 +3 398 272 1223 +3 383 867 539 +3 414 296 928 +3 1176 1194 1172 +3 1028 1020 1013 +3 173 176 448 +3 1591 878 1009 +3 444 287 263 +3 1083 444 263 +3 272 952 1223 +3 1192 854 1191 +3 854 585 357 +3 1119 1152 1139 +3 1547 461 513 +3 296 329 595 +3 296 595 928 +3 603 749 1166 +3 1319 1329 1381 +3 1138 1152 1172 +3 63 18 33 +3 433 63 104 +3 769 433 104 +3 1174 1171 1147 +3 1372 1381 1375 +3 1613 1424 1603 +3 1113 1138 1107 +3 571 1218 1219 +3 1528 1551 1548 +3 1007 398 34 +3 1738 1737 1717 +3 1396 1329 1380 +3 1063 572 1066 +3 1153 1176 1152 +3 1139 1113 1127 +3 1119 1139 1127 +3 1191 357 1190 +3 357 240 1190 +3 1148 1174 1147 +3 29 460 325 +3 317 619 1039 +3 1754 1762 1737 +3 1329 311 1396 +3 1309 1380 1316 +3 1225 247 1218 +3 1448 1387 247 +3 1028 1045 1038 +3 1635 1453 1452 +3 116 1256 735 +3 514 1032 962 +3 1095 1078 1086 +3 1079 1095 1086 +3 357 433 240 +3 1174 1170 1171 +3 1218 1219 959 +3 1067 942 846 +3 1057 1095 1079 +3 10 114 287 +3 150 853 620 +3 555 10 287 +3 1152 1138 1139 +3 1052 1085 1370 +3 1704 1721 1703 +3 89 51 1002 +3 512 89 1002 +3 1152 1176 1172 +3 981 1206 992 +3 991 512 1002 +3 402 673 48 +3 1016 1551 1022 +3 1151 571 1219 +3 433 769 240 +3 1291 1380 1309 +3 1571 785 884 +3 589 490 605 +3 584 572 1063 +3 1057 1079 1045 +3 1138 1112 1107 +3 1045 1086 1078 +3 1095 1113 1107 +3 76 512 991 +3 1549 1552 1548 +3 203 769 271 +3 992 76 991 +3 274 89 512 +3 76 274 512 +3 274 51 89 +3 139 118 51 +3 274 139 51 +3 11 248 118 +3 139 11 118 +3 1056 1042 1068 +3 737 103 17 +3 871 302 858 +3 273 489 153 +3 1826 1835 1820 +3 197 48 294 +3 975 197 294 +3 197 713 402 +3 48 197 402 +3 584 1076 1040 +3 1079 1086 1045 +3 1029 1057 1028 +3 1139 1138 1113 +3 572 584 1040 +3 198 412 1040 +3 1076 198 1040 +3 298 273 153 +3 1500 1531 1359 +3 1096 1119 1095 +3 1194 1193 1172 +3 1560 785 1571 +3 882 866 894 +3 49 139 274 +3 1189 1207 1206 +3 1102 1133 1132 +3 1717 1721 1704 +3 1674 1487 1653 +3 584 570 1076 +3 894 1102 907 +3 821 1167 1199 +3 17 103 140 +3 50 17 140 +3 1042 1056 866 +3 1056 1068 894 +3 866 1056 894 +3 894 1068 1102 +3 1102 1132 936 +3 907 1102 936 +3 1160 950 936 +3 1132 1160 936 +3 1174 1191 1190 +3 1206 85 76 +3 992 1206 76 +3 397 274 76 +3 85 397 76 +3 275 49 274 +3 397 275 274 +3 140 139 49 +3 275 140 49 +3 103 11 139 +3 140 103 139 +3 409 642 329 +3 296 409 329 +3 436 975 1241 +3 436 605 975 +3 605 26 975 +3 26 197 975 +3 26 379 713 +3 197 26 713 +3 1010 539 937 +3 59 454 346 +3 652 408 413 +3 21 61 149 +3 171 345 347 +3 94 2 130 +3 130 256 134 +3 1004 1393 715 +3 313 368 367 +3 544 90 146 +3 81 535 379 +3 1257 527 950 +3 1257 950 1160 +3 302 301 259 +3 1004 414 928 +3 1160 1238 1257 +3 102 214 186 +3 1238 1160 1161 +3 1226 1238 1161 +3 1257 227 527 +3 95 233 364 +3 620 853 29 +3 1257 534 227 +3 282 454 230 +3 1453 1653 1452 +3 232 233 95 +3 821 1199 1886 +3 1232 1238 1226 +3 1238 981 1257 +3 1257 981 534 +3 417 408 652 +3 1233 1238 1232 +3 1027 436 42 +3 196 504 111 +3 169 180 81 +3 61 21 479 +3 631 231 388 +3 372 631 388 +3 1300 1382 1270 +3 1558 1559 857 +3 714 298 800 +3 298 153 800 +3 981 974 534 +3 704 348 5 +3 706 226 234 +3 388 231 443 +3 311 1330 1329 +3 1282 1300 1270 +3 1189 981 1238 +3 1233 1189 1238 +3 334 94 256 +3 1462 1672 1473 +3 895 786 787 +3 595 58 10 +3 1242 1251 1256 +3 489 231 125 +3 1236 1256 1250 +3 0 717 40 +3 470 212 0 +3 717 279 40 +3 276 230 59 +3 454 282 1237 +3 521 219 213 +3 417 652 346 +3 1266 417 346 +3 364 521 213 +3 171 363 345 +3 279 704 40 +3 470 0 160 +3 94 95 2 +3 42 281 717 +3 97 375 540 +3 61 479 363 +3 1216 705 706 +3 349 372 233 +3 453 42 717 +3 1241 975 150 +3 150 975 294 +3 214 362 282 +3 959 417 1266 +3 959 1219 417 +3 281 42 279 +3 408 607 372 +3 372 607 631 +3 0 40 25 +3 1221 69 1242 +3 287 114 263 +3 279 147 157 +3 704 279 157 +3 134 94 130 +3 81 52 535 +3 1265 58 329 +3 1249 1265 329 +3 82 97 13 +3 364 643 158 +3 82 375 97 +3 156 542 1214 +3 479 232 345 +3 35 82 13 +3 147 620 29 +3 102 186 58 +3 64 102 58 +3 363 479 345 +3 21 413 479 +3 652 413 21 +3 372 388 233 +3 216 43 5 +3 61 171 52 +3 413 349 479 +3 186 114 10 +3 619 288 1039 +3 697 1221 412 +3 171 61 363 +3 212 717 0 +3 1236 1242 1256 +3 607 408 417 +3 92 21 149 +3 279 42 147 +3 1221 1222 412 +3 697 1217 457 +3 156 1214 1213 +3 453 717 1 +3 552 829 868 +3 114 276 263 +3 570 734 701 +3 324 29 325 +3 1 717 212 +3 214 102 101 +3 2 364 213 +3 95 364 2 +3 74 97 68 +3 108 58 1265 +3 196 241 504 +3 416 325 326 +3 1346 900 767 +3 642 1205 1249 +3 71 135 6 +3 665 261 260 +3 389 43 216 +3 108 64 58 +3 1255 1236 1250 +3 7 1261 71 +3 1261 135 71 +3 83 737 17 +3 165 380 327 +3 147 29 324 +3 279 717 281 +3 417 1218 607 +3 1218 247 607 +3 83 573 737 +3 737 1239 7 +3 1239 1261 7 +3 42 620 147 +3 1215 697 1214 +3 1221 1242 1236 +3 1261 172 135 +3 651 62 6 +3 117 332 6 +3 62 117 6 +3 416 324 325 +3 157 324 416 +3 40 5 43 +3 1227 1239 737 +3 573 1227 737 +3 1261 1262 172 +3 172 651 6 +3 135 172 6 +3 62 807 117 +3 0 25 160 +3 364 388 643 +3 345 95 94 +3 1214 909 1215 +3 336 149 180 +3 233 388 364 +3 807 832 117 +3 1243 1262 1261 +3 1239 1243 1261 +3 42 150 620 +3 1215 1217 697 +3 1214 412 198 +3 1213 1214 198 +3 293 1227 573 +3 172 62 651 +3 878 1591 67 +3 1214 697 412 +3 1228 1243 1239 +3 1227 1228 1239 +3 96 45 438 +3 40 704 5 +3 59 92 181 +3 172 9 62 +3 643 22 158 +3 388 22 643 +3 92 149 181 +3 345 94 334 +3 652 21 92 +3 345 232 95 +3 214 101 362 +3 535 171 713 +3 1262 678 172 +3 678 9 172 +3 9 592 62 +3 479 349 233 +3 326 325 333 +3 117 832 332 +3 347 345 334 +3 234 1216 706 +3 486 62 592 +3 486 807 62 +3 884 1340 1884 +3 1270 1381 1372 +3 348 157 299 +3 1320 1418 1395 +3 1243 452 1262 +3 1262 452 678 +3 343 592 9 +3 149 61 52 +3 1224 1230 1228 +3 1246 1253 1243 +3 1243 1253 452 +3 163 486 592 +3 163 96 486 +3 2 87 54 +3 1474 1497 1496 +3 1488 1474 1496 +3 525 115 731 +3 1230 1246 1243 +3 1228 1230 1243 +3 452 343 9 +3 678 452 9 +3 31 592 343 +3 31 163 592 +3 743 226 437 +3 334 256 347 +3 149 52 180 +3 6 875 248 +3 1482 1474 1488 +3 1246 1230 1253 +3 452 31 343 +3 45 96 163 +3 364 158 521 +3 737 7 103 +3 213 73 87 +3 1063 533 584 +3 45 44 438 +3 42 436 150 +3 1244 1240 1092 +3 211 445 23 +3 1459 1465 1482 +3 1440 988 1442 +3 163 44 45 +3 1418 1354 1863 +3 436 1241 150 +3 453 1027 42 +3 108 1265 1249 +3 230 454 59 +3 1465 1474 1482 +3 311 1329 1319 +3 677 1234 1230 +3 1230 1234 1253 +3 452 374 31 +3 163 323 44 +3 282 214 230 +3 214 282 230 +3 1258 374 452 +3 1253 1258 452 +3 1215 909 1217 +3 1354 1418 1320 +3 1234 1240 1253 +3 294 418 853 +3 558 234 226 +3 11 103 71 +3 1240 1258 1253 +3 31 77 163 +3 77 323 163 +3 558 280 234 +3 214 224 186 +3 1205 1250 1249 +3 586 1296 1282 +3 1240 1234 677 +3 114 230 276 +3 1125 47 32 +3 308 77 31 +3 868 780 340 +3 1250 108 1249 +3 694 226 707 +3 288 1125 32 +3 319 31 374 +3 31 319 308 +3 529 323 77 +3 323 24 44 +3 280 309 234 +3 234 309 1216 +3 1491 1012 183 +3 77 308 529 +3 323 41 24 +3 225 361 1313 +3 6 248 71 +3 1258 669 374 +3 669 319 374 +3 249 41 323 +3 529 249 323 +3 115 444 782 +3 146 90 3 +3 309 705 1216 +3 669 1258 1240 +3 1264 109 636 +3 1302 185 1293 +3 1217 909 960 +3 237 265 1302 +3 337 1337 1336 +3 547 541 205 +3 1313 691 705 +3 286 352 337 +3 1327 1332 370 +3 798 846 901 +3 337 1338 1337 +3 361 225 611 +3 451 439 484 +3 677 1092 1240 +3 225 1313 109 +3 264 228 277 +3 352 1334 337 +3 785 783 1340 +3 309 1313 705 +3 674 683 682 +3 663 623 602 +3 622 663 710 +3 995 1591 806 +3 450 206 1047 +3 1283 99 215 +3 611 563 593 +3 475 246 664 +3 1294 1264 636 +3 442 1337 1347 +3 465 527 227 +3 659 630 636 +3 1454 1499 1527 +3 602 674 663 +3 107 1293 185 +3 1829 1851 1850 +3 109 690 660 +3 1313 690 109 +3 563 611 1264 +3 362 101 1237 +3 337 1334 1338 +3 206 450 517 +3 1347 471 503 +3 167 554 1323 +3 1468 1472 1489 +3 1091 1141 702 +3 471 563 1294 +3 715 1167 821 +3 1264 611 225 +3 1332 337 1336 +3 1004 1887 399 +3 586 1283 215 +3 1023 1252 1400 +3 1179 1370 1383 +3 1313 726 1324 +3 471 636 630 +3 352 420 1334 +3 1047 39 450 +3 99 1283 586 +3 237 1302 107 +3 14 446 330 +3 1313 361 645 +3 530 525 784 +3 1338 553 1348 +3 1337 1338 1348 +3 370 1332 442 +3 1332 1336 442 +3 715 821 414 +3 237 283 1322 +3 362 1237 282 +3 187 1303 237 +3 257 27 131 +3 801 430 1335 +3 1287 36 213 +3 554 167 338 +3 335 1331 1330 +3 311 335 1330 +3 1331 439 451 +3 506 420 421 +3 1330 1331 451 +3 663 674 1284 +3 674 385 1284 +3 184 107 185 +3 1322 283 314 +3 14 27 446 +3 439 520 484 +3 265 185 1302 +3 420 553 1338 +3 554 338 916 +3 1400 1298 1023 +3 553 563 471 +3 1324 726 1313 +3 1285 14 446 +3 434 435 451 +3 338 167 175 +3 277 311 1319 +3 546 783 244 +3 801 1335 1274 +3 338 1297 916 +3 1294 563 1264 +3 420 1338 1334 +3 783 606 244 +3 1337 1348 1347 +3 1313 1324 690 +3 311 312 335 +3 220 1285 1310 +3 1284 385 1278 +3 1128 1023 1252 +3 1285 220 14 +3 622 623 663 +3 109 660 636 +3 524 446 330 +3 1589 1402 1403 +3 338 220 1310 +3 674 682 385 +3 284 337 1332 +3 107 1302 1293 +3 663 1284 710 +3 1888 517 1067 +3 350 1251 69 +3 435 434 415 +3 435 415 428 +3 1297 338 1310 +3 682 307 385 +3 1306 1305 1280 +3 1276 1306 1280 +3 313 367 312 +3 1327 284 1332 +3 1336 1337 442 +3 1264 225 109 +3 180 169 1229 +3 475 801 246 +3 352 267 353 +3 1403 1404 1589 +3 1285 1292 1310 +3 307 682 748 +3 682 718 748 +3 1277 1276 1275 +3 1158 237 107 +3 1067 517 511 +3 1271 1282 1270 +3 489 125 443 +3 446 14 330 +3 586 1282 1271 +3 1292 1285 446 +3 446 330 1287 +3 443 125 489 +3 108 116 735 +3 813 100 99 +3 1276 1307 1306 +3 1483 1260 1317 +3 1272 586 1271 +3 1348 553 471 +3 1287 213 219 +3 330 446 1287 +3 443 231 489 +3 330 36 1287 +3 86 35 955 +3 450 785 1560 +3 1312 1304 1260 +3 1329 435 428 +3 1289 1276 1277 +3 1289 1290 1276 +3 1158 187 237 +3 1311 556 1248 +3 558 226 743 +3 1323 554 993 +3 1292 446 524 +3 273 443 489 +3 1290 1289 1277 +3 1290 1307 1276 +3 215 264 1296 +3 1304 1286 1273 +3 1260 1304 1273 +3 1311 1248 1273 +3 1286 1311 1273 +3 246 801 250 +3 1322 314 278 +3 1019 1572 1036 +3 307 748 608 +3 182 307 608 +3 1321 443 273 +3 471 1294 636 +3 215 1296 586 +3 1322 278 265 +3 542 701 1129 +3 1101 1284 1278 +3 39 783 785 +3 1304 400 1286 +3 400 1311 1286 +3 1339 244 1200 +3 1324 309 726 +3 674 602 683 +3 265 237 1322 +3 1653 1487 1470 +3 446 36 330 +3 1321 22 443 +3 1277 1267 1290 +3 1290 1308 1307 +3 1313 309 1324 +3 467 68 97 +3 1312 1279 1304 +3 367 1331 335 +3 524 330 1287 +3 1347 1348 471 +3 1308 1315 1307 +3 1365 1529 1108 +3 531 530 784 +3 123 531 784 +3 1041 556 1311 +3 666 1041 1311 +3 312 367 335 +3 1705 1707 1711 +3 690 1324 725 +3 1331 367 439 +3 710 1284 1101 +3 608 748 758 +3 170 699 169 +3 1308 1309 1315 +3 1368 1362 1371 +3 306 1200 244 +3 1279 1299 1304 +3 1304 1299 400 +3 666 1311 400 +3 251 283 237 +3 1853 1866 1871 +3 1312 963 1279 +3 1101 1279 963 +3 1314 1321 273 +3 699 1229 169 +3 1268 1290 1267 +3 1290 1309 1308 +3 386 1320 1315 +3 1320 386 1315 +3 314 1327 370 +3 542 156 701 +3 475 1486 1684 +3 1297 1185 528 +3 1031 916 60 +3 1297 1310 1185 +3 158 1321 1314 +3 1379 1305 1306 +3 553 420 506 +3 291 1342 782 +3 608 758 1041 +3 666 608 1041 +3 1635 1452 1453 +3 60 916 528 +3 916 1297 528 +3 1314 1287 158 +3 601 471 630 +3 1291 1290 1268 +3 1316 1315 1309 +3 1316 1320 1315 +3 400 608 666 +3 1292 524 1185 +3 187 189 188 +3 68 467 1318 +3 187 188 1303 +3 1281 1291 1268 +3 1290 1291 1309 +3 1320 1316 386 +3 1278 385 1299 +3 1279 1278 1299 +3 385 307 400 +3 1299 385 400 +3 307 182 400 +3 400 182 608 +3 801 208 430 +3 243 547 205 +3 1292 1185 1310 +3 1324 726 725 +3 699 170 105 +3 105 68 1318 +3 699 105 1318 +3 1316 1325 386 +3 1325 1187 386 +3 1096 1587 1114 +3 515 208 801 +3 1287 1314 524 +3 1287 219 158 +3 1541 1546 1545 +3 1540 1541 1545 +3 1361 519 1520 +3 570 1129 701 +3 785 1340 884 +3 176 903 127 +3 1232 1226 1233 +3 570 1366 1129 +3 1571 884 1560 +3 378 533 1432 +3 210 570 533 +3 378 210 533 +3 570 210 1366 +3 210 290 1129 +3 1366 210 1129 +3 1129 290 542 +3 290 909 542 +3 290 960 909 +3 124 697 290 +3 210 124 290 +3 697 457 290 +3 290 457 960 +3 960 457 1217 +3 378 124 210 +3 1477 1420 1006 +3 591 378 597 +3 1165 591 597 +3 378 591 124 +3 124 457 697 +3 124 1394 457 +3 1653 1470 1452 +3 1377 1378 1388 +3 1199 1048 1231 +3 124 350 1394 +3 1394 350 457 +3 1048 1165 1231 +3 1048 671 591 +3 1165 1048 591 +3 671 350 124 +3 591 671 124 +3 350 69 457 +3 98 467 97 +3 827 155 1880 +3 1544 1545 1157 +3 176 173 18 +3 1273 700 1260 +3 1369 1048 1199 +3 671 588 350 +3 1545 1546 1204 +3 1546 640 1204 +3 607 247 231 +3 1278 1279 1101 +3 154 1081 1513 +3 1777 1770 1785 +3 1295 499 143 +3 1850 1849 1834 +3 1199 732 1369 +3 732 1183 1369 +3 926 1048 1369 +3 1183 926 1369 +3 926 635 671 +3 1048 926 671 +3 671 635 588 +3 635 1251 350 +3 588 635 350 +3 1449 1472 1468 +3 1490 1489 1472 +3 1425 1074 1389 +3 1198 494 1065 +3 758 718 759 +3 1449 1468 1472 +3 1260 700 1317 +3 732 926 1183 +3 1449 1451 1468 +3 1468 1451 1472 +3 1490 538 1489 +3 272 406 952 +3 1183 926 732 +3 926 1183 635 +3 1426 1435 1434 +3 1449 1450 1451 +3 1421 1422 1426 +3 1426 1422 1435 +3 1469 1486 1490 +3 1472 1469 1490 +3 1183 455 635 +3 1435 1450 1449 +3 1434 1435 1449 +3 1451 1469 1472 +3 475 538 1490 +3 1486 475 1490 +3 475 664 538 +3 250 289 538 +3 664 250 538 +3 306 260 575 +3 455 1183 732 +3 1169 455 732 +3 455 469 635 +3 469 1256 1251 +3 635 469 1251 +3 1204 1389 1074 +3 1319 1381 1382 +3 1364 1370 1085 +3 1329 1396 1381 +3 1330 435 1329 +3 1444 1451 1450 +3 1435 1444 1450 +3 1520 519 1120 +3 1505 1120 1326 +3 640 883 1425 +3 1357 1364 1355 +3 1357 1370 1364 +3 1357 1211 1370 +3 1225 1245 1448 +3 1408 1423 1422 +3 1411 1408 1422 +3 1423 1436 1435 +3 1422 1423 1435 +3 1436 1437 1444 +3 1435 1436 1444 +3 1437 1452 1451 +3 1444 1437 1451 +3 1452 1470 1469 +3 1451 1452 1469 +3 1469 1470 1486 +3 1486 1674 1487 +3 1413 980 1420 +3 1470 1487 1486 +3 1537 154 1105 +3 1393 1054 1169 +3 668 455 1169 +3 1054 668 1169 +3 668 735 469 +3 455 668 469 +3 1455 1445 1446 +3 1185 524 298 +3 459 552 38 +3 1731 1739 1722 +3 1376 1211 1357 +3 1409 1408 1398 +3 1427 1437 1436 +3 1423 1427 1436 +3 1403 1388 1404 +3 84 1367 1363 +3 596 556 1041 +3 714 1185 298 +3 1004 1054 1393 +3 1210 574 399 +3 1320 1307 1315 +3 1635 1453 1438 +3 1359 1357 1356 +3 1358 1359 1356 +3 1377 1376 1357 +3 1359 1377 1357 +3 1388 1211 1376 +3 1377 1388 1376 +3 1402 1409 1398 +3 1388 1398 1211 +3 1402 1408 1409 +3 1402 1424 1423 +3 1408 1402 1423 +3 1423 1424 1427 +3 1424 1438 1437 +3 1427 1424 1437 +3 1438 1453 1452 +3 1437 1438 1452 +3 1197 828 650 +3 1111 1511 1510 +3 1300 1319 1382 +3 1010 808 539 +3 208 1198 430 +3 1200 459 38 +3 1539 1540 1544 +3 1507 1094 1405 +3 1094 976 1405 +3 475 515 801 +3 533 378 1432 +3 744 491 668 +3 1054 744 668 +3 491 101 735 +3 668 491 735 +3 384 459 1200 +3 306 384 1200 +3 1512 1197 650 +3 7 71 103 +3 1466 1295 1074 +3 1325 1328 1187 +3 1329 428 1328 +3 1507 1405 1397 +3 1120 897 1184 +3 1388 1403 1402 +3 1110 859 576 +3 1431 1110 576 +3 399 1212 744 +3 1363 800 153 +3 575 384 306 +3 1178 1100 1512 +3 1425 883 1074 +3 733 84 1363 +3 55 54 87 +3 1296 1300 1282 +3 1378 1377 1359 +3 1004 715 414 +3 1462 1479 1478 +3 1479 1492 222 +3 1478 1479 222 +3 1492 30 179 +3 222 1492 179 +3 30 351 179 +3 1544 1157 154 +3 429 297 709 +3 1110 1483 1475 +3 86 306 391 +3 700 159 1498 +3 1317 700 1498 +3 205 467 540 +3 828 518 650 +3 1672 1462 1473 +3 399 574 1212 +3 574 634 744 +3 1212 574 744 +3 634 1237 491 +3 744 634 491 +3 1367 714 1363 +3 375 606 112 +3 375 82 606 +3 82 86 391 +3 1457 1181 640 +3 1546 1457 640 +3 1479 1493 1492 +3 1493 258 30 +3 1492 1493 30 +3 429 1248 297 +3 39 375 199 +3 336 181 149 +3 1439 1511 1111 +3 1684 515 475 +3 1483 1317 1475 +3 1317 1498 1475 +3 429 342 159 +3 700 429 159 +3 1510 1052 1179 +3 1181 1130 883 +3 640 1181 883 +3 1405 980 1413 +3 1140 964 1181 +3 1509 1439 1517 +3 1479 1480 1493 +3 403 351 30 +3 258 403 30 +3 390 389 1121 +3 1400 897 1298 +3 604 272 709 +3 1460 749 603 +3 403 523 351 +3 1249 329 642 +3 1390 1466 883 +3 1382 1381 1270 +3 1363 714 800 +3 342 429 709 +3 540 375 1047 +3 297 604 709 +3 1467 1461 1201 +3 1130 1390 883 +3 1374 1454 1515 +3 1462 1480 1479 +3 1136 523 403 +3 964 1441 1181 +3 1059 1522 1128 +3 1003 221 500 +3 976 1003 500 +3 1100 1197 1512 +3 390 25 43 +3 1407 1416 1415 +3 1406 1407 1415 +3 1455 1446 1458 +3 1446 1463 1462 +3 1458 1446 1462 +3 1463 1464 1462 +3 1464 1481 1480 +3 1462 1464 1480 +3 1481 1494 1493 +3 1480 1481 1493 +3 1494 994 258 +3 1493 1494 258 +3 456 403 258 +3 994 456 258 +3 621 1136 403 +3 456 621 403 +3 621 523 1136 +3 621 745 523 +3 141 473 523 +3 745 141 523 +3 1516 1524 1476 +3 1128 245 1471 +3 1155 321 634 +3 574 1155 634 +3 599 681 202 +3 298 524 273 +3 681 236 202 +3 1368 1371 1527 +3 1263 1254 1540 +3 1502 1524 1476 +3 1476 1046 1115 +3 321 454 1237 +3 634 321 1237 +3 541 467 205 +3 467 97 540 +3 98 97 467 +3 236 84 733 +3 1446 1464 1463 +3 621 141 745 +3 1516 1476 1503 +3 1467 1201 828 +3 174 639 142 +3 202 236 733 +3 1686 1703 1702 +3 1494 1495 994 +3 1495 1123 994 +3 516 141 621 +3 1037 1059 1128 +3 590 467 541 +3 701 156 1164 +3 1398 1408 1383 +3 493 1301 322 +3 639 321 1155 +3 1429 1446 1445 +3 1481 1495 1494 +3 1220 456 994 +3 1123 1220 994 +3 954 322 495 +3 1373 493 322 +3 987 321 639 +3 260 306 86 +3 1370 1384 1383 +3 1280 1305 1362 +3 1305 1371 1362 +3 1305 1379 1371 +3 1392 1386 1371 +3 1392 1395 1386 +3 1395 1407 1386 +3 1395 1417 1416 +3 1407 1395 1416 +3 1703 1694 1704 +3 1428 1430 1429 +3 1430 1442 1446 +3 1429 1430 1446 +3 1442 1459 1464 +3 1446 1442 1464 +3 1459 1482 1481 +3 1464 1459 1481 +3 1482 1488 1481 +3 1488 1496 1495 +3 1481 1488 1495 +3 1496 468 1123 +3 1495 1496 1123 +3 637 1220 1123 +3 468 637 1123 +3 637 456 1220 +3 637 1203 456 +3 161 621 456 +3 1203 161 456 +3 75 516 621 +3 161 75 621 +3 1687 1694 1703 +3 75 34 495 +3 954 495 34 +3 34 32 322 +3 954 34 322 +3 32 47 322 +3 47 1373 322 +3 47 493 1373 +3 47 183 493 +3 183 1055 493 +3 1055 1012 174 +3 1012 639 174 +3 959 987 639 +3 1012 959 639 +3 959 321 987 +3 959 346 321 +3 346 454 321 +3 1341 1229 541 +3 1229 699 541 +3 699 1318 590 +3 541 699 590 +3 637 161 1203 +3 1615 1635 1438 +3 1300 1296 1319 +3 1379 1395 1392 +3 1615 1438 1424 +3 1613 1615 1424 +3 75 1007 34 +3 1229 1341 336 +3 700 1273 1248 +3 1392 1395 1379 +3 70 161 637 +3 183 1012 1055 +3 1673 1184 1504 +3 1159 1504 1184 +3 1266 346 959 +3 1604 1613 1603 +3 1459 1442 1456 +3 1075 1502 1503 +3 221 1100 500 +3 677 1084 1092 +3 1230 1224 677 +3 1537 1544 154 +3 1105 1097 1088 +3 1121 1105 1088 +3 1146 1346 767 +3 1087 293 176 +3 1100 1467 1197 +3 1154 585 1209 +3 962 1032 1065 +3 1765 1759 1024 +3 1408 1501 1383 +3 1516 1502 1524 +3 143 499 519 +3 1147 1142 1126 +3 1074 1094 680 +3 1399 897 1400 +3 1087 176 366 +3 235 1087 653 +3 897 1399 1184 +3 1149 1135 1061 +3 1685 1687 1360 +3 1379 1392 1371 +3 1810 259 242 +3 293 448 176 +3 1521 1537 1105 +3 235 653 677 +3 1100 1361 1467 +3 373 1538 1537 +3 1514 585 1059 +3 1059 585 341 +3 462 796 1023 +3 964 1106 1419 +3 1505 1326 1201 +3 711 63 1514 +3 964 1140 1092 +3 340 780 868 +3 796 1037 1128 +3 1037 127 796 +3 127 1037 796 +3 18 903 127 +3 1059 341 1522 +3 1508 366 1098 +3 1410 176 127 +3 293 1087 235 +3 1117 187 1876 +3 366 1508 1106 +3 1399 1159 1184 +3 1399 1400 1252 +3 1170 1099 1142 +3 1410 1037 1098 +3 903 18 127 +3 1383 1384 1211 +3 1522 341 1154 +3 1120 1505 1201 +3 1087 366 653 +3 1060 1135 1485 +3 964 1419 1130 +3 293 235 1224 +3 1244 1092 1457 +3 1545 1204 1157 +3 1252 1471 1399 +3 366 964 653 +3 1525 1126 1142 +3 160 360 1173 +3 366 176 1098 +3 499 1401 1298 +3 1539 1544 1537 +3 677 653 1084 +3 176 18 903 +3 199 375 112 +3 1520 1120 1461 +3 644 1539 1538 +3 80 1535 216 +3 176 1410 1098 +3 1140 1181 1457 +3 462 1098 796 +3 1541 1457 1546 +3 1361 1520 1467 +3 1467 1520 1461 +3 373 644 1538 +3 1106 462 781 +3 1591 834 67 +3 390 594 360 +3 160 390 360 +3 1254 1247 1541 +3 1075 1503 980 +3 903 711 127 +3 181 263 276 +3 444 1083 291 +3 1538 1539 1537 +3 1419 1106 1390 +3 519 1361 143 +3 216 1535 1521 +3 1094 976 680 +3 1441 1130 1181 +3 1006 672 1385 +3 1060 1485 1149 +3 43 389 390 +3 181 809 263 +3 1120 1201 1461 +3 1130 1419 1390 +3 1081 680 1507 +3 1231 1165 597 +3 809 1083 263 +3 964 366 1106 +3 809 181 336 +3 809 291 1083 +3 496 1506 1046 +3 650 496 1046 +3 390 1121 594 +3 1295 1003 1074 +3 1832 1845 1831 +3 1204 640 1389 +3 341 585 1154 +3 1081 1507 1082 +3 511 1884 569 +3 1197 1467 828 +3 1341 809 336 +3 1094 680 976 +3 1540 1545 1544 +3 1398 1388 1402 +3 594 1121 1088 +3 1233 1099 1189 +3 1502 1516 1503 +3 1506 1344 1115 +3 291 1137 1342 +3 1097 1513 1082 +3 1412 812 123 +3 498 831 812 +3 1412 498 812 +3 883 1466 1074 +3 1006 1420 962 +3 1399 1471 1159 +3 962 672 1006 +3 1118 1091 702 +3 1686 1687 1703 +3 653 964 1084 +3 1735 1756 1747 +3 1 470 1536 +3 127 1059 1037 +3 1046 1506 1115 +3 1288 1006 1385 +3 1044 1288 1385 +3 1147 1171 1170 +3 1170 1142 1147 +3 1137 291 1346 +3 808 1008 1011 +3 1159 245 1504 +3 672 962 1065 +3 1390 1106 781 +3 1390 1156 1466 +3 1466 1156 1295 +3 1015 1016 1021 +3 644 1540 1539 +3 1137 1533 1542 +3 1088 1089 1288 +3 594 1088 1288 +3 1721 1746 1729 +3 360 594 1044 +3 594 1288 1044 +3 245 1108 1504 +3 216 1521 389 +3 1370 1211 1384 +3 1089 1006 1288 +3 461 587 513 +3 513 587 1351 +3 1351 1414 1412 +3 1091 498 1412 +3 1414 1091 1412 +3 1115 1530 538 +3 1092 1140 1457 +3 1509 1090 1534 +3 1137 1146 1533 +3 1349 461 1547 +3 767 1 1064 +3 1529 1365 1195 +3 964 1130 1441 +3 1351 587 1414 +3 1115 538 289 +3 1405 1413 1397 +3 1513 1081 1082 +3 980 514 1420 +3 680 1094 1507 +3 461 1414 587 +3 1106 1508 462 +3 1052 1370 1179 +3 1457 1541 1247 +3 587 1414 461 +3 1420 514 962 +3 545 1201 1326 +3 63 585 1514 +3 1105 154 1097 +3 1064 1533 1146 +3 1414 587 461 +3 973 1414 587 +3 1414 973 587 +3 250 1476 289 +3 1157 1204 680 +3 1398 1383 1211 +3 1507 1397 1082 +3 1543 1349 1533 +3 1536 1543 1533 +3 1543 410 461 +3 1349 1543 461 +3 973 1141 1414 +3 1141 1091 1414 +3 1476 1115 289 +3 1084 964 1092 +3 373 1537 1521 +3 1521 1105 1121 +3 1476 250 1274 +3 1149 1525 1142 +3 1254 1541 1540 +3 1064 1 1533 +3 1082 1397 1089 +3 1088 1082 1089 +3 80 373 1521 +3 1535 80 1521 +3 1341 541 547 +3 39 199 783 +3 1536 1533 1 +3 973 1414 461 +3 410 973 461 +3 1397 1413 1420 +3 1089 1397 1420 +3 1111 1383 1501 +3 1503 1476 1274 +3 606 82 391 +3 780 38 868 +3 1135 1104 1061 +3 711 1514 1059 +3 1365 1194 1195 +3 1111 1510 1179 +3 1485 1135 1149 +3 796 1128 1252 +3 1228 293 1224 +3 644 1263 1540 +3 390 160 25 +3 63 33 104 +3 391 306 606 +3 306 244 606 +3 1097 154 1513 +3 494 672 1065 +3 1543 618 410 +3 537 973 410 +3 618 537 410 +3 1141 1352 702 +3 972 992 991 +3 1509 1534 1439 +3 1088 1097 1082 +3 1401 1023 1298 +3 53 569 1884 +3 1536 470 1543 +3 1410 127 1037 +3 1227 293 1228 +3 1128 1522 245 +3 1522 1154 245 +3 1850 1870 1849 +3 796 1252 1023 +3 173 83 33 +3 1543 470 618 +3 1242 69 1251 +3 1515 1527 1371 +3 1162 1135 1060 +3 1188 537 618 +3 1109 973 537 +3 1109 1141 973 +3 1109 1352 1141 +3 545 518 828 +3 1201 545 828 +3 1244 1457 1247 +3 1386 1515 1371 +3 1454 1518 1499 +3 1089 1477 1006 +3 462 1401 781 +3 1401 499 781 +3 63 433 585 +3 1886 1066 304 +3 1204 1074 680 +3 127 711 1059 +3 640 1425 1389 +3 1188 618 537 +3 499 1298 519 +3 1226 1060 1099 +3 1233 1226 1099 +3 1515 1454 1386 +3 1298 897 1120 +3 519 1298 1120 +3 1188 537 618 +3 1524 1502 1046 +3 1178 980 550 +3 1178 1512 1075 +3 1515 1386 1391 +3 1386 1454 1515 +3 1149 1142 1099 +3 1060 1149 1099 +3 1508 1098 462 +3 1401 462 1023 +3 1178 1075 980 +3 552 868 459 +3 1061 1525 1149 +3 1098 1037 796 +3 1524 1502 1476 +3 1476 1524 1046 +3 1828 1829 1834 +3 1089 1420 1477 +3 1352 672 494 +3 1502 1512 650 +3 1252 1128 1471 +3 1531 1518 1454 +3 1374 1531 1454 +3 1512 1502 1075 +3 1173 618 470 +3 160 1173 470 +3 1173 1188 618 +3 1173 360 1188 +3 1188 360 537 +3 360 1044 537 +3 537 1044 1109 +3 1044 1385 1109 +3 672 1352 1109 +3 1385 672 1109 +3 511 517 1560 +3 1390 781 1156 +3 223 222 178 +3 831 123 812 +3 141 1333 1618 +3 1812 1829 1828 +3 115 1005 1210 +3 1636 1637 1656 +3 1515 1454 1527 +3 1682 538 1530 +3 1637 1657 1656 +3 1072 1525 1061 +3 1071 1072 1061 +3 548 1350 142 +3 1072 1592 1525 +3 1487 1674 1684 +3 67 937 1010 +3 1754 1784 1762 +3 1462 1478 1473 +3 1137 1542 778 +3 1614 1637 1616 +3 1036 1572 1049 +3 1049 1584 1072 +3 1072 1584 1592 +3 1126 1525 1592 +3 1584 1126 1592 +3 199 606 783 +3 1499 1362 1368 +3 1680 1678 1679 +3 1049 1586 1584 +3 799 178 1558 +3 702 494 1198 +3 1499 1368 1527 +3 868 552 459 +3 1486 1487 1674 +3 1572 1584 1586 +3 1049 1572 1586 +3 779 702 1198 +3 1799 1812 1795 +3 1618 1333 141 +3 1662 1676 1675 +3 805 1350 548 +3 1026 1570 1572 +3 1572 1073 1584 +3 1073 1078 1584 +3 1112 1126 1584 +3 1078 1112 1584 +3 1617 1620 1416 +3 1676 560 483 +3 1675 1676 483 +3 1659 1678 1663 +3 1572 1570 1073 +3 1054 1004 399 +3 827 1880 1870 +3 1404 1590 1604 +3 1374 1515 1391 +3 1345 472 498 +3 802 1555 1519 +3 1655 1675 1674 +3 1416 1614 1415 +3 1407 1406 1386 +3 482 560 1676 +3 1678 1677 1663 +3 1146 1137 1346 +3 1026 1562 1570 +3 1562 1570 1572 +3 1570 1562 1572 +3 1677 482 1676 +3 547 1556 798 +3 701 734 570 +3 1589 1404 1603 +3 1641 1638 1634 +3 1639 1641 1634 +3 1657 1658 1662 +3 260 261 575 +3 156 701 1164 +3 1639 1634 1621 +3 1638 1658 1657 +3 1637 1638 1657 +3 1519 1118 702 +3 1415 1605 1590 +3 779 1519 702 +3 1406 1415 1590 +3 1663 1677 1662 +3 1641 1659 1638 +3 1658 1663 1662 +3 1635 1636 1654 +3 1562 1073 1570 +3 1687 1686 1439 +3 1047 375 39 +3 1621 1620 1617 +3 738 1519 779 +3 483 515 1674 +3 473 1333 531 +3 481 473 531 +3 1155 142 639 +3 1662 1675 1655 +3 1656 1662 1655 +3 1038 1045 1073 +3 1562 1038 1073 +3 222 179 178 +3 1428 1621 1617 +3 1675 483 1674 +3 1159 1471 245 +3 1365 245 1154 +3 1209 1365 1154 +3 245 1365 1108 +3 1637 1636 1616 +3 1416 1620 1614 +3 1638 1637 1614 +3 884 1340 1884 +3 1049 1043 1036 +3 1605 1616 1607 +3 1620 1638 1614 +3 1455 1428 1445 +3 1622 1529 1195 +3 1177 1622 1195 +3 550 976 500 +3 1587 1523 1119 +3 1428 1455 1639 +3 1096 1079 1080 +3 553 536 563 +3 1404 1604 1603 +3 1153 1622 1177 +3 641 638 661 +3 1013 1020 1038 +3 1051 1114 1096 +3 1080 1051 1096 +3 1114 1587 1096 +3 1556 243 798 +3 1532 1623 1622 +3 1153 1532 1622 +3 1642 1529 1622 +3 1623 1642 1622 +3 1642 1504 1108 +3 1529 1642 1108 +3 1378 1404 1388 +3 178 179 1559 +3 1455 1473 1641 +3 1653 1655 1674 +3 805 530 531 +3 33 18 173 +3 1605 1604 1590 +3 179 1259 1559 +3 1051 1587 1114 +3 1118 1345 1091 +3 851 523 532 +3 715 732 1167 +3 1636 1655 1654 +3 1621 1634 1620 +3 1093 1280 1362 +3 1051 1114 1587 +3 1604 1605 1607 +3 1022 1563 1051 +3 1030 1022 1051 +3 1563 1573 1114 +3 1051 1563 1114 +3 1573 1585 1587 +3 1114 1573 1587 +3 1585 1599 1523 +3 1587 1585 1523 +3 1599 1608 1532 +3 1523 1599 1532 +3 1608 1624 1623 +3 1532 1608 1623 +3 1643 1642 1623 +3 1624 1643 1623 +3 1643 1673 1504 +3 1642 1643 1504 +3 551 547 798 +3 1014 1016 1015 +3 1306 1307 1379 +3 805 548 525 +3 1656 1655 1636 +3 1333 805 531 +3 1683 1184 1673 +3 1608 1625 1624 +3 1644 1643 1624 +3 1625 1644 1624 +3 1664 1673 1643 +3 1644 1664 1643 +3 1023 1128 1252 +3 585 854 1209 +3 1351 1412 123 +3 322 1301 495 +3 799 844 474 +3 516 495 141 +3 1555 1345 1118 +3 495 1618 141 +3 1047 205 540 +3 141 1333 473 +3 1433 1426 1434 +3 597 378 1063 +3 1528 1564 1563 +3 1022 1528 1563 +3 1564 1574 1573 +3 1563 1564 1573 +3 1573 1574 1585 +3 1574 1576 1585 +3 1585 1576 1599 +3 1576 1600 1599 +3 1600 1609 1608 +3 1599 1600 1608 +3 1609 1626 1625 +3 1608 1609 1625 +3 1645 1644 1625 +3 1626 1645 1625 +3 1645 1665 1664 +3 1644 1645 1664 +3 1665 1673 1664 +3 1665 1326 1683 +3 1673 1665 1683 +3 1326 1184 1683 +3 1590 1404 1378 +3 1614 1616 1605 +3 1415 1614 1605 +3 495 1333 1618 +3 738 802 1519 +3 1473 1659 1641 +3 1301 805 1333 +3 205 206 517 +3 1405 976 550 +3 495 1301 1333 +3 1593 1601 1600 +3 1576 1593 1600 +3 1600 1601 1609 +3 716 208 515 +3 500 1178 550 +3 1259 523 851 +3 1559 1259 851 +3 831 481 812 +3 513 1349 1547 +3 1616 1636 1635 +3 222 223 1680 +3 1301 493 1350 +3 805 1301 1350 +3 1548 1552 1528 +3 1552 1565 1564 +3 1528 1552 1564 +3 1564 1565 1574 +3 1574 1565 1576 +3 1565 1577 1576 +3 1594 1593 1576 +3 1577 1594 1576 +3 1602 1601 1593 +3 1594 1602 1593 +3 1602 1610 1609 +3 1601 1602 1609 +3 1610 1627 1626 +3 1609 1610 1626 +3 1627 1646 1645 +3 1626 1627 1645 +3 1666 1665 1645 +3 1646 1666 1645 +3 1666 545 1326 +3 1665 1666 1326 +3 483 716 515 +3 547 243 1556 +3 221 1003 1295 +3 143 221 1295 +3 809 1341 547 +3 551 809 547 +3 782 1342 778 +3 731 782 778 +3 1458 1660 1455 +3 752 309 753 +3 1424 1402 1603 +3 1519 1555 1118 +3 1549 1553 1552 +3 1552 1553 1565 +3 1775 1799 1784 +3 1406 1590 1378 +3 493 174 142 +3 1350 493 142 +3 1656 1657 1662 +3 291 809 551 +3 731 778 513 +3 523 473 481 +3 1365 1209 1194 +3 1346 291 551 +3 784 731 513 +3 1550 1554 1553 +3 1549 1550 1553 +3 1566 1565 1553 +3 1554 1566 1553 +3 1566 1578 1577 +3 1565 1566 1577 +3 1578 1579 1577 +3 1577 1579 1594 +3 1579 1595 1602 +3 1594 1579 1602 +3 1595 1611 1610 +3 1602 1595 1610 +3 1628 1627 1610 +3 1611 1628 1610 +3 1628 1647 1646 +3 1627 1628 1646 +3 1647 1667 1666 +3 1646 1647 1666 +3 1667 1668 1666 +3 518 545 1666 +3 1668 518 1666 +3 1074 1003 1094 +3 1607 1616 1615 +3 123 784 513 +3 1499 1527 1454 +3 1604 1607 1615 +3 1566 1579 1578 +3 1628 1648 1647 +3 1648 1668 1667 +3 1647 1648 1667 +3 1681 518 1668 +3 778 1533 1349 +3 513 778 1349 +3 496 650 497 +3 1615 1616 1635 +3 1429 1445 1428 +3 718 758 748 +3 1678 1680 474 +3 1680 223 474 +3 778 1542 1533 +3 206 205 1047 +3 1478 222 1680 +3 1679 1678 1659 +3 857 831 498 +3 1386 1406 1391 +3 1360 1090 1554 +3 1550 1360 1554 +3 1567 1566 1554 +3 1090 1567 1554 +3 1567 1580 1579 +3 1566 1567 1579 +3 1580 1596 1595 +3 1579 1580 1595 +3 1596 1606 1611 +3 1595 1596 1611 +3 1606 1629 1628 +3 1611 1606 1628 +3 1629 1630 1628 +3 1630 1649 1648 +3 1628 1630 1648 +3 1649 1526 1668 +3 1648 1649 1668 +3 496 1681 1668 +3 1526 496 1668 +3 497 518 1681 +3 496 497 1681 +3 518 497 650 +3 1005 574 1210 +3 123 513 1351 +3 1877 1876 1865 +3 1558 1555 802 +3 799 1558 802 +3 472 857 498 +3 1455 1641 1639 +3 1634 1638 1620 +3 482 802 738 +3 1248 429 700 +3 1654 1655 1653 +3 1606 1630 1629 +3 1473 1478 1680 +3 1362 1499 1557 +3 1558 857 472 +3 1120 1184 1326 +3 857 851 831 +3 844 802 482 +3 474 844 482 +3 1555 1558 472 +3 844 799 802 +3 1342 1137 778 +3 1649 1669 1526 +3 1669 1506 496 +3 1526 1669 496 +3 1421 1411 1422 +3 851 532 481 +3 780 340 383 +3 1008 780 383 +3 1568 1567 1090 +3 1509 1568 1090 +3 1568 1581 1580 +3 1567 1568 1580 +3 1597 1596 1580 +3 1581 1597 1580 +3 1596 1597 1606 +3 1597 1612 1606 +3 1612 1631 1630 +3 1606 1612 1630 +3 1631 1650 1649 +3 1630 1631 1649 +3 1649 1650 1669 +3 1678 482 1677 +3 560 738 716 +3 1345 498 1091 +3 500 1100 1178 +3 1678 474 482 +3 1009 878 53 +3 1841 1855 1851 +3 1454 1527 1499 +3 827 107 1864 +3 495 516 75 +3 208 716 1198 +3 1428 1639 1621 +3 1771 1280 1093 +3 842 1008 808 +3 378 533 1063 +3 1582 1581 1568 +3 1659 1663 1658 +3 1865 1864 1851 +3 1503 514 980 +3 1583 1582 1568 +3 1588 1581 1582 +3 1583 1588 1582 +3 1598 1597 1581 +3 1588 1598 1581 +3 1433 1612 1597 +3 1433 1619 1612 +3 1632 1631 1612 +3 1619 1632 1612 +3 1651 1650 1631 +3 1632 1651 1631 +3 1651 1670 1669 +3 1650 1651 1669 +3 1670 1344 1506 +3 1669 1670 1506 +3 1660 1473 1455 +3 1353 842 808 +3 995 1353 808 +3 1353 1008 842 +3 1353 842 1008 +3 38 780 1008 +3 842 38 1008 +3 1517 1569 1568 +3 1509 1517 1568 +3 1569 1583 1568 +3 716 779 1198 +3 716 738 779 +3 560 482 738 +3 1360 1687 1534 +3 1353 38 842 +3 1111 1179 1383 +3 1598 1433 1597 +3 868 38 552 +3 1045 1078 1073 +3 1124 406 272 +3 1433 1632 1619 +3 474 223 1122 +3 1033 1765 1024 +3 1378 1359 1374 +3 1269 1270 1281 +3 291 782 444 +3 483 560 716 +3 1462 1473 1660 +3 499 1156 781 +3 1214 542 909 +3 1555 472 1345 +3 178 1559 1558 +3 851 481 831 +3 1269 1281 1268 +3 824 1856 1846 +3 53 1884 1009 +3 1439 1111 1517 +3 1111 1501 1569 +3 1517 1111 1569 +3 1411 1583 1569 +3 1411 1588 1583 +3 1411 1421 1588 +3 1421 1598 1588 +3 1421 1426 1598 +3 1426 1433 1598 +3 1434 1433 1598 +3 1433 1434 1598 +3 1633 1632 1433 +3 1434 1633 1433 +3 1633 1640 1632 +3 1652 1651 1632 +3 1640 1652 1632 +3 1671 1670 1651 +3 1652 1671 1651 +3 1671 1682 1344 +3 1670 1671 1344 +3 1274 1032 514 +3 1503 1274 514 +3 532 523 481 +3 1319 264 277 +3 546 806 1591 +3 546 995 806 +3 546 746 995 +3 1339 1353 995 +3 746 1339 995 +3 1339 1200 38 +3 1353 1339 38 +3 223 178 799 +3 1530 1344 1682 +3 1449 1633 1434 +3 399 744 1054 +3 831 812 123 +3 1122 223 799 +3 243 205 517 +3 1473 1679 1659 +3 1024 1034 1033 +3 1591 1340 546 +3 1501 1411 1569 +3 1156 499 1295 +3 1449 1640 1633 +3 1209 953 854 +3 1458 1462 1660 +3 1224 235 677 +3 1523 1153 1119 +3 1085 1355 1364 +3 1468 1652 1640 +3 1449 1468 1640 +3 1489 1671 1652 +3 1468 1489 1652 +3 1671 1489 1682 +3 1489 538 1682 +3 1836 1857 1844 +3 803 189 1117 +3 1685 1696 1695 +3 1785 1791 1801 +3 1808 1801 1791 +3 1791 1792 1815 +3 1751 1750 1735 +3 1843 1862 1842 +3 1210 444 115 +3 1800 1816 1799 +3 1803 1821 1802 +3 995 834 1591 +3 758 759 1182 +3 1836 1858 1857 +3 810 168 1857 +3 1858 810 1857 +3 1740 1757 1764 +3 873 872 865 +3 1808 1815 1801 +3 1815 1819 1801 +3 804 803 1117 +3 1741 1757 1740 +3 1793 865 1788 +3 1812 1816 1830 +3 804 1117 1878 +3 1561 1725 1726 +3 1857 168 824 +3 1757 1779 1764 +3 1764 1779 1786 +3 78 815 1868 +3 1822 1821 1803 +3 1717 1737 1721 +3 1844 1857 1846 +3 1725 1724 1013 +3 824 168 79 +3 1713 1718 1696 +3 1715 1714 1699 +3 1722 1730 1711 +3 1843 1842 1825 +3 1819 1843 1825 +3 1857 824 1846 +3 1821 1827 1826 +3 1809 1821 1826 +3 1815 1843 1819 +3 1821 1809 1802 +3 1548 1689 1549 +3 1733 1561 1562 +3 1733 1725 1561 +3 604 599 406 +3 406 599 202 +3 1822 1836 1821 +3 815 1881 1867 +3 1852 1855 1830 +3 1699 1706 1016 +3 54 55 845 +3 158 219 521 +3 1742 1741 1725 +3 1733 1742 1725 +3 1763 1777 1785 +3 1033 1788 1765 +3 1769 1776 1749 +3 1749 1755 1734 +3 1756 1769 1747 +3 1732 1751 1735 +3 1707 1714 1722 +3 1738 1754 1737 +3 1876 1864 1865 +3 1722 1714 1731 +3 865 1810 1787 +3 1788 865 1787 +3 1715 1732 1714 +3 1742 1757 1741 +3 1804 1803 1786 +3 1779 1804 1786 +3 1770 1791 1785 +3 1806 1810 242 +3 1722 1747 1730 +3 1705 1706 1707 +3 1804 1805 1803 +3 1835 1843 1815 +3 1346 551 1883 +3 1802 1809 1792 +3 1837 1836 1822 +3 1017 1837 1822 +3 1878 1117 1877 +3 1711 1730 1713 +3 1690 1706 1705 +3 1837 136 1836 +3 1830 1855 1841 +3 1868 1867 1856 +3 599 20 681 +3 136 1858 1836 +3 1791 1815 1808 +3 1024 1759 1018 +3 1730 1734 1713 +3 1785 1790 1756 +3 20 596 681 +3 1831 1830 1817 +3 1797 1802 1792 +3 1864 1876 827 +3 1881 815 814 +3 1787 1806 1781 +3 1116 916 1031 +3 814 1882 1872 +3 1711 1713 1697 +3 1110 1475 859 +3 1690 1705 1698 +3 1785 1801 1790 +3 1765 1787 1759 +3 596 20 556 +3 596 1180 681 +3 681 1180 1031 +3 1882 804 1872 +3 1698 1711 1697 +3 1759 1781 1758 +3 900 1883 979 +3 1696 1717 1704 +3 1026 1561 1562 +3 1769 1796 1776 +3 1013 1723 1715 +3 1734 1717 1718 +3 1832 1831 1813 +3 1180 316 1116 +3 1031 1180 1116 +3 1561 1742 1733 +3 1882 814 804 +3 1820 1835 1815 +3 1442 988 1447 +3 710 577 622 +3 1810 1806 1787 +3 596 1752 1180 +3 1180 316 1116 +3 316 1180 1116 +3 316 993 916 +3 1116 316 916 +3 1759 1787 1781 +3 1776 1800 1775 +3 1732 1735 1714 +3 1886 409 821 +3 1703 1729 1710 +3 1693 1685 1550 +3 1016 1706 1690 +3 1693 1689 1697 +3 1842 1862 1861 +3 1694 1695 1704 +3 1687 1685 1694 +3 988 382 1447 +3 1447 382 576 +3 747 797 120 +3 1776 1775 1755 +3 1199 1167 732 +3 1041 758 596 +3 596 758 1752 +3 1876 1158 107 +3 1685 1695 1694 +3 1858 818 810 +3 382 1431 576 +3 1693 1697 1696 +3 243 1888 798 +3 1117 189 187 +3 1823 1822 1803 +3 1805 1823 1803 +3 1442 1430 1443 +3 818 1858 136 +3 356 477 424 +3 382 1575 1431 +3 916 993 554 +3 467 590 1318 +3 1685 1693 1696 +3 1845 1866 1853 +3 1431 1575 1110 +3 1182 1752 758 +3 1182 1180 1752 +3 1182 825 1180 +3 1180 825 316 +3 1017 136 1837 +3 1430 1440 1443 +3 1440 908 988 +3 988 908 382 +3 1575 549 1110 +3 549 1150 963 +3 1110 549 963 +3 1825 1813 1814 +3 1796 1817 1800 +3 825 633 316 +3 1699 1714 1706 +3 633 993 316 +3 633 1323 993 +3 1430 1869 1440 +3 908 1575 382 +3 1101 963 1150 +3 1734 1738 1717 +3 1819 1825 1814 +3 1801 1819 1814 +3 633 825 1182 +3 1440 1869 908 +3 908 996 1575 +3 759 787 786 +3 1809 1826 1820 +3 1869 1145 908 +3 549 1101 1150 +3 1723 1732 1715 +3 1428 1847 1430 +3 1145 56 908 +3 908 56 996 +3 1144 1101 549 +3 1809 1820 1815 +3 1793 1788 1033 +3 797 633 1182 +3 759 797 1182 +3 1735 1750 1756 +3 996 56 1575 +3 56 549 1575 +3 1750 1763 1756 +3 1847 1848 1430 +3 1848 1859 1430 +3 1430 1859 1869 +3 56 1168 549 +3 1690 1689 1548 +3 1758 1779 1757 +3 786 797 759 +3 747 633 797 +3 633 747 1323 +3 1323 747 167 +3 865 866 873 +3 1778 1791 1770 +3 78 1868 824 +3 1805 1804 1779 +3 1428 1848 1847 +3 56 1053 1168 +3 1168 1131 1144 +3 549 1168 1144 +3 1877 1117 1876 +3 1707 1722 1711 +3 1731 1735 1739 +3 830 1823 1805 +3 830 1822 1823 +3 1859 1873 1145 +3 1869 1859 1145 +3 1131 1101 1144 +3 1814 1813 1790 +3 830 1017 1822 +3 207 562 561 +3 1772 1771 1093 +3 1557 1772 1093 +3 866 1033 1042 +3 1617 1417 1428 +3 1428 1417 1848 +3 1734 1755 1738 +3 1821 1836 1844 +3 1801 1814 1790 +3 895 797 786 +3 787 759 760 +3 1873 961 1145 +3 1145 961 56 +3 1053 1131 1168 +3 1833 1101 1131 +3 1833 710 1101 +3 1853 1871 1852 +3 1689 1690 1698 +3 1772 1275 1771 +3 1848 1417 1859 +3 242 830 1806 +3 1713 1734 1718 +3 1800 1799 1775 +3 1695 1696 1704 +3 1518 1557 1499 +3 1794 1275 1772 +3 1809 1815 1792 +3 1417 1418 1859 +3 961 951 56 +3 56 951 1053 +3 1833 1131 710 +3 1019 1742 1561 +3 1758 1757 1742 +3 1780 1779 1758 +3 1748 1557 1518 +3 1794 1277 1275 +3 1873 1879 961 +3 951 559 1053 +3 1053 559 1131 +3 1876 107 827 +3 1747 1769 1749 +3 1267 1277 1794 +3 1418 1863 1859 +3 1859 1863 1873 +3 1868 815 1867 +3 1766 1772 1557 +3 1748 1766 1557 +3 866 1793 1033 +3 559 1196 1131 +3 1196 1343 1131 +3 1131 1343 710 +3 1766 1794 1772 +3 180 1229 336 +3 415 1879 1873 +3 415 961 1879 +3 1343 577 710 +3 866 865 1793 +3 1362 1557 1093 +3 1789 1794 1766 +3 1873 1863 415 +3 1456 1442 1447 +3 1018 1742 1019 +3 1743 1748 1518 +3 1531 1743 1518 +3 1789 1267 1794 +3 434 961 415 +3 434 951 961 +3 1781 1779 1780 +3 1811 1267 1789 +3 1781 1805 1779 +3 404 522 438 +3 434 736 951 +3 736 559 951 +3 1743 1766 1748 +3 559 736 1196 +3 1722 1739 1747 +3 715 1393 1169 +3 1534 1090 1360 +3 1269 1271 1270 +3 604 1124 272 +3 1358 1531 1500 +3 1824 1268 1267 +3 1811 1824 1267 +3 155 813 1880 +3 736 480 1196 +3 1196 480 1343 +3 1343 480 577 +3 1790 1813 1796 +3 1782 1789 1766 +3 1760 1782 1766 +3 1803 1802 1797 +3 1777 1770 1785 +3 1719 1743 1531 +3 1760 1766 1743 +3 1838 1269 1268 +3 1824 1838 1268 +3 1750 1770 1777 +3 480 578 577 +3 1689 1693 1550 +3 1763 1750 1777 +3 1770 1777 1785 +3 1691 1358 1356 +3 1719 1531 1358 +3 736 1062 480 +3 1813 1831 1817 +3 1549 1689 1550 +3 1756 1763 1785 +3 1691 1356 1355 +3 1085 1691 1355 +3 1761 1760 1743 +3 1744 1761 1743 +3 1807 1811 1789 +3 1838 1271 1269 +3 78 824 79 +3 1876 187 1158 +3 1821 1844 1827 +3 1708 1719 1358 +3 1744 1743 1719 +3 1782 1807 1789 +3 1807 1824 1811 +3 1860 1271 1838 +3 736 451 1062 +3 1756 1790 1769 +3 1725 1740 1724 +3 1698 1705 1711 +3 1510 1691 1085 +3 1708 1358 1691 +3 1761 1782 1760 +3 1818 1824 1807 +3 1860 1272 1271 +3 1718 1717 1696 +3 451 207 480 +3 1062 451 480 +3 1817 1830 1816 +3 1796 1800 1776 +3 1510 1085 1052 +3 1818 1838 1824 +3 1875 1272 1860 +3 1813 1817 1796 +3 1720 1719 1708 +3 1736 1744 1719 +3 1839 1838 1818 +3 96 807 486 +3 1018 1758 1742 +3 1842 1861 1845 +3 1881 814 1872 +3 1781 1780 1758 +3 1867 1881 1872 +3 1692 1691 1510 +3 1720 1736 1719 +3 1783 1782 1761 +3 1839 1860 1838 +3 1875 1661 586 +3 1272 1875 586 +3 1806 1805 1781 +3 1712 1716 1708 +3 1727 1720 1708 +3 1716 1727 1708 +3 1854 1860 1839 +3 1143 1661 1875 +3 1661 99 586 +3 1143 99 1661 +3 1031 60 236 +3 1709 1708 1691 +3 1692 1709 1691 +3 1709 1712 1708 +3 1709 1716 1712 +3 1709 1727 1716 +3 1727 1728 1720 +3 1786 1803 1797 +3 747 120 167 +3 484 207 451 +3 1736 1753 1744 +3 1753 1761 1744 +3 1753 1783 1761 +3 1874 1860 1854 +3 1874 1875 1860 +3 1792 1791 1778 +3 824 1868 1856 +3 1817 1816 1800 +3 520 207 484 +3 1692 1700 1709 +3 1728 1727 1709 +3 1728 1745 1727 +3 1511 1688 1510 +3 1688 1692 1510 +3 1874 1143 1875 +3 1013 1715 1699 +3 1749 1776 1755 +3 1759 1758 1018 +3 1688 1701 1700 +3 1692 1688 1700 +3 1773 1783 1753 +3 1849 1854 1839 +3 813 1143 1874 +3 813 99 1143 +3 1842 1845 1832 +3 1710 1709 1700 +3 1701 1710 1700 +3 1872 804 1878 +3 1825 1842 1832 +3 1853 1852 1830 +3 1730 1749 1734 +3 1689 1698 1697 +3 1805 1806 830 +3 1710 1728 1709 +3 1840 1849 1839 +3 1831 1853 1830 +3 1724 1723 1013 +3 1729 1728 1710 +3 1849 1874 1854 +3 1849 1870 1874 +3 1741 1740 1725 +3 1755 1775 1754 +3 1731 1714 1735 +3 1747 1749 1730 +3 1706 1714 1707 +3 1729 1745 1728 +3 1767 1773 1753 +3 1880 813 1874 +3 1870 1880 1874 +3 865 858 1810 +3 1810 858 259 +3 1861 1866 1845 +3 1790 1796 1769 +3 1755 1754 1738 +3 1739 1735 1747 +3 1686 1688 1511 +3 1439 1686 1511 +3 1746 1745 1729 +3 1774 1773 1767 +3 1834 1849 1840 +3 1016 1690 1548 +3 1788 1787 1765 +3 1551 1016 1548 +3 1686 1702 1701 +3 1688 1686 1701 +3 1703 1710 1701 +3 1702 1703 1701 +3 1795 1798 1773 +3 1825 1832 1813 +3 1697 1713 1696 +3 1762 1745 1746 +3 1762 1768 1745 +3 1795 1773 1774 diff --git a/samples/cpp/tutorial_code/viz/transformations.cpp b/samples/cpp/tutorial_code/viz/transformations.cpp index e3e3d094a..d357f4abf 100644 --- a/samples/cpp/tutorial_code/viz/transformations.cpp +++ b/samples/cpp/tutorial_code/viz/transformations.cpp @@ -6,6 +6,7 @@ #include #include +#include using namespace cv; using namespace std; @@ -22,10 +23,32 @@ void help() << "how to use makeCameraPose and Viz3d::setViewerPose. You can observe the scene " << "from camera point of view (C) or global point of view (G)" << endl << "Usage:" << endl - << "./coordinate_frame [ G | C ]" << endl + << "./transformations [ G | C ]" << endl << endl; } +/** + * @function cvcloud_load + * @brief load bunny.ply + */ +Mat cvcloud_load() +{ + Mat cloud(1, 1889, CV_32FC3); + ifstream ifs("bunny.ply"); + + string str; + for(size_t i = 0; i < 12; ++i) + getline(ifs, str); + + Point3f* data = cloud.ptr(); + float dummy1, dummy2; + for(size_t i = 0; i < 1889; ++i) + ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2; + + cloud *= 5.0f; + return cloud; +} + /** * @function main */ @@ -48,20 +71,23 @@ int main(int argn, char **argv) myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); /// Let's assume camera has the following properties - Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f, 3.0f, 2.0f), cam_y_dir(-1.0,0.0,0.0); + Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); + /// We can get the pose of the cam using makeCameraPose Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + /// We can get the transformation matrix from camera coordinate system to global using /// - makeTransformToGlobal. We need the axes of the camera Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); /// Create a cloud widget. - viz::SphereWidget sphere_widget(Point3f(0.0,0.0,0.0), 0.5, 10, viz::Color::red()); + Mat bunny_cloud = cvcloud_load(); + viz::CloudWidget cloud_widget(bunny_cloud, viz::Color::green()); /// Pose of the widget in camera frame - Affine3f sphere_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); + Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); /// Pose of the widget in global frame - Affine3f sphere_pose_global = transform * sphere_pose; + Affine3f cloud_pose_global = transform * cloud_pose; /// Visualize camera frame if (!camera_pov) @@ -73,7 +99,7 @@ int main(int argn, char **argv) } /// Visualize widget - myWindow.showWidget("sphere", sphere_widget, sphere_pose_global); + myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); /// Set the viewer pose to that of camera if (camera_pov) From 286f81f3051800c2f87e92b6e25e3ef43002a425 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 8 Sep 2013 00:15:14 +0200 Subject: [PATCH 187/205] fix crucial bug in get method, hide add and remove methods from user --- modules/viz/include/opencv2/viz.hpp | 7 +++++-- modules/viz/src/viz.cpp | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 7f7cc7d2f..df89339dd 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -101,8 +101,6 @@ namespace cv static void release(); Viz3d get(const String &window_name); - void add(Viz3d window); - void remove(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); @@ -111,9 +109,14 @@ namespace cv VizAccessor(); // Singleton ~VizAccessor(); + void add(Viz3d window); + void remove(const String &window_name); + static VizAccessor * instance_; static bool is_instantiated_; static VizMap viz_map_; + + friend class Viz3d; }; } /* namespace viz */ } /* namespace cv */ diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index c8e09ba9e..8bce61ca2 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -126,7 +126,7 @@ cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name) VizMap::iterator vm_itr = viz_map_.find(name); bool exists = vm_itr != viz_map_.end(); if (exists) return vm_itr->second; - else return viz_map_.insert(VizPair(window_name, Viz3d(window_name))).first->second; + else return Viz3d(window_name); } void cv::viz::VizAccessor::add(Viz3d window) @@ -135,7 +135,7 @@ void cv::viz::VizAccessor::add(Viz3d window) VizMap::iterator vm_itr = viz_map_.find(window_name); bool exists = vm_itr != viz_map_.end(); if (exists) return ; - viz_map_.insert(std::pair(window_name, window)); + viz_map_.insert(VizPair(window_name, window)); } void cv::viz::VizAccessor::remove(const String &window_name) From 2170559bed4e2ba54c9f53ffb5713f9cc7df677d Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 8 Sep 2013 12:19:14 +0200 Subject: [PATCH 188/205] text3dwidget offers now users to decide whether it should face the camera or not --- modules/viz/include/opencv2/viz/viz3d.hpp | 2 +- modules/viz/include/opencv2/viz/widgets.hpp | 3 +- modules/viz/src/shape_widgets.cpp | 33 ++++++++++++++------- modules/viz/src/viz3d.cpp | 2 +- modules/viz/src/viz3d_impl.cpp | 4 +-- modules/viz/src/viz3d_impl.hpp | 2 +- 6 files changed, 28 insertions(+), 18 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 3e7d99935..f118dd6bb 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -62,7 +62,7 @@ namespace cv void setRenderingProperty(const String &id, int property, double value); double getRenderingProperty(const String &id, int property); - void setDesiredUpdateRate(double time); + void setDesiredUpdateRate(double rate); double getDesiredUpdateRate(); void setRepresentation(int representation); diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 1adc9fccd..4769073a2 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -14,7 +14,6 @@ namespace cv OPACITY, LINE_WIDTH, FONT_SIZE, - COLOR, REPRESENTATION, IMMEDIATE_RENDERING, SHADING @@ -162,7 +161,7 @@ namespace cv class CV_EXPORTS Text3DWidget : public Widget3D { public: - Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()); + Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, bool face_camera = true, const Color &color = Color::white()); void setText(const String &text); String getText() const; diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 84fdc7728..f10c39fb3 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -521,21 +521,32 @@ template<> cv::viz::GridWidget cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// text3D widget implementation -cv::viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position, double text_scale, const Color &color) +cv::viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position, double text_scale, bool face_camera, const Color &color) { - vtkSmartPointer textSource = vtkSmartPointer::New (); - textSource->SetText (text.c_str()); - textSource->Update (); + vtkSmartPointer textSource = vtkSmartPointer::New(); + textSource->SetText(text.c_str()); + textSource->Update(); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInputConnection (textSource->GetOutputPort ()); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputConnection (textSource->GetOutputPort()); - vtkSmartPointer actor = vtkSmartPointer::New (); - actor->SetMapper (mapper); - actor->SetPosition (position.x, position.y, position.z); - actor->SetScale (text_scale); + if (face_camera) + { + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + actor->SetPosition(position.x, position.y, position.z); + actor->SetScale(text_scale); + WidgetAccessor::setProp(*this, actor); + } + else + { + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + actor->SetPosition(position.x, position.y, position.z); + actor->SetScale(text_scale); + WidgetAccessor::setProp(*this, actor); + } - WidgetAccessor::setProp(*this, actor); setColor(color); } diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index ba323c243..eeea94277 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -84,7 +84,7 @@ void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgrou void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double value) { getWidget(id).setRenderingProperty(property, value); } double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { return getWidget(id).getRenderingProperty(property); } -void cv::viz::Viz3d::setDesiredUpdateRate(double time) { impl_->setDesiredUpdateRate(time); } +void cv::viz::Viz3d::setDesiredUpdateRate(double rate) { impl_->setDesiredUpdateRate(rate); } double cv::viz::Viz3d::getDesiredUpdateRate() { return impl_->getDesiredUpdateRate(); } void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 765e71b22..fd6a82eb4 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -189,10 +189,10 @@ cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setDesiredUpdateRate(double time) +void cv::viz::Viz3d::VizImpl::setDesiredUpdateRate(double rate) { if (interactor_) - interactor_->SetDesiredUpdateRate(time); + interactor_->SetDesiredUpdateRate(rate); } ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 98c2c4554..26d817a13 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -24,7 +24,7 @@ public: void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; - void setDesiredUpdateRate(double time); + void setDesiredUpdateRate(double rate); double getDesiredUpdateRate(); /** \brief Returns true when the user tried to close the window */ From 3bdb55e1efc9d67eee6d91dd3557774d8c3168e8 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 8 Sep 2013 13:06:40 +0200 Subject: [PATCH 189/205] another constructor for CameraPositionWidget for displaying image by also using field of view instead of intrinsic matrix --- modules/viz/include/opencv2/viz/widgets.hpp | 5 + modules/viz/src/shape_widgets.cpp | 185 +++++++++++--------- 2 files changed, 107 insertions(+), 83 deletions(-) diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 4769073a2..1216d040a 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -206,6 +206,11 @@ namespace cv CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); //! Creates frustum and display given image at the far plane CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane + CameraPositionWidget(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + + private: + struct ProjectImage; }; class CV_EXPORTS TrajectoryWidget : public Widget3D diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index f10c39fb3..f42cebdf0 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -846,6 +846,96 @@ template<> cv::viz::Image3DWidget cv::viz::Widget::cast( /////////////////////////////////////////////////////////////////////////////////////////////// /// camera position widget implementation +struct cv::viz::CameraPositionWidget::ProjectImage +{ + static void projectImage(float fovy, float far_end_height, const Mat &image, + double scale, const Color &color, vtkSmartPointer actor) + { + // Create a camera + vtkSmartPointer camera = vtkSmartPointer::New(); + float aspect_ratio = float(image.cols)/float(image.rows); + + // Create the vtk image + vtkSmartPointer vtk_image = vtkSmartPointer::New(); + ConvertToVtkImage::convert(image, vtk_image); + + // Adjust a pixel of the vtk_image + vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 0, color[2]); + vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 1, color[1]); + vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 2, color[0]); + + // Need to flip the image as the coordinates are different in OpenCV and VTK + vtkSmartPointer flipFilter = vtkSmartPointer::New(); + flipFilter->SetFilteredAxis(1); // Vertical flip + flipFilter->SetInputConnection(vtk_image->GetProducerPort()); + flipFilter->Update(); + + Vec3d plane_center(0.0, 0.0, scale); + + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); + plane->SetNormal(0.0, 0.0, 1.0); + + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->PreMultiply(); + transform->Translate(plane_center[0], plane_center[1], plane_center[2]); + transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0); + transform->RotateY(180.0); + transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); + + // Apply the texture + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(flipFilter->GetOutputPort()); + + vtkSmartPointer texturePlane = vtkSmartPointer::New(); + texturePlane->SetInputConnection(plane->GetOutputPort()); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(texturePlane->GetOutputPort()); + transform_filter->Update(); + + // Create frustum + camera->SetViewAngle(fovy); + camera->SetPosition(0.0,0.0,0.0); + camera->SetViewUp(0.0,1.0,0.0); + camera->SetFocalPoint(0.0,0.0,1.0); + camera->SetClippingRange(0.01, scale); + + double planesArray[24]; + camera->GetFrustumPlanes(aspect_ratio, planesArray); + + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planesArray); + + vtkSmartPointer frustumSource = + vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + frustumSource->Update(); + + vtkSmartPointer filter = vtkSmartPointer::New(); + filter->SetInput(frustumSource->GetOutput()); + filter->Update(); + + // Frustum needs to be textured or else it can't be combined with image + vtkSmartPointer frustum_texture = vtkSmartPointer::New(); + frustum_texture->SetInputConnection(filter->GetOutputPort()); + // Texture mapping with only one pixel from the image to have constant color + frustum_texture->SetSRange(0.0, 0.0); + frustum_texture->SetTRange(0.0, 0.0); + + vtkSmartPointer appendFilter = vtkSmartPointer::New(); + appendFilter->AddInputConnection(frustum_texture->GetOutputPort()); + appendFilter->AddInputConnection(transform_filter->GetOutputPort()); + + vtkSmartPointer planeMapper = vtkSmartPointer::New(); + planeMapper->SetInputConnection(appendFilter->GetOutputPort()); + + actor->SetMapper(planeMapper); + actor->SetTexture(texture); + } +}; + cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) { vtkSmartPointer axes = vtkSmartPointer::New (); @@ -963,96 +1053,25 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double sca cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat &image, double scale, const Color &color) { CV_Assert(!image.empty() && image.depth() == CV_8U); - - // Create a camera - vtkSmartPointer camera = vtkSmartPointer::New(); float f_y = K(1,1); float c_y = K(1,2); - float aspect_ratio = float(image.cols)/float(image.rows); // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) - float fovy = 2.0f * atan2(c_y,f_y) * 180 / CV_PI; + float fovy = 2.0f * atan2(c_y,f_y) * 180.0f / CV_PI; float far_end_height = 2.0f * c_y * scale / f_y; - // Create the vtk image - vtkSmartPointer vtk_image = vtkSmartPointer::New(); - ConvertToVtkImage::convert(image, vtk_image); - - // Adjust a pixel of the vtk_image - vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 0, color[2]); - vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 1, color[1]); - vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 2, color[0]); - - // Need to flip the image as the coordinates are different in OpenCV and VTK - vtkSmartPointer flipFilter = vtkSmartPointer::New(); - flipFilter->SetFilteredAxis(1); // Vertical flip - flipFilter->SetInputConnection(vtk_image->GetProducerPort()); - flipFilter->Update(); - - Vec3d plane_center(0.0, 0.0, scale); - - vtkSmartPointer plane = vtkSmartPointer::New(); - plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); - plane->SetNormal(0.0, 0.0, 1.0); - - vtkSmartPointer transform = vtkSmartPointer::New(); - transform->PreMultiply(); - transform->Translate(plane_center[0], plane_center[1], plane_center[2]); - transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0); - transform->RotateY(180.0); - transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); - - // Apply the texture - vtkSmartPointer texture = vtkSmartPointer::New(); - texture->SetInputConnection(flipFilter->GetOutputPort()); - - vtkSmartPointer texturePlane = vtkSmartPointer::New(); - texturePlane->SetInputConnection(plane->GetOutputPort()); - - vtkSmartPointer transform_filter = vtkSmartPointer::New(); - transform_filter->SetTransform(transform); - transform_filter->SetInputConnection(texturePlane->GetOutputPort()); - transform_filter->Update(); - - // Create frustum - camera->SetViewAngle(fovy); - camera->SetPosition(0.0,0.0,0.0); - camera->SetViewUp(0.0,1.0,0.0); - camera->SetFocalPoint(0.0,0.0,1.0); - camera->SetClippingRange(0.01, scale); - - double planesArray[24]; - camera->GetFrustumPlanes(aspect_ratio, planesArray); - - vtkSmartPointer planes = vtkSmartPointer::New(); - planes->SetFrustumPlanes(planesArray); - - vtkSmartPointer frustumSource = - vtkSmartPointer::New(); - frustumSource->SetPlanes(planes); - frustumSource->Update(); - - vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(frustumSource->GetOutput()); - filter->Update(); - - // Frustum needs to be textured or else it can't be combined with image - vtkSmartPointer frustum_texture = vtkSmartPointer::New(); - frustum_texture->SetInputConnection(filter->GetOutputPort()); - // Texture mapping with only one pixel from the image to have constant color - frustum_texture->SetSRange(0.0, 0.0); - frustum_texture->SetTRange(0.0, 0.0); - - vtkSmartPointer appendFilter = vtkSmartPointer::New(); - appendFilter->AddInputConnection(frustum_texture->GetOutputPort()); - appendFilter->AddInputConnection(transform_filter->GetOutputPort()); - - vtkSmartPointer planeMapper = vtkSmartPointer::New(); - planeMapper->SetInputConnection(appendFilter->GetOutputPort()); + vtkSmartPointer actor = vtkSmartPointer::New(); + ProjectImage::projectImage(fovy, far_end_height, image, scale, color, actor); + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, const Mat &image, double scale, const Color &color) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + float fovy = fov[1] * 180.0f / CV_PI; + float far_end_height = 2.0 * scale * tan(fov[1] * 0.5); vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(planeMapper); - actor->SetTexture(texture); - + ProjectImage::projectImage(fovy, far_end_height, image, scale, color, actor); WidgetAccessor::setProp(*this, actor); } From c773061457e18efda269f2d17b1605e6244672d7 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 8 Sep 2013 14:26:58 +0200 Subject: [PATCH 190/205] updated documentation --- modules/viz/doc/images/cpw1.png | Bin 0 -> 4321 bytes modules/viz/doc/images/cpw2.png | Bin 0 -> 3548 bytes modules/viz/doc/images/cpw3.png | Bin 0 -> 17724 bytes modules/viz/doc/images/cube_widget.png | Bin 0 -> 6507 bytes modules/viz/doc/viz3d.rst | 387 +- modules/viz/doc/widget.rst | 495 +- samples/cpp/bunny.ply | 5752 ++++++++++++++++++++++++ 7 files changed, 6337 insertions(+), 297 deletions(-) create mode 100644 modules/viz/doc/images/cpw1.png create mode 100644 modules/viz/doc/images/cpw2.png create mode 100644 modules/viz/doc/images/cpw3.png create mode 100644 modules/viz/doc/images/cube_widget.png create mode 100644 samples/cpp/bunny.ply diff --git a/modules/viz/doc/images/cpw1.png b/modules/viz/doc/images/cpw1.png new file mode 100644 index 0000000000000000000000000000000000000000..985b1eeaffbed1e207128eaa8167cde04d3dcf04 GIT binary patch literal 4321 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 literal 0 HcmV?d00001 diff --git a/modules/viz/doc/images/cpw2.png b/modules/viz/doc/images/cpw2.png new file mode 100644 index 0000000000000000000000000000000000000000..5733a6af6579373d6b9512b70cd5ada26b62db3d GIT binary patch literal 3548 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 literal 0 HcmV?d00001 diff --git a/modules/viz/doc/images/cpw3.png b/modules/viz/doc/images/cpw3.png new file mode 100644 index 0000000000000000000000000000000000000000..585b836b66ddfdbfa34219972f9c766eccb5f9d4 GIT binary patch literal 17724 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

gB=@dpOOp^?a9R9TDL$j)- zMXOuI1HZR%h@Qv%*6b@~Dzl3CHF6(_6hN@Pn5ESv@|UTNF@KR5V80 zeqQbSQC<-?VBq<9-g?orw&{7rquy$+mTtD{C~19`EHgAs3SMqCYfQ?quZO7#yGC)7v?)rzgR4l89MG2c zc&Yb1DNMd>9g-_Y4kOg4EhZj_ktSHNGYy~%Vy^kmRIhj(d z&buf!6zpinUc1qYuI4r+@U!IR$M)Kd32JEdzh=ywF6X~bnW6`%e<6b`H(9T}zuXz) zD$q|T>}Yg@sd+_BeP|SoT4NLA{cZCBrG4h@vc;=W_NJne>CAocLr%)#wx;ti_o!yLg0JF`UWOn$p=}DJU z%?I;CSdrj-t=YEw;}JYjK{1#Ka$D_L1^jzffBZ!U&v+(cb=>@Xeij+s!k#krUdGj$ zm~9$2TcjPL-o06qQP`G>{3q+!`5_L;+oS$}qLg~$)X%bVZYCX>?4((H@i|`c63jom zh0V&tZxPB-v*-&m#~Ca22gdsPL?smnHGF&@_j3x&VJLc+jL{3HsN%zr@Fq_AlKJ@UVEZVh9RXW1!)b9 zM0~m{XqT=B2mZ%z|p7*2`oMvA$r?AU+-ujC=p<7XAng1 z0YpJV{s-pzEytS|-Bvp|SBW%@Xzg%6YYLKysE)mfq^%z~+Xgx>|Ag-#$hu4VDlxy4 zl0Ds+=hN=vTCF*nrDc9wh?kUwEXw`kkhv!1+5eUnzS>kBu2e_5v#hXFF-FQzg2xO5?Aa> z@y*024CT%xeU`U0?%yyqxL+!2dhpHTl1Ga0)olCFQwY1HE5iR;{qAp%7Xk>( z-T>_vs2fT9Xtqhm?<_y^+maaLL@?GH7(+n zLK35fg@W_1t*yL6RH$WcGRxSadQE>|m`qki|=%l-| zbE8`l1FP|9LdDo|Of5Mb9ab1`2m-E4Al4$W;Zh4Ffu@GWasBRM01_{|@8`SqTGPy{ zor$C&uh|P*0aWFO0Mx%hBmSjv(3<8=V*gSLKBC9&6wAX&1OrCpCdcxa*8Gk&q9%X^k`+j=Go`4zw znStr%je*87etcKBikbN<5?9~R{$EpQaDLS8AkOBhC3vQFJem40lvDBIaj2dq>wtOl z{Sc$jV^KK?TO$7*hV|7Ri4z}zz#kx^9DMiFLRZ~ee4*`mc?Mfu-Z6hI#X1`s8^e;~ zl5Ue0GB4HKjjNgj{L0|vgu&Q%p})P&zK8UGc|TypNB51%$#Nk%Hk~wA=r|b{h=`2V z;25HjNe?5>MB>M83Jf+m`xeH}dc&t)V~c-y-QC^MwH@a{;k)tAPoyvyj>P@U7mGg3 zkot$1Q&1p`j_-9XpnwhNfOiMNk$9iCX*8RL6RgIU!6dYgXV(#6js0(OzFL;f0fA8j z`~$6by4QzChBKx+_eBt{P#IGrfBvG;&$XtB=0_Qpf~}d2T(ccBaQ!hSTN1%Zq!W|9 zx;j8v_!v4bl}3ykKJfW|#5XnuWb`wk5Jd002{v*bB<7Ltxl4C_KBVz!i`Y zD~RDe01)zX>gzqaq_m`j{i0!x->nzn#pss7TNW_ELA) z=yfcK{ZZ!Uj~QKc^*__j2U^dA+aFz)78V8N(uDg<>$>9tro(eYj^Ae48eYffQvs|; zQJfLiMyOB-yipo_GV+=@_RKiw58wA2648hh7R$xb;;c5e8v~Hq-_l;nA^MaW4P=>! zdapawqz!eemsatf%rZP%un*2@uLw#8b8J3O?W6KcL#1TXA|7yRIMCJKn&(K3Ch31s z$*ZYBZ6_$nGWcF%U|;|p(rE5mXlp*8ch6ur7&_Q%inz_S^)d+x^@DJ94?ypSDTbe) zPu<{d2Z?I3+&97swmYoqH$}0ee<^In!HO{LuK%6yMeB1CORLNuz~{Yk!|#wqF&kERi-7H7e#Are81hHLx(zjBAQJTqTiH_0#w2 z&3~+M=bU%jjhWcuO=@E2QyJZAHt2hH z_jZ@9S#pKcgS~8;9mGD~i1l)?YcR<%l>uM}o*#~gg!s{7`3i$6d+sKJ^c}#G&UpNS zWvP~+7OP4?yvQ-TdpXLs{korv4niA`_<+ZcE25c;rLVSI){k3IElxwV2HUQms&TJB zXg5>mTywcfillM;^L;w6qq!!gkbq&vSrC0Q^4;SU5kpdc3Dt;va( z7G`QCF`mv5pi--vrv&1Z>0}1Q<6k9TT&v9o<^UabG2@>H-Ix8W*~p2#H&}IAU9NN{ z6R@^$qHJ96s#W;(WGPYdFNp%E~y{pobm8+Xu`fYy|))|lWAFQ`J@;z?{gy4G|18t9lC^irJ=lN14I5;?6&kGi&B>lU?2`<;m z0w!pZoJ1#y^}r72S&53=f7OqlEO>eipdg=*Yv-*;HHJ`8JeVMB?a2&~gUc#vwSYP^ zaJgu*`k|;{r2*#Pz-zU^90%8B1`F7Rgri+W>M{=Z&8N_zJ)jL)z_H9+yt+RUFXFcv z$+r1C&NS5%v%lLDu)3)DGWlJc|&2a@6SVgyf6FlmX?+WT{kM_s$n?(=AL{bzD{2< zq$RS^+7KXKZ)>VJQkmATtBH#(jTnRIdN0R*p8_dUh&X+Wjy%$N*(WqRZkydDWn~`k zH$x)ouj5CPnN<5Hz-CW~0XQ@mfdJ7@v@+XyQGJ(hx4HYn8fSvla1dSz9g1R3;D#RT z>m~b;vVp>!;@qB2_&ZePkb3rmwq;Nd&Uc`&rMOSBZ{mg6fIi{g&2w|tLuLFgIaPF%LG0^Q%W9c4W(igsOG`9vD0y97 zAQ?#On}-+PdcQqNX!4MLfU}v=omHNhT7OD5`ZX1a7}F_pSizcB+TN+BC}*=pFD(L< zK-US0V_`GQucN3lYu?hD*%!IXNINFJyc&_3PAqG0V3~dYXLAurAW+Nhhk!{H!yYy`zrJ z>XlFeY}sb=#N&R+Ivx^QI?f9!dHguEolZv?j#1}3xgq#*=7}HH_*uFeTBym%PXDYH zKF%BF%%tI*6N8@nQ0$U%AQ1kF^XH#Hm&O*rBwyFw?*b9Nqoh zf1A*LLX&GP>CAnFBAh={Rz~^HjzatAl*q(%u8@dfS}+P^-_x2c-wolz_!vFABY0|8 zYJ|8mMc>_>l724aFLl2hMEfR&#$e0@wFsQPSuSJ_k{FWz8J>FRw3DxAs&X+;9iGqg z&aJAD5I8i`QiZzEhWV~QX;m~HS5sl3@h4D1A5F1s;i7vXvK$}u!YOFNCH|d<674)r zI9;rx7}p=Y774G@@UI)`4mJeq9040hY z%o~1ffcgLe z!xJEC0f}JP$ulf7;dMHe|GuT6t^kS~Iq}n8cHGvV;N4Fq?c4DwbH^BBrnSb?YNawj zx!Z61uaLGeAQv=4HotUm0j=qUx*|BcZ8g`ek5Q`Xl;#qjstY2lpyo{vsdEi~YwPtk znjgYtj&!Uho7_!?Vw|(sCotCTFn*EW2a;(FQyY1Msh=qM6$$e*Xlerc-R0%3ub*p_ zwSd9qbUfYG#u-k4h^&8+?LAml786`QQPB1W0?zJ!rqn?c4?l?vGQ$BMEZKn>wz^H*KC4-dS}OsrTI>_0kb?EYPxrza6%dQyJfXm|ZOH|0Z1 zto=RSCYY6+?0VJtQe)xy#CJayZ? z3<6@Ve*sXYRse6y?%|3Ubwmc#s_yQs&>jr`I$5ki%Uw54o#&468hRl04n`9LAQ2=x zX(Q)?*lhY|#PUm^X=unPKzp7p3^ym824u)hO01m9VAu~j9PK>X!+?3s>1lfZZ&k3v z*ov*|jTQ@(cQ@MYE+e-9;zDx6(SQaf)CB1c(pr0dCTj_9nIQ_TAvxZTc5|zy}FAE`sA;{-0fGQb2`(RO64H zRMRXNzf$!%&7d@JD(EkE-XEUo)HVhUwhK*g>u zdvCM|ooNNlDcHn&{e*ae=V-o5qiyiLgn8}XP4Oi^2&$&P_4vN;5kzA%2&%Hi{5Y;7 zsFWV5Hg?Ttsk2uNw*howgg>Sr`uIqWaOBGfJdShecY8~Zc@0;Y6@E9EpvOSVAPk4vlDvRT>XL{} zfGwVW5EcMcaBv43$+|x3zNPwZbDHwTEg2r9SM?fBeKYN940`b+$~+(Uk1UosG~=Q1 z!J*^pGR$|`ZfP8b5u7_$-Cv*At{0n~nn_y#w+wP|ap8dEzT9PB_xG^;VAgBfOEBqw z?|}fR7Z+CM=GB+RGCNxo6J;;L#J2~p5TlL>aeI5GKde&*aSq(8?o*8K73Jt1(4hm; z+;lDO{IZrqzWV2#Pz!lQt&EG}Ee?+-3P|*+v)!A>?hhJhec?_m_c%BczLya>(utCt zPO}-}3w5{TyrRy|OwOa*yE`01-?z1`{z9V`b1cI7l|g@Cdhvf6JT51Q?^BM>N){V) za<p4yo>a;{xIoJbE34^K@ikkJEx+ta!u(j6+3e5i2vA#syx5)m!1H+hH2 z-S34~OjgVEE3;cW)-5a89MBT)=@-u({1&l8ofz~iz~>+z{u{2Xu7OTzt6#)%WYzUMyAh4pVd5=^lE{oSixQL{^O zW1(df`^kt`yz`tALr#{nnRAUyHX{YNf@5EJ*n3};5hqrul_HkD(aG&w{z`KHr+mz| zon>p1)A;S%zGHMdd_sOnIkkxcgqx&ny@V{MY^`|~)9Z##G z31g~T7s0L8=}dE^-5VhQt_4Ke8fW!|g(67}MFo0oi~3_!P(hsdqA42*?iC znyk_81_Ebie`UE5$A776`{ldZ5Qn<~C0V0>AEe`582MB>TQs9qK+F{MZTZ@xb2x<_ zKtcYDDEWD{#L$p#9Lp0Q%op{afT5e=`un1K4Mc z@IyU;&Q7%My8;Nvx90yo7hwMp7?w^klx6Ynh)QSQ$K1VfFH^;_l0ExsNs2K^XBWA z?k6!VK$R9+%Ir3+*)XB8ZaGfz92^|1qyWf+{e;IZ)<1n}V%iDx^5U5LVP46w7Legm z4MpLlw~3_jyq(wAQ8Q&r^&8aw7gjY6fND~f=V3kr9Z(ay@CV;$1s8=&(RBYkq{$D7 zu*)eem3VZ#Xk41LA@F(DpYs4Z9cyBd-xCdiq5~Lb=B?nqO4bjpVO@5hRHAS60t|I@ z%zkfhWrt!7zclI4Y|l5R47`L6|QI7@^S<|mOvw$ZQZVKMvTCE z#VIKqc#z|7uR%w|b_;1r>L&KvJ%Hg#+5))1`et`PLk$2CxO_ex*L}(8ShibTJRvMV zS#BFrr9YNLV{qejwpeL66lHB?WfUPo9IG?>;~n7mM2TaGghDhP>}rYLPs^(}+g+X!3y?NBKcDw@M!tZ}snl*~T~opfAz8}1{_*;M#$7A$#R@n!adP>bLp@&& z7#{4|y7lWNZ++gXGT`{u{onV#uSlBj4IBx406K%9f$cEk3*O3qpHAyfpE5_+0V zPZG&G`ugveO!nK%-`fj^Uxd!{ZaXa%Kf}1}K!>2( z;q$iN?--x6a9-vh*7hA30Yyf@5G-D6`9-WMGdL?Yb}lfzUkfM&6)*+=em?*IfZd+K zcg`H=%rn+4ptBkJ(tDn2yDYT$ z-T&2B-p{i9g+K80jsD}0^Y{Hs1FnUh`Yt63t50!3OH1o%4>QewNjyF zQvmR^f(Z*>giPX8JiL8!vEUTl)SgaZ54ICkGmbFKIw`YB_T`Dsw{G21khHttVm{|f z*$Jg3lYN%0TJ`GVarx=bCwSQLI{+8x=C|j#R2a={YisM3Hg~!!Iqxv%RVU!e%?U?2 zZq?{*T6Q{(Ik@ET&3k-1TY%dtJ6%?-Uj6vvjuY$E4&7o~aP{qj37dgqRu?lubV}-f zJZxtU&=oHTp5?6Ptha=Bjzb7L-9Y=9qyO1!m5)w)^J=p%@ca`7Pgg&ebxsLQ0QrLz AnE(I) literal 0 HcmV?d00001 diff --git a/modules/viz/doc/images/cube_widget.png b/modules/viz/doc/images/cube_widget.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe56811aedb6fc57e77097e6b2840cdd6bb64e4 GIT binary patch literal 6507 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 V6?X0&0K6`tFw`^Ct<-jn{U22ce2xGB literal 0 HcmV?d00001 diff --git a/modules/viz/doc/viz3d.rst b/modules/viz/doc/viz3d.rst index b2e2d4914..1aff05150 100644 --- a/modules/viz/doc/viz3d.rst +++ b/modules/viz/doc/viz3d.rst @@ -1,10 +1,145 @@ -Viz3d -===== +Viz +=== .. highlight:: cpp -Viz3d ------ +This section describes 3D visualization window as well as classes and methods +that are used to interact with it. + +3D visualization window (see :ocv:class:`Viz3d`) is used to display widgets (see :ocv:class:`Widget`), and it provides +several methods to interact with scene and widgets. + +viz::makeTransformToGlobal +-------------------------- +Takes coordinate frame data and builds transform to global coordinate frame. + +.. ocv:function:: Affine3f viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)) + + :param axis_x: X axis vector in global coordinate frame. + :param axis_y: Y axis vector in global coordinate frame. + :param axis_z: Z axis vector in global coordinate frame. + :param origin: Origin of the coordinate frame in global coordinate frame. + +This function returns affine transform that describes transformation between global coordinate frame and a given coordinate frame. + +viz::makeCameraPose +------------------- +Constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation). + +.. ocv:function:: Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir) + + :param position: Position of the camera in global coordinate frame. + :param focal_point: Focal point of the camera in global coordinate frame. + :param y_dir: Up vector of the camera in global coordinate frame. + +This function returns pose of the camera in global coordinate frame. + +viz::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::isNan +---------- +Checks **float/double** value for nan. + + .. ocv:function:: bool isNan(float x) + + .. ocv:function:: bool isNan(double x) + + :param x: return true if nan. + +Checks **vector** for nan. + + .. ocv:function:: bool isNan(const Vec<_Tp, cn>& v) + + :param v: return true if **any** of the elements of the vector is *nan*. + +Checks **point** for nan + + .. ocv:function:: bool isNan(const Point3_<_Tp>& p) + + :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 The Viz3d class represents a 3D visualizer window. This class is implicitly shared. :: @@ -62,41 +197,39 @@ The Viz3d class represents a 3D visualizer window. This class is implicitly shar void setDesiredUpdateRate(double rate); double getDesiredUpdateRate(); - void setRepresentationToSurface(); - void setRepresentationToWireframe(); - void setRepresentationToPoints(); + void setRepresentation(int representation); private: /* hidden */ }; -Viz3d::Viz3d ------------- +viz::Viz3d::Viz3d +----------------- The constructors. .. ocv:function:: Viz3d::Viz3d(const String& window_name = String()) :param window_name: Name of the window. -Viz3d::showWidget ------------------ +viz::Viz3d::showWidget +---------------------- Shows a widget in the window. .. ocv:function:: void Viz3d::showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()) :param id: A unique id for the widget. - :param widget: The widget to be rendered in the window. + :param widget: The widget to be displayed in the window. :param pose: Pose of the widget. -Viz3d::removeWidget -------------------- +viz::Viz3d::removeWidget +------------------------ Removes a widget from the window. .. ocv:function:: void removeWidget(const String &id) :param id: The id of the widget that will be removed. -Viz3d::getWidget ----------------- +viz::Viz3d::getWidget +--------------------- Retrieves a widget from the window. A widget is implicitly shared; that is, if the returned widget is modified, the changes will be immediately visible in the window. @@ -105,14 +238,14 @@ immediately visible in the window. :param id: The id of the widget that will be returned. -Viz3d::removeAllWidgets ------------------------ +viz::Viz3d::removeAllWidgets +---------------------------- Removes all widgets from the window. .. ocv:function:: void removeAllWidgets() -Viz3d::setWidgetPose --------------------- +viz::Viz3d::setWidgetPose +------------------------- Sets pose of a widget in the window. .. ocv:function:: void setWidgetPose(const String &id, const Affine3f &pose) @@ -120,8 +253,8 @@ Sets pose of a widget in the window. :param id: The id of the widget whose pose will be set. :param pose: The new pose of the widget. -Viz3d::updateWidgetPose ------------------------ +viz::Viz3d::updateWidgetPose +---------------------------- Updates pose of a widget in the window by pre-multiplying its current pose. .. ocv:function:: void updateWidgetPose(const String &id, const Affine3f &pose) @@ -129,58 +262,58 @@ Updates pose of a widget in the window by pre-multiplying its current pose. :param id: The id of the widget whose pose will be updated. :param pose: The pose that the current pose of the widget will be pre-multiplied by. -Viz3d::getWidgetPose --------------------- +viz::Viz3d::getWidgetPose +------------------------- Returns the current pose of a widget in the window. .. ocv:function:: Affine3f getWidgetPose(const String &id) const :param id: The id of the widget whose pose will be returned. -Viz3d::setCamera ----------------- +viz::Viz3d::setCamera +--------------------- Sets the intrinsic parameters of the viewer using Camera. .. ocv:function:: void setCamera(const Camera &camera) :param camera: Camera object wrapping intrinsinc parameters. -Viz3d::getCamera ----------------- +viz::Viz3d::getCamera +--------------------- Returns a camera object that contains intrinsic parameters of the current viewer. .. ocv:function:: Camera getCamera() const -Viz3d::getViewerPose --------------------- +viz::Viz3d::getViewerPose +------------------------- Returns the current pose of the viewer. ..ocv:function:: Affine3f getViewerPose() -Viz3d::setViewerPose --------------------- +viz::Viz3d::setViewerPose +------------------------- Sets pose of the viewer. .. ocv:function:: void setViewerPose(const Affine3f &pose) :param pose: The new pose of the viewer. -Viz3d::resetCameraViewpoint ---------------------------- +viz::Viz3d::resetCameraViewpoint +-------------------------------- Resets camera viewpoint to a 3D widget in the scene. .. ocv:function:: void resetCameraViewpoint (const String &id) :param pose: Id of a 3D widget. -Viz3d::resetCamera ------------------- +viz::Viz3d::resetCamera +----------------------- Resets camera. .. ocv:function:: void resetCamera() -Viz3d::convertToWindowCoordinates ---------------------------------- +viz::Viz3d::convertToWindowCoordinates +-------------------------------------- Transforms a point in world coordinate system to window coordinate system. .. ocv:function:: void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) @@ -188,8 +321,8 @@ Transforms a point in world coordinate system to window coordinate system. :param pt: Point in world coordinate system. :param window_coord: Output point in window coordinate system. -Viz3d::converTo3DRay --------------------- +viz::Viz3d::converTo3DRay +------------------------- Transforms a point in window coordinate system to a 3D ray in world coordinate system. .. ocv:function:: void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) @@ -198,36 +331,36 @@ Transforms a point in window coordinate system to a 3D ray in world coordinate s :param origin: Output origin of the ray. :param direction: Output direction of the ray. -Viz3d::getWindowSize --------------------- +viz::Viz3d::getWindowSize +------------------------- Returns the current size of the window. .. ocv:function:: Size getWindowSize() const -Viz3d::setWindowSize --------------------- +viz::Viz3d::setWindowSize +------------------------- Sets the size of the window. .. ocv:function:: void setWindowSize(const Size &window_size) :param window_size: New size of the window. -Viz3d::getWindowName --------------------- +viz::Viz3d::getWindowName +------------------------- Returns the name of the window which has been set in the constructor. .. ocv:function:: String getWindowName() const -Viz3d::saveScreenshot ---------------------- +viz::Viz3d::saveScreenshot +-------------------------- Saves screenshot of the current scene. .. ocv:function:: void saveScreenshot(const String &file) :param file: Name of the file. -Viz3d::setWindowPosition ------------------------- +viz::Viz3d::setWindowPosition +----------------------------- Sets the position of the window in the screen. .. ocv:function:: void setWindowPosition(int x, int y) @@ -235,28 +368,28 @@ Sets the position of the window in the screen. :param x: x coordinate of the window :param y: y coordinate of the window -Viz3d::setFullScreen --------------------- +viz::Viz3d::setFullScreen +------------------------- Sets or unsets full-screen rendering mode. .. ocv:function:: void setFullScreen(bool mode) :param mode: If true, window will use full-screen mode. -Viz3d::setBackgroundColor -------------------------- +viz::Viz3d::setBackgroundColor +------------------------------ Sets background color. .. ocv:function:: void setBackgroundColor(const Color& color = Color::black()) -Viz3d::spin ------------ +viz::Viz3d::spin +---------------- The window renders and starts the event loop. .. ocv:function:: void spin() -Viz3d::spinOnce ---------------- +viz::Viz3d::spinOnce +-------------------- Starts the event loop for a given time. .. ocv:function:: void spinOnce(int time = 1, bool force_redraw = false) @@ -264,32 +397,32 @@ Starts the event loop for a given time. :param time: Amount of time in milliseconds for the event loop to keep running. :param force_draw: If true, window renders. -Viz3d::wasStopped ------------------ +viz::Viz3d::wasStopped +---------------------- Returns whether the event loop has been stopped. .. ocv:function:: bool wasStopped() -Viz3d::registerKeyboardCallback -------------------------------- +viz::Viz3d::registerKeyboardCallback +------------------------------------ Sets keyboard handler. .. ocv:function:: void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0) - :param callback: Keyboard callback. + :param callback: Keyboard callback ``(void (*KeyboardCallbackFunction(const KeyboardEvent&, void*))``. :param cookie: The optional parameter passed to the callback. -Viz3d::registerMouseCallback ----------------------------- +viz::Viz3d::registerMouseCallback +--------------------------------- Sets mouse handler. .. ocv:function:: void registerMouseCallback(MouseCallback callback, void* cookie = 0) - :param callback: Mouse callback. + :param callback: Mouse callback ``(void (*MouseCallback)(const MouseEvent&, void*))``. :param cookie: The optional parameter passed to the callback. -Viz3d::setRenderingProperty ---------------------------- +viz::Viz3d::setRenderingProperty +-------------------------------- Sets rendering property of a widget. .. ocv:function:: void setRenderingProperty(const String &id, int property, double value) @@ -298,49 +431,79 @@ Sets rendering property of a widget. :param property: Property that will be modified. :param value: The new value of the property. -Viz3d::getRenderingProperty ---------------------------- + **Rendering property** can be one of the following: + + * **POINT_SIZE** + * **OPACITY** + * **LINE_WIDTH** + * **FONT_SIZE** + * **REPRESENTATION**: Expected values are + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + * **IMMEDIATE_RENDERING**: + * Turn on immediate rendering by setting the value to ``1``. + * Turn off immediate rendering by setting the value to ``0``. + * **SHADING**: Expected values are + * **SHADING_FLAT** + * **SHADING_GOURAUD** + * **SHADING_PHONG** + +viz::Viz3d::getRenderingProperty +-------------------------------- Returns rendering property of a widget. .. ocv:function:: double getRenderingProperty(const String &id, int property) :param id: Id of the widget. :param property: Property. + + **Rendering property** can be one of the following: + + * **POINT_SIZE** + * **OPACITY** + * **LINE_WIDTH** + * **FONT_SIZE** + * **REPRESENTATION**: Expected values are + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + * **IMMEDIATE_RENDERING**: + * Turn on immediate rendering by setting the value to ``1``. + * Turn off immediate rendering by setting the value to ``0``. + * **SHADING**: Expected values are + * **SHADING_FLAT** + * **SHADING_GOURAUD** + * **SHADING_PHONG** -Viz3d::setDesiredUpdateRate ---------------------------- +viz::Viz3d::setDesiredUpdateRate +-------------------------------- Sets desired update rate of the window. .. ocv:function:: void setDesiredUpdateRate(double rate) :param rate: Desired update rate. The default is 30. -Viz3d::getDesiredUpdateRate ---------------------------- +viz::Viz3d::getDesiredUpdateRate +-------------------------------- Returns desired update rate of the window. .. ocv:function:: double getDesiredUpdateRate() -Viz3d::setRepresentationToSurface ---------------------------------- -Sets geometry representation of the widgets to surface. +viz::Viz3d::setRepresentation +----------------------------- +Sets geometry representation of the widgets to surface, wireframe or points. -.. ocv:function:: void setRepresentationToSurface() +.. ocv:function:: void setRepresentation(int representation) -Viz3d::setRepresentationToWireframe ------------------------------------ -Sets geometry representation of the widgets to wireframe. - -.. ocv:function:: void setRepresentationToWireframe() - -Viz3d::setRepresentationToPoints --------------------------------- -Sets geometry representation of the widgets to points. - -.. ocv:function:: void setRepresentationToPoints() - -Color ------ + :param representation: Geometry representation which can be one of the following: + + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + +viz::Color +---------- .. ocv:class:: Color This class a represents BGR color. :: @@ -367,8 +530,8 @@ This class a represents BGR color. :: static Color gray(); }; -Mesh3d ------- +viz::Mesh3d +----------- .. ocv:class:: Mesh3d This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. :: @@ -387,8 +550,8 @@ This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. :: /* hidden */ }; -Mesh3d::loadMesh ----------------- +viz::Mesh3d::loadMesh +--------------------- Loads a mesh from a ``ply`` file. .. ocv:function:: static Mesh3d loadMesh(const String& file) @@ -396,8 +559,8 @@ Loads a mesh from a ``ply`` file. :param file: File name. -KeyboardEvent -------------- +viz::KeyboardEvent +------------------ .. ocv:class:: KeyboardEvent This class represents a keyboard event. :: @@ -427,8 +590,8 @@ This class represents a keyboard event. :: /* hidden */ }; -KeyboardEvent::KeyboardEvent ----------------------------- +viz::KeyboardEvent::KeyboardEvent +--------------------------------- Constructs a KeyboardEvent. .. ocv:function:: KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift) @@ -440,8 +603,8 @@ Constructs a KeyboardEvent. :param ctrl: If true, ``ctrl`` is pressed. :param shift: If true, ``shift`` is pressed. -MouseEvent ----------- +viz::MouseEvent +--------------- .. ocv:class:: MouseEvent This class represents a mouse event. :: @@ -460,8 +623,8 @@ This class represents a mouse event. :: unsigned int key_state; }; -MouseEvent::MouseEvent ----------------------- +viz::MouseEvent::MouseEvent +--------------------------- Constructs a MouseEvent. .. ocv:function:: MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift) @@ -473,8 +636,8 @@ Constructs a MouseEvent. :param ctrl: If true, ``ctrl`` is pressed. :param shift: If true, ``shift`` is pressed. -Camera ------- +viz::Camera +----------- .. ocv:class:: Camera This class wraps intrinsic parameters of a camera. It provides several constructors @@ -509,8 +672,8 @@ that can extract the intrinsic parameters from ``field of view``, ``intrinsic ma /* hidden */ }; -Camera::Camera --------------- +viz::Camera::Camera +------------------- Constructs a Camera. .. ocv:function:: Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size) @@ -538,16 +701,16 @@ Constructs a Camera. :param proj: Projection matrix of the camera. :param window_size: Size of the window. This together with projection matrix determines the field of view. -Camera::computeProjectionMatrix -------------------------------- +viz::Camera::computeProjectionMatrix +------------------------------------ Computes projection matrix using intrinsic parameters of the camera. .. ocv:function:: void computeProjectionMatrix(Matx44f &proj) const :param proj: Output projection matrix. -Camera::KinectCamera --------------------- +viz::Camera::KinectCamera +------------------------- Creates a Kinect Camera. .. ocv:function:: static Camera KinectCamera(const Size &window_size) diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index bf724956d..ef1e82868 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -3,13 +3,29 @@ Widget .. highlight:: cpp -In this section, the built-in widgets are presented. +In this section, the widget framework is explained. Widgets represent +2D or 3D objects, varying from simple ones such as lines to complex one such as +point clouds and meshes. -Widget ------- +Widgets are **implicitly shared**. Therefore, one can add a widget to the scene, +and modify the widget without re-adding the widget. + +.. code-block:: cpp + + ... + /// Create a cloud widget + viz::CloudWidget cw(cloud, viz::Color::red()); + /// Display it in a window + myWindow.showWidget("CloudWidget1", cw); + /// Modify it, and it will be modified in the window. + cw.setColor(viz::Color::yellow()); + ... + +viz::Widget +----------- .. ocv:class:: Widget -Base class of all widgets. Widget is implicitly shared.:: +Base class of all widgets. Widget is implicitly shared. :: class CV_EXPORTS Widget { @@ -32,16 +48,16 @@ Base class of all widgets. Widget is implicitly shared.:: /* hidden */ }; -Widget::fromPlyFile -------------------- +viz::Widget::fromPlyFile +------------------------ Creates a widget from ply file. .. ocv:function:: static Widget fromPlyFile(const String &file_name) :param file_name: Ply file name. -Widget::setRenderingProperty ----------------------------- +viz::Widget::setRenderingProperty +--------------------------------- Sets rendering property of the widget. .. ocv:function:: void setRenderingProperty(int property, double value) @@ -49,22 +65,67 @@ Sets rendering property of the widget. :param property: Property that will be modified. :param value: The new value of the property. -Widget::getRenderingProperty ----------------------------- + **Rendering property** can be one of the following: + + * **POINT_SIZE** + * **OPACITY** + * **LINE_WIDTH** + * **FONT_SIZE** + * **REPRESENTATION**: Expected values are + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + * **IMMEDIATE_RENDERING**: + * Turn on immediate rendering by setting the value to ``1``. + * Turn off immediate rendering by setting the value to ``0``. + * **SHADING**: Expected values are + * **SHADING_FLAT** + * **SHADING_GOURAUD** + * **SHADING_PHONG** + +viz::Widget::getRenderingProperty +--------------------------------- Returns rendering property of the widget. .. ocv:function:: double getRenderingProperty(int property) const :param property: Property. -Widget::cast ------------- + **Rendering property** can be one of the following: + + * **POINT_SIZE** + * **OPACITY** + * **LINE_WIDTH** + * **FONT_SIZE** + * **REPRESENTATION**: Expected values are + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + * **IMMEDIATE_RENDERING**: + * Turn on immediate rendering by setting the value to ``1``. + * Turn off immediate rendering by setting the value to ``0``. + * **SHADING**: Expected values are + * **SHADING_FLAT** + * **SHADING_GOURAUD** + * **SHADING_PHONG** + +viz::Widget::cast +----------------- Casts a widget to another. .. ocv:function:: template _W cast() -WidgetAccessor --------------- +.. code-block:: cpp + + // Create a sphere widget + viz::SphereWidget sw(Point3f(0.0f,0.0f,0.0f), 0.5f); + // Cast sphere widget to cloud widget + viz::CloudWidget cw = sw.cast(); + +.. note:: 3D Widgets can only be cast to 3D Widgets. 2D Widgets can only be cast to 2D Widgets. + +viz::WidgetAccessor +------------------- .. ocv:class:: WidgetAccessor This class is for users who want to develop their own widgets using VTK library API. :: @@ -75,8 +136,31 @@ This class is for users who want to develop their own widgets using VTK library static void setProp(Widget &widget, vtkSmartPointer prop); }; -Widget3D --------- +viz::WidgetAccessor::getProp +---------------------------- +Returns ``vtkProp`` of a given widget. + +.. ocv:function:: static vtkSmartPointer getProp(const Widget &widget) + + :param widget: Widget whose ``vtkProp`` is to be returned. + +.. note:: vtkProp has to be down cast appropriately to be modified. + + .. code-block:: cpp + + vtkActor * actor = vtkActor::SafeDownCast(viz::WidgetAccessor::getProp(widget)); + +viz::WidgetAccessor::setProp +---------------------------- +Sets ``vtkProp`` of a given widget. + +.. ocv:function:: static void setProp(Widget &widget, vtkSmartPointer prop) + + :param widget: Widget whose ``vtkProp`` is to be set. + :param prop: A ``vtkProp``. + +viz::Widget3D +------------- .. ocv:class:: Widget3D Base class of all 3D widgets. :: @@ -95,38 +179,38 @@ Base class of all 3D widgets. :: /* hidden */ }; -Widget3D::setPose ------------------ +viz::Widget3D::setPose +---------------------- Sets pose of the widget. .. ocv:function:: void setPose(const Affine3f &pose) :param pose: The new pose of the widget. -Widget3D::updateWidgetPose --------------------------- +viz::Widget3D::updateWidgetPose +------------------------------- Updates pose of the widget by pre-multiplying its current pose. .. ocv:function:: void updateWidgetPose(const Affine3f &pose) :param pose: The pose that the current pose of the widget will be pre-multiplied by. -Widget3D::getPose ------------------ +viz::Widget3D::getPose +---------------------- Returns the current pose of the widget. .. ocv:function:: Affine3f getWidgetPose() const -Widget3D::setColor ------------------- +viz::Widget3D::setColor +----------------------- Sets the color of the widget. .. ocv:function:: void setColor(const Color &color) - :param color: Color + :param color: color of type :ocv:class:`Color` -Widget2D --------- +viz::Widget2D +------------- .. ocv:class:: Widget2D Base class of all 2D widgets. :: @@ -139,16 +223,16 @@ Base class of all 2D widgets. :: void setColor(const Color &color); }; -Widget2D::setColor ------------------- +viz::Widget2D::setColor +----------------------- Sets the color of the widget. .. ocv:function:: void setColor(const Color &color) - :param color: Color + :param color: color of type :ocv:class:`Color` -LineWidget ----------- +viz::LineWidget +--------------- .. ocv:class:: LineWidget This 3D Widget defines a finite line. :: @@ -159,18 +243,18 @@ This 3D Widget defines a finite line. :: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); }; -LineWidget::LineWidget ----------------------- +viz::LineWidget::LineWidget +--------------------------- Constructs a LineWidget. .. ocv:function:: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()) :param pt1: Start point of the line. :param pt2: End point of the line. - :param color: Color of the line. + :param color: :ocv:class:`Color` of the line. -PlaneWidget ------------ +viz::PlaneWidget +---------------- .. ocv:class:: PlaneWidget This 3D Widget defines a finite plane. :: @@ -184,24 +268,25 @@ This 3D Widget defines a finite plane. :: /* hidden */ }; -PlaneWidget::PlaneWidget ------------------------- +viz::PlaneWidget::PlaneWidget +----------------------------- Constructs a PlaneWidget. .. ocv:function:: PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()) :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. :param size: Size of the plane. - :param color: Color of the plane. + :param color: :ocv:class:`Color` of the plane. .. ocv:function:: PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()) :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. :param pt: Position of the plane. - :param color: Color of the plane. + :param size: Size of the plane. + :param color: :ocv:class:`Color` of the plane. -SphereWidget ------------- +viz::SphereWidget +----------------- .. ocv:class:: SphereWidget This 3D Widget defines a sphere. :: @@ -212,8 +297,8 @@ This 3D Widget defines a sphere. :: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) }; -SphereWidget::SphereWidget --------------------------- +viz::SphereWidget::SphereWidget +------------------------------- Constructs a SphereWidget. .. ocv:function:: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) @@ -221,10 +306,10 @@ Constructs a SphereWidget. :param center: Center of the sphere. :param radius: Radius of the sphere. :param sphere_resolution: Resolution of the sphere. - :param color: Color of the sphere. + :param color: :ocv:class:`Color` of the sphere. -ArrowWidget ------------ +viz::ArrowWidget +---------------- .. ocv:class:: ArrowWidget This 3D Widget defines an arrow. :: @@ -235,8 +320,8 @@ This 3D Widget defines an arrow. :: ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); }; -ArrowWidget::ArrowWidget ------------------------- +viz::ArrowWidget::ArrowWidget +----------------------------- Constructs an ArrowWidget. .. ocv:function:: ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()) @@ -244,12 +329,12 @@ Constructs an ArrowWidget. :param pt1: Start point of the arrow. :param pt2: End point of the arrow. :param thickness: Thickness of the arrow. Thickness of arrow head is also adjusted accordingly. - :param color: Color of the arrow. + :param color: :ocv:class:`Color` of the arrow. Arrow head is located at the end point of the arrow. -CircleWidget ------------- +viz::CircleWidget +----------------- .. ocv:class:: CircleWidget This 3D Widget defines a circle. :: @@ -260,8 +345,8 @@ This 3D Widget defines a circle. :: CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); }; -CircleWidget::CircleWidget --------------------------- +viz::CircleWidget::CircleWidget +------------------------------- Constructs a CircleWidget. .. ocv:function:: CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()) @@ -269,10 +354,10 @@ Constructs a CircleWidget. :param pt: Center of the circle. :param radius: Radius of the circle. :param thickness: Thickness of the circle. - :param color: Color of the circle. + :param color: :ocv:class:`Color` of the circle. -CylinderWidget --------------- +viz::CylinderWidget +------------------- .. ocv:class:: CylinderWidget This 3D Widget defines a cylinder. :: @@ -283,8 +368,8 @@ This 3D Widget defines a cylinder. :: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()); }; -CylinderWidget::CylinderWidget ------------------------------- +viz::CylinderWidget::CylinderWidget +----------------------------------- Constructs a CylinderWidget. .. ocv:function:: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()) @@ -293,10 +378,10 @@ Constructs a CylinderWidget. :param axis_direction: Direction of the axis of the cylinder. :param radius: Radius of the cylinder. :param numsides: Resolution of the cylinder. - :param color: Color of the cylinder. + :param color: :ocv:class:`Color` of the cylinder. -CubeWidget ----------- +viz::CubeWidget +--------------- .. ocv:class:: CubeWidget This 3D Widget defines a cube. :: @@ -307,8 +392,8 @@ This 3D Widget defines a cube. :: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); }; -CubeWidget::CubeWidget ----------------------- +viz::CubeWidget::CubeWidget +--------------------------- Constructs a CudeWidget. .. ocv:function:: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()) @@ -316,10 +401,14 @@ Constructs a CudeWidget. :param pt_min: Specifies minimum point of the bounding box. :param pt_max: Specifies maximum point of the bounding box. :param wire_frame: If true, cube is represented as wireframe. - :param color: Color of the cube. + :param color: :ocv:class:`Color` of the cube. -CoordinateSystemWidget ----------------------- +.. image:: images/cube_widget.png + :alt: Cube Widget + :align: center + +viz::CoordinateSystemWidget +--------------------------- .. ocv:class:: CoordinateSystemWidget This 3D Widget represents a coordinate system. :: @@ -330,16 +419,16 @@ This 3D Widget represents a coordinate system. :: CoordinateSystemWidget(double scale = 1.0); }; -CoordinateSystemWidget::CoordinateSystemWidget ----------------------------------------------- +viz::CoordinateSystemWidget::CoordinateSystemWidget +--------------------------------------------------- Constructs a CoordinateSystemWidget. .. ocv:function:: CoordinateSystemWidget(double scale = 1.0) :param scale: Determines the size of the axes. -PolyLineWidget --------------- +viz::PolyLineWidget +------------------- .. ocv:class:: PolyLineWidget This 3D Widget defines a poly line. :: @@ -353,17 +442,17 @@ This 3D Widget defines a poly line. :: /* hidden */ }; -PolyLineWidget::PolyLineWidget ------------------------------- +viz::PolyLineWidget::PolyLineWidget +----------------------------------- Constructs a PolyLineWidget. .. ocv:function:: PolyLineWidget(InputArray points, const Color &color = Color::white()) :param points: Point set. - :param color: Color of the poly line. + :param color: :ocv:class:`Color` of the poly line. -GridWidget ----------- +viz::GridWidget +--------------- .. ocv:class:: GridWidget This 3D Widget defines a grid. :: @@ -379,25 +468,25 @@ This 3D Widget defines a grid. :: /* hidden */ }; -GridWidget::GridWidget ----------------------- +viz::GridWidget::GridWidget +--------------------------- Constructs a GridWidget. .. ocv:function:: GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) :param dimensions: Number of columns and rows, respectively. :param spacing: Size of each column and row, respectively. - :param color: Color of the grid. + :param color: :ocv:class:`Color` of the grid. .. ocv:function: GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) :param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. :param dimensions: Number of columns and rows, respectively. :param spacing: Size of each column and row, respectively. - :param color: Color of the grid. + :param color: :ocv:class:`Color` of the grid. -Text3DWidget ------------- +viz::Text3DWidget +----------------- .. ocv:class:: Text3DWidget This 3D Widget represents 3D text. The text always faces the camera. :: @@ -405,39 +494,40 @@ This 3D Widget represents 3D text. The text always faces the camera. :: class CV_EXPORTS Text3DWidget : public Widget3D { public: - Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()); + Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, double face_camera = true, const Color &color = Color::white()); void setText(const String &text); String getText() const; }; -Text3DWidget::Text3DWidget --------------------------- +viz::Text3DWidget::Text3DWidget +------------------------------- Constructs a Text3DWidget. -.. ocv:function:: Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, const Color &color = Color::white()) +.. ocv:function:: Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, double face_camera = true, const Color &color = Color::white()) :param text: Text content of the widget. :param position: Position of the text. :param text_scale: Size of the text. - :param color: Color of the text. + :param face_camera: If true, text always faces the camera. + :param color: :ocv:class:`Color` of the text. -Text3DWidget::setText ---------------------- +viz::Text3DWidget::setText +-------------------------- Sets the text content of the widget. .. ocv:function:: void setText(const String &text) :param text: Text content of the widget. -Text3DWidget::getText ---------------------- +viz::Text3DWidget::getText +-------------------------- Returns the current text content of the widget. .. ocv:function:: String getText() const -TextWidget ----------- +viz::TextWidget +--------------- .. ocv:class:: TextWidget This 2D Widget represents text overlay. :: @@ -451,8 +541,8 @@ This 2D Widget represents text overlay. :: String getText() const; }; -TextWidget::TextWidget ----------------------- +viz::TextWidget::TextWidget +--------------------------- Constructs a TextWidget. .. ocv:function:: TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()) @@ -460,24 +550,24 @@ Constructs a TextWidget. :param text: Text content of the widget. :param pos: Position of the text. :param font_size: Font size. - :param color: Color of the text. + :param color: :ocv:class:`Color` of the text. -TextWidget::setText ---------------------- +viz::TextWidget::setText +------------------------ Sets the text content of the widget. .. ocv:function:: void setText(const String &text) :param text: Text content of the widget. -TextWidget::getText ---------------------- +viz::TextWidget::getText +------------------------ Returns the current text content of the widget. .. ocv:function:: String getText() const -ImageOverlayWidget ------------------- +viz::ImageOverlayWidget +----------------------- .. ocv:class:: ImageOverlayWidget This 2D Widget represents an image overlay. :: @@ -490,28 +580,28 @@ This 2D Widget represents an image overlay. :: void setImage(const Mat &image); }; -ImageOverlayWidget::ImageOverlayWidget --------------------------------------- -Constructs a ImageOverlayWidget. +viz::ImageOverlayWidget::ImageOverlayWidget +------------------------------------------- +Constructs an ImageOverlayWidget. .. ocv:function:: ImageOverlayWidget(const Mat &image, const Rect &rect) :param image: BGR or Gray-Scale image. :param rect: Image is scaled and positioned based on rect. -ImageOverlayWidget::setImage ----------------------------- +viz::ImageOverlayWidget::setImage +--------------------------------- Sets the image content of the widget. .. ocv:function:: void setImage(const Mat &image) :param image: BGR or Gray-Scale image. -Image3DWidget -------------- +viz::Image3DWidget +------------------ .. ocv:class:: Image3DWidget -This 3D Widget represents 3D image. :: +This 3D Widget represents an image in 3D space. :: class CV_EXPORTS Image3DWidget : public Widget3D { @@ -524,9 +614,9 @@ This 3D Widget represents 3D image. :: void setImage(const Mat &image); }; -Image3DWidget::Image3DWidget ----------------------------- -Constructs a Image3DWidget. +viz::Image3DWidget::Image3DWidget +--------------------------------- +Constructs an Image3DWidget. .. ocv:function:: Image3DWidget(const Mat &image, const Size &size) @@ -541,19 +631,19 @@ Constructs a Image3DWidget. :param image: BGR or Gray-Scale image. :param size: Size of the image. -Image3DWidget::setImage ------------------------ +viz::Image3DWidget::setImage +---------------------------- Sets the image content of the widget. .. ocv:function:: void setImage(const Mat &image) :param image: BGR or Gray-Scale image. -CameraPositionWidget --------------------- +viz::CameraPositionWidget +------------------------- .. ocv:class:: CameraPositionWidget -This 3D Widget represents camera position. :: +This 3D Widget represents camera position in a scene by its axes or viewing frustum. :: class CV_EXPORTS CameraPositionWidget : public Widget3D { @@ -566,43 +656,72 @@ This 3D Widget represents camera position. :: CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); //! Creates frustum and display given image at the far plane CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane + CameraPositionWidget(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()); }; -CameraPositionWidget::CameraPositionWidget ------------------------------------------- +viz::CameraPositionWidget::CameraPositionWidget +----------------------------------------------- Constructs a CameraPositionWidget. -.. ocv:function:: CameraPositionWidget(double scale = 1.0) +- **Display camera coordinate frame.** - Creates camera coordinate frame at the origin. - -.. ocv:function:: CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) + .. ocv:function:: CameraPositionWidget(double scale = 1.0) - :param K: Intrinsic matrix of the camera. - :param scale: Scale of the frustum. - :param color: Color of the frustum. - - Creates viewing frustum of the camera based on its intrinsic matrix K. - -.. ocv:function:: CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) + Creates camera coordinate frame at the origin. + + .. image:: images/cpw1.png + :alt: Camera coordinate frame + :align: center - :param fov: Field of view of the camera (horizontal, vertical). - :param scale: Scale of the frustum. - :param color: Color of the frustum. - - Creates viewing frustum of the camera based on its field of view fov. +- **Display the viewing frustum.** -.. ocv:function:: CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()) + .. ocv:function:: CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) - :param K: Intrinsic matrix of the camera. - :param img: BGR or Gray-Scale image that is going to be displayed at the far plane of the frustum. - :param scale: Scale of the frustum and image. - :param color: Color of the frustum. + :param K: Intrinsic matrix of the camera. + :param scale: Scale of the frustum. + :param color: :ocv:class:`Color` of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K. - Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. - -TrajectoryWidget ----------------- + .. ocv:function:: CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) + + :param fov: Field of view of the camera (horizontal, vertical). + :param scale: Scale of the frustum. + :param color: :ocv:class:`Color` of the frustum. + + Creates viewing frustum of the camera based on its field of view fov. + + .. image:: images/cpw2.png + :alt: Camera viewing frustum + :align: center + +- **Display image on the far plane of the viewing frustum.** + + .. ocv:function:: CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()) + + :param K: Intrinsic matrix of the camera. + :param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum. + :param scale: Scale of the frustum and image. + :param color: :ocv:class:`Color` of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. + + .. ocv:function:: CameraPositionWidget(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()) + + :param fov: Field of view of the camera (horizontal, vertical). + :param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum. + :param scale: Scale of the frustum and image. + :param color: :ocv:class:`Color` of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. + + .. image:: images/cpw3.png + :alt: Camera viewing frustum with image + :align: center + +viz::TrajectoryWidget +--------------------- .. ocv:class:: TrajectoryWidget This 3D Widget represents a trajectory. :: @@ -623,15 +742,15 @@ This 3D Widget represents a trajectory. :: /* hidden */ }; -TrajectoryWidget::TrajectoryWidget ----------------------------------- +viz::TrajectoryWidget::TrajectoryWidget +--------------------------------------- Constructs a TrajectoryWidget. .. ocv:function:: TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0) :param path: List of poses on a trajectory. :param display_mode: Display mode. This can be DISPLAY_PATH, DISPLAY_FRAMES, DISPLAY_PATH & DISPLAY_FRAMES. - :param color: Color of the polyline that represents path. Frames are not affected. + :param color: :ocv:class:`Color` of the polyline that represents path. Frames are not affected. :param scale: Scale of the frames. Polyline is not affected. Displays trajectory of the given path as follows: @@ -645,7 +764,7 @@ Constructs a TrajectoryWidget. :param path: List of poses on a trajectory. :param K: Intrinsic matrix of the camera. :param scale: Scale of the frustums. - :param color: Color of the frustums. + :param color: :ocv:class:`Color` of the frustums. Displays frustums at each pose of the trajectory. @@ -654,12 +773,12 @@ Constructs a TrajectoryWidget. :param path: List of poses on a trajectory. :param fov: Field of view of the camera (horizontal, vertical). :param scale: Scale of the frustums. - :param color: Color of the frustums. + :param color: :ocv:class:`Color` of the frustums. Displays frustums at each pose of the trajectory. -SpheresTrajectoryWidget ------------------------ +viz::SpheresTrajectoryWidget +---------------------------- .. ocv:class:: SpheresTrajectoryWidget This 3D Widget represents a trajectory using spheres and lines, where spheres represent the positions of the camera, and lines @@ -673,8 +792,8 @@ represent the direction from previous position to the current. :: Color &line_color = Color::white(), const Color &sphere_color = Color::white()); }; -SpheresTrajectoryWidget::SpheresTrajectoryWidget ------------------------------------------------- +viz::SpheresTrajectoryWidget::SpheresTrajectoryWidget +----------------------------------------------------- Constructs a SpheresTrajectoryWidget. .. ocv:function:: SpheresTrajectoryWidget(const std::vector &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()) @@ -683,11 +802,11 @@ Constructs a SpheresTrajectoryWidget. :param line_length: Length of the lines. :param init_sphere_radius: Radius of the first sphere which represents the initial position of the camera. :param sphere_radius: Radius of the rest of the spheres. - :param line_color: Color of the lines. - :param sphere_color: Color of the spheres. + :param line_color: :ocv:class:`Color` of the lines. + :param sphere_color: :ocv:class:`Color` of the spheres. -CloudWidget ------------ +viz::CloudWidget +---------------- .. ocv:class:: CloudWidget This 3D Widget defines a point cloud. :: @@ -704,26 +823,28 @@ This 3D Widget defines a point cloud. :: /* hidden */ }; -CloudWidget::CloudWidget ------------------------- +viz::CloudWidget::CloudWidget +----------------------------- Constructs a CloudWidget. .. ocv:function:: CloudWidget(InputArray cloud, InputArray colors) - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param colors: Set of colors. It has to be of the same size with cloud. Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). .. ocv:function:: CloudWidget(InputArray cloud, const Color &color = Color::white()) - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. - :param color: A single color for the whole cloud. + :param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. + :param color: A single :ocv:class:`Color` for the whole cloud. Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +.. note:: In case there are four channels in the cloud, fourth channel is ignored. -CloudCollectionWidget ---------------------- +viz::CloudCollectionWidget +-------------------------- .. ocv:class:: CloudCollectionWidget This 3D Widget defines a collection of clouds. :: @@ -742,19 +863,19 @@ This 3D Widget defines a collection of clouds. :: /* hidden */ }; -CloudCollectionWidget::CloudCollectionWidget --------------------------------------------- +viz::CloudCollectionWidget::CloudCollectionWidget +------------------------------------------------- Constructs a CloudCollectionWidget. .. ocv:function:: CloudCollectionWidget() -CloudCollectionWidget::addCloud -------------------------------- +viz::CloudCollectionWidget::addCloud +------------------------------------ Adds a cloud to the collection. .. ocv:function:: void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()) - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param colors: Set of colors. It has to be of the same size with cloud. :param pose: Pose of the cloud. @@ -762,14 +883,16 @@ Adds a cloud to the collection. .. ocv:function:: void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity()) - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. - :param colors: A single color for the whole cloud. + :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. + :param colors: A single :ocv:class:`Color` for the whole cloud. :param pose: Pose of the cloud. Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +.. note:: In case there are four channels in the cloud, fourth channel is ignored. -CloudNormalsWidget ------------------- +viz::CloudNormalsWidget +----------------------- .. ocv:class:: CloudNormalsWidget This 3D Widget represents normals of a point cloud. :: @@ -783,20 +906,22 @@ This 3D Widget represents normals of a point cloud. :: /* hidden */ }; -CloudNormalsWidget::CloudNormalsWidget --------------------------------------- +viz::CloudNormalsWidget::CloudNormalsWidget +------------------------------------------- Constructs a CloudNormalsWidget. .. ocv:function:: CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()) - :param cloud: Point set which can be of type: CV_32FC3, CV_32FC4, CV_64FC3, CV_64FC4. + :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param normals: A set of normals that has to be of same type with cloud. - :param level: Display only every levelth normal. + :param level: Display only every ``level`` th normal. :param scale: Scale of the arrows that represent normals. - :param color: Color of the arrows that represent normals. + :param color: :ocv:class:`Color` of the arrows that represent normals. -MeshWidget ----------- +.. note:: In case there are four channels in the cloud, fourth channel is ignored. + +viz::MeshWidget +--------------- .. ocv:class:: MeshWidget This 3D Widget defines a mesh. :: @@ -810,13 +935,13 @@ This 3D Widget defines a mesh. :: /* hidden */ }; -MeshWidget::MeshWidget ----------------------- +viz::MeshWidget::MeshWidget +--------------------------- Constructs a MeshWidget. .. ocv:function:: MeshWidget(const Mesh3d &mesh) - :param mesh: Mesh object that will be displayed. + :param mesh: :ocv:class:`Mesh3d` object that will be displayed. diff --git a/samples/cpp/bunny.ply b/samples/cpp/bunny.ply new file mode 100644 index 000000000..10ae64fc3 --- /dev/null +++ b/samples/cpp/bunny.ply @@ -0,0 +1,5752 @@ +ply +format ascii 1.0 +comment zipper output +element vertex 1889 +property float x +property float y +property float z +property float confidence +property float intensity +element face 3851 +property list uchar int vertex_indices +end_header +-0.0369122 0.127512 0.00276757 0.850855 0.5 +-0.0457707 0.130327 0.00306785 0.900159 0.5 +-0.0708847 0.149834 0.0388672 0.398443 0.5 +-0.00331557 0.130403 0.0212208 0.85268 0.5 +-0.0211979 0.1272 0.00915278 0.675938 0.5 +-0.0265255 0.12592 0.00874866 0.711533 0.5 +0.0339261 0.112038 0.0269672 0.652757 0.5 +0.0376485 0.110455 0.0145481 0.708171 0.5 +-0.0259368 0.111118 0.0379115 0.454541 0.437538 +0.027952 0.120939 0.0215377 0.533079 0.5 +-0.0628308 0.155987 -0.0150105 0.404517 0.5 +0.0390029 0.106711 0.0215202 0.535542 0.5 +0.0447976 0.0950477 0.00866471 0.579563 0.425995 +-0.0330636 0.173619 -0.0031267 0.365607 0.5 +-0.0808069 0.136243 0.0495014 0.499575 0.5 +-0.0705086 0.12445 0.0526685 0.564827 0.5 +0.00874873 0.131225 0.0145345 0.748371 0.5 +0.0401015 0.106711 0.00874166 0.680399 0.5 +0.0379483 0.100145 -0.00827134 0.600054 0.5 +-0.0906538 0.137201 0.0207305 0.824561 0.5 +-0.0841655 0.110667 0.0275273 0.690889 0.5 +-0.0705214 0.156214 0.0144536 0.807492 0.5 +-0.083872 0.15212 0.0282652 0.248168 0.41865 +0.00305028 0.12432 0.0332425 0.555044 0.354559 +0.00870828 0.124165 0.0330348 0.653433 0.5 +-0.0328896 0.12613 0.00300653 0.898771 0.5 +-0.0506302 0.143065 0.0150611 0.691477 0.5 +-0.0757863 0.13637 0.050172 0.566256 0.5 +-0.0027191 0.128962 0.0264678 0.271491 0.462815 +-0.0460961 0.125118 0.0263142 0.539149 0.5 +-0.0785104 0.0942728 -0.0109192 0.710999 0.5 +0.0216915 0.125373 0.0211452 0.530957 0.5 +-0.0888469 0.124305 0.00237041 0.635593 0.5 +0.040386 0.100825 -0.00303043 0.574857 0.5 +-0.0884145 0.117791 0.00268555 0.487167 0.430737 +-0.0319074 0.177421 -0.00491879 0.269231 0.447035 +-0.0765825 0.143224 0.0455148 0.414139 0.5 +-0.0209748 0.112544 0.0388613 0.482541 0.5 +-0.020836 0.179425 -0.0221622 0.341071 0.440034 +-0.0377039 0.167987 -0.0130391 0.396317 0.473039 +-0.0331765 0.12681 0.00839958 0.896274 0.5 +0.00893926 0.127114 0.0292916 0.350014 0.41288 +-0.044944 0.131083 0.0147963 0.599596 0.5 +-0.0266041 0.12515 0.00282384 0.73687 0.5 +0.0144285 0.12328 0.0319185 0.625269 0.5 +0.019244 0.122284 0.0308314 0.611204 0.34486 +-0.0390225 0.167317 0.00215527 0.413994 0.469929 +-0.08808 0.129976 0.00206377 0.625486 0.5 +-0.0537203 0.142608 0.0266058 0.696873 0.5 +0.043095 0.0980072 0.0191617 0.665192 0.5 +0.0432138 0.100117 0.00866473 0.691828 0.5 +0.0415448 0.0944954 0.0275695 0.671611 0.5 +-0.0578726 0.155337 0.0149245 0.394763 0.437313 +-0.0231577 0.157375 -0.0046304 0.136389 0.380194 +-0.0683123 0.145735 0.0420568 0.751812 0.5 +-0.0708351 0.142847 0.0451248 0.627973 0.5 +-0.070664 0.0642894 0.0209789 0.413051 0.5 +-0.0761519 0.130581 0.0525324 0.629117 0.5 +-0.0640036 0.161784 -0.0208118 0.449093 0.5 +-0.0706461 0.155711 0.00252406 0.855717 0.5 +-0.0924366 0.118434 0.0399838 0.673877 0.5 +-0.0635349 0.156052 0.0148814 0.798496 0.5 +0.0282675 0.118192 0.0274382 0.635485 0.5 +0.0392736 0.0938857 -0.00915453 0.585857 0.459742 +-0.0695973 0.164844 -0.0174846 0.548789 0.5 +-0.00892354 0.123904 0.0330319 0.602316 0.374044 +0.0269099 0.0942476 0.0444911 0.649753 0.5 +-0.0146258 0.162377 -0.0144398 0.338176 0.5 +-0.0450983 0.167072 0.00289327 0.449091 0.5 +-0.0761536 0.172742 -0.0384391 0.256591 0.4298 +-0.0858274 0.105458 0.00472318 0.523819 0.297125 +0.0370431 0.110443 0.0207229 0.52623 0.448558 +0.0321593 0.0994027 0.0380657 0.733041 0.5 +-0.075287 0.146433 0.0428582 0.424358 0.5 +-0.0395145 0.171107 0.000531747 0.452893 0.5 +-0.0839586 0.11215 0.00148754 0.436727 0.419097 +0.0446848 0.0883378 0.0216285 0.487783 0.481728 +0.0161783 0.127819 0.0220535 0.481793 0.5 +-0.00251635 0.0397232 0.0474087 0.280725 0.5 +0.00303163 0.0406968 0.0460422 0.331809 0.5 +-0.0143059 0.128197 0.00333856 0.693854 0.5 +-0.0526117 0.155596 0.0109972 0.561042 0.5 +-0.0332043 0.17776 -0.00906223 0.212789 0.5 +0.0394391 0.106654 0.00306577 0.522321 0.489889 +-0.0923799 0.1249 0.0327641 0.848517 0.5 +0.0454681 0.0882959 0.0146642 0.575503 0.5 +-0.0274495 0.179802 -0.00925837 0.258799 0.457369 +-0.072504 0.146297 0.0429682 0.549207 0.5 +-0.0579959 0.129793 0.0383118 0.658867 0.444043 +0.043117 0.0923689 0.0251649 0.622686 0.5 +-0.00865718 0.130323 0.0149721 0.633691 0.5 +-0.0141304 0.129188 0.0147431 0.547632 0.5 +-0.0707877 0.15583 0.00921954 0.739059 0.5 +-0.00952731 0.127041 0.0281475 0.375412 0.377874 +-0.0646289 0.153404 0.0329146 0.855321 0.5 +-0.0706939 0.15347 0.0328596 0.444959 0.455263 +0.0208126 0.118434 0.0336393 0.519282 0.5 +-0.0396566 0.173008 -0.00299705 0.274377 0.177706 +-0.0442176 0.170815 -0.00391429 0.245926 0.5 +-0.0582565 0.0395149 0.0457796 0.417977 0.459314 +-0.0523033 0.0401501 0.04623 0.454776 0.456044 +-0.0760211 0.161274 -0.0145891 0.267801 0.372187 +-0.0693983 0.163016 -0.0140293 0.403228 0.45768 +0.0399663 0.106491 0.014952 0.713602 0.5 +0.041536 0.0950084 -0.00475737 0.490139 0.464008 +-0.0470079 0.163779 0.00528295 0.432857 0.486946 +-0.0402546 0.161678 0.00298655 0.447592 0.5 +-0.0386569 0.0389805 0.0441153 0.509262 0.5 +-0.0704175 0.166991 -0.0216976 0.332592 0.447054 +-0.0254201 0.0886622 0.0503827 0.608282 0.5 +-0.0886334 0.137429 0.00876953 0.549009 0.5 +-0.014179 0.12627 0.0266417 0.420759 0.5 +-0.0360017 0.17408 -0.0118959 0.409753 0.289042 +-0.0886251 0.0937834 0.00823534 0.753697 0.5 +-0.0648672 0.155874 -0.00891497 0.595216 0.5 +-0.0704508 0.137752 -0.00774011 0.446131 0.5 +-0.0750154 0.166247 -0.0219558 0.263106 0.5 +0.0299465 0.114869 0.0300239 0.642356 0.5 +0.0398138 0.0998788 0.0273101 0.51725 0.5 +-0.015242 0.111698 0.0407424 0.605597 0.5 +-0.0700387 0.118219 0.0524379 0.585543 0.5 +0.0149973 0.112399 0.0386082 0.669811 0.5 +-0.036487 0.171225 0.000545037 0.438578 0.5 +-0.0641664 0.118551 -0.00968333 0.569796 0.5 +-0.071817 0.166979 -0.0463822 0.381568 0.451091 +-0.0913559 0.14534 0.0246937 0.648478 0.5 +0.00903703 0.112569 0.0396571 0.549283 0.408623 +0.0324674 0.0997396 -0.0141603 0.732658 0.5 +0.0417911 0.101845 0.00188609 0.547756 0.5 +0.00302992 0.112517 0.0415434 0.592572 0.5 +-0.0650368 0.148485 0.0382561 0.62562 0.5 +-0.0706519 0.13063 0.0502497 0.563116 0.5 +-0.0144471 0.128935 0.00903509 0.682121 0.5 +0.00292575 0.131541 0.00912318 0.795238 0.5 +-0.0625682 0.151125 0.035875 0.463512 0.5 +0.0349829 0.113328 0.0214487 0.620597 0.5 +0.021327 0.0385664 0.0392992 0.259499 0.426724 +0.0145125 0.093771 0.0501571 0.654705 0.5 +-0.00923752 0.112849 0.0413907 0.615633 0.5 +0.0415329 0.100906 0.0210277 0.662312 0.5 +0.0422859 0.101486 0.0146614 0.569693 0.490777 +-0.0773783 0.112839 -0.00448759 0.505277 0.5 +-0.078035 0.137641 -0.00517379 0.466714 0.5 +0.00873437 0.106347 -0.0202193 0.792948 0.5 +0.0090324 0.13035 0.0211569 0.465873 0.5 +0.00301322 0.130902 0.0206741 0.592486 0.5 +-0.00286342 0.13115 0.0147367 0.587804 0.5 +-0.0391578 0.12569 0.0207996 0.438744 0.464814 +-0.0205725 0.123523 0.0265579 0.445477 0.415699 +-0.0644194 0.155634 0.00928477 0.611624 0.331941 +-0.0463385 0.131411 0.0207671 0.674928 0.5 +-0.0532034 0.0439067 0.044658 0.417403 0.440199 +-0.00297651 0.131046 0.00884967 0.738924 0.5 +-0.089664 0.137755 0.0263925 0.80362 0.5 +-0.00888731 0.124273 -0.00880284 0.767738 0.284429 +-0.0460971 0.0385107 0.0446891 0.654962 0.5 +-0.0649255 0.178874 -0.0579325 0.245129 0.411885 +-0.0329347 0.124601 0.0211235 0.32811 0.5 +-0.0831301 0.149901 0.0334123 0.331963 0.314683 +-0.0895652 0.093948 0.0149303 0.603378 0.5 +-0.0328901 0.124518 -0.00282055 0.63839 0.5 +-0.0845271 0.106161 0.00204328 0.338681 0.43162 +-0.0469341 0.155816 0.00872921 0.470367 0.484595 +0.0206202 0.123943 0.0267275 0.477255 0.5 +-0.026256 0.117499 0.0321672 0.543293 0.5 +-0.021392 0.118632 0.0336445 0.468887 0.429556 +-0.0195069 0.116132 0.0368525 0.534732 0.411301 +-0.0761618 0.118382 0.0520923 0.490413 0.5 +0.00889281 0.0395765 0.0451727 0.476347 0.38769 +-0.0534736 0.159548 0.00753828 0.476667 0.5 +-0.0469464 0.161226 0.00680216 0.495992 0.483766 +-0.0574886 0.154862 0.0204748 0.677314 0.5 +0.0317199 0.117635 0.0202007 0.579556 0.5 +0.0378683 0.105514 -0.00259159 0.588286 0.5 +-0.0811847 0.137693 -0.00253994 0.641736 0.5 +-0.0764348 0.124515 0.0528345 0.65366 0.5 +0.0343816 0.106104 -0.00900254 0.534403 0.5 +0.0457922 0.088316 0.00867097 0.586292 0.439394 +-0.0703288 0.0944195 -0.0159143 0.511499 0.5 +-0.0756048 0.0937947 -0.0135536 0.429902 0.5 +-0.058657 0.156369 0.0093256 0.31374 0.5 +-0.0637335 0.153848 0.00222718 0.478676 0.5 +-0.0777278 0.0960024 0.0363437 0.678588 0.5 +-0.0868519 0.136556 0.00309926 0.517441 0.5 +-0.0455299 0.0432404 0.0432162 0.712662 0.5 +-0.0402011 0.045749 0.0408051 0.669165 0.320516 +-0.0654123 0.160403 -0.0149066 0.335302 0.5 +-0.0318898 0.0387174 0.0510004 0.553401 0.5 +-0.0267997 0.0453977 0.0509311 0.501112 0.5 +-0.0271043 0.0396972 0.0535379 0.487956 0.5 +-0.0215575 0.0460868 0.0517209 0.709553 0.5 +-0.0143078 0.0445295 0.0504368 0.575852 0.5 +-0.00981594 0.043264 0.0493162 0.448927 0.393067 +-0.00348436 0.044054 0.0472086 0.598081 0.5 +0.009577 0.0458139 0.0465877 0.519814 0.433928 +0.02048 0.111086 0.0379569 0.681163 0.5 +-0.0141831 0.128547 0.0200007 0.293349 0.5 +-0.0526702 0.144108 0.0210347 0.639643 0.5 +-0.0634838 0.17384 -0.0527131 0.549906 0.5 +-0.0366553 0.171999 -0.0125745 0.436075 0.5 +-0.0525548 0.131228 0.0328277 0.727547 0.5 +-0.0659567 0.132023 0.0442925 0.724494 0.5 +-0.0921726 0.11832 0.0267606 0.794672 0.5 +0.0452792 0.0882737 0.00268175 0.507794 0.5 +-0.00305651 0.112889 0.0417789 0.635396 0.5 +-0.0451955 0.161396 -0.00871567 0.424682 0.5 +-0.0402914 0.160933 -0.0115368 0.411895 0.405943 +-0.0521414 0.0701165 0.0389584 0.682177 0.456916 +-0.0383315 0.093604 -0.0232581 0.72469 0.5 +-0.0690556 0.137374 0.046352 0.61723 0.5 +-0.0695996 0.167401 -0.0516299 0.518552 0.5 +-0.00246047 0.124102 0.0337609 0.444043 0.5 +-0.0398624 0.128204 0.00299348 0.864483 0.5 +-0.0753331 0.149032 0.0395625 0.432149 0.5 +-0.0701432 0.160618 -0.00917801 0.464361 0.5 +-0.0589378 0.0440425 0.0434222 0.437887 0.447715 +-0.0207164 0.126445 0.00312493 0.710427 0.5 +-0.00850666 0.0467286 0.0481052 0.613173 0.5 +0.00300323 0.0450308 0.0469911 0.464978 0.5 +-0.0802174 0.148665 0.0379438 0.47939 0.5 +-0.0819961 0.130698 0.0513437 0.54405 0.5 +0.00273088 0.106333 -0.0209927 0.733954 0.5 +-0.0757273 0.0885687 -0.0138399 0.397424 0.5 +-0.0698477 0.0882875 -0.0167823 0.420617 0.5 +-0.0668508 0.159243 -0.0102161 0.42216 0.440727 +-0.0226988 0.0885773 0.0536309 0.546444 0.5 +-0.00281419 0.0990077 0.0505614 0.455087 0.5 +0.0452902 0.0696213 0.0253974 0.33948 0.5 +-0.0525629 0.0472823 0.040482 0.279548 0.5 +-0.046959 0.0466581 0.0408127 0.43714 0.5 +-0.0691348 0.156682 -0.00276369 0.629099 0.5 +-0.0897599 0.150073 0.0220744 0.276354 0.5 +-0.0702883 0.155637 0.0263654 0.47565 0.441038 +-0.0765031 0.154893 0.0266005 0.799832 0.5 +-0.00804843 0.0987379 0.0505998 0.327523 0.438474 +0.0300791 0.11567 -0.00430465 0.66246 0.5 +-0.0923054 0.117757 0.0334441 0.476916 0.5 +-0.0331192 0.0449511 0.0462474 0.432059 0.466683 +-0.0337794 0.113308 0.034612 0.683562 0.5 +-0.0521291 0.113769 0.0349566 0.515399 0.5 +0.0437636 0.0825382 -0.0027974 0.568535 0.5 +-0.0202819 0.126016 0.0210507 0.374818 0.437592 +0.0327872 0.043925 0.0295904 0.650152 0.5 +-0.0453372 0.155266 -0.0075525 0.386286 0.5 +-0.0284609 0.173987 -0.0175958 0.379432 0.418735 +0.0268448 0.0881755 -0.0223077 0.715629 0.5 +-0.0308231 0.0923023 -0.0246377 0.474586 0.431409 +-0.0899732 0.149975 0.0141115 0.257143 0.5 +0.0381804 0.105121 0.0266947 0.534482 0.490368 +0.00842001 0.12907 0.0258154 0.374593 0.448613 +-0.0266549 0.0942999 -0.0265555 0.294426 0.332222 +-0.0279896 0.0475815 0.0485532 0.381268 0.5 +-0.0150037 0.048073 0.0483203 0.576068 0.5 +-0.00298993 0.0473817 0.0491102 0.446744 0.431743 +0.00376754 0.0477551 0.0502037 0.495901 0.44823 +0.00748504 0.0473851 0.0493363 0.494952 0.5 +-0.0581651 0.149751 0.032858 0.470966 0.5 +-0.0720688 0.136456 0.0490662 0.625357 0.5 +-0.0810638 0.0939541 -0.0082617 0.685573 0.5 +0.0380863 0.0458646 0.0307423 0.807573 0.5 +-0.0253234 0.182998 -0.0108168 0.245054 0.5 +-0.0230508 0.183235 -0.0110157 0.246322 0.458572 +0.00323317 0.129146 0.0263855 0.347796 0.441746 +-0.0626125 0.149788 -0.00343342 0.691705 0.5 +-0.0591471 0.0466998 0.0395843 0.0883466 0.213805 +-0.0353862 0.0471292 0.0414241 0.656538 0.5 +-0.0194948 0.0486404 0.0485565 0.373069 0.5 +-0.00849455 0.0521633 0.0517688 0.61481 0.5 +-0.00296485 0.051429 0.0527827 0.53012 0.5 +0.00279019 0.0517664 0.0528352 0.560812 0.423049 +0.00904034 0.0517165 0.051222 0.558244 0.5 +0.0443839 0.0943042 0.00268377 0.582116 0.455816 +-0.0886145 0.111113 0.0148415 0.604102 0.5 +-0.0885219 0.144027 0.0329221 0.623335 0.5 +0.0440719 0.0937787 0.0206165 0.493368 0.454688 +0.0436531 0.0980341 0.0146596 0.668233 0.5 +-0.0650976 0.153799 -0.00285808 0.715743 0.5 +-0.0517297 0.0490759 0.0371355 0 0 +-0.0331222 0.0518259 0.0385377 0.676102 0.5 +-0.0377352 0.127448 0.0152358 0.612182 0.5 +-0.00906608 0.100701 0.0460122 0.338462 0.5 +-0.0410683 0.128416 0.0134054 0.417331 0.5 +-0.0712056 0.158724 -0.00521868 0.246338 0.5 +-0.0266313 0.0501544 0.044695 0.182016 0.5 +-0.0211065 0.0519946 0.0455753 0.195646 0.404388 +-0.0168667 0.0505241 0.0476889 0.520032 0.5 +-0.0147601 0.0527687 0.050103 0.451613 0.5 +-0.0626395 0.149972 -0.00897733 0.363787 0.461156 +-0.090861 0.124732 0.00627835 0.587249 0.5 +-0.0255786 0.0923499 -0.0315595 0.294527 0.5 +-0.0709738 0.172947 -0.052768 0.460427 0.5 +-0.0588974 0.143232 -0.00327646 0.48145 0.5 +-0.0943643 0.12436 0.0216467 0.570519 0.5 +0.0337044 0.112449 -0.00269877 0.532211 0.5 +-0.0515051 0.136557 0.0263185 0.72719 0.5 +-0.00886593 0.121199 0.0360577 0.614897 0.5 +-0.061729 0.155665 -0.0259512 0.690546 0.5 +-0.0862637 0.10567 0.0206042 0.519516 0.5 +-0.0895584 0.138606 0.032689 0.685876 0.5 +-0.0268168 0.123904 0.0208113 0.428255 0.5 +0.0341937 0.0515433 0.033081 0.609925 0.5 +0.0401268 0.0512743 0.0322702 0.669803 0.5 +0.0449306 0.0526595 0.0319582 0.655209 0.5 +-0.0405348 0.117168 0.0319438 0.657986 0.5 +-0.0636902 0.155546 -0.0390642 0.523327 0.5 +0.0278663 0.100401 0.0410064 0.689793 0.5 +-0.0275828 0.179275 -0.0157605 0.314049 0.5 +-0.0758871 0.0942302 0.0383961 0.647987 0.457049 +0.0138371 0.129201 0.0203961 0.412341 0.5 +-0.0152723 0.0998429 0.0451638 0.271215 0.427554 +-0.00916763 0.129718 0.0206646 0.438679 0.430152 +-0.0512444 0.0516901 0.0334801 0.192432 0.5 +-0.0461563 0.0523184 0.0379981 0.311543 0.5 +-0.0410001 0.05272 0.0393793 0.629588 0.477809 +-0.0270993 0.0526642 0.0393104 0.155274 0.5 +0.0434924 0.0931097 -0.00154028 0.576953 0.480183 +-0.0823819 0.112683 0.045427 0.438131 0.5 +-0.092066 0.118055 0.00909937 0.325678 0.5 +-0.00448884 0.121713 0.0362976 0.591545 0.5 +0.0147346 0.129423 0.0143146 0.840212 0.5 +-0.0158113 0.161888 -0.00973584 0.202865 0.5 +-0.0778838 0.149704 -0.00337488 0.403345 0.5 +-0.0865357 0.12477 -0.00166991 0.677311 0.5 +0.0153656 0.126058 0.0275381 0.479299 0.429147 +-0.0388913 0.123761 0.0249778 0.514489 0.5 +-0.0390351 0.121238 0.0283673 0.510424 0.470651 +-0.0324963 0.120237 0.0283344 0.568849 0.348087 +-0.0149052 0.12311 0.0316417 0.446842 0.5 +-0.0582873 0.117688 0.0386719 0.634635 0.5 +-0.0626536 0.161861 -0.0264031 0.685413 0.5 +-0.0818147 0.141639 0.0444825 0.392929 0.5 +0.0350734 0.100071 0.0345975 0.716199 0.5 +0.0311856 0.11215 0.0310216 0.689434 0.5 +-0.0335778 0.11743 0.031458 0.525408 0.5 +-0.059637 0.153475 0.031348 0.93076 0.5 +-0.0481256 0.0536625 0.0362191 0.58186 0.5 +-0.059026 0.156388 0.00269852 0.133166 0.5 +-0.0211187 0.0578754 0.0461125 0.660553 0.5 +-0.082738 0.124721 0.050554 0.665202 0.5 +-0.0466997 0.11363 0.0348133 0.568902 0.5 +-0.0107262 0.179662 -0.0277472 0.400699 0.458536 +0.0347725 0.0894441 -0.0170339 0.702331 0.5 +-0.0891825 0.100351 0.0148945 0.574286 0.477791 +0.0257275 0.122894 0.0207337 0.498278 0.5 +-0.0883949 0.100277 0.00841226 0.477822 0.5 +-0.0649858 0.155518 0.0263367 0.864791 0.5 +-0.0768402 0.154073 0.00257877 0.57436 0.5 +-0.0576877 0.154146 0.0262123 0.402162 0.5 +-0.0266966 0.125729 0.0145923 0.393422 0.5 +-0.076376 0.155782 0.0208875 0.505065 0.5 +-0.0763295 0.167188 -0.039594 0.405226 0.426366 +-0.0771877 0.100229 -0.0103313 0.528684 0.5 +-0.0153681 0.0590839 0.0519909 0.652683 0.5 +-0.010206 0.0576345 0.0535443 0.781548 0.413019 +-0.00350044 0.0578672 0.0543757 0.774384 0.5 +0.00300818 0.0568916 0.0538692 0.704357 0.5 +0.0088308 0.0580497 0.0529859 0.692645 0.5 +0.0410915 0.0820775 -0.00893411 0.500391 0.430286 +0.0395449 0.0576373 0.0318985 0.612032 0.4505 +-0.0762443 0.139336 0.0484763 0.588653 0.42756 +-0.0324306 0.120379 -0.00955344 0.656019 0.5 +-0.0194451 0.0881559 0.0557639 0.449983 0.473992 +-0.074787 0.159471 -0.00898201 0.281303 0.5 +-0.0639935 0.15611 0.0210031 0.687157 0.5 +-0.0762438 0.153101 0.0322442 0.323875 0.45561 +-0.00876679 0.128727 0.025102 0.735708 0.5 +0.0282216 0.112237 -0.00983067 0.567922 0.385391 +-0.0451341 0.0593225 0.0387559 0.511245 0.5 +-0.0405005 0.0579499 0.040202 0.540369 0.5 +-0.033993 0.0584028 0.038704 0.646744 0.5 +-0.0272756 0.0585468 0.0382285 0.571263 0.5 +-0.0248608 0.122913 0.0245429 0.379391 0.5 +-0.0825276 0.154355 0.0206132 0.385494 0.444119 +-0.00884271 0.129403 0.00305159 0.702319 0.5 +0.0207587 0.126654 0.0147646 0.624434 0.5 +-0.0394868 0.173351 -0.00839443 0.199648 0.251821 +-0.028421 0.114019 0.0347746 0.603313 0.5 +-0.0193575 0.122009 0.0306737 0.55532 0.5 +-0.0691626 0.161675 -0.0514614 0.38665 0.5 +-0.0516736 0.15006 0.0148119 0.716684 0.5 +-0.0156325 0.120151 0.0349054 0.470635 0.336572 +0.0467454 0.0582319 0.0314404 0.576429 0.5 +-0.0770165 0.0685425 0.0147863 0.703257 0.5 +-0.00967101 0.173225 -0.0264945 0.379771 0.5 +-0.0213141 0.184813 -0.0151112 0.186313 0.403961 +-0.0766524 0.0882188 0.0382876 0.650646 0.5 +-0.0540219 0.0521463 0.0110698 0.270787 0.5 +-0.0219451 0.126821 0.0155536 0.534695 0.5 +-0.0820391 0.153392 0.0264506 0.292051 0.4047 +-0.0213183 0.124468 -0.00290836 0.782181 0.5 +-0.0268364 0.123465 -0.00321538 0.727949 0.5 +-0.0312035 0.177796 -0.0133521 0.371348 0.5 +-0.00749945 0.0598042 0.0553302 0.778631 0.5 +-0.00108951 0.0601245 0.0554892 0.776353 0.5 +0.00280202 0.0599746 0.0555283 0.768603 0.5 +-0.051797 0.118119 0.033678 0.677092 0.438456 +0.00302464 0.131618 0.0149353 0.692956 0.5 +0.0446005 0.0942619 0.0151198 0.554026 0.5 +-0.0880636 0.111855 0.00852285 0.304511 0.3924 +-0.0704321 0.144096 -0.0148369 0.130446 0.5 +-0.0820967 0.0943634 0.0322765 0.629357 0.5 +-0.0269642 0.120812 0.0275676 0.345323 0.386314 +-0.0540164 0.149968 0.0253393 0.49489 0.5 +-0.0800337 0.0995053 -0.00770139 0.499264 0.5 +0.00922138 0.12038 0.0360924 0.562107 0.5 +0.00286056 0.117968 0.0387331 0.649494 0.5 +-0.0936229 0.118494 0.0206524 0.664933 0.5 +-0.0409923 0.113229 0.035109 0.667726 0.5 +-0.0822185 0.154488 0.0146661 0.500539 0.5 +-0.0625956 0.155202 -0.0329876 0.814083 0.5 +-0.0462511 0.124621 -0.00898124 0.590842 0.5 +-0.0220336 0.160676 -0.00426008 0.309766 0.47069 +-0.065621 0.172767 -0.0466049 0.613718 0.5 +-0.0762614 0.155884 0.0148687 0.717415 0.5 +-0.0644988 0.149044 -0.0265159 0.690046 0.5 +-0.0581979 0.0593456 0.0210895 0.079935 0 +-0.0335439 0.122618 0.0254024 0.514037 0.5 +-0.0826578 0.153434 0.00921403 0.601617 0.5 +-0.049999 0.132417 0.0286961 0.650903 0.5 +0.0088217 0.131096 0.00864908 0.834131 0.5 +-0.0154842 0.0644282 0.0533754 0.608033 0.445048 +-0.00871951 0.065015 0.0556827 0.650491 0.470895 +-0.00324815 0.0640003 0.0562816 0.762387 0.5 +0.00292601 0.0643094 0.0563956 0.748671 0.5 +0.00738462 0.0651614 0.0553402 0.488299 0.46872 +-0.0143174 0.116971 0.037836 0.441459 0.5 +-0.00299223 0.118083 0.0390751 0.65526 0.5 +-0.00864301 0.117816 0.0385662 0.681198 0.5 +-0.0532884 0.0571719 0.0206631 0.106703 0 +-0.0882588 0.100387 0.0210097 0.535268 0.5 +-0.0324377 0.099703 -0.0227313 0.620611 0.5 +0.0425072 0.0603725 0.0302275 0.744481 0.5 +0.0523383 0.0580401 0.0290457 0.405493 0.41666 +0.0413612 0.0877503 -0.00929235 0.635782 0.5 +-0.0581547 0.0620148 0.0270981 0.448705 0.5 +-0.0530328 0.0590503 0.0266933 0.136202 0.5 +-0.0477227 0.135526 0.0148654 0.740469 0.5 +0.00323512 0.0983053 0.0504424 0.395048 0.366076 +0.0150627 0.119642 0.034806 0.696033 0.374342 +-0.0453373 0.0643061 0.0391142 0.587502 0.5 +-0.0394097 0.0644278 0.0414133 0.715885 0.5 +-0.033068 0.0642666 0.0396407 0.650585 0.5 +-0.0270237 0.0644489 0.0395335 0.617817 0.5 +-0.0881604 0.149479 0.0268507 0.265855 0.5 +-0.0640727 0.143434 -0.00894036 0.668887 0.5 +0.00286033 0.121151 0.036139 0.623932 0.5 +-0.0827306 0.138152 0.0466993 0.412428 0.5 +-0.00261511 0.127006 0.030132 0.335862 0.5 +0.0355841 0.108498 -0.00452523 0.461807 0.466834 +0.0219203 0.114136 0.0356941 0.554683 0.5 +-0.0379555 0.161954 -0.0128021 0.499753 0.5 +-0.0526362 0.0643632 0.0340621 0.277414 0.5 +0.025874 0.123374 0.0143811 0.506732 0.5 +-0.0451406 0.131184 0.00901599 0.493237 0.5 +-0.075778 0.155361 -0.00310678 0.708579 0.5 +-0.0739145 0.156437 -0.0274945 0.645327 0.5 +-0.0833056 0.100778 -0.00354288 0.490806 0.397415 +-0.0767099 0.173942 -0.0452732 0.259897 0.5 +0.00846106 0.116985 0.038033 0.66824 0.5 +-0.0200899 0.184788 -0.020546 0.237973 0.106197 +-0.046571 0.120413 0.0285524 0.752764 0.5 +-0.0515313 0.123718 -0.0088569 0.538005 0.5 +0.0212116 0.105804 -0.0171101 0.576137 0.468722 +-0.0938613 0.124487 0.0151416 0.737559 0.5 +0.0414591 0.064577 0.0290352 0.617794 0.5 +0.0466725 0.0643471 0.0285539 0.486488 0.5 +0.0526423 0.0634018 0.0283831 0.501229 0.5 +-0.0468141 0.168322 -0.00285433 0.371444 0.5 +-0.0869152 0.0944156 0.00293118 0.494536 0.346642 +-0.0773713 0.161559 -0.0267238 0.476378 0.5 +-0.0396095 0.126677 -0.00334699 0.853498 0.5 +-0.0271315 0.0764239 0.0455715 0.693464 0.5 +-0.0587953 0.107012 -0.0177177 0.484023 0.5 +-0.0748314 0.11156 -0.00720996 0.44421 0.5 +-0.0642623 0.0888181 -0.018733 0.676741 0.5 +-0.0325172 0.0881157 -0.0255424 0.370176 0.330832 +0.00325654 0.0700086 0.0561047 0.731659 0.5 +0.0103151 0.0636713 0.0537558 0.477793 0.458716 +0.0432701 0.0979967 0.00267804 0.544182 0.465461 +-0.0708223 0.156244 0.021207 0.768676 0.5 +-0.0584176 0.0702277 0.0384322 0.673529 0.5 +-0.0703207 0.112305 -0.00963846 0.530989 0.5 +-0.0581653 0.0881983 -0.0208369 0.619673 0.5 +-0.0443038 0.0877156 -0.0218942 0.693083 0.5 +-0.0488091 0.0660127 0.0373959 0.829801 0.5 +0.00269411 0.126911 0.030114 0.419275 0.5 +0.0239692 0.12105 0.0288706 0.523768 0.5 +-0.0469203 0.117468 0.0314407 0.649888 0.5 +-0.091552 0.143361 0.0201623 0.515231 0.5 +-0.0907563 0.143859 0.0263089 0.504684 0.469425 +-0.0495713 0.144022 0.00976642 0.636632 0.45621 +-0.0770934 0.15583 -0.0147903 0.519503 0.5 +-0.0868322 0.105634 0.00887573 0.731519 0.5 +-0.082848 0.131648 -0.00299747 0.386393 0.5 +-0.0384249 0.106407 -0.0201393 0.79815 0.5 +-0.0823953 0.118841 -0.00336022 0.540306 0.5 +-0.0102333 0.0876697 -0.0375101 0.564234 0.5 +-0.00789361 0.089842 -0.0363492 0.755212 0.5 +-0.0579097 0.111769 -0.0161856 0.463258 0.5 +0.0140074 0.105793 -0.0193841 0.554632 0.5 +-0.00328561 0.105435 -0.0225198 0.740261 0.5 +-0.0409613 0.070972 0.0419904 0.795206 0.5 +-0.033501 0.0710512 0.0409793 0.706864 0.5 +-0.0272732 0.0701361 0.0410332 0.726443 0.5 +-0.0161963 0.127121 0.0228897 0.305628 0.5 +-0.0190644 0.127936 0.0133818 0.519435 0.5 +-0.0149926 0.0694778 0.0545159 0.595577 0.5 +-0.00932719 0.0707313 0.0562936 0.785998 0.5 +-0.002994 0.0710941 0.0575426 0.779773 0.5 +0.00838831 0.0714267 0.0556585 0.671976 0.5 +0.0102531 0.0693533 0.0547665 0.525573 0.5 +-0.0323939 0.153399 -0.00240332 0.209483 0.5 +0.0435981 0.0881514 0.0254203 0.603121 0.478265 +-0.0586529 0.124882 -0.00781093 0.700525 0.5 +-0.0204287 0.107045 -0.022046 0.723165 0.5 +-0.0382961 0.0879422 -0.0229335 0.629507 0.5 +-0.081573 0.113394 -0.00173083 0.508624 0.426711 +-0.0380811 0.154778 -0.00889149 0.748063 0.5 +-0.00212588 0.0889926 -0.0354677 0.782073 0.5 +0.00904065 0.100193 -0.0222794 0.54652 0.5 +-0.0467068 0.0700493 0.0405769 0.710023 0.5 +-0.0779974 0.151244 0.0352264 0.347296 0.5 +0.0149019 0.116126 0.0367849 0.635361 0.5 +-0.07603 0.106301 -0.0087688 0.520423 0.5 +-0.0885261 0.137839 0.0393964 0.651389 0.5 +-0.0703112 0.131278 -0.00857724 0.737784 0.5 +0.0419377 0.0703605 0.0288832 0.54196 0.5 +0.0514194 0.0684326 0.0256968 0.512602 0.5 +-0.0922548 0.124813 0.0393757 0.806636 0.5 +0.0135035 0.128105 0.0250558 0.487288 0.424656 +-0.0704618 0.125421 -0.00881334 0.801453 0.5 +-0.0703931 0.118731 -0.00840961 0.381625 0.5 +-0.0719685 0.106305 -0.0114493 0.499561 0.5 +-0.0646972 0.161498 -0.0573125 0.41682 0.5 +0.0463693 0.0715128 0.0216754 0.461473 0.448797 +-0.0538246 0.153497 0.0152346 0.602795 0.402362 +-0.0142869 0.0724666 0.0554243 0.617853 0.5 +-0.0394057 0.118512 -0.01336 0.602235 0.5 +-0.0280509 0.0880065 -0.0330858 0.33771 0.5 +-0.00957701 0.168254 -0.0212321 0.359593 0.5 +-0.0445856 0.167324 -0.00782662 0.413138 0.327414 +-0.0513101 0.161594 -0.00355965 0.292939 0.5 +-0.0702356 0.179304 -0.0569867 0.253404 0.5 +-0.0644695 0.168402 -0.0398946 0.676128 0.5 +-0.0089459 0.130139 0.00911776 0.703889 0.5 +0.00219503 0.0880369 -0.0342201 0.75972 0.5 +-0.0268891 0.16726 -0.0174204 0.847505 0.5 +-0.0525985 0.155054 -0.00368706 0.37123 0.419006 +-0.0761618 0.131736 -0.00696723 0.42394 0.44361 +-0.0759576 0.07099 0.0265672 0.757943 0.5 +-0.00875341 0.10588 -0.02285 0.71177 0.5 +-0.0519242 0.1493 -0.00277595 0.483301 0.5 +-0.016371 0.18465 -0.0214272 0.271878 0.5 +-0.020548 0.0705632 0.0520411 0.601639 0.5 +-0.0813371 0.120073 0.049533 0.662828 0.5 +-0.0625087 0.149934 -0.0150319 0.415531 0.480025 +-0.0831098 0.10651 0.0273461 0.515033 0.5 +-0.011119 0.163582 -0.018751 0.17813 0.5 +-0.00291057 0.101147 0.0456419 0.307462 0.5 +-0.0635467 0.0660523 0.0318653 0.49936 0.45677 +-0.0511979 0.0873878 -0.0217212 0.75515 0.5 +-0.0530335 0.0740367 0.0417219 0.727079 0.5 +-0.0465007 0.0756701 0.0421325 0.696934 0.5 +-0.022314 0.0760359 0.0530306 0.607912 0.5 +-0.0151351 0.0764056 0.0563566 0.616605 0.5 +-0.00900601 0.0766621 0.0575852 0.791265 0.5 +-0.00299732 0.0767339 0.0584651 0.678647 0.450838 +0.00347424 0.0769755 0.0565905 0.523043 0.5 +0.00860763 0.0767538 0.0557293 0.612782 0.5 +-0.0271239 0.156216 -0.00302734 0.139755 0.329034 +-0.0633091 0.16738 -0.0580906 0.358909 0.45373 +-0.0873943 0.144225 0.00902371 0.583528 0.5 +-0.0626891 0.162297 -0.0470925 0.70746 0.5 +0.0370111 0.110397 0.00265294 0.516602 0.481774 +-0.0744006 0.144062 -0.00864565 0.417075 0.5 +-0.0244124 0.183841 -0.0135068 0.166659 0.5 +-0.0803381 0.0715473 0.0150483 0.5669 0.5 +-0.0644528 0.0761561 0.040638 0.610448 0.476331 +-0.0588413 0.0753794 0.0421022 0.634349 0.5 +-0.0524294 0.077372 0.0433357 0.774603 0.5 +-0.0484981 0.0769334 0.043281 0.674446 0.5 +-0.0414954 0.0773856 0.0429005 0.752035 0.5 +-0.0395008 0.0754808 0.0425134 0.72256 0.5 +-0.033488 0.0764759 0.0414605 0.748994 0.5 +-0.0627838 0.162163 -0.0530538 0.691143 0.5 +0.0381456 0.0881056 -0.0138675 0.676152 0.5 +-0.0642837 0.0396418 0.039624 0.532543 0.5 +-0.0526672 0.121335 -0.010917 0.523608 0.5 +-0.0738104 0.162942 -0.037093 0.458525 0.324439 +-0.0490869 0.13938 0.00889895 0.657159 0.5 +-0.0495771 0.166027 -0.00171113 0.322064 0.5 +-0.0709736 0.161609 -0.0450808 0.365011 0.420984 +0.0251847 0.12195 0.0254854 0.524179 0.5 +-0.0193615 0.0781018 0.0558163 0.595703 0.4544 +-0.0265458 0.120645 -0.00911332 0.52669 0.5 +-0.061796 0.155741 -0.0207923 0.443336 0.5 +-0.082476 0.110295 0.0324103 0.745977 0.5 +-0.0691674 0.156314 -0.050857 0.360984 0.5 +-0.0622848 0.16236 -0.0396288 0.427869 0.464762 +-0.088248 0.113803 0.0264606 0.595923 0.5 +-0.0575392 0.0787026 0.0436363 0.801201 0.5 +-0.0298439 0.0782596 0.0421168 0.771067 0.5 +-0.0677617 0.0876701 0.0434928 0.59211 0.5 +-0.0921939 0.131884 0.015227 0.781723 0.5 +-0.0878987 0.111742 0.0209206 0.698028 0.5 +-0.049353 0.139298 0.0147955 0.761861 0.5 +-0.0327071 0.173321 -0.0149209 0.384317 0.5 +-0.0866298 0.152851 0.0149144 0.267781 0.5 +-0.0779646 0.100025 0.035185 0.697079 0.5 +-0.0935537 0.118404 0.0151524 0.667612 0.5 +-0.084908 0.10801 0.0228537 0.694681 0.5 +-0.0210677 0.0821213 0.0562096 0.557699 0.5 +-0.0149957 0.082187 0.0572635 0.665194 0.5 +-0.00899671 0.0822178 0.0576875 0.71377 0.5 +-0.00299966 0.0822055 0.0574653 0.668024 0.472979 +0.0034748 0.0817533 0.0567544 0.69456 0.5 +0.00824833 0.082992 0.0556315 0.615627 0.5 +0.0102414 0.0812949 0.0546523 0.424956 0.485927 +-0.0398496 0.123966 -0.00878898 0.60318 0.5 +-0.092257 0.124769 0.00902091 0.309094 0.468872 +-0.0436728 0.126191 0.0209533 0.472028 0.413108 +-0.0820425 0.105873 -0.00271871 0.341089 0.347157 +-0.0663016 0.0807623 0.0424437 0.632223 0.5 +-0.0639939 0.0836688 0.0439754 0.778832 0.5 +-0.058539 0.0825906 0.0439671 0.770991 0.5 +-0.0521209 0.0822523 0.0446262 0.782751 0.5 +-0.0467559 0.0828569 0.0439458 0.699516 0.399968 +-0.0424962 0.0810729 0.0423266 0.617938 0.5 +-0.0404903 0.0830123 0.0430984 0.712874 0.5 +-0.0365108 0.0825773 0.0434355 0.675696 0.5 +-0.032204 0.0824171 0.0421121 0.529763 0.5 +-0.0864005 0.152981 0.0204492 0.250247 0.416029 +-0.0235661 0.115415 0.0353667 0.518805 0.471584 +-0.0764871 0.111685 0.0461598 0.498936 0.5 +-0.0763895 0.14977 -0.00829972 0.604451 0.5 +-0.0754801 0.161855 -0.0327796 0.39691 0.5 +-0.0285733 0.0828247 0.0462702 0.636794 0.5 +-0.0862819 0.100797 0.0028483 0.65379 0.5 +0.021088 0.08242 0.0504086 0.491924 0.475524 +-0.0801892 0.143128 -0.00230055 0.641961 0.5 +0.00844098 0.124407 -0.00878569 0.555015 0.5 +0.0147552 0.0825883 0.0529115 0.480476 0.5 +-0.061995 0.161169 -0.032654 0.499509 0.5 +-0.0807571 0.1525 0.0307996 0.295115 0.454522 +-0.00295953 0.130272 0.00279699 0.742188 0.5 +-0.0153619 0.0884791 0.0565599 0.818561 0.5 +-0.00899729 0.0878977 0.0570287 0.818958 0.5 +-0.00299611 0.0880658 0.0568489 0.695384 0.5 +0.00301457 0.0885291 0.0562756 0.81087 0.5 +0.00834267 0.0873808 0.0555541 0.577038 0.479545 +-0.00897481 0.0941651 -0.0338408 0.678465 0.5 +0.0314278 0.11673 0.0250113 0.597807 0.5 +-0.0760602 0.155337 0.0093949 0.68566 0.5 +0.0257808 0.116776 -0.00728909 0.54747 0.36626 +-0.0646577 0.0882843 0.0447113 0.69894 0.5 +-0.058996 0.0882997 0.0449149 0.778337 0.5 +-0.0529958 0.0883132 0.0451395 0.696869 0.45083 +-0.0465421 0.0881579 0.0443187 0.605881 0.5 +-0.0404961 0.0876863 0.0430941 0.556958 0.5 +-0.0331792 0.0885648 0.04366 0.668172 0.5 +-0.0280482 0.0879652 0.046363 0.699915 0.5 +0.0150626 0.0881784 0.0517745 0.702815 0.5 +0.0205955 0.087113 0.0492325 0.678548 0.5 +-0.0702712 0.0823874 0.0409431 0.628092 0.5 +-0.0296926 0.0896882 -0.0286839 0.317989 0.390463 +-0.0236137 0.179242 -0.0115629 0.264741 0.5 +-0.0809391 0.100029 0.0323433 0.683272 0.5 +-0.0928336 0.130683 0.0207107 0.62518 0.472282 +-0.0761771 0.156201 -0.0204165 0.612769 0.5 +0.0146577 0.129396 0.00843576 0.595962 0.5 +0.0104845 0.089766 0.0542005 0.46622 0.5 +-0.072579 0.161253 -0.0389447 0.482103 0.5 +-0.0322741 0.110391 -0.0184574 0.809584 0.5 +-0.0550172 0.150108 0.027792 0.412797 0.5 +-0.071635 0.0883254 0.0414652 0.604622 0.463567 +-0.0424904 0.0895336 0.0426086 0.959715 0.5 +0.0207945 0.0897491 0.0484315 0.669841 0.5 +0.0273189 0.118845 -0.00265658 0.615055 0.5 +0.0285218 0.121112 0.0162366 0.593248 0.434231 +-0.00899735 0.0930598 0.0559298 0.639163 0.5 +-0.00291176 0.118727 -0.0144021 0.826286 0.5 +-0.0885191 0.113233 0.0327948 0.447552 0.461926 +-0.0713744 0.0938304 0.0415269 0.544171 0.444972 +-0.0641029 0.0935514 0.0439488 0.597795 0.395518 +-0.0584965 0.0944146 0.0446213 0.678752 0.5 +-0.0515853 0.0939836 0.0442383 0.634435 0.477778 +-0.0465591 0.0937901 0.0436103 0.714507 0.5 +-0.0414914 0.0942416 0.0425268 0.490492 0.46307 +-0.0377723 0.0933327 0.0434889 0.620752 0.5 +-0.0332864 0.0945766 0.0443868 0.723538 0.5 +-0.0263807 0.094318 0.0450568 0.620324 0.5 +-0.0141606 0.0929618 0.0553898 0.503825 0.5 +-0.00319641 0.0930898 0.0557853 0.624082 0.5 +0.00150357 0.0931879 0.0551544 0.492015 0.5 +0.00367616 0.0950752 0.0535295 0.508462 0.5 +0.00915739 0.0941794 0.0519212 0.597357 0.452723 +0.0216553 0.0937794 0.0473202 0.671835 0.5 +-0.0702968 0.174481 -0.045888 0.43732 0.455145 +-0.0305889 0.168899 -0.00702359 0.59106 0.5 +-0.0528191 0.162649 0.00296711 0.343566 0.5 +-0.0890968 0.0940104 0.0208024 0.539357 0.478012 +-0.0626249 0.173112 -0.0586131 0.353011 0.447085 +-0.0443835 0.105923 -0.0201903 0.683228 0.5 +-0.0664958 0.0951776 0.0424531 0.672396 0.5 +-0.0324384 0.126415 0.0146752 0.445893 0.463327 +-0.0152469 0.0961657 0.0518098 0.323594 0.5 +-0.0097537 0.0960506 0.0535818 0.446732 0.426556 +-0.00304601 0.0963367 0.0537791 0.579525 0.5 +0.01642 0.0957081 0.0480381 0.687032 0.5 +-0.0876548 0.105191 0.0148253 0.774556 0.5 +-0.0699417 0.0763232 0.0381496 0.596573 0.5 +0.0358078 0.0958594 -0.0120328 0.738943 0.5 +0.0374966 0.100154 0.031249 0.720944 0.5 +-0.0530195 0.150059 0.0207323 0.696139 0.5 +-0.0905911 0.131765 0.0328667 0.816274 0.5 +-0.0709717 0.147309 -0.0268389 0.224341 0.389051 +-0.0443321 0.0935075 -0.0222668 0.709831 0.5 +-0.0400911 0.128618 0.00909496 0.81345 0.5 +-0.0710054 0.100275 0.0398128 0.481571 0.5 +-0.0653063 0.100124 0.0417262 0.670525 0.470095 +-0.0589969 0.0980495 0.0430328 0.779482 0.5 +-0.0529938 0.0980631 0.0432952 0.836255 0.5 +-0.0469951 0.0980659 0.043235 0.637806 0.5 +-0.0408476 0.100401 0.0414668 0.648927 0.395789 +-0.0323344 0.0988071 0.0435216 0.652032 0.5 +-0.0259464 0.0998425 0.0438947 0.737424 0.5 +-0.0212066 0.0999849 0.0444194 0.576924 0.5 +0.00749586 0.09835 0.0488255 0.46146 0.5 +0.0090271 0.101109 0.0469975 0.470012 0.5 +0.0153076 0.100008 0.0472449 0.600016 0.5 +0.0208175 0.100067 0.0453866 0.595024 0.46889 +-0.0648326 0.131509 -0.00838673 0.790869 0.5 +-0.0740297 0.150832 -0.0323367 0.406089 0.5 +-0.0932444 0.124885 0.026841 0.802537 0.5 +-0.0633239 0.169093 -0.0610358 0.362406 0.5 +-0.0771158 0.162488 -0.0202679 0.465605 0.5 +-0.0585669 0.0647555 0.0323611 0.494963 0.328305 +0.0377689 0.110383 0.00969065 0.710008 0.5 +-0.0503559 0.0935892 -0.0218956 0.807094 0.5 +-0.0589961 0.101543 0.042437 0.529374 0.5 +-0.0516647 0.101981 0.0417488 0.647378 0.5 +-0.0469248 0.101325 0.0421166 0.608323 0.5 +-0.0352173 0.101965 0.0413638 0.751982 0.5 +0.00285015 0.100935 0.0464433 0.395489 0.5 +-0.075479 0.150312 -0.0143808 0.730394 0.5 +-0.078936 0.108126 -0.00525459 0.540251 0.381971 +-0.0251472 0.168981 -0.0187156 0.757996 0.5 +-0.071457 0.113692 0.0499983 0.429195 0.5 +-0.0747771 0.0997536 0.0377868 0.551123 0.5 +-0.0902919 0.137212 0.0146286 0.495279 0.5 +-0.0264568 0.105883 0.0411765 0.58994 0.471484 +-0.0209966 0.1044 0.0429589 0.797197 0.5 +-0.0145208 0.105597 0.0430511 0.780555 0.5 +-0.00899316 0.10622 0.0435541 0.510194 0.5 +-0.00289533 0.105882 0.0438861 0.384284 0.5 +0.00245231 0.105621 0.0429868 0.332307 0.5 +0.00945613 0.104903 0.0439002 0.435482 0.5 +0.0149913 0.104769 0.0443348 0.548532 0.5 +-0.0772186 0.106139 0.0350601 0.430274 0.367589 +-0.0708601 0.106945 0.0381598 0.402417 0.5 +-0.0652985 0.106577 0.0390805 0.558067 0.398761 +-0.0583896 0.105623 0.0405326 0.594554 0.5 +-0.0529341 0.106445 0.0398435 0.644542 0.398207 +-0.0461638 0.105797 0.0404843 0.759883 0.5 +-0.0400204 0.106789 0.0388993 0.653599 0.5 +-0.03311 0.106322 0.0394461 0.532024 0.5 +0.0193026 0.10477 0.0431964 0.486674 0.480281 +-0.0501412 0.13774 0.00286739 0.569746 0.5 +0.0266104 0.105911 0.0384052 0.650339 0.5 +0.0438719 0.088439 -0.0031027 0.506353 0.478726 +-0.0590381 0.113203 0.0362299 0.87726 0.5 +-0.021499 0.107851 0.0414162 0.584043 0.5 +-0.0164951 0.107881 0.0420289 0.633836 0.5 +0.00450524 0.107918 0.0419336 0.79888 0.5 +0.00856234 0.108229 0.0410531 0.820786 0.5 +0.0149994 0.10779 0.0412845 0.598409 0.5 +0.0213049 0.106041 0.0409433 0.561561 0.479574 +-0.0336665 0.167843 -0.00338268 0.478764 0.5 +-0.0587789 0.131705 -0.00671001 0.673026 0.5 +-0.0443517 0.100306 -0.0215281 0.825942 0.5 +-0.0147306 0.179604 -0.0266222 0.40888 0.5 +0.0159582 0.108177 -0.0177822 0.564672 0.468958 +-0.0638447 0.138119 -0.00733006 0.633194 0.5 +-0.0330953 0.167861 -0.0155539 0.527374 0.428366 +-0.0643684 0.125359 -0.00876153 0.813046 0.5 +-0.032583 0.161992 -0.0142418 0.852313 0.5 +-0.068568 0.110392 0.0392194 0.353622 0.364353 +-0.0643494 0.112195 0.0388907 0.34696 0.5 +-0.0593722 0.112082 0.0373875 0.588374 0.5 +-0.0529986 0.110472 0.0373551 0.513233 0.408461 +-0.0468613 0.11028 0.0378862 0.569336 0.5 +-0.040984 0.110496 0.0370883 0.553647 0.5 +-0.0320055 0.110468 0.0370438 0.565129 0.5 +-0.0074871 0.110717 0.042649 0.617568 0.5 +-0.00449218 0.110714 0.0426582 0.621679 0.5 +0.0250033 0.110611 0.0368459 0.631257 0.5 +0.025919 0.0995286 -0.0189206 0.684181 0.5 +-0.06973 0.112153 0.0457184 0.746569 0.5 +-0.045604 0.148834 -0.00329924 0.521986 0.5 +-0.0653006 0.0947889 -0.0177657 0.582853 0.5 +-0.0906677 0.13318 0.0277848 0.773217 0.5 +-0.0331508 0.094474 -0.0237799 0.742 0.5 +-0.0575764 0.0941613 -0.0208023 0.703326 0.5 +-0.0200586 0.0397198 0.0532237 0.447203 0.5 +-0.0203685 0.0352888 0.051184 0.291685 0.457265 +-0.0764163 0.125947 -0.00745144 0.524375 0.5 +-0.0205906 0.167551 -0.0139677 0.809186 0.5 +0.025858 0.116851 0.0315289 0.660225 0.5 +-0.0139279 0.167191 -0.021044 0.669958 0.5 +-0.0587481 0.149802 -0.00133886 0.562881 0.5 +0.0144191 0.0395247 0.0443396 0.266796 0.5 +0.0332953 0.105473 0.0329627 0.721815 0.5 +-0.0647461 0.114313 -0.0115219 0.592211 0.5 +-0.0520818 0.0353771 0.0449331 0.341981 0.5 +-0.015004 0.0392095 0.0513548 0.312679 0.5 +-0.0094925 0.0384962 0.049554 0.302651 0.5 +-0.0638496 0.117631 0.0454477 0.559641 0.5 +-0.0573025 0.136864 0.033162 0.554568 0.5 +0.0189101 0.0400942 0.0428502 0.270107 0.5 +-0.0508192 0.124393 0.0332635 0.581555 0.5 +-0.0182623 0.180885 -0.017743 0.594618 0.5 +-0.0651271 0.150343 -0.0325707 0.505808 0.5 +0.0332966 0.0936886 0.0400216 0.637373 0.5 +-0.0463011 0.149493 0.00833001 0.611316 0.5 +0.00260773 0.0354887 0.0450013 0.261253 0.345588 +-0.0780807 0.10971 0.0423535 0.916894 0.5 +-0.0542262 0.124756 0.0369858 0.64506 0.5 +-0.0402584 0.0361447 0.0436625 0.193197 0.5 +-0.00317483 0.0942874 -0.0331049 0.71511 0.325502 +-0.0151032 0.179716 -0.0207621 0.731902 0.5 +0.026141 0.0403246 0.0327265 0.294647 0.339561 +-0.0640247 0.111376 -0.0136272 0.608847 0.5 +0.027817 0.112309 0.0339118 0.692282 0.5 +-0.0586332 0.142774 0.0334953 0.761767 0.5 +-0.0146622 0.167501 -0.0154455 0.61604 0.5 +-0.0270893 0.167298 -0.00866399 0.642638 0.5 +0.0152056 0.045813 0.0442638 0.487785 0.5 +0.0190988 0.0442996 0.0429 0.362689 0.463942 +0.0215694 0.0456112 0.041209 0.479281 0.5 +0.0257452 0.0459137 0.0381185 0.444171 0.5 +0.0387365 0.0944447 0.0327088 0.718127 0.5 +0.0287308 0.0456722 0.0347466 0.335561 0.431941 +-0.0151805 0.173809 -0.0213305 0.730436 0.5 +-0.0658903 0.118253 0.0498126 0.307185 0.5 +-0.0628345 0.093206 -0.0188544 0.659442 0.5 +-0.0643065 0.142451 0.0394123 0.621016 0.5 +-0.040079 0.150283 0.00280951 0.491474 0.5 +-0.026851 0.173268 -0.00983852 0.620534 0.5 +-0.0207913 0.173767 -0.0147826 0.653794 0.5 +-0.0582334 0.124238 0.0403406 0.70004 0.5 +-0.0683337 0.131545 0.0479709 0.732904 0.5 +-0.0693547 0.10637 -0.012803 0.472443 0.5 +-0.0428668 0.157627 0.0050419 0.670804 0.5 +-0.0476449 0.130368 0.0258834 0.623828 0.5 +0.0379451 0.0817167 -0.0141547 0.644934 0.5 +0.0312298 0.0470286 0.0324465 0.426433 0.5 +-0.0662284 0.138149 0.042896 0.72515 0.5 +-0.0644094 0.105575 -0.0158634 0.566501 0.5 +0.0411271 0.0443713 0.0285474 0.466284 0.5 +-0.0830031 0.0762361 0.0150296 0.67606 0.5 +-0.0660167 0.123488 0.0501643 0.718404 0.5 +-0.0416352 0.155329 0.00636435 0.466436 0.5 +-0.0388456 0.155994 0.00477206 0.438555 0.402124 +-0.0551732 0.116538 0.0359195 0.457649 0.5 +-0.0600069 0.134082 0.0369434 0.682472 0.5 +0.0452816 0.0453284 0.0263124 0.471094 0.5 +0.0513161 0.0463154 0.0204963 0.342211 0.398387 +-0.0106687 0.172847 -0.0215627 0.69267 0.5 +-0.0147735 0.18419 -0.0259341 0.309641 0.5 +0.0301064 0.106776 0.0358091 0.72383 0.5 +-0.063709 0.125122 0.0457451 0.712215 0.420475 +0.0473431 0.0499217 0.0295077 0.554948 0.5 +0.0497106 0.0482066 0.0259506 0.48379 0.5 +0.0518484 0.0518415 0.0267161 0.416499 0.5 +-0.0162732 0.172938 -0.0174582 0.719256 0.5 +0.0355097 0.107304 0.0291151 0.718782 0.5 +-0.0552656 0.143077 0.0300537 0.622521 0.5 +-0.0637191 0.136482 0.0388176 0.603354 0.5 +-0.0199086 0.161072 -0.00863325 0.350317 0.5 +-0.0209172 0.179282 -0.0148523 0.455842 0.5 +0.014511 0.0513519 0.0474271 0.589102 0.5 +-0.0610259 0.126912 0.0416133 0.698375 0.5 +0.0539905 0.0494141 0.0219114 0.418448 0.5 +0.00925922 0.118865 -0.0148674 0.54369 0.457314 +-0.0268384 0.162091 -0.00836699 0.546076 0.486591 +-0.0367024 0.163198 -0.00107067 0.680811 0.5 +-0.0336432 0.155948 0.00188963 0.445666 0.44081 +-0.0280966 0.159587 0.000483069 0.431301 0.5 +-0.026491 0.16163 -0.00321758 0.537982 0.323001 +0.0206613 0.0528733 0.0451655 0.647628 0.324331 +0.0231576 0.0513069 0.0414753 0.507052 0.5 +0.0266044 0.0526516 0.039853 0.635463 0.446542 +0.0309772 0.0527823 0.0371348 0.671735 0.5 +0.0239371 0.103424 0.0418106 0.654526 0.5 +0.0568895 0.0527484 0.0209204 0.474964 0.5 +-0.0664209 0.11329 0.0441331 0.212624 0.5 +-0.0326789 0.162384 -0.00243762 0.543585 0.5 +0.0145199 0.0932586 -0.026363 0.546403 0.5 +-0.0543983 0.119186 0.0365781 0.502204 0.44785 +-0.0564272 0.132376 0.0357966 0.720059 0.5 +-0.0501636 0.142911 0.00230897 0.376445 0.5 +-0.043714 0.147707 0.0038501 0.245798 0.5 +-0.0291346 0.177171 -0.00534178 0.371295 0.5 +0.0357304 0.100363 -0.0111604 0.61591 0.5 +0.0133943 0.0541536 0.0499521 0.532724 0.5 +0.0551089 0.0545007 0.0253961 0.545646 0.5 +0.0291033 0.0572886 0.0407089 0.633826 0.5 +0.0585723 0.0583402 0.0214893 0.549998 0.477428 +-0.0740322 0.0656952 0.0144875 0.594594 0.5 +-0.0749844 0.179305 -0.0518221 0.216638 0.5 +0.0145778 0.0585769 0.0501691 0.387785 0.5 +0.0214876 0.058332 0.0470549 0.596242 0.5 +0.0259507 0.0590004 0.0437762 0.663038 0.5 +0.032833 0.0585633 0.0387158 0.630786 0.5 +0.0358218 0.0578374 0.0350365 0.591179 0.5 +0.0360585 0.0951301 0.0364902 0.726421 0.5 +-0.0886806 0.118283 0.0459142 0.444358 0.5 +0.0562736 0.0586365 0.0253398 0.57284 0.5 +0.0303311 0.0951295 0.0419589 0.717458 0.5 +-0.0222315 0.167389 -0.0110472 0.688671 0.5 +-0.0543257 0.136577 0.0307959 0.688078 0.5 +-0.0500074 0.150447 0.0117579 0.563476 0.5 +-0.0616289 0.137406 0.0354744 0.592141 0.5 +-0.0319367 0.159507 0.00191749 0.44862 0.5 +-0.0634458 0.132148 0.0406867 0.731705 0.5 +0.0368678 0.0921989 0.0367449 0.708135 0.5 +-0.0728433 0.156137 -0.0339112 0.713518 0.5 +0.0389872 0.0640689 0.0330299 0.521361 0.5 +-0.0636611 0.1488 -0.0205996 0.618447 0.5 +0.0153938 0.0648444 0.0513036 0.554385 0.463079 +0.0213958 0.0645506 0.0473078 0.414803 0.412252 +0.0265105 0.0649235 0.0439721 0.611901 0.5 +0.0302364 0.0650657 0.0415975 0.600683 0.487653 +0.0331295 0.0642221 0.0397381 0.500385 0.490901 +0.0367885 0.065027 0.0366867 0.593561 0.5 +0.0563131 0.0650782 0.0252208 0.639437 0.5 +0.0591364 0.0644742 0.0211357 0.550839 0.448044 +-0.0110683 0.167098 -0.0167807 0.360187 0.5 +-0.0605202 0.146205 0.0366666 0.591479 0.5 +0.0194528 0.0665736 0.0491642 0.603282 0.5 +-0.0286777 0.158132 0.000508817 0.402765 0.431383 +0.0253025 0.0989569 0.0434277 0.623394 0.5 +-0.0349979 0.152158 8.20736e-05 0.217633 0.5 +0.014665 0.070627 0.0528306 0.52613 0.5 +0.0202908 0.071041 0.0498828 0.634288 0.435356 +0.0230702 0.0702991 0.0473835 0.571849 0.5 +0.0263693 0.0706238 0.0441789 0.622852 0.474797 +0.0328306 0.0707606 0.0401362 0.612279 0.409693 +0.0368832 0.070672 0.0365953 0.662199 0.5 +0.0398878 0.0705632 0.0325808 0.656566 0.5 +0.0579544 0.0694794 0.0198345 0.6125 0.5 +-0.0641704 0.063724 0.0268682 0.425507 0.418571 +-0.0919499 0.114216 0.0149265 0.530043 0.5 +0.0351624 0.0819076 -0.0172502 0.760295 0.5 +-0.0862408 0.119271 -0.00117534 0.455279 0.5 +-0.0294401 0.174958 -0.00579982 0.562984 0.5 +-0.0175288 0.165418 -0.0114925 0.675539 0.5 +-0.0617869 0.117789 0.0409144 0.40334 0.5 +0.0301891 0.0723658 0.0418804 0.606777 0.5 +-0.0822099 0.149486 0.00288044 0.385889 0.468811 +-0.0760271 0.175704 -0.0506937 0.340571 0.5 +-0.0652343 0.0614738 0.0211346 0.414933 0.425841 +-0.0266574 0.110394 -0.019007 0.783101 0.5 +-0.0813538 0.0779161 0.0268055 0.756683 0.5 +0.021417 0.118723 -0.00893569 0.549 0.5 +0.0149346 0.0759297 0.0536191 0.48671 0.476705 +0.0209886 0.0761609 0.0506055 0.575091 0.5 +0.0268396 0.0762089 0.0459193 0.572664 0.5 +0.0336785 0.0760737 0.0405166 0.630563 0.5 +0.0373422 0.0760306 0.0366776 0.505468 0.5 +0.0400324 0.0763062 0.0328345 0.645662 0.5 +0.0419048 0.076876 0.0296092 0.673034 0.5 +0.0438094 0.0763805 0.0258638 0.624347 0.5 +-0.0452412 0.118472 -0.0142046 0.833781 0.5 +0.0456773 0.0768089 0.0208187 0.458504 0.467907 +-0.050165 0.137714 0.0207618 0.606401 0.481088 +-0.00327054 0.111563 -0.0203549 0.551699 0.482404 +-0.0483236 0.145111 0.00757835 0.59165 0.5 +0.0310833 0.0775315 0.0432282 0.624343 0.5 +-0.046855 0.145222 0.00288431 0.195425 0.432502 +-0.0141716 0.10541 -0.0225802 0.672132 0.5 +0.0470348 0.0753979 0.0148736 0.455861 0.5 +-0.0611433 0.140542 0.0356184 0.646306 0.5 +0.0272779 0.0823714 0.0459243 0.61663 0.478488 +0.0309212 0.08255 0.0430252 0.611382 0.5 +0.0343037 0.0825412 0.0402907 0.613309 0.465282 +0.0370354 0.0824663 0.0369099 0.642585 0.5 +-0.0799946 0.147989 -0.000835337 0.484293 0.5 +-0.0774435 0.0690153 0.00961977 0.704234 0.277826 +0.0404363 0.0826995 0.0326021 0.686672 0.5 +0.0417479 0.0827335 0.0302524 0.63553 0.5 +0.0436887 0.0825508 0.0263844 0.61829 0.5 +0.0454407 0.0825465 0.0207137 0.601475 0.480065 +-0.0822812 0.116295 0.0482855 0.66926 0.5 +-0.0844726 0.0947391 -0.00345192 0.592061 0.5 +-0.020271 0.168003 -0.0193935 0.821267 0.5 +-0.0742716 0.0668501 0.0190414 0.706894 0.5 +0.026747 0.0882417 0.0458314 0.539865 0.389736 +0.0308722 0.0882572 0.0430146 0.948814 0.5 +0.0344922 0.0883047 0.0403697 0.638338 0.5 +0.0372481 0.0881263 0.0366393 0.643327 0.5 +0.039927 0.088094 0.0326668 0.711283 0.5 +0.0419027 0.0877782 0.0290815 0.667656 0.5 +0.00264738 0.112302 -0.019871 0.766242 0.5 +-0.0703315 0.1455 -0.0205576 0.136819 0.239158 +-0.0749446 0.137879 -0.00653312 0.459033 0.397283 +-0.0266967 0.114299 -0.0159903 0.856895 0.5 +-0.0869924 0.113518 0.00410409 0.344807 0.5 +-0.0142186 0.174013 -0.0259807 0.439072 0.5 +-0.0221564 0.157852 -0.00861651 0.254248 0.5 +-0.011587 0.164129 -0.0163045 0.228563 0.367524 +-0.00997381 0.169338 -0.0247765 0.42189 0.5 +-0.082875 0.143405 0.00186692 0.494272 0.5 +0.0203757 0.0354405 -0.00287175 0 0 +0.0191274 0.0363337 -0.00917714 0.174536 0.5 +0.0184456 0.036388 -0.013479 0.173751 0.5 +0.0149535 0.0347732 -0.0154937 0.144529 0.253209 +0.0221204 0.0372026 0.0342324 0.156956 0.287305 +0.039271 0.0382866 0.00854708 0.245023 0.5 +0.0397549 0.0398545 0.002614 0.276002 0.5 +0.0221892 0.0380614 -0.00446361 0.173629 0.5 +0.0179901 0.0369066 -0.0161835 0.336518 0.5 +0.0154148 0.0392444 -0.0212861 0.367832 0.5 +0.0208023 0.100118 -0.0213392 0.648293 0.46589 +0.0446004 0.0409064 0.00927401 0.208963 0.5 +0.0435625 0.0411355 0.00427044 0.357471 0.452104 +0.0381381 0.0411139 -0.00147908 0.514406 0.5 +-0.0478807 0.135207 0.00885778 0.482359 0.5 +0.0217274 0.0404287 -0.00964433 0.311593 0.5 +0.0206744 0.0405956 -0.0144437 0.473825 0.5 +0.0192578 0.0411681 -0.0195074 0.414351 0.5 +-0.0885736 0.112913 0.0395856 0.488806 0.5 +-0.026793 0.106457 -0.0218501 0.617481 0.5 +0.0481487 0.0428585 0.0145594 0.265572 0.5 +0.0521212 0.0461655 0.0089655 0.199267 0.5 +0.0480438 0.0430647 0.00724585 0.412258 0.5 +0.0460936 0.0434131 0.00284357 0.566688 0.5 +0.0285003 0.100485 -0.0168103 0.728425 0.5 +0.0269462 0.0395833 -0.00334578 0.464947 0.5 +-0.0907856 0.117838 0.00647331 0.421552 0.5 +-0.062721 0.167567 -0.0470628 0.645866 0.5 +-0.0799532 0.106813 0.0316838 0.420249 0.5 +0.0527437 0.0462125 0.0139554 0.286197 0.5 +0.0504533 0.0466263 0.00264513 0.57721 0.5 +-0.0322581 0.117324 -0.0133273 0.811815 0.5 +0.0272475 0.0455966 -0.00927071 0.533119 0.5 +-0.0146455 0.0942084 -0.0337341 0.520871 0.5 +-0.0411545 0.16722 -0.010818 0.48116 0.5 +-0.0721385 0.156112 -0.0384102 0.511983 0.468875 +0.0456803 0.0474217 -0.00311192 0.412576 0.5 +0.0239407 0.0433254 -0.00969837 0.651864 0.5 +0.021084 0.0462585 -0.0205303 0.476548 0.5 +-0.0348527 0.0351549 -0.0307351 0.16856 0.5 +-0.0699867 0.0663066 0.0259153 0.590849 0.43032 +-0.0747071 0.149891 -0.0201453 0.5851 0.5 +-0.0845448 0.13725 0.000743181 0.580039 0.5 +0.0549514 0.0484178 0.0163982 0.295573 0.5 +0.0264565 0.0466261 -0.0141039 0.515417 0.5 +0.0225276 0.0444655 -0.0157683 0.505631 0.5 +0.0330538 0.0938135 -0.0160538 0.699679 0.5 +0.0526476 0.0694992 0.00297306 0.629664 0.372945 +0.0528544 0.0581339 -0.00277966 0.592036 0.5 +-0.0571464 0.0671799 0.0361705 0.503626 0.472266 +-0.0651544 0.157167 -0.0515491 0.708429 0.5 +-0.0493189 0.133682 0.00119868 0.355836 0.438333 +-0.032962 0.10595 -0.0206729 0.810434 0.5 +-0.0649538 0.155656 -0.045631 0.820472 0.5 +-0.0390456 0.150445 -0.00354536 0.204281 0.5 +0.0574365 0.051618 0.0145183 0.351624 0.5 +0.0574129 0.0522531 0.00903377 0.511629 0.5 +0.0536112 0.0500965 0.00204174 0.768402 0.5 +0.0512204 0.0520121 -0.00218354 0.534755 0.5 +0.0471226 0.0515811 -0.00481298 0.434179 0.5 +0.033443 0.047576 -0.0063817 0.557462 0.465257 +0.00280933 0.118297 -0.0158208 0.570337 0.473222 +-0.0147841 0.10125 -0.0238408 0.771507 0.5 +-0.0620037 0.167422 -0.0527165 0.538383 0.466596 +0.0559147 0.0528382 0.00339683 0.824166 0.5 +0.0334801 0.0518506 -0.00825293 0.591066 0.5 +0.0287814 0.0501171 -0.0157926 0.574224 0.5 +0.0256197 0.0485542 -0.0190548 0.421586 0.5 +-0.00863537 0.118406 -0.0146114 0.827086 0.5 +-0.0148322 0.117675 -0.014701 0.559736 0.5 +-0.0615138 0.145712 -0.00481276 0.466074 0.5 +0.0232531 0.12083 -0.00456186 0.617393 0.5 +-0.0401535 0.0342718 -0.0275149 0.0979878 0.5 +0.0302657 0.0496868 -0.0107289 0.647285 0.5 +0.0320066 0.111334 -0.00737407 0.536101 0.5 +-0.0211003 0.120417 -0.0102482 0.732965 0.5 +-0.0204991 0.117125 -0.0140803 0.767014 0.5 +-0.00910263 0.0383602 -0.025776 0.274297 0.5 +-0.0525144 0.11229 -0.0171034 0.442719 0.484227 +0.0202353 0.123713 -0.00247094 0.59012 0.5 +-0.0701749 0.0347541 -0.0017891 0.135623 0.5 +-0.00340266 0.114844 -0.0176928 0.826111 0.5 +0.0310248 0.053713 -0.0140522 0.572913 0.5 +0.0268191 0.0528482 -0.020339 0.412387 0.455219 +-0.0147458 0.120673 -0.0105853 0.653192 0.5 +0.0270905 0.106214 -0.0146756 0.603346 0.5 +0.0465541 0.0697991 0.00228503 0.590477 0.5 +-0.00300122 0.100676 -0.0235814 0.77298 0.5 +-0.0755874 0.076212 0.033468 0.651011 0.5 +0.059738 0.0572998 0.0151736 0.624329 0.5 +0.0595394 0.0578717 0.00861672 0.650231 0.5 +0.0572091 0.0580526 0.00253507 0.577167 0.5 +-0.0142907 0.123147 -0.00746744 0.689207 0.5 +0.0211831 0.112303 -0.0140834 0.636933 0.5 +0.0347455 0.0565046 -0.010714 0.517615 0.5 +0.0249138 0.0825163 -0.0245877 0.759593 0.5 +-0.0382227 0.114521 -0.016178 0.845616 0.5 +-0.0819485 0.0761672 0.0208322 0.76776 0.5 +-0.0269557 0.0392251 -0.0293943 0.537642 0.5 +0.0377037 0.0593401 -0.00852013 0.537798 0.5 +0.0330295 0.0586306 -0.014729 0.60439 0.5 +0.0218121 0.0515865 -0.0236492 0.56032 0.5 +-0.0204953 0.0935908 -0.0331675 0.485557 0.5 +-0.0872217 0.113521 0.0440666 0.448078 0.427651 +-0.0271537 0.0351608 0.0509267 0.96808 0.5 +-0.0503825 0.106302 -0.0194598 0.649024 0.5 +0.0266611 0.0585067 -0.0219134 0.622435 0.5 +0.00975018 0.0945932 -0.0280451 0.504262 0.457756 +-0.0205524 0.122391 -0.00754739 0.498583 0.5 +-0.0668021 0.0909191 -0.0174744 0.566525 0.5 +-0.0856155 0.0942099 -0.00109094 0.420789 0.436678 +-0.0915274 0.11444 0.0204492 0.759207 0.5 +-0.0909048 0.131701 0.00809159 0.558083 0.5 +0.0404851 0.0578886 -0.0051698 0.425865 0.437223 +0.0295964 0.0580473 -0.0178274 0.608291 0.460655 +0.0266986 0.0941359 -0.0205949 0.662934 0.5 +-0.0677104 0.172869 -0.0572602 0.695141 0.5 +0.0142001 0.118043 -0.013917 0.45799 0.403894 +-0.0698171 0.0699687 0.0326375 0.529959 0.5 +0.0607097 0.0648802 0.0151632 0.434757 0.451533 +0.0609346 0.0630505 0.0131585 0.526971 0.5 +0.0602205 0.0643718 0.00864139 0.443146 0.456896 +0.0574055 0.0638877 0.00271573 0.413274 0.5 +-0.0797793 0.103858 -0.00660016 0.553637 0.5 +-0.0563867 0.137359 -0.00421998 0.659682 0.5 +0.0344512 0.0638263 -0.0152012 0.581486 0.5 +0.0307139 0.0605317 -0.0184589 0.617611 0.449874 +0.0185684 0.121789 -0.00725624 0.61441 0.349043 +-0.0456617 0.112414 -0.0169658 0.70381 0.5 +0.0456177 0.0644845 -0.00162168 0.572144 0.5 +-0.0584268 0.0349015 0.0441202 0.767369 0.5 +-0.0747982 0.0723674 0.0308514 0.656357 0.5 +-0.0699373 0.0621854 0.0151778 0.587415 0.5 +-0.052889 0.136519 -0.00170821 0.593683 0.5 +0.0410205 0.0644886 -0.00476733 0.363401 0.5 +0.0388712 0.0646166 -0.00976797 0.384344 0.5 +0.0514871 0.0637279 -0.00174794 0.518067 0.5 +-0.0787297 0.0744551 0.0267421 0.809934 0.5 +-0.0850281 0.144269 0.00618082 0.578063 0.5 +0.0313094 0.064487 -0.0188936 0.672704 0.5 +0.0267274 0.0646171 -0.0220842 0.752591 0.5 +0.0318737 0.0877439 -0.0192705 0.740422 0.5 +-0.0772455 0.143995 -0.00470939 0.452269 0.5 +0.0132576 0.110443 -0.0183541 0.539267 0.5 +-0.00289343 0.124723 -0.00863032 0.516883 0.5 +-0.0342868 0.038582 0.0485461 0.546061 0.5 +0.0200397 0.0876233 -0.0261205 0.735721 0.5 +0.0585453 0.0705354 0.0146976 0.608535 0.5 +0.0581405 0.0699819 0.00856199 0.483528 0.5 +0.056099 0.069436 0.00424359 0.385578 0.5 +0.0370479 0.0665186 -0.0132637 0.645736 0.5 +-0.062561 0.172971 -0.0616721 0.43069 0.5 +-0.0702718 0.15494 -0.0455472 0.29179 0.457421 +-0.0916259 0.130499 0.00930481 0.432982 0.472725 +-0.070021 0.148229 -0.0328231 0.322588 0.195946 +-0.0721274 0.0680183 0.0267753 0.656727 0.5 +-0.0745337 0.15067 -0.0264303 0.331486 0.5 +0.0431087 0.0713461 -0.002764 0.390428 0.45538 +0.0421659 0.0692525 -0.00466106 0.55545 0.5 +0.0345404 0.0699378 -0.0160391 0.727409 0.5 +-0.0342368 0.122912 -0.00708584 0.432969 0.5 +0.0401518 0.070932 -0.00951127 0.706551 0.5 +0.0370706 0.0707408 -0.013301 0.722628 0.5 +0.0310856 0.0702175 -0.0192905 0.761897 0.5 +0.0283004 0.0705453 -0.0222447 0.701199 0.5 +-0.00859023 0.101699 -0.0237897 0.731824 0.5 +-0.0328234 0.0400139 -0.029875 0.413461 0.5 +-0.0830588 0.11047 0.0397334 0.931001 0.5 +0.0142724 0.123237 -0.00806485 0.479991 0.484444 +-0.0760443 0.108637 0.0389078 0.769887 0.5 +-0.0732762 0.154939 -0.0321392 0.640327 0.5 +0.0160324 0.0889232 -0.0282477 0.595959 0.5 +-0.0901677 0.131361 0.0394374 0.633972 0.457764 +0.0455828 0.0768365 0.00270178 0.323813 0.5 +-0.0516717 0.0553965 0.014906 0.168077 0.5 +-0.0376545 0.121002 -0.0109724 0.599451 0.451266 +0.0466318 0.0762885 0.00910629 0.334003 0.5 +0.0437303 0.0769241 -0.00295564 0.541016 0.5 +0.0405043 0.0766784 -0.0084913 0.540094 0.5 +0.0369463 0.0762836 -0.0128837 0.716695 0.5 +0.0349351 0.0766648 -0.0155944 0.687304 0.5 +0.0319237 0.0763904 -0.0194186 0.722365 0.5 +0.0285208 0.0758075 -0.0225233 0.729644 0.5 +-0.0646857 0.068809 0.0348219 0.518098 0.396839 +-0.00335573 0.0986136 -0.0269283 0.762285 0.5 +-0.0383606 0.100112 -0.0217661 0.633523 0.5 +-0.0705433 0.149897 -0.0387319 0.143598 0.5 +-0.0247871 0.179215 -0.0188356 0.466421 0.5 +0.00339058 0.0937023 -0.0318365 0.697748 0.5 +-0.09099 0.142689 0.0226645 0.743514 0.5 +-0.0851088 0.102115 0.000391121 0.420019 0.403283 +0.00299202 0.124707 -0.00864775 0.631346 0.5 +-0.0649459 0.167336 -0.0329944 0.692397 0.5 +0.045975 0.0827243 0.0146716 0.494123 0.463874 +0.0461931 0.0827376 0.00867911 0.540283 0.443947 +0.0453461 0.0826602 0.00269811 0.520808 0.5 +0.032594 0.082231 -0.0190597 0.700575 0.5 +-0.0707752 0.142011 -0.00901143 0.440829 0.5 +-0.0396694 0.045239 -0.0210351 0.371561 0.5 +-0.0736488 0.145787 -0.0131048 0.298566 0.5 +-0.0661855 0.1779 -0.0529018 0.456268 0.5 +-0.0698006 0.179227 -0.0517285 0.330383 0.5 +-0.0719677 0.177848 -0.0474604 0.498199 0.393806 +-0.0131817 0.0974247 0.0509808 0.29677 0.5 +-0.0760529 0.177651 -0.0471457 0.200482 0.341482 +-0.0875274 0.149451 0.00937476 0.260452 0.5 +-0.0847504 0.149536 0.00652369 0.220089 0.5 +-0.0853843 0.0980412 -0.000554198 0.453316 0.5 +-0.070162 0.172945 -0.0393132 0.377002 0.42015 +-0.0669053 0.17136 -0.0404187 0.587367 0.5 +-0.0915765 0.114644 0.0108349 0.335405 0.476851 +0.0311175 0.116345 -0.00142056 0.524001 0.485056 +-0.09039 0.144074 0.0142555 0.571623 0.5 +0.0533752 0.0724173 0.00805773 0.504643 0.5 +0.0348115 0.113636 0.00289967 0.517745 0.5 +0.0321047 0.117128 0.00373672 0.512637 0.481334 +-0.0558554 0.16013 0.00226313 0.176407 0.35978 +0.0284127 0.12005 0.00266093 0.800124 0.5 +-0.0693417 0.151526 -0.0443255 0.162625 0.220555 +0.0509143 0.0733396 0.0112131 0.81315 0.5 +0.0485286 0.0726358 0.00856732 0.779683 0.5 +0.0251471 0.122517 0.00254898 0.804299 0.5 +-0.0684168 0.170157 -0.0319531 0.535557 0.5 +-0.071028 0.171274 -0.0325886 0.712016 0.5 +-0.0765634 0.155757 -0.00874762 0.256295 0.5 +0.0525206 0.0734678 0.0148876 0.468908 0.45355 +0.035521 0.113454 0.00908801 0.654915 0.5 +0.0208324 0.125627 0.00327965 0.76886 0.5 +-0.0476722 0.134348 0.0194434 0.579216 0.488505 +-0.0746083 0.171229 -0.0326516 0.439107 0.422901 +0.0322027 0.117616 0.0093642 0.646061 0.5 +0.0162523 0.127588 0.00132734 0.679655 0.445027 +-0.0914669 0.142805 0.0167223 0.344959 0.5 +0.0290775 0.120474 0.00686894 0.798143 0.5 +0.0135909 0.12914 0.00336546 0.632038 0.474565 +-0.0861635 0.100458 0.025719 0.514874 0.431291 +-0.0653051 0.165945 -0.0269849 0.665887 0.5 +-0.0698492 0.16889 -0.0268648 0.536219 0.5 +-0.07827 0.167473 -0.032496 0.259817 0.452429 +0.0215557 0.0945234 -0.0226594 0.630702 0.48336 +0.0260612 0.123082 0.00873766 0.803075 0.5 +0.00920342 0.130081 0.00248247 0.641161 0.5 +-0.0709934 0.170517 -0.0295248 0.566905 0.409383 +-0.0760202 0.167938 -0.0272636 0.242234 0.5 +0.0525229 0.0716654 0.0211203 0.349876 0.431389 +0.0207167 0.126566 0.00922145 0.763786 0.5 +-0.0746025 0.0998033 -0.0126456 0.503102 0.5 +-0.0864333 0.0890874 0.0257055 0.752441 0.5 +0.0354941 0.113435 0.0150848 0.708057 0.5 +0.0320737 0.117698 0.0146262 0.694886 0.5 +0.00294754 0.130714 0.00292443 0.849802 0.5 +-0.0256391 0.0823957 0.0519489 0.764034 0.5 +-0.0666258 0.165416 -0.0221631 0.534987 0.5 +-0.0804177 0.153092 0.00488677 0.321879 0.39417 +-0.0645623 0.0350017 0.0151892 0.352362 0.5 +-0.0627936 0.0352479 0.02012 0.616295 0.5 +-0.0642932 0.0349381 0.0264604 0.161121 0.384305 +-0.0642421 0.0397497 0.0267659 0.206373 0.5 +-0.0652419 0.0352202 0.0324357 0.167045 0.5 +-0.06432 0.0352261 0.0387914 0.349097 0.5 +-0.0869014 0.0944088 0.0260869 0.722262 0.5 +-0.026376 0.100403 -0.0237519 0.527518 0.47737 +-0.0704394 0.0348288 0.00888692 0.228898 0.5 +-0.0696375 0.039673 0.0091864 0.30841 0.5 +-0.0678064 0.035728 0.013362 0.509091 0.5 +-0.0778433 0.0819732 0.0354617 0.774608 0.5 +-0.0809318 0.0827942 0.0325 0.767831 0.5 +-0.0712316 0.038974 0.00275642 0.155719 0.237906 +-0.0616101 0.0379618 0.0219344 0 0 +-0.0653778 0.0407054 0.0323415 0.379158 0.5 +-0.0612949 0.040108 0.0438783 0.388361 0.5 +-0.0748891 0.0826916 0.0381154 0.772848 0.5 +-0.0841641 0.133769 0.0486564 0.546232 0.467433 +-0.0849106 0.0945271 0.0290479 0.754258 0.5 +-0.082994 0.144712 0.0404065 0.382972 0.420138 +-0.0265479 0.117619 -0.0132781 0.755106 0.5 +-0.0679678 0.0383221 0.0123903 0.271535 0.306541 +-0.0639259 0.0401146 0.0151101 0.258252 0.450399 +-0.0588527 0.0407802 0.0202136 0.51937 0.5 +-0.0869621 0.135589 0.0440584 0.520567 0.5 +-0.038827 0.0398484 0.042564 0.570175 0.5 +-0.0253238 0.0773437 0.0501603 0.646885 0.5 +0.00864855 0.111878 -0.0192252 0.821439 0.5 +-0.0625014 0.04424 0.0388616 0.455153 0.47063 +-0.088493 0.125258 0.0461673 0.674925 0.5 +0.0150785 0.10107 -0.0220372 0.749486 0.5 +-0.0810533 0.0876325 0.0334622 0.750019 0.5 +-0.0636602 0.0439221 0.0322355 0.437404 0.5 +-0.0823757 0.12585 -0.00459555 0.376136 0.464207 +-0.0374554 0.042873 0.0429512 0.492581 0.5 +-0.031328 0.0432863 0.0501185 0.483275 0.5 +-0.0841802 0.0875016 0.0285815 0.671149 0.464325 +-0.0690099 0.0427216 0.00298087 0.372436 0.5 +-0.0690323 0.0427133 0.00739115 0.277083 0.5 +-0.0642007 0.0449178 0.00895163 0.562755 0.5 +-0.0630005 0.0427497 0.0133004 0.520064 0.348086 +-0.0580777 0.0444032 0.0143596 0.493924 0.5 +-0.087476 0.130712 0.0458544 0.531379 0.477045 +-0.0837712 0.0999337 0.029339 0.668895 0.5 +-0.083719 0.0822846 0.0270932 0.660348 0.5 +-0.0209183 0.0934772 0.0512134 0.479975 0.5 +-0.0868983 0.142651 0.0383505 0.486766 0.469754 +-0.0588984 0.0467651 0.00989959 0.460736 0.319245 +-0.0529144 0.0464475 0.0158024 0.381525 0.5 +-0.0881654 0.0882094 0.0209192 0.624947 0.5 +-0.0494075 0.165901 0.000731671 0.369742 0.391777 +-0.0586114 0.0473978 0.0337061 0.152377 0.410418 +-0.05614 0.0517476 0.00835186 0.396733 0.5 +-0.0865231 0.148073 0.0321271 0.367072 0.452379 +-0.0308497 0.0493297 0.0429654 0.330168 0.454747 +-0.0769102 0.114994 0.0501188 0.653806 0.5 +-0.0209065 0.0959579 0.0474195 0.622864 0.5 +-0.0509947 0.0509637 0.0150799 0.759028 0.5 +0.00842415 0.0889657 -0.0320537 0.627702 0.5 +-0.0240561 0.0544386 0.0416973 0.433194 0.5 +-0.0510392 0.0524223 0.0203213 0.262945 0.5 +-0.0526208 0.0518271 0.027021 0.695325 0.5 +-0.0504022 0.0591186 0.0326891 0.768296 0.5 +-0.0478821 0.0590694 0.0363134 0.800191 0.5 +-0.0239128 0.0586553 0.0421308 0.768223 0.5 +-0.0759314 0.119228 -0.00697007 0.568703 0.5 +-0.0183181 0.0604564 0.0506182 0.70539 0.5 +-0.0298441 0.0972531 -0.0235715 0.830462 0.5 +-0.0241926 0.0628773 0.0422936 0.709715 0.5 +-0.0223998 0.06467 0.045979 0.606456 0.5 +-0.0192899 0.0641483 0.0503928 0.754401 0.5 +-0.0260109 0.172925 -0.0191453 0.51739 0.5 +-0.0265331 0.161574 -0.0144318 0.84044 0.5 +-0.0558556 0.15572 -0.00121016 0.41523 0.5 +-0.0599028 0.136466 -0.0064456 0.660892 0.5 +-0.063538 0.071665 0.0379463 0.556494 0.5 +-0.0200417 0.0869862 -0.0378876 0.500126 0.449734 +-0.0557176 0.105745 -0.0186241 0.707273 0.5 +-0.0530691 0.143914 -0.00100898 0.728895 0.5 +-0.0256688 0.0704637 0.0438935 0.717372 0.393932 +-0.0235577 0.0693774 0.0470203 0.657726 0.5 +-0.0525759 0.127247 -0.00521525 0.567734 0.5 +-0.0787859 0.131858 -0.00545913 0.44224 0.460808 +-0.0580212 0.120088 -0.0102747 0.564344 0.455328 +-0.0396294 0.110441 -0.0186258 0.62346 0.5 +-0.0210282 0.173113 -0.0214922 0.42389 0.352327 +-0.0547593 0.0563289 0.0107147 0.179388 0.5 +-0.0435534 0.0345758 -0.024752 0.176398 0.205782 +-0.0449833 0.0346921 -0.0207483 0.159962 0.261208 +-0.0443576 0.0390403 -0.0217491 0.178142 0.5 +-0.0462855 0.0345037 -0.0153112 0.189574 0.5 +-0.046619 0.0396457 -0.0141457 0.194812 0.5 +-0.00904923 0.0343826 -0.0246429 0.15305 0.5 +0.00311748 0.100303 -0.0227929 0.684313 0.5 +-0.0690809 0.0392217 -0.00181724 0.169982 0.409113 +-0.0920289 0.131041 0.0262349 0.856795 0.5 +-0.043414 0.0372487 -0.0253064 0.219927 0.5 +0.0280974 0.0818294 -0.0220931 0.752623 0.5 +-0.067702 0.169446 -0.0560134 0.487347 0.455218 +-0.0915377 0.129674 0.0312365 0.601516 0.48259 +-0.0663086 0.0411162 -0.00443149 0.346306 0.5 +-0.0731255 0.151935 -0.0368879 0.40925 0.5 +-0.0390145 0.0394889 -0.027598 0.3765 0.5 +-0.0637372 0.0437827 -0.00264533 0.37233 0.5 +-0.0605427 0.0425565 0.0246975 0.23689 0.5 +-0.0857603 0.130763 -0.000714461 0.66754 0.5 +-0.0520472 0.0403573 -0.0107411 0.62257 0.5 +-0.0568522 0.0434504 0.0224413 0.404188 0.5 +-0.043239 0.0429342 -0.0193166 0.339314 0.38382 +-0.0438787 0.0441322 -0.0144222 0.427488 0.468839 +-0.0457505 0.046486 -0.0105694 0.340556 0.5 +-0.0645938 0.0456897 0.00313082 0.3549 0.5 +-0.0525978 0.0464843 0.0207116 0.3335 0.5 +-0.0572578 0.0459489 0.026887 0.439332 0.5 +-0.0618962 0.0443648 0.0286813 0.302557 0.45843 +-0.0331467 0.0453179 -0.0267282 0.481653 0.5 +-0.0377669 0.0443547 -0.0252099 0.392631 0.5 +-0.0320922 0.114425 -0.0162304 0.853943 0.5 +-0.0578027 0.0470669 -0.0032674 0.530144 0.5 +-0.0914954 0.147994 0.0205137 0.478387 0.480384 +-0.0400067 0.0471536 -0.0151042 0.224844 0.33752 +0.00454895 0.121869 -0.0124797 0.622385 0.5 +0.0151282 0.112708 -0.0165496 0.634759 0.463552 +-0.0525787 0.0463291 -0.00775444 0.598118 0.5 +-0.0599276 0.0475112 0.00267117 0.286734 0.429608 +-0.0726458 0.147126 -0.0218625 0.235551 0.5 +-0.0740924 0.168686 -0.0440312 0.451963 0.347747 +-0.057494 0.0515426 0.00319413 0.311918 0.5 +-0.0536918 0.0483048 0.0264945 0.447469 0.5 +-0.0147156 0.114453 -0.0172255 0.634887 0.5 +-0.0335191 0.0480424 -0.021246 0.299501 0.5 +0.019461 0.0924333 -0.0244344 0.636237 0.5 +0.0169402 0.0952065 -0.0238278 0.793707 0.5 +0.0201047 0.104156 -0.0188197 0.859301 0.5 +-0.0319642 0.0516657 -0.0152509 0.265727 0.5 +-0.0368448 0.0488256 -0.0131071 0.109826 0.5 +-0.0391265 0.0518909 -0.0109467 0.555432 0.5 +-0.00892221 0.111576 -0.0202733 0.785262 0.5 +-0.0515659 0.0515158 -0.00751393 0.527245 0.5 +-0.0557028 0.05294 -0.00268598 0.514955 0.5 +-0.0293421 0.0526398 -0.0213991 0.356317 0.5 +-0.0314453 0.0496351 -0.0193539 0.306544 0.5 +0.0322381 0.10409 -0.0128482 0.653044 0.5 +-0.0261025 0.0525801 -0.0264669 0.366688 0.5 +-0.0583031 0.116733 -0.0130038 0.568329 0.5 +-0.014851 0.111599 -0.0191484 0.630253 0.463696 +-0.0521348 0.118189 -0.0137451 0.464136 0.474515 +-0.0517493 0.0582798 -0.00896954 0.683087 0.5 +-0.0561982 0.0582462 -0.00310645 0.618759 0.5 +-0.0587989 0.0586119 0.00276734 0.328771 0.427166 +-0.0585564 0.0578416 0.00857596 0.293131 0.5 +0.019026 0.11614 -0.0131686 0.497701 0.5 +-0.0211893 0.111662 -0.0190883 0.650648 0.5 +-0.0239176 0.0561149 -0.030057 0.484351 0.5 +-0.0272603 0.058548 -0.027478 0.457773 0.5 +-0.0295766 0.0582799 -0.0217551 0.550969 0.5 +-0.0320928 0.0589382 -0.0147618 0.534177 0.453646 +0.0073938 0.121789 -0.0126555 0.654152 0.5 +-0.0251946 0.0595227 -0.0308632 0.509396 0.5 +-0.0307167 0.06013 -0.0194181 0.549851 0.422118 +-0.0650113 0.0632174 -0.00293095 0.168435 0.5 +-0.0696479 0.065751 -0.00198101 0.165663 0.5 +-0.0699926 0.0635013 0.00374106 0.275779 0.5 +-0.0799435 0.0724812 0.0191514 0.599916 0.5 +-0.0676844 0.160922 -0.0559942 0.35716 0.5 +-0.0215435 0.0636559 -0.0350431 0.45692 0.5 +-0.0258325 0.0648252 -0.0322087 0.452259 0.5 +-0.028982 0.0636438 -0.0274997 0.410415 0.5 +-0.0304226 0.0629368 -0.0224261 0.908229 0.5 +-0.0319042 0.0651819 -0.0201942 0.518875 0.434998 +-0.0332741 0.0636337 -0.0160032 0.40837 0.447765 +-0.0205547 0.034111 -0.026401 0.174612 0.215481 +-0.0743367 0.0658286 0.00833126 0.649876 0.5 +0.016103 0.120745 -0.0103843 0.509865 0.5 +-0.0770212 0.0700544 0.00316631 0.305775 0.384345 +-0.0748219 0.06693 0.00451345 0.433069 0.463791 +-0.0306317 0.0657524 -0.025453 0.517895 0.5 +-0.0711433 0.0687078 -0.00390291 0.256016 0.135401 +-0.0762625 0.0716316 -0.00295918 0.293636 0.296358 +-0.0802204 0.0713935 0.00991267 0.507181 0.5 +-0.0913413 0.148143 0.0161458 0.474933 0.5 +-0.0273736 0.0700052 -0.0335323 0.445714 0.5 +-0.0300274 0.0692073 -0.0289677 0.511122 0.5 +-0.0316277 0.0711218 -0.0266514 0.502235 0.5 +-0.0330629 0.0699765 -0.0212743 0.929225 0.5 +-0.0353642 0.0705896 -0.0177097 0.263666 0.5 +-0.0587004 0.0391044 -0.0090027 0.295521 0.5 +-0.0697696 0.0703857 -0.00808666 0.238472 0.5 +-0.0804832 0.0726462 0.00472466 0.630221 0.5 +0.0151616 0.126104 -0.00266395 0.542796 0.5 +-0.0745721 0.072883 -0.00757069 0.303203 0.5 +-0.0823908 0.076277 0.00270117 0.615888 0.5 +-0.0912831 0.133698 0.0142161 0.68945 0.5 +0.00371049 0.0968817 -0.0280931 0.670854 0.5 +-0.0761392 0.0766258 -0.00859487 0.260107 0.5 +-0.0784749 0.0748827 -0.00523624 0.238143 0.440892 +-0.0806781 0.0771902 -0.00290803 0.36458 0.43512 +-0.0834622 0.0765209 0.00927112 0.562933 0.5 +0.00983826 0.11402 -0.0178612 0.519736 0.475688 +0.00210649 0.0981565 -0.0261244 0.689185 0.5 +-0.0285085 0.0757575 -0.0348118 0.64535 0.304239 +-0.0330874 0.0761249 -0.0270661 0.564742 0.5 +-0.0346568 0.0757906 -0.0215029 0.930953 0.5 +0.0231104 0.0892807 -0.0240236 0.697809 0.45449 +-0.0312132 0.0771357 -0.0320416 0.687582 0.5 +-0.0700425 0.0763633 -0.0141464 0.485274 0.5 +-0.0861137 0.0814707 0.00908143 0.590509 0.5 +-0.086319 0.08152 0.0149936 0.698173 0.5 +-0.0208042 0.0963182 -0.0270563 0.75553 0.5 +-0.0211078 0.114391 -0.0171285 0.793027 0.5 +-0.0746162 0.0828529 -0.0139325 0.683447 0.5 +-0.077295 0.081216 -0.0100568 0.47673 0.5 +-0.0800127 0.0821605 -0.00722237 0.637376 0.5 +-0.0826334 0.0820868 -0.00324616 0.569954 0.5 +-0.0844667 0.0817669 0.00249573 0.601403 0.5 +-0.0860445 0.0832591 0.0203255 0.630527 0.5 +-0.084816 0.0816746 0.0219849 0.638209 0.5 +0.0545549 0.0661692 0.000765649 0.628404 0.43579 +-0.0331604 0.0828369 -0.0270493 0.417784 0.5 +-0.0358028 0.0829047 -0.0227723 0.112354 0 +-0.0861942 0.0842505 0.00298565 0.418742 0.5 +-0.0287072 0.0827267 -0.0349537 0.48086 0.471486 +-0.0311601 0.0822387 -0.0315627 0.627475 0.5 +-0.085403 0.141865 0.00516647 0.463398 0.5 +-0.0785169 0.0885628 -0.0107607 0.69884 0.5 +-0.0807046 0.0887676 -0.00826584 0.689404 0.5 +-0.0843972 0.0878743 -0.00349923 0.402052 0.5 +-0.0855708 0.0882073 -0.00109946 0.425364 0.422235 +-0.0876157 0.0881286 0.00369184 0.414972 0.435161 +-0.0885339 0.0876942 0.00897158 0.630733 0.5 +-0.0885791 0.0877213 0.0149616 0.665472 0.5 +-0.0643854 0.0348576 -0.00775085 0.279509 0.5 +-0.0512932 0.034227 -0.0129013 0.159841 0.5 +-0.0266839 0.0458556 -0.027274 0.610127 0.5 +-0.0146368 0.0981541 -0.0264318 0.44201 0.5 +-0.0213468 0.10077 -0.0239588 0.58675 0.5 +0.020932 0.0825954 -0.0267347 0.750174 0.5 +0.00759225 0.0928541 -0.0309237 0.580726 0.5 +-0.0144478 0.0879274 -0.0380297 0.689122 0.5 +-0.00859724 0.11451 -0.0173132 0.77831 0.5 +0.0264818 0.109935 -0.0126182 0.652634 0.5 +-0.0145855 0.0385179 -0.0267991 0.230538 0.5 +-0.0330054 0.0337044 -0.0272991 0.262513 0.5 +-0.0267872 0.0340475 -0.0271901 0.244173 0 +-0.00849157 0.0985859 -0.0270535 0.53889 0.411612 +-0.0110954 0.120824 -0.0120135 0.770076 0.5 +0.0367379 0.0925992 -0.0129888 0.684003 0.5 +-0.0571635 0.0435755 -0.00717607 0.581004 0.404197 +-0.0193328 0.0979251 -0.024792 0.661276 0.5 +-0.0203798 0.0385467 -0.0283088 0.392689 0.5 +-0.0587681 0.0337133 -0.00871891 0.1361 0.5 +-0.0517919 0.100655 -0.0213258 0.798237 0.5 +0.00702627 0.0978418 -0.0246055 0.732067 0.326346 +-0.0148892 0.126068 -0.00252126 0.467449 0.5 +0.0307578 0.092446 -0.0188519 0.704525 0.5 +0.0211049 0.0578126 -0.0266116 0.685576 0.5 +-0.0169237 0.0970481 -0.0278718 0.775366 0.5 +0.0460004 0.0581866 -0.00508589 0.612698 0.5 +-0.00944331 0.0822271 -0.0381067 0.670336 0.467319 +-0.0635881 0.0392124 -0.00717766 0.572252 0.5 +0.00864227 0.0386371 -0.0233053 0.540697 0.5 +0.0252935 0.0769557 -0.0248407 0.75695 0.5 +-0.0229653 0.0895159 -0.036199 0.454072 0.467569 +-0.0523791 0.0341193 -0.00994653 0.132813 0.5 +0.0211693 0.0643935 -0.0268578 0.690366 0.5 +-0.0515867 0.13164 -0.0028092 0.545448 0.5 +-0.0149669 0.0345529 -0.0254273 0.17846 0.5 +-0.0161167 0.127288 0.00169291 0.694465 0.5 +-0.0469232 0.128515 -0.00163965 0.389857 0.5 +-0.00961381 0.127158 -0.00378809 0.714685 0.5 +-0.0074566 0.128562 -0.00130751 0.72817 0.5 +-0.00304493 0.128909 -0.00174857 0.778769 0.5 +0.0028379 0.129022 -0.00194723 0.574275 0.5 +0.00903363 0.128674 -0.00165013 0.617309 0.5 +-0.0561607 0.131588 -0.00571429 0.687735 0.5 +-0.0457551 0.127167 -0.00484962 0.645893 0.5 +-0.00304746 0.127678 -0.00456004 0.562309 0.5 +0.00303811 0.12768 -0.00442 0.624596 0.5 +0.0101526 0.126812 -0.00466464 0.64326 0.5 +-0.0553259 0.126836 -0.00601308 0.517644 0.5 +0.00799473 0.034846 -0.0206913 0.278473 0.5 +0.0027179 0.0342191 -0.0204737 0.322372 0.5 +-0.00295804 0.0342418 -0.0216222 0.194059 0.5 +0.0134674 0.0353221 -0.0196961 0.466171 0.5 +0.00440963 0.0383063 -0.0240776 0.3469 0.5 +0.00140752 0.0383474 -0.0246147 0.361099 0.5 +-0.00309177 0.0383877 -0.0251866 0.314174 0.5 +-0.0575023 0.100661 -0.0195211 0.459895 0.452391 +-0.0485739 0.15316 -0.00547278 0.691758 0.5 +-0.0646573 0.0334831 -0.00296009 0.187639 0.5 +-0.0640796 0.100426 -0.0173936 0.44544 0.466101 +-0.0704415 0.100139 -0.0146037 0.499781 0.478548 +-0.0326376 0.155806 -0.00949884 0.828995 0.5 +0.0336094 0.0373624 0.00273412 0.290019 0.5 +0.0320943 0.0397885 -0.00195136 0.323719 0.5 +0.0158502 0.0449602 -0.0237212 0.910511 0.5 +0.00889467 0.0426449 -0.0242659 0.891863 0.5 +0.00312499 0.0452721 -0.026588 0.665265 0.460024 +-0.00298345 0.044686 -0.0272222 0.905955 0.5 +-0.00912346 0.0448524 -0.0280671 0.895801 0.5 +-0.0145351 0.0443266 -0.0277771 0.887903 0.5 +-0.0209223 0.0460913 -0.0281918 0.705844 0.5 +0.034052 0.0448434 -0.00540113 0.626363 0.5 +-0.0312646 0.158257 -0.01223 0.732334 0.5 +0.0401509 0.0448981 -0.00354586 0.446696 0.5 +0.0143253 0.0473484 -0.0251513 0.546545 0.456757 +0.00937888 0.0466526 -0.0261685 0.907397 0.5 +-0.0766531 0.0695423 0.0207982 0.774152 0.5 +0.0087246 0.0517916 -0.0291615 0.840924 0.5 +0.00299372 0.0506927 -0.0298557 0.901259 0.5 +-0.00164566 0.0489436 -0.0304144 0.872257 0.5 +-0.00321397 0.0522596 -0.0314075 0.634884 0.475184 +-0.00915341 0.0509217 -0.0318681 0.650022 0.5 +-0.0146018 0.0513752 -0.0319045 0.891033 0.5 +-0.0161558 0.0488543 -0.0303763 0.808351 0.5 +-0.0205843 0.0508011 -0.0296435 0.813106 0.5 +0.0405252 0.0518855 -0.00654453 0.65569 0.5 +0.0149309 0.0520772 -0.0273859 0.655547 0.5 +0.041884 0.0490868 -0.00604367 0.898378 0.5 +0.019962 0.0529908 -0.0261219 0.592286 0.5 +-0.0198501 0.0534234 -0.0312267 0.768335 0.5 +-0.0336273 0.0527187 -0.0106243 0.102172 0.5 +-0.0461112 0.0529158 -0.0101664 0.636429 0.372142 +-0.0204 0.161875 -0.014658 0.822907 0.5 +0.0449924 0.0530898 -0.00614891 0.575737 0.5 +0.00733679 0.0546532 -0.0305038 0.688621 0.5 +0.00283568 0.0546532 -0.0307468 0.611749 0.5 +-0.00302245 0.0577 -0.0331477 0.67582 0.5 +-0.00914668 0.0576676 -0.0341165 0.698389 0.5 +-0.01517 0.058199 -0.0349877 0.856637 0.5 +-0.0202707 0.0581031 -0.0333681 0.552506 0.5 +0.0140844 0.057965 -0.028983 0.564173 0.483714 +0.0103301 0.0588553 -0.0299472 0.602031 0.489059 +0.00732823 0.0588898 -0.0306117 0.710141 0.5 +0.0027369 0.0590151 -0.0321928 0.690932 0.5 +-0.0337187 0.0579742 -0.0115824 0.143826 0.5 +-0.0390711 0.0582467 -0.0115033 0.780735 0.5 +-0.0460474 0.0579124 -0.0115174 0.472305 0.5 +-0.00961439 0.0642168 -0.0358564 0.670518 0.457134 +-0.044157 0.0599825 -0.0123877 0.830365 0.5 +0.015251 0.0645803 -0.029567 0.626368 0.396114 +0.00839294 0.0649214 -0.0316957 0.79033 0.385997 +0.00325858 0.0643529 -0.0332439 0.728322 0.418376 +-0.00361257 0.0645861 -0.034907 0.670644 0.5 +-0.0144709 0.065006 -0.0371603 0.712311 0.5 +-0.0366623 0.060679 -0.0122791 0.525705 0.5 +-0.0526404 0.0636402 -0.0101297 0.452904 0.5 +-0.0381866 0.0648919 -0.0142073 0.543504 0.5 +-0.0452495 0.0647856 -0.0139819 0.883769 0.5 +-0.0599262 0.0622966 -0.00429285 0.195385 0.344922 +-0.0778641 0.117463 -0.00576778 0.523105 0.5 +-0.0187447 0.0664151 -0.0374779 0.820087 0.5 +-0.0577616 0.0644884 -0.00779097 0.472929 0.5 +-0.0625778 0.0655353 -0.00741131 0.379588 0.453283 +0.0251088 0.0710945 -0.0248604 0.704567 0.5 +0.021457 0.0702729 -0.0273415 0.740248 0.5 +0.0166747 0.0701586 -0.0297203 0.658948 0.5 +0.0132745 0.0702643 -0.0312074 0.651019 0.5 +0.00867525 0.0703509 -0.0324278 0.818076 0.5 +0.00229643 0.0708694 -0.0343123 0.73028 0.5 +-0.0030646 0.070381 -0.0353565 0.764349 0.5 +-0.00773679 0.0691749 -0.0362051 0.757441 0.5 +-0.0101988 0.0715122 -0.0373778 0.76291 0.5 +-0.0147454 0.0704429 -0.0382943 0.581028 0.470136 +-0.0203984 0.0706516 -0.038158 0.645161 0.5 +-0.0240967 0.0693418 -0.0362521 0.4533 0.5 +-0.0605175 0.0673597 -0.0108259 0.635082 0.5 +-0.0387293 0.0706355 -0.0168457 0.666323 0.5 +-0.0451347 0.0705064 -0.0164504 0.875899 0.5 +-0.0523435 0.0697862 -0.0145984 0.401473 0.5 +-0.0591515 0.0702891 -0.0147203 0.639534 0.5 +-0.0652515 0.0688492 -0.00993982 0.422384 0.422462 +-0.0247614 0.0719777 -0.0368317 0.497524 0.5 +-0.0637884 0.0712697 -0.0138535 0.437166 0.5 +0.0211454 0.0769268 -0.0268772 0.737516 0.5 +0.0162128 0.0765268 -0.0293784 0.712202 0.5 +0.0133247 0.0760196 -0.0306715 0.679361 0.5 +0.00907695 0.076038 -0.0330382 0.719764 0.5 +0.00245085 0.0760857 -0.0351615 0.721395 0.5 +-0.00176321 0.0762288 -0.0360688 0.799862 0.5 +-0.00476487 0.076286 -0.0369742 0.814155 0.377247 +-0.00962992 0.0765936 -0.0378651 0.627364 0.487104 +-0.0144481 0.0764118 -0.0385775 0.832444 0.5 +-0.021453 0.0763574 -0.038668 0.751656 0.5 +-0.024977 0.0762484 -0.0374518 0.39297 0.457854 +-0.0377453 0.0766164 -0.0189124 0.273711 0.5 +-0.0397395 0.0746623 -0.0180255 0.973337 0.5 +-0.0437423 0.0765905 -0.0187922 0.595439 0.440211 +-0.0466377 0.0744845 -0.0173668 0.538698 0.468502 +-0.0518623 0.0745812 -0.0175084 0.855826 0.5 +-0.0589866 0.0745368 -0.01766 0.879682 0.5 +-0.0644081 0.0756279 -0.0167529 0.562234 0.481782 +-0.0721295 0.0740256 -0.0105719 0.341576 0.432723 +-0.0615233 0.0354132 0.043881 0.499903 0.5 +-0.0524971 0.0769872 -0.0189536 0.873913 0.5 +-0.0587482 0.0767445 -0.0187462 0.882838 0.5 +0.013102 0.0809953 -0.0307917 0.69611 0.5 +0.00892296 0.0820652 -0.0325478 0.700162 0.5 +0.0022917 0.0820297 -0.0349279 0.829579 0.5 +-0.00177837 0.0804805 -0.0364471 0.647084 0.379833 +-0.00379684 0.0824193 -0.037328 0.824332 0.5 +-0.0142988 0.0820384 -0.0390211 0.832022 0.373406 +-0.0207708 0.0823862 -0.0387335 0.805306 0.5 +-0.0248089 0.0818968 -0.0377031 0.470046 0.439483 +-0.0735819 0.0777026 -0.0122023 0.445372 0.5 +0.015425 0.0831288 -0.0295207 0.735694 0.5 +-0.0383994 0.0817919 -0.0209596 0.290803 0.5 +-0.0451184 0.0815526 -0.020434 0.548777 0.45056 +-0.051814 0.0818472 -0.0211348 0.886135 0.5 +-0.0583689 0.0812724 -0.0202975 0.847354 0.5 +-0.063949 0.082768 -0.0188935 0.606874 0.5 +-0.0662709 0.080065 -0.0177832 0.593549 0.449354 +-0.0695594 0.0830593 -0.0170582 0.4495 0.5 +-0.00481814 0.086841 -0.0367951 0.827149 0.5 +-0.0248206 0.0867524 -0.0367639 0.487957 0.5 +0.0132046 0.0871602 -0.0305473 0.663835 0.5 +-0.0360837 0.0867076 -0.023791 0.366486 0.5 +-0.00877843 0.0340556 -0.0204927 0 0 +-0.0207128 0.0342382 -0.0208728 0.319674 0.5 +-0.0147915 0.0341096 -0.0207616 0.312592 0.5 +-0.0265767 0.0342963 -0.0210989 0.482378 0.5 +0.00282685 0.0351053 -0.0158136 0.508357 0.5 +0.00885967 0.034471 -0.0147487 0.490133 0.5 +-0.0390848 0.0337228 -0.0202617 0.628543 0.5 +-0.0326656 0.0345334 -0.0201874 0.788348 0.5 +-0.00224535 0.0351539 -0.0166234 0.756398 0.5 +-0.0149096 0.0357313 -0.0180956 0.933106 0.5 +-0.0114808 0.0353662 -0.0177045 0.933613 0.5 +-0.00921575 0.0380183 -0.0149732 0.909294 0.5 +-0.00282494 0.0382292 -0.0140636 0.920543 0.5 +0.00285919 0.0377324 -0.0134715 0.965028 0.5 +0.0159109 0.0347098 -0.00882204 0.420938 0.5 +-0.0306839 0.036693 -0.0184598 0.875112 0.5 +-0.0265216 0.0367471 -0.0188177 0.84266 0.5 +-0.0218341 0.0369718 -0.0184303 0.873319 0.5 +-0.0203027 0.0382765 -0.0152577 0.887215 0.5 +-0.0152596 0.0382328 -0.0156428 0.873575 0.5 +0.00738356 0.0366172 -0.0125003 0.962688 0.5 +0.00992361 0.0351979 -0.00924624 0.9642 0.5 +0.00702596 0.0378387 -0.00879015 0.927286 0.5 +-0.0396958 0.0342843 -0.014578 0.76643 0.5 +-0.0329517 0.0382154 -0.014678 0.654319 0.5 +-0.0263862 0.0385778 -0.0153644 0.924592 0.5 +0.00320835 0.0389424 -0.00953857 0.945732 0.5 +-0.0364387 0.0357946 -0.0155844 0.543249 0.5 +-0.00301526 0.0391061 -0.00886496 0.816802 0.5 +0.00831664 0.0348156 -0.00321961 0.671683 0.5 +0.0145039 0.0343685 -0.0028433 0.748562 0.5 +-0.0365752 0.0370276 -0.0136534 0.498247 0.5 +-0.0146234 0.0388055 -0.00887465 0.759701 0.5 +-0.00886749 0.0389394 -0.00890173 0.761944 0.5 +-0.0451032 0.0336721 -0.00848668 0.772585 0.5 +-0.040313 0.0350801 -0.00861758 0.462745 0.5 +-0.0206235 0.0386 -0.00878063 0.747754 0.5 +0.00267879 0.038424 -0.00319748 0.448355 0.5 +0.015044 0.0350517 0.00289039 0.579133 0.5 +0.0201479 0.0347806 0.00348327 0.403273 0.5 +0.027119 0.0353514 0.00366834 0.0909279 0.5 +0.0280785 0.0365531 0.000826759 0 0 +-0.0376066 0.0375692 -0.00942418 0.22755 0.5 +-0.0332748 0.0384549 -0.00855692 0.752109 0.5 +-0.0264541 0.0384497 -0.00886193 0.729343 0.5 +-0.00299262 0.0389582 -0.00292437 0.746846 0.5 +0.00451408 0.0356078 -0.00103635 0.413486 0.5 +0.00881079 0.0350428 0.00356828 0.588251 0.5 +0.0314184 0.0360255 0.00457907 0.187967 0.5 +-0.00888202 0.0387884 -0.00299409 0.73859 0.5 +0.00271787 0.0349091 0.00339755 0.645421 0.5 +-0.041199 0.0341471 -0.00327644 0 0 +-0.0205479 0.0384259 -0.00283766 0.741413 0.5 +-0.0146618 0.0385908 -0.00288739 0.718901 0.5 +0.00103528 0.0375917 0.000952222 0.441385 0.5 +0.0215747 0.0354906 0.0086194 0.395945 0.5 +0.0264794 0.0346514 0.00870654 0.414057 0.5 +0.0322391 0.0355412 0.00882378 0.515667 0.5 +-0.0521057 0.0334794 -0.00318207 0.614129 0.5 +-0.0455078 0.0336572 -0.00225818 0.757211 0.5 +-0.0334104 0.0383259 -0.00292317 0.611245 0.5 +-0.0265122 0.0383343 -0.00296504 0.763748 0.5 +-0.00224847 0.0383354 0.00320971 0.728422 0.5 +-0.0589386 0.0334143 -0.00291301 0.444064 0.5 +-0.00874044 0.0385976 0.00291227 0.735039 0.5 +0.00273457 0.0342734 0.0088248 0.796819 0.5 +0.00621941 0.0351341 0.00654928 0 0 +-0.080018 0.109279 0.0373655 0.503151 0.426569 +-0.0393178 0.0336443 0.00354096 0.266658 0.5 +-0.0213111 0.0382973 0.00334866 0.753895 0.5 +-0.0146196 0.0384265 0.00290922 0.762157 0.5 +-0.00353554 0.0379644 0.00874752 0.658939 0.5 +0.0276681 0.0349662 0.0149532 0.360666 0.5 +0.03282 0.0359255 0.0147037 0.719837 0.5 +0.0389763 0.0383079 0.0145025 0.635106 0.5 +-0.0523961 0.0335249 0.00326874 0.742717 0.5 +-0.0462346 0.0335696 0.00267776 0.743661 0.5 +-0.0277984 0.0382296 0.00286126 0.456211 0.5 +-0.000947006 0.0357374 0.0103469 0.779853 0.5 +0.0222276 0.0358262 0.0160256 0.180494 0.5 +0.0448051 0.0411192 0.0150961 0.294679 0.5 +-0.0581064 0.033504 0.00272997 0.775526 0.5 +-0.0352323 0.0337248 0.00491425 0.152905 0 +-0.0312985 0.0381858 0.00167702 0 0 +-0.0088641 0.03847 0.00876261 0.73345 0.5 +0.0028919 0.0342894 0.0147059 0.676527 0.5 +-0.0703332 0.0340583 0.00286723 0.639535 0.5 +-0.0648245 0.0334924 0.00301734 0.793089 0.5 +-0.0387963 0.034763 0.00935652 0.458758 0.5 +-0.0332327 0.0337932 0.00943608 0.151116 0.5 +-0.0203456 0.0382265 0.00836296 0.759992 0.5 +-0.0152156 0.0383161 0.00935801 0.755179 0.5 +-0.000385714 0.0351459 0.0134171 0.848157 0.5 +0.00663645 0.0342324 0.0159688 0 0 +0.0268074 0.0356469 0.0204126 0.619176 0.5 +0.0309391 0.0362152 0.0189937 0.762661 0.5 +0.0334119 0.0376179 0.0210082 0.70177 0.5 +-0.0515734 0.0338904 0.00817232 0.493124 0.5 +-0.0454999 0.0352808 0.00804865 0.53914 0.5 +-0.0263229 0.0380313 0.00871732 0.143858 0.5 +-0.0031858 0.0377098 0.014513 0.797449 0.5 +0.0211051 0.0351552 0.0207004 0.432057 0.5 +0.0391983 0.0395969 0.0205879 0.670001 0.5 +0.0441778 0.0418755 0.0204802 0.609797 0.5 +-0.0580282 0.0335624 0.00918162 0.776077 0.5 +-0.00922404 0.0383488 0.0150261 0.754001 0.5 +0.00313746 0.0352426 0.0204176 0.692001 0.5 +0.00877508 0.0346179 0.020856 0.290121 0.5 +0.0468489 0.0434226 0.0210936 0.239557 0.5 +-0.0648031 0.0337402 0.00884817 0.802283 0.5 +-0.0338156 0.0345063 0.0150293 0.572312 0.5 +-0.0149173 0.0382498 0.0147214 0.753708 0.5 +0.0146344 0.0345628 0.0222588 0.157065 0.5 +-0.0365655 0.0357926 0.0130139 0.391807 0.5 +-0.0262153 0.0376693 0.0148666 0.146481 0.5 +-0.0205165 0.0381248 0.0146779 0.715632 0.5 +-0.00229335 0.0382456 0.020565 0.923102 0.5 +0.014723 0.0347707 0.0263935 0.310145 0.5 +0.0210245 0.0353476 0.0265418 0.313898 0.5 +0.0250756 0.0364517 0.0246847 0.678097 0.5 +0.0273584 0.0381522 0.0267127 0.778478 0.5 +0.0321164 0.0401984 0.026762 0.778536 0.5 +-0.053829 0.0335431 0.0139547 0.458851 0.5 +0.00114114 0.037661 0.0223414 0.978558 0.5 +0.00915473 0.0353589 0.0262457 0.701449 0.5 +0.0380552 0.0412819 0.02589 0.374179 0.417844 +-0.0588034 0.0336951 0.0146283 0.798139 0.5 +-0.0339319 0.0346253 0.0202274 0.513983 0.5 +-0.0152545 0.0382629 0.0204704 0.75125 0.5 +-0.00888844 0.0384087 0.0207206 0.746481 0.5 +0.00307272 0.0384964 0.0264151 0.996029 0.5 +-0.0261643 0.0378491 0.0205422 0.603577 0.5 +-0.0205429 0.0381473 0.0213758 0.772551 0.5 +-0.0538188 0.0335608 0.0210581 0 0 +-0.00301594 0.03875 0.0263901 0.805634 0.5 +0.00756209 0.0380712 0.0285007 0.978659 0.5 +0.0143741 0.0348327 0.0331833 0.915728 0.5 +0.0198279 0.03555 0.0321213 0.749506 0.5 +0.0236875 0.0373106 0.0299772 0.517201 0.5 +-0.0588476 0.033906 0.020465 0.657735 0.5 +-0.00882687 0.0386047 0.0265705 0.756827 0.5 +0.00847025 0.0383344 0.0315598 0.739987 0.5 +0.0108958 0.035647 0.0330663 0.649316 0.5 +-0.0366651 0.0353042 0.023032 0.153172 0.5 +-0.0340084 0.0344659 0.0266224 0.263742 0.5 +-0.0270447 0.0379104 0.0270529 0.074682 0.5 +-0.0210471 0.0383013 0.026282 0.782021 0.5 +-0.0147317 0.0384888 0.0265233 0.791552 0.5 +-0.0712786 0.0733348 0.0355839 0.683322 0.427231 +-0.0388887 0.0346255 0.0265538 0.109729 0 +0.00290004 0.0393205 0.032168 0.626516 0.5 +0.0155389 0.0350901 0.0393977 0.759188 0.5 +0.0195159 0.0358111 0.0367948 0.405286 0.5 +-0.0589139 0.0341314 0.0264586 0.808252 0.5 +-0.052234 0.0340737 0.0268887 0.497915 0.5 +-0.0447866 0.0339274 0.0274346 0.154159 0.5 +-0.0310127 0.0369382 0.02848 0.240675 0.5 +-0.00908756 0.0390146 0.0330901 0.79352 0.5 +-0.00293287 0.039209 0.03365 0.804769 0.5 +0.00861952 0.0346654 0.0391536 0.125418 0.5 +-0.0149144 0.0388312 0.0324344 0.795183 0.5 +0.00392423 0.0347398 0.0399064 0.146347 0.5 +-0.0657827 0.0618455 0.00187562 0.442355 0.5 +-0.0640051 0.0606097 0.00361345 0.333039 0.5 +-0.0455164 0.0345095 0.0326748 0.510388 0.5 +-0.0385699 0.0344168 0.033204 0.485482 0.5 +-0.0342024 0.0351611 0.0325685 0.248514 0.5 +-0.0270303 0.0384799 0.0326469 0.783767 0.5 +-0.0209433 0.0387397 0.0332273 0.806699 0.5 +-0.0520994 0.0344582 0.0326775 0.466807 0.5 +-0.0313489 0.0377268 0.0321213 0.178238 0.5 +-0.00219023 0.0348305 0.0410082 0.139343 0 +0.00818206 0.0355366 0.0443043 0.642932 0.5 +0.014947 0.0361331 0.0431407 0.796588 0.5 +-0.0642564 0.0597236 0.0092932 0.716255 0.5 +-0.0584732 0.0343588 0.0331559 0.775713 0.5 +-0.0145859 0.0393004 0.0380317 0.483641 0.5 +-0.00937548 0.0394517 0.037871 0.328321 0.5 +-0.0588297 0.0579582 0.0145443 0 0 +-0.038732 0.0346956 0.0400227 0.628019 0.5 +-0.0331487 0.034492 0.0390527 0.154826 0.5 +-0.0201914 0.0391628 0.0381696 0.483919 0.5 +-0.00878985 0.0348233 0.0452949 0.139305 0.5 +-0.0031441 0.0351515 0.045825 0.295611 0.5 +-0.0701619 0.0622789 0.00863964 0.42197 0.408074 +-0.0451191 0.034688 0.0396457 0.766116 0.5 +-0.0256628 0.0389081 0.0373249 0 0 +-0.0146115 0.0348173 0.0458198 0.143796 0.5 +-0.0636462 0.0593677 0.014889 0.807508 0.5 +-0.0531671 0.0345191 0.0391729 0.74918 0.5 +-0.0595372 0.034497 0.0397515 0.783724 0.5 +-0.0329555 0.0349777 0.045552 0.474674 0.5 +-0.0262436 0.034809 0.0452831 0.162616 0.5 +-0.0215554 0.0348112 0.0459347 0.152356 0 +-0.0633407 0.0601272 0.0190813 0.939061 0.5 +-0.0471 0.0351015 0.0434178 0.627709 0.5 +-0.0120723 0.0353434 0.0494553 0.877126 0.5 +-0.016313 0.0351836 0.0504037 0.67915 0.5 +-0.0483699 0.146034 -0.00115148 0.583019 0.5 +-0.0264335 0.156562 -0.00835956 0.469485 0.437523 +-0.065003 0.144791 -0.0142909 0.400803 0.470167 +-0.066228 0.151547 -0.0394609 0.538048 0.5 +-0.0663323 0.145309 -0.018858 0.764025 0.5 +-0.0412403 0.152108 -0.00674014 0.633348 0.5 +3 4 132 80 +3 80 132 544 +3 373 80 544 +3 387 299 241 +3 859 1475 1474 +3 371 299 401 +3 401 326 333 +3 347 673 402 +3 1187 1354 386 +3 1221 457 69 +3 186 224 114 +3 1250 1256 116 +3 164 333 376 +3 19 488 1245 +3 749 19 1245 +3 667 19 749 +3 1040 412 543 +3 1359 1358 1500 +3 216 4 80 +3 152 544 146 +3 4 387 505 +3 543 1235 1205 +3 610 604 297 +3 250 801 1274 +3 504 148 111 +3 387 348 299 +3 401 333 164 +3 1484 1483 1110 +3 91 196 310 +3 90 91 310 +3 952 406 609 +3 1244 1247 1240 +3 93 327 65 +3 373 544 152 +3 373 152 644 +3 1321 158 22 +3 401 416 326 +3 644 152 1263 +3 276 59 181 +3 294 853 150 +3 308 249 529 +3 406 1124 604 +3 609 406 463 +3 146 3 145 +3 90 310 3 +3 58 186 10 +3 575 261 384 +3 25 40 43 +3 379 535 713 +3 348 704 157 +3 388 443 22 +3 396 146 145 +3 152 133 1263 +3 1830 1829 1812 +3 214 114 224 +3 157 147 324 +3 1335 430 1274 +3 282 230 214 +3 92 346 652 +3 1151 1012 1491 +3 571 1151 1491 +3 571 1491 183 +3 310 196 111 +3 91 4 505 +3 1250 116 108 +3 110 183 47 +3 1209 854 953 +3 132 4 91 +3 111 148 327 +3 93 111 327 +3 110 571 183 +3 713 171 402 +3 294 920 200 +3 81 180 52 +3 525 731 784 +3 347 256 673 +3 175 57 220 +3 338 175 220 +3 27 14 220 +3 57 27 220 +3 359 446 27 +3 359 36 446 +3 145 28 262 +3 133 16 419 +3 1447 576 1465 +3 1885 287 444 +3 133 396 16 +3 598 543 1205 +3 447 93 65 +3 73 213 36 +3 1236 1255 1250 +3 1235 1236 1250 +3 115 782 731 +3 28 93 447 +3 525 548 115 +3 299 416 401 +3 667 603 463 +3 292 667 463 +3 492 70 637 +3 133 146 396 +3 1166 1125 619 +3 1151 1219 959 +3 821 304 409 +3 1486 1487 1684 +3 15 175 167 +3 120 15 167 +3 15 131 57 +3 175 15 57 +3 57 131 27 +3 257 209 359 +3 27 257 359 +3 209 55 36 +3 359 209 36 +3 55 87 73 +3 36 55 73 +3 101 108 735 +3 108 101 64 +3 310 365 3 +3 576 859 1465 +3 262 28 447 +3 102 64 101 +3 544 91 90 +3 262 447 485 +3 485 447 211 +3 1443 1440 1442 +3 697 457 1221 +3 1008 383 1011 +3 451 435 1330 +3 129 405 426 +3 70 75 161 +3 648 693 692 +3 204 129 426 +3 812 481 123 +3 406 292 463 +3 878 1591 1009 +3 478 128 50 +3 900 979 977 +3 490 900 977 +3 241 299 371 +3 1164 701 734 +3 683 703 682 +3 719 718 682 +3 703 719 682 +3 760 759 718 +3 719 760 718 +3 137 729 728 +3 54 130 2 +3 302 358 301 +3 566 567 614 +3 1069 1103 1068 +3 1186 1190 1208 +3 4 348 387 +3 277 311 228 +3 707 226 706 +3 355 394 393 +3 773 129 755 +3 646 647 679 +3 356 355 269 +3 270 356 269 +3 424 394 356 +3 623 654 602 +3 654 683 602 +3 193 217 192 +3 1677 1676 1662 +3 1018 1019 1025 +3 597 1231 1165 +3 490 26 605 +3 299 157 416 +3 504 241 148 +3 84 528 714 +3 1247 669 1240 +3 683 719 703 +3 1886 1231 1066 +3 79 168 218 +3 211 318 426 +3 165 377 148 +3 91 505 387 +3 577 623 622 +3 692 693 707 +3 255 254 218 +3 194 270 255 +3 695 137 728 +3 1475 1498 1474 +3 67 808 1010 +3 1190 240 1208 +3 242 259 300 +3 476 509 567 +3 743 755 558 +3 1025 1024 1018 +3 194 255 218 +3 270 269 254 +3 203 271 12 +3 603 667 749 +3 1379 1395 1392 +3 783 546 1340 +3 578 600 577 +3 624 623 577 +3 600 624 577 +3 655 654 623 +3 684 683 654 +3 655 684 654 +3 720 719 683 +3 684 720 683 +3 720 739 719 +3 761 760 719 +3 739 761 719 +3 218 254 253 +3 694 695 437 +3 255 270 254 +3 1202 488 19 +3 412 1222 543 +3 60 528 84 +3 1352 494 702 +3 624 655 623 +3 1361 221 143 +3 755 129 204 +3 132 91 544 +3 543 1221 1235 +3 216 5 4 +3 1221 1236 1235 +3 754 755 204 +3 1169 732 715 +3 756 755 743 +3 1036 1035 1024 +3 728 756 743 +3 476 567 508 +3 4 5 348 +3 244 1339 546 +3 405 445 211 +3 254 269 268 +3 253 254 268 +3 381 358 302 +3 346 92 59 +3 517 450 1560 +3 1618 1333 141 +3 1498 1497 1474 +3 1231 597 1165 +3 228 264 215 +3 100 151 99 +3 151 215 99 +3 151 228 215 +3 1864 827 1870 +3 561 578 480 +3 207 561 480 +3 579 600 578 +3 561 579 578 +3 600 625 624 +3 656 655 624 +3 625 656 624 +3 685 684 655 +3 656 685 655 +3 685 721 720 +3 684 685 720 +3 721 740 739 +3 720 721 739 +3 739 740 761 +3 762 789 788 +3 761 762 788 +3 789 239 770 +3 788 789 770 +3 328 770 239 +3 423 424 476 +3 121 195 522 +3 423 476 422 +3 381 431 358 +3 148 371 401 +3 579 625 600 +3 465 464 431 +3 381 465 431 +3 464 465 227 +3 248 11 71 +3 548 142 1005 +3 740 762 761 +3 767 900 490 +3 728 743 437 +3 776 195 121 +3 1177 1176 1153 +3 1043 1034 1035 +3 137 708 729 +3 91 387 196 +3 1721 1729 1703 +3 728 729 756 +3 727 728 437 +3 196 387 241 +3 404 458 522 +3 355 354 268 +3 647 648 692 +3 979 846 901 +3 241 371 148 +3 142 1155 574 +3 269 355 268 +3 358 301 300 +3 301 358 300 +3 753 754 793 +3 184 229 228 +3 229 277 228 +3 312 311 277 +3 1845 1853 1831 +3 1523 1532 1153 +3 580 579 561 +3 1276 1280 1771 +3 580 626 625 +3 579 580 625 +3 626 657 656 +3 625 626 656 +3 656 657 685 +3 722 721 685 +3 741 740 721 +3 722 741 721 +3 740 763 762 +3 790 789 762 +3 763 790 762 +3 790 339 239 +3 789 790 239 +3 377 165 327 +3 476 508 422 +3 259 301 300 +3 162 170 169 +3 81 162 169 +3 580 561 562 +3 657 686 685 +3 229 312 277 +3 28 365 93 +3 1263 419 1254 +3 396 145 144 +3 685 686 722 +3 741 763 740 +3 133 152 146 +3 1263 133 419 +3 207 520 562 +3 520 562 580 +3 562 520 580 +3 562 626 580 +3 239 339 487 +3 597 1063 1066 +3 3 365 28 +3 649 648 615 +3 108 64 116 +3 571 1225 1218 +3 184 185 229 +3 313 312 229 +3 185 313 229 +3 439 501 520 +3 501 581 562 +3 520 501 562 +3 627 626 562 +3 581 627 562 +3 627 628 626 +3 658 657 626 +3 628 658 626 +3 658 675 657 +3 687 686 657 +3 675 687 657 +3 723 722 686 +3 687 723 686 +3 722 723 741 +3 741 723 763 +3 764 791 790 +3 763 764 790 +3 791 407 339 +3 790 791 339 +3 407 303 339 +3 303 487 339 +3 303 460 487 +3 303 325 460 +3 170 106 105 +3 105 106 68 +3 439 440 501 +3 723 764 763 +3 1 1027 453 +3 1067 511 942 +3 775 121 774 +3 1281 1270 1291 +3 368 440 439 +3 367 368 439 +3 582 581 501 +3 628 627 581 +3 658 688 687 +3 675 658 687 +3 1733 1562 1561 +3 757 775 756 +3 74 68 46 +3 398 1223 317 +3 631 607 231 +3 1465 859 1474 +3 1775 1784 1754 +3 204 138 793 +3 74 122 97 +3 584 533 570 +3 278 313 185 +3 265 278 185 +3 369 368 313 +3 278 369 313 +3 369 440 368 +3 502 501 440 +3 583 582 501 +3 502 583 501 +3 583 581 582 +3 629 628 581 +3 583 629 581 +3 629 659 658 +3 628 629 658 +3 658 659 688 +3 724 723 687 +3 688 724 687 +3 724 742 723 +3 742 765 764 +3 723 742 764 +3 764 238 791 +3 791 238 407 +3 407 238 303 +3 238 333 303 +3 333 325 303 +3 614 615 647 +3 46 122 74 +3 606 199 112 +3 441 440 369 +3 83 173 573 +3 775 776 121 +3 846 979 901 +3 441 502 440 +3 659 689 688 +3 84 714 1367 +3 535 52 171 +3 551 798 1883 +3 630 629 583 +3 629 630 659 +3 689 724 688 +3 792 238 764 +3 765 792 764 +3 1207 1208 177 +3 195 96 522 +3 122 13 97 +3 344 492 637 +3 1025 1036 1024 +3 775 774 756 +3 1012 1151 959 +3 1270 1372 1291 +3 145 3 28 +3 649 670 695 +3 517 1888 243 +3 444 399 1885 +3 370 369 278 +3 724 765 742 +3 376 333 238 +3 1372 1375 1291 +3 1060 1161 1162 +3 16 396 144 +3 369 442 441 +3 583 601 630 +3 690 689 659 +3 318 295 427 +3 138 204 427 +3 693 694 707 +3 310 111 365 +3 365 111 93 +3 636 660 659 +3 567 566 508 +3 426 405 211 +3 121 126 774 +3 471 601 583 +3 251 237 188 +3 1303 188 237 +3 278 314 370 +3 370 442 369 +3 442 503 502 +3 441 442 502 +3 503 471 583 +3 502 503 583 +3 858 302 259 +3 16 144 319 +3 660 690 659 +3 690 725 724 +3 689 690 724 +3 750 765 724 +3 725 750 724 +3 8 792 765 +3 750 8 765 +3 376 238 792 +3 8 376 792 +3 164 376 238 +3 376 164 238 +3 1381 1380 1375 +3 1135 1134 1103 +3 1104 1135 1103 +3 794 204 793 +3 447 65 211 +3 442 1347 503 +3 249 262 485 +3 1036 1043 1035 +3 522 96 438 +3 204 426 427 +3 188 283 251 +3 1235 1250 1205 +3 485 262 23 +3 597 1066 1165 +3 144 308 319 +3 1027 767 589 +3 648 649 694 +3 567 615 614 +3 821 409 304 +3 63 711 903 +3 8 164 376 +3 12 478 50 +3 171 347 402 +3 284 1327 314 +3 1447 1465 1459 +3 1456 1447 1459 +3 1329 1328 1380 +3 755 756 773 +3 756 774 773 +3 193 218 253 +3 648 694 693 +3 168 194 218 +3 190 188 189 +3 284 283 188 +3 190 284 188 +3 283 284 314 +3 262 485 23 +3 108 116 64 +3 751 750 725 +3 726 751 725 +3 751 771 750 +3 37 8 750 +3 771 37 750 +3 632 164 8 +3 569 53 411 +3 511 1560 1884 +3 386 1354 1320 +3 165 632 8 +3 37 165 8 +3 165 164 632 +3 662 661 638 +3 354 393 422 +3 401 165 148 +3 979 1883 798 +3 144 145 262 +3 413 408 349 +3 16 319 669 +3 318 211 295 +3 156 1213 198 +3 1153 1152 1119 +3 1225 1448 247 +3 190 266 284 +3 419 669 1247 +3 479 233 232 +3 166 165 37 +3 709 492 344 +3 567 568 615 +3 107 827 1864 +3 695 727 437 +3 485 211 23 +3 1254 419 1247 +3 419 16 669 +3 1884 1591 1009 +3 249 485 24 +3 41 249 24 +3 1103 1134 1133 +3 272 398 492 +3 754 204 794 +3 1498 159 113 +3 24 485 23 +3 1102 1103 1133 +3 308 144 249 +3 164 165 401 +3 692 707 706 +3 509 568 567 +3 191 252 190 +3 190 252 266 +3 252 285 284 +3 266 252 284 +3 285 286 284 +3 284 286 337 +3 144 262 249 +3 536 564 563 +3 563 564 593 +3 564 612 611 +3 593 564 611 +3 645 361 611 +3 612 645 611 +3 645 691 1313 +3 309 752 751 +3 726 309 751 +3 752 772 771 +3 751 752 771 +3 119 37 771 +3 772 119 771 +3 425 166 37 +3 119 425 37 +3 380 165 166 +3 425 380 166 +3 128 83 17 +3 50 128 17 +3 729 757 756 +3 394 423 422 +3 589 767 490 +3 424 509 476 +3 1374 1359 1531 +3 408 372 349 +3 679 692 706 +3 855 242 300 +3 766 757 730 +3 354 355 393 +3 79 218 193 +3 129 126 405 +3 126 458 405 +3 647 692 679 +3 757 766 775 +3 766 776 775 +3 1699 1014 1013 +3 393 394 422 +3 252 286 285 +3 752 119 772 +3 425 327 380 +3 696 730 729 +3 708 696 729 +3 649 695 694 +3 78 79 193 +3 1497 1498 113 +3 901 979 798 +3 404 24 445 +3 24 23 445 +3 776 795 195 +3 1340 1591 1884 +3 1035 1034 1024 +3 177 203 12 +3 380 327 425 +3 510 509 424 +3 477 510 424 +3 458 404 405 +3 192 217 252 +3 191 192 252 +3 217 267 286 +3 252 217 286 +3 286 267 352 +3 353 421 420 +3 352 353 420 +3 421 507 506 +3 506 507 536 +3 507 565 564 +3 536 507 564 +3 565 613 612 +3 564 565 612 +3 646 645 612 +3 613 646 612 +3 646 679 691 +3 645 646 691 +3 706 705 691 +3 679 706 691 +3 753 309 280 +3 138 119 752 +3 753 138 752 +3 427 425 119 +3 138 427 119 +3 295 380 425 +3 427 295 425 +3 65 327 380 +3 295 65 380 +3 769 104 315 +3 426 318 427 +3 568 616 615 +3 695 728 727 +3 404 445 405 +3 1635 1653 1453 +3 271 478 12 +3 839 136 830 +3 615 648 647 +3 311 277 228 +3 749 1245 1225 +3 353 392 421 +3 793 138 753 +3 315 104 33 +3 432 466 465 +3 381 432 465 +3 465 466 527 +3 1170 1190 1099 +3 754 794 793 +3 558 754 280 +3 193 253 217 +3 253 268 267 +3 217 253 267 +3 268 354 353 +3 267 268 353 +3 354 392 353 +3 422 421 392 +3 354 422 392 +3 422 508 507 +3 421 422 507 +3 508 566 565 +3 507 508 565 +3 614 613 565 +3 566 614 565 +3 614 647 646 +3 613 614 646 +3 168 810 194 +3 886 940 923 +3 946 945 930 +3 929 939 944 +3 940 569 887 +3 661 649 616 +3 320 919 878 +3 227 526 464 +3 882 873 866 +3 552 384 820 +3 464 927 358 +3 917 432 905 +3 879 829 820 +3 194 836 880 +3 935 466 432 +3 917 935 432 +3 1038 1725 1013 +3 1378 1391 1406 +3 173 448 293 +3 477 943 510 +3 616 568 617 +3 1405 550 980 +3 665 86 847 +3 891 906 912 +3 845 130 54 +3 999 925 822 +3 1885 928 555 +3 904 910 270 +3 315 33 478 +3 1033 1034 1042 +3 490 921 26 +3 850 257 131 +3 1070 1077 1034 +3 843 860 15 +3 120 843 15 +3 850 209 257 +3 914 913 300 +3 880 911 910 +3 641 661 616 +3 843 120 797 +3 860 870 15 +3 870 131 15 +3 870 850 131 +3 894 873 882 +3 811 248 875 +3 974 981 992 +3 850 201 131 +3 131 201 850 +3 850 201 209 +3 907 917 905 +3 694 437 226 +3 895 843 797 +3 870 860 843 +3 816 870 843 +3 870 201 850 +3 913 933 932 +3 968 969 986 +3 840 118 712 +3 816 843 895 +3 201 856 209 +3 856 845 55 +3 209 856 55 +3 931 930 911 +3 228 151 184 +3 1340 884 1884 +3 553 506 536 +3 539 867 842 +3 870 924 201 +3 977 823 490 +3 868 829 780 +3 999 1000 925 +3 198 701 156 +3 787 816 895 +3 924 877 856 +3 201 924 856 +3 877 845 856 +3 66 305 941 +3 769 203 1208 +3 848 847 919 +3 880 889 911 +3 1027 589 605 +3 957 816 787 +3 849 870 816 +3 957 849 816 +3 414 821 409 +3 1887 1004 928 +3 569 888 887 +3 459 384 552 +3 891 889 890 +3 839 892 891 +3 1080 1057 1051 +3 957 328 816 +3 328 957 816 +3 849 881 870 +3 881 849 870 +3 870 849 924 +3 481 531 123 +3 777 835 698 +3 891 892 906 +3 912 911 889 +3 891 912 889 +3 546 1339 746 +3 328 849 957 +3 849 88 924 +3 1043 1070 1034 +3 777 122 46 +3 477 929 943 +3 617 641 616 +3 822 915 72 +3 915 331 72 +3 834 806 956 +3 788 957 787 +3 770 788 787 +3 788 328 957 +3 864 877 924 +3 833 938 130 +3 845 833 130 +3 938 256 130 +3 1005 142 574 +3 661 676 137 +3 730 305 776 +3 1186 1208 1207 +3 1189 1186 1207 +3 798 1888 1067 +3 864 924 88 +3 864 922 877 +3 982 845 877 +3 922 982 877 +3 982 833 845 +3 894 905 873 +3 879 665 86 +3 879 665 847 +3 817 922 864 +3 833 982 922 +3 817 833 922 +3 894 907 905 +3 1562 1561 1038 +3 305 893 776 +3 899 864 88 +3 1071 1049 1072 +3 788 770 328 +3 776 768 795 +3 835 919 847 +3 817 864 899 +3 833 256 938 +3 1177 1195 1176 +3 1276 1771 1275 +3 155 100 813 +3 832 96 449 +3 879 384 665 +3 879 86 665 +3 834 956 320 +3 863 898 328 +3 826 849 328 +3 898 826 328 +3 849 826 88 +3 826 899 88 +3 1346 1883 900 +3 930 945 944 +3 939 930 944 +3 810 818 836 +3 838 836 837 +3 1077 1069 1034 +3 891 890 838 +3 1473 1680 1679 +3 44 24 438 +3 899 200 817 +3 1374 1391 1378 +3 466 935 527 +3 66 941 730 +3 913 906 912 +3 956 919 320 +3 662 676 661 +3 239 395 863 +3 395 898 863 +3 819 826 898 +3 826 200 899 +3 35 86 82 +3 880 270 194 +3 935 950 527 +3 670 661 695 +3 134 256 94 +3 818 837 836 +3 848 879 847 +3 395 819 898 +3 826 819 200 +3 200 920 817 +3 920 876 833 +3 817 920 833 +3 833 876 256 +3 1034 1069 1068 +3 932 933 947 +3 997 676 662 +3 836 889 880 +3 757 729 730 +3 956 806 919 +3 603 749 1460 +3 876 48 256 +3 827 107 155 +3 107 184 155 +3 830 855 841 +3 1042 1034 1068 +3 832 449 795 +3 997 662 638 +3 384 261 665 +3 997 696 676 +3 294 48 876 +3 920 294 876 +3 925 915 822 +3 1199 1231 1886 +3 941 305 730 +3 200 418 294 +3 569 940 886 +3 100 155 184 +3 840 712 331 +3 921 379 26 +3 1016 1014 1699 +3 776 766 730 +3 983 997 638 +3 676 696 137 +3 487 395 239 +3 487 819 395 +3 569 886 511 +3 940 887 923 +3 986 1000 985 +3 1125 110 47 +3 947 968 958 +3 842 874 834 +3 822 918 66 +3 985 999 998 +3 984 985 998 +3 999 822 998 +3 983 984 997 +3 984 998 997 +3 819 418 200 +3 177 85 1206 +3 12 275 397 +3 1231 1165 1066 +3 240 769 1208 +3 1000 999 985 +3 943 965 568 +3 906 913 932 +3 300 913 892 +3 997 998 66 +3 998 822 66 +3 478 33 128 +3 570 701 1076 +3 305 72 768 +3 72 811 768 +3 878 884 411 +3 878 835 884 +3 930 939 929 +3 968 978 967 +3 958 968 967 +3 946 958 967 +3 819 853 418 +3 510 943 509 +3 509 943 568 +3 151 100 184 +3 978 984 983 +3 967 978 983 +3 474 1122 799 +3 932 931 912 +3 487 460 819 +3 460 29 819 +3 819 29 853 +3 340 867 383 +3 1134 1135 1161 +3 947 946 931 +3 1411 1501 1408 +3 300 892 855 +3 356 910 929 +3 136 838 837 +3 1259 351 523 +3 887 896 923 +3 260 86 665 +3 774 129 773 +3 872 873 871 +3 906 932 912 +3 661 137 695 +3 511 886 942 +3 985 984 978 +3 968 985 978 +3 818 136 837 +3 1559 851 857 +3 872 871 865 +3 1222 1221 543 +3 548 1005 115 +3 430 1198 1065 +3 768 811 832 +3 945 967 944 +3 1132 1134 1160 +3 1019 1036 1025 +3 1134 1161 1160 +3 615 616 649 +3 1560 884 1884 +3 884 835 888 +3 214 230 114 +3 811 332 832 +3 878 411 53 +3 848 842 879 +3 842 829 879 +3 48 673 256 +3 869 811 768 +3 912 931 911 +3 935 936 950 +3 871 302 381 +3 972 991 971 +3 708 137 696 +3 1225 571 110 +3 847 955 13 +3 803 190 189 +3 865 871 858 +3 986 985 968 +3 929 944 943 +3 227 972 526 +3 888 835 896 +3 1001 1002 840 +3 1830 1841 1829 +3 50 140 275 +3 394 424 423 +3 411 884 888 +3 936 935 917 +3 907 936 917 +3 835 847 698 +3 811 6 332 +3 842 867 829 +3 1161 1060 1226 +3 1885 399 1887 +3 808 834 995 +3 1659 1658 1638 +3 65 295 211 +3 918 822 305 +3 302 871 381 +3 847 86 955 +3 1001 840 925 +3 1010 937 834 +3 1208 203 177 +3 1135 1162 1161 +3 921 81 379 +3 271 315 478 +3 948 969 947 +3 464 526 927 +3 834 848 806 +3 409 296 414 +3 302 873 432 +3 885 896 777 +3 841 892 839 +3 811 875 6 +3 1077 1104 1069 +3 1104 1103 1069 +3 68 106 46 +3 823 921 490 +3 162 81 921 +3 823 162 921 +3 989 1001 1000 +3 986 989 1000 +3 1000 1001 925 +3 888 896 887 +3 929 477 356 +3 974 972 534 +3 87 2 213 +3 915 840 331 +3 970 969 948 +3 965 641 568 +3 1207 177 1206 +3 1726 1725 1038 +3 1002 51 840 +3 814 191 803 +3 191 190 803 +3 855 892 841 +3 302 432 381 +3 173 293 573 +3 880 904 270 +3 871 873 302 +3 358 914 300 +3 239 863 328 +3 910 911 929 +3 331 712 811 +3 438 24 404 +3 892 913 906 +3 991 1002 990 +3 128 33 83 +3 810 836 194 +3 788 770 787 +3 814 803 804 +3 774 126 129 +3 242 855 830 +3 981 1189 1206 +3 927 934 914 +3 847 13 777 +3 301 358 300 +3 822 72 305 +3 641 617 568 +3 839 838 136 +3 904 880 910 +3 1850 1864 1870 +3 118 248 811 +3 949 970 948 +3 970 989 986 +3 1328 1325 1316 +3 358 927 914 +3 867 340 829 +3 943 944 966 +3 1100 221 1361 +3 530 805 525 +3 327 148 377 +3 1259 179 351 +3 1029 1028 1014 +3 969 968 947 +3 970 986 969 +3 832 795 768 +3 888 569 411 +3 342 344 113 +3 458 126 121 +3 943 966 965 +3 979 901 823 +3 823 861 162 +3 701 198 1076 +3 966 638 641 +3 769 315 271 +3 760 761 787 +3 965 966 641 +3 927 949 934 +3 949 948 934 +3 558 755 754 +3 919 835 878 +3 270 910 356 +3 852 162 861 +3 106 170 162 +3 852 106 162 +3 947 958 946 +3 815 192 191 +3 814 815 191 +3 820 384 879 +3 305 768 893 +3 698 847 777 +3 829 340 780 +3 534 972 227 +3 121 522 458 +3 1071 1077 1070 +3 846 823 901 +3 846 861 823 +3 918 305 66 +3 893 768 776 +3 1190 1186 1099 +3 67 1010 937 +3 925 840 915 +3 862 861 846 +3 862 852 861 +3 835 777 896 +3 946 945 944 +3 862 106 852 +3 1885 1887 928 +3 464 358 431 +3 526 949 927 +3 946 944 945 +3 890 889 838 +3 66 696 997 +3 1019 1561 1026 +3 1375 1380 1291 +3 1071 1061 1077 +3 712 118 811 +3 806 848 919 +3 971 990 970 +3 661 670 649 +3 971 970 949 +3 749 1225 110 +3 122 777 13 +3 35 13 955 +3 734 701 1164 +3 795 449 195 +3 874 842 848 +3 990 1002 989 +3 977 979 823 +3 526 971 949 +3 78 193 192 +3 815 78 192 +3 990 989 970 +3 834 539 842 +3 839 891 838 +3 1146 767 1064 +3 1002 1001 989 +3 840 51 118 +3 886 862 846 +3 280 754 753 +3 811 869 768 +3 906 913 912 +3 967 966 944 +3 931 946 930 +3 829 552 820 +3 886 106 862 +3 885 46 106 +3 1061 1104 1077 +3 320 67 834 +3 905 432 873 +3 874 848 834 +3 911 930 929 +3 1026 1572 1019 +3 972 974 992 +3 934 933 913 +3 914 934 913 +3 923 106 886 +3 777 46 885 +3 355 356 394 +3 449 96 195 +3 66 730 696 +3 807 96 832 +3 72 331 811 +3 896 106 923 +3 896 885 106 +3 1071 1070 1043 +3 932 947 931 +3 1049 1071 1043 +3 450 39 785 +3 946 967 945 +3 836 838 889 +3 787 761 788 +3 967 983 638 +3 966 967 638 +3 991 990 971 +3 597 1165 1231 +3 937 539 834 +3 934 948 947 +3 933 934 947 +3 886 846 942 +3 972 971 526 +3 1737 1762 1746 +3 1841 1851 1829 +3 417 1219 1218 +3 1166 110 1125 +3 159 342 113 +3 1065 1032 1274 +3 430 1065 1274 +3 1307 1320 1395 +3 767 1027 1 +3 846 798 1067 +3 735 1256 469 +3 1829 1850 1834 +3 398 317 1039 +3 288 32 34 +3 1051 1057 1058 +3 515 1684 1674 +3 1080 1079 1057 +3 1051 1058 1029 +3 1039 288 34 +3 1561 1726 1038 +3 1379 1307 1395 +3 304 642 409 +3 1396 1380 1381 +3 1030 1051 1029 +3 1219 1218 959 +3 598 1205 642 +3 1604 1615 1613 +3 1209 953 1193 +3 389 1521 1121 +3 398 75 70 +3 1314 273 524 +3 1022 1030 1021 +3 1022 1021 1016 +3 1030 1029 1021 +3 598 642 304 +3 528 1185 714 +3 1194 1209 1193 +3 177 12 397 +3 878 67 320 +3 1057 1045 1028 +3 1096 1095 1079 +3 1296 264 1319 +3 101 491 1237 +3 834 808 67 +3 1312 1484 1110 +3 963 1312 1110 +3 113 344 637 +3 1497 113 1496 +3 1119 1127 1113 +3 1312 1483 1484 +3 1799 1816 1812 +3 1079 1095 1057 +3 854 357 1191 +3 399 444 1210 +3 539 1011 383 +3 246 250 664 +3 1028 1038 1020 +3 1058 1057 1029 +3 311 1329 1396 +3 1260 1483 1312 +3 1187 1328 428 +3 1851 1864 1850 +3 317 609 619 +3 609 463 619 +3 1223 952 317 +3 603 1166 619 +3 1003 976 1094 +3 1248 556 297 +3 287 1885 555 +3 1138 1172 1163 +3 297 556 610 +3 1591 878 1009 +3 463 603 619 +3 749 110 1166 +3 1157 680 1081 +3 1886 304 409 +3 436 1027 605 +3 1015 1029 1014 +3 556 20 610 +3 20 604 610 +3 1099 1186 1189 +3 20 599 604 +3 1209 854 953 +3 1360 1550 1685 +3 492 398 70 +3 1172 1193 1192 +3 1175 1172 1192 +3 733 292 406 +3 202 733 406 +3 1010 834 67 +3 468 113 637 +3 154 1157 1081 +3 1172 1175 1163 +3 1193 854 1192 +3 953 854 1193 +3 1055 174 493 +3 1502 650 1046 +3 236 60 84 +3 1195 1194 1176 +3 85 177 397 +3 1163 1175 1148 +3 585 433 357 +3 1050 1045 1028 +3 1138 1148 1112 +3 1603 1402 1589 +3 1174 1192 1191 +3 1170 1174 1190 +3 1416 1417 1617 +3 398 1039 34 +3 75 398 1007 +3 1095 1107 1078 +3 1133 1134 1132 +3 1528 1022 1551 +3 1066 598 304 +3 292 733 667 +3 63 903 18 +3 619 1125 288 +3 1357 1355 1356 +3 733 1363 667 +3 470 1 212 +3 1017 830 136 +3 1119 1113 1095 +3 1387 231 247 +3 1107 1112 1078 +3 113 468 1496 +3 1028 1045 1050 +3 1014 1028 1013 +3 808 1011 539 +3 830 841 839 +3 12 50 275 +3 1344 1530 1115 +3 1363 153 19 +3 667 1363 19 +3 1103 1102 1068 +3 952 609 317 +3 1175 1174 1148 +3 1031 236 681 +3 595 10 555 +3 1119 1114 1587 +3 1114 1119 1096 +3 709 272 492 +3 451 736 434 +3 1174 1175 1192 +3 1380 1328 1316 +3 928 595 555 +3 153 489 1202 +3 572 598 1066 +3 19 153 1202 +3 1737 1746 1721 +3 1418 1417 1395 +3 1148 1147 1126 +3 488 1387 1448 +3 1245 488 1448 +3 1040 543 598 +3 572 1040 598 +3 1021 1029 1015 +3 1654 1653 1635 +3 329 58 595 +3 489 125 488 +3 1163 1148 1138 +3 1534 1687 1439 +3 342 709 344 +3 1112 1148 1126 +3 1202 489 488 +3 125 231 1387 +3 488 125 1387 +3 398 272 1223 +3 383 867 539 +3 414 296 928 +3 1176 1194 1172 +3 1028 1020 1013 +3 173 176 448 +3 1591 878 1009 +3 444 287 263 +3 1083 444 263 +3 272 952 1223 +3 1192 854 1191 +3 854 585 357 +3 1119 1152 1139 +3 1547 461 513 +3 296 329 595 +3 296 595 928 +3 603 749 1166 +3 1319 1329 1381 +3 1138 1152 1172 +3 63 18 33 +3 433 63 104 +3 769 433 104 +3 1174 1171 1147 +3 1372 1381 1375 +3 1613 1424 1603 +3 1113 1138 1107 +3 571 1218 1219 +3 1528 1551 1548 +3 1007 398 34 +3 1738 1737 1717 +3 1396 1329 1380 +3 1063 572 1066 +3 1153 1176 1152 +3 1139 1113 1127 +3 1119 1139 1127 +3 1191 357 1190 +3 357 240 1190 +3 1148 1174 1147 +3 29 460 325 +3 317 619 1039 +3 1754 1762 1737 +3 1329 311 1396 +3 1309 1380 1316 +3 1225 247 1218 +3 1448 1387 247 +3 1028 1045 1038 +3 1635 1453 1452 +3 116 1256 735 +3 514 1032 962 +3 1095 1078 1086 +3 1079 1095 1086 +3 357 433 240 +3 1174 1170 1171 +3 1218 1219 959 +3 1067 942 846 +3 1057 1095 1079 +3 10 114 287 +3 150 853 620 +3 555 10 287 +3 1152 1138 1139 +3 1052 1085 1370 +3 1704 1721 1703 +3 89 51 1002 +3 512 89 1002 +3 1152 1176 1172 +3 981 1206 992 +3 991 512 1002 +3 402 673 48 +3 1016 1551 1022 +3 1151 571 1219 +3 433 769 240 +3 1291 1380 1309 +3 1571 785 884 +3 589 490 605 +3 584 572 1063 +3 1057 1079 1045 +3 1138 1112 1107 +3 1045 1086 1078 +3 1095 1113 1107 +3 76 512 991 +3 1549 1552 1548 +3 203 769 271 +3 992 76 991 +3 274 89 512 +3 76 274 512 +3 274 51 89 +3 139 118 51 +3 274 139 51 +3 11 248 118 +3 139 11 118 +3 1056 1042 1068 +3 737 103 17 +3 871 302 858 +3 273 489 153 +3 1826 1835 1820 +3 197 48 294 +3 975 197 294 +3 197 713 402 +3 48 197 402 +3 584 1076 1040 +3 1079 1086 1045 +3 1029 1057 1028 +3 1139 1138 1113 +3 572 584 1040 +3 198 412 1040 +3 1076 198 1040 +3 298 273 153 +3 1500 1531 1359 +3 1096 1119 1095 +3 1194 1193 1172 +3 1560 785 1571 +3 882 866 894 +3 49 139 274 +3 1189 1207 1206 +3 1102 1133 1132 +3 1717 1721 1704 +3 1674 1487 1653 +3 584 570 1076 +3 894 1102 907 +3 821 1167 1199 +3 17 103 140 +3 50 17 140 +3 1042 1056 866 +3 1056 1068 894 +3 866 1056 894 +3 894 1068 1102 +3 1102 1132 936 +3 907 1102 936 +3 1160 950 936 +3 1132 1160 936 +3 1174 1191 1190 +3 1206 85 76 +3 992 1206 76 +3 397 274 76 +3 85 397 76 +3 275 49 274 +3 397 275 274 +3 140 139 49 +3 275 140 49 +3 103 11 139 +3 140 103 139 +3 409 642 329 +3 296 409 329 +3 436 975 1241 +3 436 605 975 +3 605 26 975 +3 26 197 975 +3 26 379 713 +3 197 26 713 +3 1010 539 937 +3 59 454 346 +3 652 408 413 +3 21 61 149 +3 171 345 347 +3 94 2 130 +3 130 256 134 +3 1004 1393 715 +3 313 368 367 +3 544 90 146 +3 81 535 379 +3 1257 527 950 +3 1257 950 1160 +3 302 301 259 +3 1004 414 928 +3 1160 1238 1257 +3 102 214 186 +3 1238 1160 1161 +3 1226 1238 1161 +3 1257 227 527 +3 95 233 364 +3 620 853 29 +3 1257 534 227 +3 282 454 230 +3 1453 1653 1452 +3 232 233 95 +3 821 1199 1886 +3 1232 1238 1226 +3 1238 981 1257 +3 1257 981 534 +3 417 408 652 +3 1233 1238 1232 +3 1027 436 42 +3 196 504 111 +3 169 180 81 +3 61 21 479 +3 631 231 388 +3 372 631 388 +3 1300 1382 1270 +3 1558 1559 857 +3 714 298 800 +3 298 153 800 +3 981 974 534 +3 704 348 5 +3 706 226 234 +3 388 231 443 +3 311 1330 1329 +3 1282 1300 1270 +3 1189 981 1238 +3 1233 1189 1238 +3 334 94 256 +3 1462 1672 1473 +3 895 786 787 +3 595 58 10 +3 1242 1251 1256 +3 489 231 125 +3 1236 1256 1250 +3 0 717 40 +3 470 212 0 +3 717 279 40 +3 276 230 59 +3 454 282 1237 +3 521 219 213 +3 417 652 346 +3 1266 417 346 +3 364 521 213 +3 171 363 345 +3 279 704 40 +3 470 0 160 +3 94 95 2 +3 42 281 717 +3 97 375 540 +3 61 479 363 +3 1216 705 706 +3 349 372 233 +3 453 42 717 +3 1241 975 150 +3 150 975 294 +3 214 362 282 +3 959 417 1266 +3 959 1219 417 +3 281 42 279 +3 408 607 372 +3 372 607 631 +3 0 40 25 +3 1221 69 1242 +3 287 114 263 +3 279 147 157 +3 704 279 157 +3 134 94 130 +3 81 52 535 +3 1265 58 329 +3 1249 1265 329 +3 82 97 13 +3 364 643 158 +3 82 375 97 +3 156 542 1214 +3 479 232 345 +3 35 82 13 +3 147 620 29 +3 102 186 58 +3 64 102 58 +3 363 479 345 +3 21 413 479 +3 652 413 21 +3 372 388 233 +3 216 43 5 +3 61 171 52 +3 413 349 479 +3 186 114 10 +3 619 288 1039 +3 697 1221 412 +3 171 61 363 +3 212 717 0 +3 1236 1242 1256 +3 607 408 417 +3 92 21 149 +3 279 42 147 +3 1221 1222 412 +3 697 1217 457 +3 156 1214 1213 +3 453 717 1 +3 552 829 868 +3 114 276 263 +3 570 734 701 +3 324 29 325 +3 1 717 212 +3 214 102 101 +3 2 364 213 +3 95 364 2 +3 74 97 68 +3 108 58 1265 +3 196 241 504 +3 416 325 326 +3 1346 900 767 +3 642 1205 1249 +3 71 135 6 +3 665 261 260 +3 389 43 216 +3 108 64 58 +3 1255 1236 1250 +3 7 1261 71 +3 1261 135 71 +3 83 737 17 +3 165 380 327 +3 147 29 324 +3 279 717 281 +3 417 1218 607 +3 1218 247 607 +3 83 573 737 +3 737 1239 7 +3 1239 1261 7 +3 42 620 147 +3 1215 697 1214 +3 1221 1242 1236 +3 1261 172 135 +3 651 62 6 +3 117 332 6 +3 62 117 6 +3 416 324 325 +3 157 324 416 +3 40 5 43 +3 1227 1239 737 +3 573 1227 737 +3 1261 1262 172 +3 172 651 6 +3 135 172 6 +3 62 807 117 +3 0 25 160 +3 364 388 643 +3 345 95 94 +3 1214 909 1215 +3 336 149 180 +3 233 388 364 +3 807 832 117 +3 1243 1262 1261 +3 1239 1243 1261 +3 42 150 620 +3 1215 1217 697 +3 1214 412 198 +3 1213 1214 198 +3 293 1227 573 +3 172 62 651 +3 878 1591 67 +3 1214 697 412 +3 1228 1243 1239 +3 1227 1228 1239 +3 96 45 438 +3 40 704 5 +3 59 92 181 +3 172 9 62 +3 643 22 158 +3 388 22 643 +3 92 149 181 +3 345 94 334 +3 652 21 92 +3 345 232 95 +3 214 101 362 +3 535 171 713 +3 1262 678 172 +3 678 9 172 +3 9 592 62 +3 479 349 233 +3 326 325 333 +3 117 832 332 +3 347 345 334 +3 234 1216 706 +3 486 62 592 +3 486 807 62 +3 884 1340 1884 +3 1270 1381 1372 +3 348 157 299 +3 1320 1418 1395 +3 1243 452 1262 +3 1262 452 678 +3 343 592 9 +3 149 61 52 +3 1224 1230 1228 +3 1246 1253 1243 +3 1243 1253 452 +3 163 486 592 +3 163 96 486 +3 2 87 54 +3 1474 1497 1496 +3 1488 1474 1496 +3 525 115 731 +3 1230 1246 1243 +3 1228 1230 1243 +3 452 343 9 +3 678 452 9 +3 31 592 343 +3 31 163 592 +3 743 226 437 +3 334 256 347 +3 149 52 180 +3 6 875 248 +3 1482 1474 1488 +3 1246 1230 1253 +3 452 31 343 +3 45 96 163 +3 364 158 521 +3 737 7 103 +3 213 73 87 +3 1063 533 584 +3 45 44 438 +3 42 436 150 +3 1244 1240 1092 +3 211 445 23 +3 1459 1465 1482 +3 1440 988 1442 +3 163 44 45 +3 1418 1354 1863 +3 436 1241 150 +3 453 1027 42 +3 108 1265 1249 +3 230 454 59 +3 1465 1474 1482 +3 311 1329 1319 +3 677 1234 1230 +3 1230 1234 1253 +3 452 374 31 +3 163 323 44 +3 282 214 230 +3 214 282 230 +3 1258 374 452 +3 1253 1258 452 +3 1215 909 1217 +3 1354 1418 1320 +3 1234 1240 1253 +3 294 418 853 +3 558 234 226 +3 11 103 71 +3 1240 1258 1253 +3 31 77 163 +3 77 323 163 +3 558 280 234 +3 214 224 186 +3 1205 1250 1249 +3 586 1296 1282 +3 1240 1234 677 +3 114 230 276 +3 1125 47 32 +3 308 77 31 +3 868 780 340 +3 1250 108 1249 +3 694 226 707 +3 288 1125 32 +3 319 31 374 +3 31 319 308 +3 529 323 77 +3 323 24 44 +3 280 309 234 +3 234 309 1216 +3 1491 1012 183 +3 77 308 529 +3 323 41 24 +3 225 361 1313 +3 6 248 71 +3 1258 669 374 +3 669 319 374 +3 249 41 323 +3 529 249 323 +3 115 444 782 +3 146 90 3 +3 309 705 1216 +3 669 1258 1240 +3 1264 109 636 +3 1302 185 1293 +3 1217 909 960 +3 237 265 1302 +3 337 1337 1336 +3 547 541 205 +3 1313 691 705 +3 286 352 337 +3 1327 1332 370 +3 798 846 901 +3 337 1338 1337 +3 361 225 611 +3 451 439 484 +3 677 1092 1240 +3 225 1313 109 +3 264 228 277 +3 352 1334 337 +3 785 783 1340 +3 309 1313 705 +3 674 683 682 +3 663 623 602 +3 622 663 710 +3 995 1591 806 +3 450 206 1047 +3 1283 99 215 +3 611 563 593 +3 475 246 664 +3 1294 1264 636 +3 442 1337 1347 +3 465 527 227 +3 659 630 636 +3 1454 1499 1527 +3 602 674 663 +3 107 1293 185 +3 1829 1851 1850 +3 109 690 660 +3 1313 690 109 +3 563 611 1264 +3 362 101 1237 +3 337 1334 1338 +3 206 450 517 +3 1347 471 503 +3 167 554 1323 +3 1468 1472 1489 +3 1091 1141 702 +3 471 563 1294 +3 715 1167 821 +3 1264 611 225 +3 1332 337 1336 +3 1004 1887 399 +3 586 1283 215 +3 1023 1252 1400 +3 1179 1370 1383 +3 1313 726 1324 +3 471 636 630 +3 352 420 1334 +3 1047 39 450 +3 99 1283 586 +3 237 1302 107 +3 14 446 330 +3 1313 361 645 +3 530 525 784 +3 1338 553 1348 +3 1337 1338 1348 +3 370 1332 442 +3 1332 1336 442 +3 715 821 414 +3 237 283 1322 +3 362 1237 282 +3 187 1303 237 +3 257 27 131 +3 801 430 1335 +3 1287 36 213 +3 554 167 338 +3 335 1331 1330 +3 311 335 1330 +3 1331 439 451 +3 506 420 421 +3 1330 1331 451 +3 663 674 1284 +3 674 385 1284 +3 184 107 185 +3 1322 283 314 +3 14 27 446 +3 439 520 484 +3 265 185 1302 +3 420 553 1338 +3 554 338 916 +3 1400 1298 1023 +3 553 563 471 +3 1324 726 1313 +3 1285 14 446 +3 434 435 451 +3 338 167 175 +3 277 311 1319 +3 546 783 244 +3 801 1335 1274 +3 338 1297 916 +3 1294 563 1264 +3 420 1338 1334 +3 783 606 244 +3 1337 1348 1347 +3 1313 1324 690 +3 311 312 335 +3 220 1285 1310 +3 1284 385 1278 +3 1128 1023 1252 +3 1285 220 14 +3 622 623 663 +3 109 660 636 +3 524 446 330 +3 1589 1402 1403 +3 338 220 1310 +3 674 682 385 +3 284 337 1332 +3 107 1302 1293 +3 663 1284 710 +3 1888 517 1067 +3 350 1251 69 +3 435 434 415 +3 435 415 428 +3 1297 338 1310 +3 682 307 385 +3 1306 1305 1280 +3 1276 1306 1280 +3 313 367 312 +3 1327 284 1332 +3 1336 1337 442 +3 1264 225 109 +3 180 169 1229 +3 475 801 246 +3 352 267 353 +3 1403 1404 1589 +3 1285 1292 1310 +3 307 682 748 +3 682 718 748 +3 1277 1276 1275 +3 1158 237 107 +3 1067 517 511 +3 1271 1282 1270 +3 489 125 443 +3 446 14 330 +3 586 1282 1271 +3 1292 1285 446 +3 446 330 1287 +3 443 125 489 +3 108 116 735 +3 813 100 99 +3 1276 1307 1306 +3 1483 1260 1317 +3 1272 586 1271 +3 1348 553 471 +3 1287 213 219 +3 330 446 1287 +3 443 231 489 +3 330 36 1287 +3 86 35 955 +3 450 785 1560 +3 1312 1304 1260 +3 1329 435 428 +3 1289 1276 1277 +3 1289 1290 1276 +3 1158 187 237 +3 1311 556 1248 +3 558 226 743 +3 1323 554 993 +3 1292 446 524 +3 273 443 489 +3 1290 1289 1277 +3 1290 1307 1276 +3 215 264 1296 +3 1304 1286 1273 +3 1260 1304 1273 +3 1311 1248 1273 +3 1286 1311 1273 +3 246 801 250 +3 1322 314 278 +3 1019 1572 1036 +3 307 748 608 +3 182 307 608 +3 1321 443 273 +3 471 1294 636 +3 215 1296 586 +3 1322 278 265 +3 542 701 1129 +3 1101 1284 1278 +3 39 783 785 +3 1304 400 1286 +3 400 1311 1286 +3 1339 244 1200 +3 1324 309 726 +3 674 602 683 +3 265 237 1322 +3 1653 1487 1470 +3 446 36 330 +3 1321 22 443 +3 1277 1267 1290 +3 1290 1308 1307 +3 1313 309 1324 +3 467 68 97 +3 1312 1279 1304 +3 367 1331 335 +3 524 330 1287 +3 1347 1348 471 +3 1308 1315 1307 +3 1365 1529 1108 +3 531 530 784 +3 123 531 784 +3 1041 556 1311 +3 666 1041 1311 +3 312 367 335 +3 1705 1707 1711 +3 690 1324 725 +3 1331 367 439 +3 710 1284 1101 +3 608 748 758 +3 170 699 169 +3 1308 1309 1315 +3 1368 1362 1371 +3 306 1200 244 +3 1279 1299 1304 +3 1304 1299 400 +3 666 1311 400 +3 251 283 237 +3 1853 1866 1871 +3 1312 963 1279 +3 1101 1279 963 +3 1314 1321 273 +3 699 1229 169 +3 1268 1290 1267 +3 1290 1309 1308 +3 386 1320 1315 +3 1320 386 1315 +3 314 1327 370 +3 542 156 701 +3 475 1486 1684 +3 1297 1185 528 +3 1031 916 60 +3 1297 1310 1185 +3 158 1321 1314 +3 1379 1305 1306 +3 553 420 506 +3 291 1342 782 +3 608 758 1041 +3 666 608 1041 +3 1635 1452 1453 +3 60 916 528 +3 916 1297 528 +3 1314 1287 158 +3 601 471 630 +3 1291 1290 1268 +3 1316 1315 1309 +3 1316 1320 1315 +3 400 608 666 +3 1292 524 1185 +3 187 189 188 +3 68 467 1318 +3 187 188 1303 +3 1281 1291 1268 +3 1290 1291 1309 +3 1320 1316 386 +3 1278 385 1299 +3 1279 1278 1299 +3 385 307 400 +3 1299 385 400 +3 307 182 400 +3 400 182 608 +3 801 208 430 +3 243 547 205 +3 1292 1185 1310 +3 1324 726 725 +3 699 170 105 +3 105 68 1318 +3 699 105 1318 +3 1316 1325 386 +3 1325 1187 386 +3 1096 1587 1114 +3 515 208 801 +3 1287 1314 524 +3 1287 219 158 +3 1541 1546 1545 +3 1540 1541 1545 +3 1361 519 1520 +3 570 1129 701 +3 785 1340 884 +3 176 903 127 +3 1232 1226 1233 +3 570 1366 1129 +3 1571 884 1560 +3 378 533 1432 +3 210 570 533 +3 378 210 533 +3 570 210 1366 +3 210 290 1129 +3 1366 210 1129 +3 1129 290 542 +3 290 909 542 +3 290 960 909 +3 124 697 290 +3 210 124 290 +3 697 457 290 +3 290 457 960 +3 960 457 1217 +3 378 124 210 +3 1477 1420 1006 +3 591 378 597 +3 1165 591 597 +3 378 591 124 +3 124 457 697 +3 124 1394 457 +3 1653 1470 1452 +3 1377 1378 1388 +3 1199 1048 1231 +3 124 350 1394 +3 1394 350 457 +3 1048 1165 1231 +3 1048 671 591 +3 1165 1048 591 +3 671 350 124 +3 591 671 124 +3 350 69 457 +3 98 467 97 +3 827 155 1880 +3 1544 1545 1157 +3 176 173 18 +3 1273 700 1260 +3 1369 1048 1199 +3 671 588 350 +3 1545 1546 1204 +3 1546 640 1204 +3 607 247 231 +3 1278 1279 1101 +3 154 1081 1513 +3 1777 1770 1785 +3 1295 499 143 +3 1850 1849 1834 +3 1199 732 1369 +3 732 1183 1369 +3 926 1048 1369 +3 1183 926 1369 +3 926 635 671 +3 1048 926 671 +3 671 635 588 +3 635 1251 350 +3 588 635 350 +3 1449 1472 1468 +3 1490 1489 1472 +3 1425 1074 1389 +3 1198 494 1065 +3 758 718 759 +3 1449 1468 1472 +3 1260 700 1317 +3 732 926 1183 +3 1449 1451 1468 +3 1468 1451 1472 +3 1490 538 1489 +3 272 406 952 +3 1183 926 732 +3 926 1183 635 +3 1426 1435 1434 +3 1449 1450 1451 +3 1421 1422 1426 +3 1426 1422 1435 +3 1469 1486 1490 +3 1472 1469 1490 +3 1183 455 635 +3 1435 1450 1449 +3 1434 1435 1449 +3 1451 1469 1472 +3 475 538 1490 +3 1486 475 1490 +3 475 664 538 +3 250 289 538 +3 664 250 538 +3 306 260 575 +3 455 1183 732 +3 1169 455 732 +3 455 469 635 +3 469 1256 1251 +3 635 469 1251 +3 1204 1389 1074 +3 1319 1381 1382 +3 1364 1370 1085 +3 1329 1396 1381 +3 1330 435 1329 +3 1444 1451 1450 +3 1435 1444 1450 +3 1520 519 1120 +3 1505 1120 1326 +3 640 883 1425 +3 1357 1364 1355 +3 1357 1370 1364 +3 1357 1211 1370 +3 1225 1245 1448 +3 1408 1423 1422 +3 1411 1408 1422 +3 1423 1436 1435 +3 1422 1423 1435 +3 1436 1437 1444 +3 1435 1436 1444 +3 1437 1452 1451 +3 1444 1437 1451 +3 1452 1470 1469 +3 1451 1452 1469 +3 1469 1470 1486 +3 1486 1674 1487 +3 1413 980 1420 +3 1470 1487 1486 +3 1537 154 1105 +3 1393 1054 1169 +3 668 455 1169 +3 1054 668 1169 +3 668 735 469 +3 455 668 469 +3 1455 1445 1446 +3 1185 524 298 +3 459 552 38 +3 1731 1739 1722 +3 1376 1211 1357 +3 1409 1408 1398 +3 1427 1437 1436 +3 1423 1427 1436 +3 1403 1388 1404 +3 84 1367 1363 +3 596 556 1041 +3 714 1185 298 +3 1004 1054 1393 +3 1210 574 399 +3 1320 1307 1315 +3 1635 1453 1438 +3 1359 1357 1356 +3 1358 1359 1356 +3 1377 1376 1357 +3 1359 1377 1357 +3 1388 1211 1376 +3 1377 1388 1376 +3 1402 1409 1398 +3 1388 1398 1211 +3 1402 1408 1409 +3 1402 1424 1423 +3 1408 1402 1423 +3 1423 1424 1427 +3 1424 1438 1437 +3 1427 1424 1437 +3 1438 1453 1452 +3 1437 1438 1452 +3 1197 828 650 +3 1111 1511 1510 +3 1300 1319 1382 +3 1010 808 539 +3 208 1198 430 +3 1200 459 38 +3 1539 1540 1544 +3 1507 1094 1405 +3 1094 976 1405 +3 475 515 801 +3 533 378 1432 +3 744 491 668 +3 1054 744 668 +3 491 101 735 +3 668 491 735 +3 384 459 1200 +3 306 384 1200 +3 1512 1197 650 +3 7 71 103 +3 1466 1295 1074 +3 1325 1328 1187 +3 1329 428 1328 +3 1507 1405 1397 +3 1120 897 1184 +3 1388 1403 1402 +3 1110 859 576 +3 1431 1110 576 +3 399 1212 744 +3 1363 800 153 +3 575 384 306 +3 1178 1100 1512 +3 1425 883 1074 +3 733 84 1363 +3 55 54 87 +3 1296 1300 1282 +3 1378 1377 1359 +3 1004 715 414 +3 1462 1479 1478 +3 1479 1492 222 +3 1478 1479 222 +3 1492 30 179 +3 222 1492 179 +3 30 351 179 +3 1544 1157 154 +3 429 297 709 +3 1110 1483 1475 +3 86 306 391 +3 700 159 1498 +3 1317 700 1498 +3 205 467 540 +3 828 518 650 +3 1672 1462 1473 +3 399 574 1212 +3 574 634 744 +3 1212 574 744 +3 634 1237 491 +3 744 634 491 +3 1367 714 1363 +3 375 606 112 +3 375 82 606 +3 82 86 391 +3 1457 1181 640 +3 1546 1457 640 +3 1479 1493 1492 +3 1493 258 30 +3 1492 1493 30 +3 429 1248 297 +3 39 375 199 +3 336 181 149 +3 1439 1511 1111 +3 1684 515 475 +3 1483 1317 1475 +3 1317 1498 1475 +3 429 342 159 +3 700 429 159 +3 1510 1052 1179 +3 1181 1130 883 +3 640 1181 883 +3 1405 980 1413 +3 1140 964 1181 +3 1509 1439 1517 +3 1479 1480 1493 +3 403 351 30 +3 258 403 30 +3 390 389 1121 +3 1400 897 1298 +3 604 272 709 +3 1460 749 603 +3 403 523 351 +3 1249 329 642 +3 1390 1466 883 +3 1382 1381 1270 +3 1363 714 800 +3 342 429 709 +3 540 375 1047 +3 297 604 709 +3 1467 1461 1201 +3 1130 1390 883 +3 1374 1454 1515 +3 1462 1480 1479 +3 1136 523 403 +3 964 1441 1181 +3 1059 1522 1128 +3 1003 221 500 +3 976 1003 500 +3 1100 1197 1512 +3 390 25 43 +3 1407 1416 1415 +3 1406 1407 1415 +3 1455 1446 1458 +3 1446 1463 1462 +3 1458 1446 1462 +3 1463 1464 1462 +3 1464 1481 1480 +3 1462 1464 1480 +3 1481 1494 1493 +3 1480 1481 1493 +3 1494 994 258 +3 1493 1494 258 +3 456 403 258 +3 994 456 258 +3 621 1136 403 +3 456 621 403 +3 621 523 1136 +3 621 745 523 +3 141 473 523 +3 745 141 523 +3 1516 1524 1476 +3 1128 245 1471 +3 1155 321 634 +3 574 1155 634 +3 599 681 202 +3 298 524 273 +3 681 236 202 +3 1368 1371 1527 +3 1263 1254 1540 +3 1502 1524 1476 +3 1476 1046 1115 +3 321 454 1237 +3 634 321 1237 +3 541 467 205 +3 467 97 540 +3 98 97 467 +3 236 84 733 +3 1446 1464 1463 +3 621 141 745 +3 1516 1476 1503 +3 1467 1201 828 +3 174 639 142 +3 202 236 733 +3 1686 1703 1702 +3 1494 1495 994 +3 1495 1123 994 +3 516 141 621 +3 1037 1059 1128 +3 590 467 541 +3 701 156 1164 +3 1398 1408 1383 +3 493 1301 322 +3 639 321 1155 +3 1429 1446 1445 +3 1481 1495 1494 +3 1220 456 994 +3 1123 1220 994 +3 954 322 495 +3 1373 493 322 +3 987 321 639 +3 260 306 86 +3 1370 1384 1383 +3 1280 1305 1362 +3 1305 1371 1362 +3 1305 1379 1371 +3 1392 1386 1371 +3 1392 1395 1386 +3 1395 1407 1386 +3 1395 1417 1416 +3 1407 1395 1416 +3 1703 1694 1704 +3 1428 1430 1429 +3 1430 1442 1446 +3 1429 1430 1446 +3 1442 1459 1464 +3 1446 1442 1464 +3 1459 1482 1481 +3 1464 1459 1481 +3 1482 1488 1481 +3 1488 1496 1495 +3 1481 1488 1495 +3 1496 468 1123 +3 1495 1496 1123 +3 637 1220 1123 +3 468 637 1123 +3 637 456 1220 +3 637 1203 456 +3 161 621 456 +3 1203 161 456 +3 75 516 621 +3 161 75 621 +3 1687 1694 1703 +3 75 34 495 +3 954 495 34 +3 34 32 322 +3 954 34 322 +3 32 47 322 +3 47 1373 322 +3 47 493 1373 +3 47 183 493 +3 183 1055 493 +3 1055 1012 174 +3 1012 639 174 +3 959 987 639 +3 1012 959 639 +3 959 321 987 +3 959 346 321 +3 346 454 321 +3 1341 1229 541 +3 1229 699 541 +3 699 1318 590 +3 541 699 590 +3 637 161 1203 +3 1615 1635 1438 +3 1300 1296 1319 +3 1379 1395 1392 +3 1615 1438 1424 +3 1613 1615 1424 +3 75 1007 34 +3 1229 1341 336 +3 700 1273 1248 +3 1392 1395 1379 +3 70 161 637 +3 183 1012 1055 +3 1673 1184 1504 +3 1159 1504 1184 +3 1266 346 959 +3 1604 1613 1603 +3 1459 1442 1456 +3 1075 1502 1503 +3 221 1100 500 +3 677 1084 1092 +3 1230 1224 677 +3 1537 1544 154 +3 1105 1097 1088 +3 1121 1105 1088 +3 1146 1346 767 +3 1087 293 176 +3 1100 1467 1197 +3 1154 585 1209 +3 962 1032 1065 +3 1765 1759 1024 +3 1408 1501 1383 +3 1516 1502 1524 +3 143 499 519 +3 1147 1142 1126 +3 1074 1094 680 +3 1399 897 1400 +3 1087 176 366 +3 235 1087 653 +3 897 1399 1184 +3 1149 1135 1061 +3 1685 1687 1360 +3 1379 1392 1371 +3 1810 259 242 +3 293 448 176 +3 1521 1537 1105 +3 235 653 677 +3 1100 1361 1467 +3 373 1538 1537 +3 1514 585 1059 +3 1059 585 341 +3 462 796 1023 +3 964 1106 1419 +3 1505 1326 1201 +3 711 63 1514 +3 964 1140 1092 +3 340 780 868 +3 796 1037 1128 +3 1037 127 796 +3 127 1037 796 +3 18 903 127 +3 1059 341 1522 +3 1508 366 1098 +3 1410 176 127 +3 293 1087 235 +3 1117 187 1876 +3 366 1508 1106 +3 1399 1159 1184 +3 1399 1400 1252 +3 1170 1099 1142 +3 1410 1037 1098 +3 903 18 127 +3 1383 1384 1211 +3 1522 341 1154 +3 1120 1505 1201 +3 1087 366 653 +3 1060 1135 1485 +3 964 1419 1130 +3 293 235 1224 +3 1244 1092 1457 +3 1545 1204 1157 +3 1252 1471 1399 +3 366 964 653 +3 1525 1126 1142 +3 160 360 1173 +3 366 176 1098 +3 499 1401 1298 +3 1539 1544 1537 +3 677 653 1084 +3 176 18 903 +3 199 375 112 +3 1520 1120 1461 +3 644 1539 1538 +3 80 1535 216 +3 176 1410 1098 +3 1140 1181 1457 +3 462 1098 796 +3 1541 1457 1546 +3 1361 1520 1467 +3 1467 1520 1461 +3 373 644 1538 +3 1106 462 781 +3 1591 834 67 +3 390 594 360 +3 160 390 360 +3 1254 1247 1541 +3 1075 1503 980 +3 903 711 127 +3 181 263 276 +3 444 1083 291 +3 1538 1539 1537 +3 1419 1106 1390 +3 519 1361 143 +3 216 1535 1521 +3 1094 976 680 +3 1441 1130 1181 +3 1006 672 1385 +3 1060 1485 1149 +3 43 389 390 +3 181 809 263 +3 1120 1201 1461 +3 1130 1419 1390 +3 1081 680 1507 +3 1231 1165 597 +3 809 1083 263 +3 964 366 1106 +3 809 181 336 +3 809 291 1083 +3 496 1506 1046 +3 650 496 1046 +3 390 1121 594 +3 1295 1003 1074 +3 1832 1845 1831 +3 1204 640 1389 +3 341 585 1154 +3 1081 1507 1082 +3 511 1884 569 +3 1197 1467 828 +3 1341 809 336 +3 1094 680 976 +3 1540 1545 1544 +3 1398 1388 1402 +3 594 1121 1088 +3 1233 1099 1189 +3 1502 1516 1503 +3 1506 1344 1115 +3 291 1137 1342 +3 1097 1513 1082 +3 1412 812 123 +3 498 831 812 +3 1412 498 812 +3 883 1466 1074 +3 1006 1420 962 +3 1399 1471 1159 +3 962 672 1006 +3 1118 1091 702 +3 1686 1687 1703 +3 653 964 1084 +3 1735 1756 1747 +3 1 470 1536 +3 127 1059 1037 +3 1046 1506 1115 +3 1288 1006 1385 +3 1044 1288 1385 +3 1147 1171 1170 +3 1170 1142 1147 +3 1137 291 1346 +3 808 1008 1011 +3 1159 245 1504 +3 672 962 1065 +3 1390 1106 781 +3 1390 1156 1466 +3 1466 1156 1295 +3 1015 1016 1021 +3 644 1540 1539 +3 1137 1533 1542 +3 1088 1089 1288 +3 594 1088 1288 +3 1721 1746 1729 +3 360 594 1044 +3 594 1288 1044 +3 245 1108 1504 +3 216 1521 389 +3 1370 1211 1384 +3 1089 1006 1288 +3 461 587 513 +3 513 587 1351 +3 1351 1414 1412 +3 1091 498 1412 +3 1414 1091 1412 +3 1115 1530 538 +3 1092 1140 1457 +3 1509 1090 1534 +3 1137 1146 1533 +3 1349 461 1547 +3 767 1 1064 +3 1529 1365 1195 +3 964 1130 1441 +3 1351 587 1414 +3 1115 538 289 +3 1405 1413 1397 +3 1513 1081 1082 +3 980 514 1420 +3 680 1094 1507 +3 461 1414 587 +3 1106 1508 462 +3 1052 1370 1179 +3 1457 1541 1247 +3 587 1414 461 +3 1420 514 962 +3 545 1201 1326 +3 63 585 1514 +3 1105 154 1097 +3 1064 1533 1146 +3 1414 587 461 +3 973 1414 587 +3 1414 973 587 +3 250 1476 289 +3 1157 1204 680 +3 1398 1383 1211 +3 1507 1397 1082 +3 1543 1349 1533 +3 1536 1543 1533 +3 1543 410 461 +3 1349 1543 461 +3 973 1141 1414 +3 1141 1091 1414 +3 1476 1115 289 +3 1084 964 1092 +3 373 1537 1521 +3 1521 1105 1121 +3 1476 250 1274 +3 1149 1525 1142 +3 1254 1541 1540 +3 1064 1 1533 +3 1082 1397 1089 +3 1088 1082 1089 +3 80 373 1521 +3 1535 80 1521 +3 1341 541 547 +3 39 199 783 +3 1536 1533 1 +3 973 1414 461 +3 410 973 461 +3 1397 1413 1420 +3 1089 1397 1420 +3 1111 1383 1501 +3 1503 1476 1274 +3 606 82 391 +3 780 38 868 +3 1135 1104 1061 +3 711 1514 1059 +3 1365 1194 1195 +3 1111 1510 1179 +3 1485 1135 1149 +3 796 1128 1252 +3 1228 293 1224 +3 644 1263 1540 +3 390 160 25 +3 63 33 104 +3 391 306 606 +3 306 244 606 +3 1097 154 1513 +3 494 672 1065 +3 1543 618 410 +3 537 973 410 +3 618 537 410 +3 1141 1352 702 +3 972 992 991 +3 1509 1534 1439 +3 1088 1097 1082 +3 1401 1023 1298 +3 53 569 1884 +3 1536 470 1543 +3 1410 127 1037 +3 1227 293 1228 +3 1128 1522 245 +3 1522 1154 245 +3 1850 1870 1849 +3 796 1252 1023 +3 173 83 33 +3 1543 470 618 +3 1242 69 1251 +3 1515 1527 1371 +3 1162 1135 1060 +3 1188 537 618 +3 1109 973 537 +3 1109 1141 973 +3 1109 1352 1141 +3 545 518 828 +3 1201 545 828 +3 1244 1457 1247 +3 1386 1515 1371 +3 1454 1518 1499 +3 1089 1477 1006 +3 462 1401 781 +3 1401 499 781 +3 63 433 585 +3 1886 1066 304 +3 1204 1074 680 +3 127 711 1059 +3 640 1425 1389 +3 1188 618 537 +3 499 1298 519 +3 1226 1060 1099 +3 1233 1226 1099 +3 1515 1454 1386 +3 1298 897 1120 +3 519 1298 1120 +3 1188 537 618 +3 1524 1502 1046 +3 1178 980 550 +3 1178 1512 1075 +3 1515 1386 1391 +3 1386 1454 1515 +3 1149 1142 1099 +3 1060 1149 1099 +3 1508 1098 462 +3 1401 462 1023 +3 1178 1075 980 +3 552 868 459 +3 1061 1525 1149 +3 1098 1037 796 +3 1524 1502 1476 +3 1476 1524 1046 +3 1828 1829 1834 +3 1089 1420 1477 +3 1352 672 494 +3 1502 1512 650 +3 1252 1128 1471 +3 1531 1518 1454 +3 1374 1531 1454 +3 1512 1502 1075 +3 1173 618 470 +3 160 1173 470 +3 1173 1188 618 +3 1173 360 1188 +3 1188 360 537 +3 360 1044 537 +3 537 1044 1109 +3 1044 1385 1109 +3 672 1352 1109 +3 1385 672 1109 +3 511 517 1560 +3 1390 781 1156 +3 223 222 178 +3 831 123 812 +3 141 1333 1618 +3 1812 1829 1828 +3 115 1005 1210 +3 1636 1637 1656 +3 1515 1454 1527 +3 1682 538 1530 +3 1637 1657 1656 +3 1072 1525 1061 +3 1071 1072 1061 +3 548 1350 142 +3 1072 1592 1525 +3 1487 1674 1684 +3 67 937 1010 +3 1754 1784 1762 +3 1462 1478 1473 +3 1137 1542 778 +3 1614 1637 1616 +3 1036 1572 1049 +3 1049 1584 1072 +3 1072 1584 1592 +3 1126 1525 1592 +3 1584 1126 1592 +3 199 606 783 +3 1499 1362 1368 +3 1680 1678 1679 +3 1049 1586 1584 +3 799 178 1558 +3 702 494 1198 +3 1499 1368 1527 +3 868 552 459 +3 1486 1487 1674 +3 1572 1584 1586 +3 1049 1572 1586 +3 779 702 1198 +3 1799 1812 1795 +3 1618 1333 141 +3 1662 1676 1675 +3 805 1350 548 +3 1026 1570 1572 +3 1572 1073 1584 +3 1073 1078 1584 +3 1112 1126 1584 +3 1078 1112 1584 +3 1617 1620 1416 +3 1676 560 483 +3 1675 1676 483 +3 1659 1678 1663 +3 1572 1570 1073 +3 1054 1004 399 +3 827 1880 1870 +3 1404 1590 1604 +3 1374 1515 1391 +3 1345 472 498 +3 802 1555 1519 +3 1655 1675 1674 +3 1416 1614 1415 +3 1407 1406 1386 +3 482 560 1676 +3 1678 1677 1663 +3 1146 1137 1346 +3 1026 1562 1570 +3 1562 1570 1572 +3 1570 1562 1572 +3 1677 482 1676 +3 547 1556 798 +3 701 734 570 +3 1589 1404 1603 +3 1641 1638 1634 +3 1639 1641 1634 +3 1657 1658 1662 +3 260 261 575 +3 156 701 1164 +3 1639 1634 1621 +3 1638 1658 1657 +3 1637 1638 1657 +3 1519 1118 702 +3 1415 1605 1590 +3 779 1519 702 +3 1406 1415 1590 +3 1663 1677 1662 +3 1641 1659 1638 +3 1658 1663 1662 +3 1635 1636 1654 +3 1562 1073 1570 +3 1687 1686 1439 +3 1047 375 39 +3 1621 1620 1617 +3 738 1519 779 +3 483 515 1674 +3 473 1333 531 +3 481 473 531 +3 1155 142 639 +3 1662 1675 1655 +3 1656 1662 1655 +3 1038 1045 1073 +3 1562 1038 1073 +3 222 179 178 +3 1428 1621 1617 +3 1675 483 1674 +3 1159 1471 245 +3 1365 245 1154 +3 1209 1365 1154 +3 245 1365 1108 +3 1637 1636 1616 +3 1416 1620 1614 +3 1638 1637 1614 +3 884 1340 1884 +3 1049 1043 1036 +3 1605 1616 1607 +3 1620 1638 1614 +3 1455 1428 1445 +3 1622 1529 1195 +3 1177 1622 1195 +3 550 976 500 +3 1587 1523 1119 +3 1428 1455 1639 +3 1096 1079 1080 +3 553 536 563 +3 1404 1604 1603 +3 1153 1622 1177 +3 641 638 661 +3 1013 1020 1038 +3 1051 1114 1096 +3 1080 1051 1096 +3 1114 1587 1096 +3 1556 243 798 +3 1532 1623 1622 +3 1153 1532 1622 +3 1642 1529 1622 +3 1623 1642 1622 +3 1642 1504 1108 +3 1529 1642 1108 +3 1378 1404 1388 +3 178 179 1559 +3 1455 1473 1641 +3 1653 1655 1674 +3 805 530 531 +3 33 18 173 +3 1605 1604 1590 +3 179 1259 1559 +3 1051 1587 1114 +3 1118 1345 1091 +3 851 523 532 +3 715 732 1167 +3 1636 1655 1654 +3 1621 1634 1620 +3 1093 1280 1362 +3 1051 1114 1587 +3 1604 1605 1607 +3 1022 1563 1051 +3 1030 1022 1051 +3 1563 1573 1114 +3 1051 1563 1114 +3 1573 1585 1587 +3 1114 1573 1587 +3 1585 1599 1523 +3 1587 1585 1523 +3 1599 1608 1532 +3 1523 1599 1532 +3 1608 1624 1623 +3 1532 1608 1623 +3 1643 1642 1623 +3 1624 1643 1623 +3 1643 1673 1504 +3 1642 1643 1504 +3 551 547 798 +3 1014 1016 1015 +3 1306 1307 1379 +3 805 548 525 +3 1656 1655 1636 +3 1333 805 531 +3 1683 1184 1673 +3 1608 1625 1624 +3 1644 1643 1624 +3 1625 1644 1624 +3 1664 1673 1643 +3 1644 1664 1643 +3 1023 1128 1252 +3 585 854 1209 +3 1351 1412 123 +3 322 1301 495 +3 799 844 474 +3 516 495 141 +3 1555 1345 1118 +3 495 1618 141 +3 1047 205 540 +3 141 1333 473 +3 1433 1426 1434 +3 597 378 1063 +3 1528 1564 1563 +3 1022 1528 1563 +3 1564 1574 1573 +3 1563 1564 1573 +3 1573 1574 1585 +3 1574 1576 1585 +3 1585 1576 1599 +3 1576 1600 1599 +3 1600 1609 1608 +3 1599 1600 1608 +3 1609 1626 1625 +3 1608 1609 1625 +3 1645 1644 1625 +3 1626 1645 1625 +3 1645 1665 1664 +3 1644 1645 1664 +3 1665 1673 1664 +3 1665 1326 1683 +3 1673 1665 1683 +3 1326 1184 1683 +3 1590 1404 1378 +3 1614 1616 1605 +3 1415 1614 1605 +3 495 1333 1618 +3 738 802 1519 +3 1473 1659 1641 +3 1301 805 1333 +3 205 206 517 +3 1405 976 550 +3 495 1301 1333 +3 1593 1601 1600 +3 1576 1593 1600 +3 1600 1601 1609 +3 716 208 515 +3 500 1178 550 +3 1259 523 851 +3 1559 1259 851 +3 831 481 812 +3 513 1349 1547 +3 1616 1636 1635 +3 222 223 1680 +3 1301 493 1350 +3 805 1301 1350 +3 1548 1552 1528 +3 1552 1565 1564 +3 1528 1552 1564 +3 1564 1565 1574 +3 1574 1565 1576 +3 1565 1577 1576 +3 1594 1593 1576 +3 1577 1594 1576 +3 1602 1601 1593 +3 1594 1602 1593 +3 1602 1610 1609 +3 1601 1602 1609 +3 1610 1627 1626 +3 1609 1610 1626 +3 1627 1646 1645 +3 1626 1627 1645 +3 1666 1665 1645 +3 1646 1666 1645 +3 1666 545 1326 +3 1665 1666 1326 +3 483 716 515 +3 547 243 1556 +3 221 1003 1295 +3 143 221 1295 +3 809 1341 547 +3 551 809 547 +3 782 1342 778 +3 731 782 778 +3 1458 1660 1455 +3 752 309 753 +3 1424 1402 1603 +3 1519 1555 1118 +3 1549 1553 1552 +3 1552 1553 1565 +3 1775 1799 1784 +3 1406 1590 1378 +3 493 174 142 +3 1350 493 142 +3 1656 1657 1662 +3 291 809 551 +3 731 778 513 +3 523 473 481 +3 1365 1209 1194 +3 1346 291 551 +3 784 731 513 +3 1550 1554 1553 +3 1549 1550 1553 +3 1566 1565 1553 +3 1554 1566 1553 +3 1566 1578 1577 +3 1565 1566 1577 +3 1578 1579 1577 +3 1577 1579 1594 +3 1579 1595 1602 +3 1594 1579 1602 +3 1595 1611 1610 +3 1602 1595 1610 +3 1628 1627 1610 +3 1611 1628 1610 +3 1628 1647 1646 +3 1627 1628 1646 +3 1647 1667 1666 +3 1646 1647 1666 +3 1667 1668 1666 +3 518 545 1666 +3 1668 518 1666 +3 1074 1003 1094 +3 1607 1616 1615 +3 123 784 513 +3 1499 1527 1454 +3 1604 1607 1615 +3 1566 1579 1578 +3 1628 1648 1647 +3 1648 1668 1667 +3 1647 1648 1667 +3 1681 518 1668 +3 778 1533 1349 +3 513 778 1349 +3 496 650 497 +3 1615 1616 1635 +3 1429 1445 1428 +3 718 758 748 +3 1678 1680 474 +3 1680 223 474 +3 778 1542 1533 +3 206 205 1047 +3 1478 222 1680 +3 1679 1678 1659 +3 857 831 498 +3 1386 1406 1391 +3 1360 1090 1554 +3 1550 1360 1554 +3 1567 1566 1554 +3 1090 1567 1554 +3 1567 1580 1579 +3 1566 1567 1579 +3 1580 1596 1595 +3 1579 1580 1595 +3 1596 1606 1611 +3 1595 1596 1611 +3 1606 1629 1628 +3 1611 1606 1628 +3 1629 1630 1628 +3 1630 1649 1648 +3 1628 1630 1648 +3 1649 1526 1668 +3 1648 1649 1668 +3 496 1681 1668 +3 1526 496 1668 +3 497 518 1681 +3 496 497 1681 +3 518 497 650 +3 1005 574 1210 +3 123 513 1351 +3 1877 1876 1865 +3 1558 1555 802 +3 799 1558 802 +3 472 857 498 +3 1455 1641 1639 +3 1634 1638 1620 +3 482 802 738 +3 1248 429 700 +3 1654 1655 1653 +3 1606 1630 1629 +3 1473 1478 1680 +3 1362 1499 1557 +3 1558 857 472 +3 1120 1184 1326 +3 857 851 831 +3 844 802 482 +3 474 844 482 +3 1555 1558 472 +3 844 799 802 +3 1342 1137 778 +3 1649 1669 1526 +3 1669 1506 496 +3 1526 1669 496 +3 1421 1411 1422 +3 851 532 481 +3 780 340 383 +3 1008 780 383 +3 1568 1567 1090 +3 1509 1568 1090 +3 1568 1581 1580 +3 1567 1568 1580 +3 1597 1596 1580 +3 1581 1597 1580 +3 1596 1597 1606 +3 1597 1612 1606 +3 1612 1631 1630 +3 1606 1612 1630 +3 1631 1650 1649 +3 1630 1631 1649 +3 1649 1650 1669 +3 1678 482 1677 +3 560 738 716 +3 1345 498 1091 +3 500 1100 1178 +3 1678 474 482 +3 1009 878 53 +3 1841 1855 1851 +3 1454 1527 1499 +3 827 107 1864 +3 495 516 75 +3 208 716 1198 +3 1428 1639 1621 +3 1771 1280 1093 +3 842 1008 808 +3 378 533 1063 +3 1582 1581 1568 +3 1659 1663 1658 +3 1865 1864 1851 +3 1503 514 980 +3 1583 1582 1568 +3 1588 1581 1582 +3 1583 1588 1582 +3 1598 1597 1581 +3 1588 1598 1581 +3 1433 1612 1597 +3 1433 1619 1612 +3 1632 1631 1612 +3 1619 1632 1612 +3 1651 1650 1631 +3 1632 1651 1631 +3 1651 1670 1669 +3 1650 1651 1669 +3 1670 1344 1506 +3 1669 1670 1506 +3 1660 1473 1455 +3 1353 842 808 +3 995 1353 808 +3 1353 1008 842 +3 1353 842 1008 +3 38 780 1008 +3 842 38 1008 +3 1517 1569 1568 +3 1509 1517 1568 +3 1569 1583 1568 +3 716 779 1198 +3 716 738 779 +3 560 482 738 +3 1360 1687 1534 +3 1353 38 842 +3 1111 1179 1383 +3 1598 1433 1597 +3 868 38 552 +3 1045 1078 1073 +3 1124 406 272 +3 1433 1632 1619 +3 474 223 1122 +3 1033 1765 1024 +3 1378 1359 1374 +3 1269 1270 1281 +3 291 782 444 +3 483 560 716 +3 1462 1473 1660 +3 499 1156 781 +3 1214 542 909 +3 1555 472 1345 +3 178 1559 1558 +3 851 481 831 +3 1269 1281 1268 +3 824 1856 1846 +3 53 1884 1009 +3 1439 1111 1517 +3 1111 1501 1569 +3 1517 1111 1569 +3 1411 1583 1569 +3 1411 1588 1583 +3 1411 1421 1588 +3 1421 1598 1588 +3 1421 1426 1598 +3 1426 1433 1598 +3 1434 1433 1598 +3 1433 1434 1598 +3 1633 1632 1433 +3 1434 1633 1433 +3 1633 1640 1632 +3 1652 1651 1632 +3 1640 1652 1632 +3 1671 1670 1651 +3 1652 1671 1651 +3 1671 1682 1344 +3 1670 1671 1344 +3 1274 1032 514 +3 1503 1274 514 +3 532 523 481 +3 1319 264 277 +3 546 806 1591 +3 546 995 806 +3 546 746 995 +3 1339 1353 995 +3 746 1339 995 +3 1339 1200 38 +3 1353 1339 38 +3 223 178 799 +3 1530 1344 1682 +3 1449 1633 1434 +3 399 744 1054 +3 831 812 123 +3 1122 223 799 +3 243 205 517 +3 1473 1679 1659 +3 1024 1034 1033 +3 1591 1340 546 +3 1501 1411 1569 +3 1156 499 1295 +3 1449 1640 1633 +3 1209 953 854 +3 1458 1462 1660 +3 1224 235 677 +3 1523 1153 1119 +3 1085 1355 1364 +3 1468 1652 1640 +3 1449 1468 1640 +3 1489 1671 1652 +3 1468 1489 1652 +3 1671 1489 1682 +3 1489 538 1682 +3 1836 1857 1844 +3 803 189 1117 +3 1685 1696 1695 +3 1785 1791 1801 +3 1808 1801 1791 +3 1791 1792 1815 +3 1751 1750 1735 +3 1843 1862 1842 +3 1210 444 115 +3 1800 1816 1799 +3 1803 1821 1802 +3 995 834 1591 +3 758 759 1182 +3 1836 1858 1857 +3 810 168 1857 +3 1858 810 1857 +3 1740 1757 1764 +3 873 872 865 +3 1808 1815 1801 +3 1815 1819 1801 +3 804 803 1117 +3 1741 1757 1740 +3 1793 865 1788 +3 1812 1816 1830 +3 804 1117 1878 +3 1561 1725 1726 +3 1857 168 824 +3 1757 1779 1764 +3 1764 1779 1786 +3 78 815 1868 +3 1822 1821 1803 +3 1717 1737 1721 +3 1844 1857 1846 +3 1725 1724 1013 +3 824 168 79 +3 1713 1718 1696 +3 1715 1714 1699 +3 1722 1730 1711 +3 1843 1842 1825 +3 1819 1843 1825 +3 1857 824 1846 +3 1821 1827 1826 +3 1809 1821 1826 +3 1815 1843 1819 +3 1821 1809 1802 +3 1548 1689 1549 +3 1733 1561 1562 +3 1733 1725 1561 +3 604 599 406 +3 406 599 202 +3 1822 1836 1821 +3 815 1881 1867 +3 1852 1855 1830 +3 1699 1706 1016 +3 54 55 845 +3 158 219 521 +3 1742 1741 1725 +3 1733 1742 1725 +3 1763 1777 1785 +3 1033 1788 1765 +3 1769 1776 1749 +3 1749 1755 1734 +3 1756 1769 1747 +3 1732 1751 1735 +3 1707 1714 1722 +3 1738 1754 1737 +3 1876 1864 1865 +3 1722 1714 1731 +3 865 1810 1787 +3 1788 865 1787 +3 1715 1732 1714 +3 1742 1757 1741 +3 1804 1803 1786 +3 1779 1804 1786 +3 1770 1791 1785 +3 1806 1810 242 +3 1722 1747 1730 +3 1705 1706 1707 +3 1804 1805 1803 +3 1835 1843 1815 +3 1346 551 1883 +3 1802 1809 1792 +3 1837 1836 1822 +3 1017 1837 1822 +3 1878 1117 1877 +3 1711 1730 1713 +3 1690 1706 1705 +3 1837 136 1836 +3 1830 1855 1841 +3 1868 1867 1856 +3 599 20 681 +3 136 1858 1836 +3 1791 1815 1808 +3 1024 1759 1018 +3 1730 1734 1713 +3 1785 1790 1756 +3 20 596 681 +3 1831 1830 1817 +3 1797 1802 1792 +3 1864 1876 827 +3 1881 815 814 +3 1787 1806 1781 +3 1116 916 1031 +3 814 1882 1872 +3 1711 1713 1697 +3 1110 1475 859 +3 1690 1705 1698 +3 1785 1801 1790 +3 1765 1787 1759 +3 596 20 556 +3 596 1180 681 +3 681 1180 1031 +3 1882 804 1872 +3 1698 1711 1697 +3 1759 1781 1758 +3 900 1883 979 +3 1696 1717 1704 +3 1026 1561 1562 +3 1769 1796 1776 +3 1013 1723 1715 +3 1734 1717 1718 +3 1832 1831 1813 +3 1180 316 1116 +3 1031 1180 1116 +3 1561 1742 1733 +3 1882 814 804 +3 1820 1835 1815 +3 1442 988 1447 +3 710 577 622 +3 1810 1806 1787 +3 596 1752 1180 +3 1180 316 1116 +3 316 1180 1116 +3 316 993 916 +3 1116 316 916 +3 1759 1787 1781 +3 1776 1800 1775 +3 1732 1735 1714 +3 1886 409 821 +3 1703 1729 1710 +3 1693 1685 1550 +3 1016 1706 1690 +3 1693 1689 1697 +3 1842 1862 1861 +3 1694 1695 1704 +3 1687 1685 1694 +3 988 382 1447 +3 1447 382 576 +3 747 797 120 +3 1776 1775 1755 +3 1199 1167 732 +3 1041 758 596 +3 596 758 1752 +3 1876 1158 107 +3 1685 1695 1694 +3 1858 818 810 +3 382 1431 576 +3 1693 1697 1696 +3 243 1888 798 +3 1117 189 187 +3 1823 1822 1803 +3 1805 1823 1803 +3 1442 1430 1443 +3 818 1858 136 +3 356 477 424 +3 382 1575 1431 +3 916 993 554 +3 467 590 1318 +3 1685 1693 1696 +3 1845 1866 1853 +3 1431 1575 1110 +3 1182 1752 758 +3 1182 1180 1752 +3 1182 825 1180 +3 1180 825 316 +3 1017 136 1837 +3 1430 1440 1443 +3 1440 908 988 +3 988 908 382 +3 1575 549 1110 +3 549 1150 963 +3 1110 549 963 +3 1825 1813 1814 +3 1796 1817 1800 +3 825 633 316 +3 1699 1714 1706 +3 633 993 316 +3 633 1323 993 +3 1430 1869 1440 +3 908 1575 382 +3 1101 963 1150 +3 1734 1738 1717 +3 1819 1825 1814 +3 1801 1819 1814 +3 633 825 1182 +3 1440 1869 908 +3 908 996 1575 +3 759 787 786 +3 1809 1826 1820 +3 1869 1145 908 +3 549 1101 1150 +3 1723 1732 1715 +3 1428 1847 1430 +3 1145 56 908 +3 908 56 996 +3 1144 1101 549 +3 1809 1820 1815 +3 1793 1788 1033 +3 797 633 1182 +3 759 797 1182 +3 1735 1750 1756 +3 996 56 1575 +3 56 549 1575 +3 1750 1763 1756 +3 1847 1848 1430 +3 1848 1859 1430 +3 1430 1859 1869 +3 56 1168 549 +3 1690 1689 1548 +3 1758 1779 1757 +3 786 797 759 +3 747 633 797 +3 633 747 1323 +3 1323 747 167 +3 865 866 873 +3 1778 1791 1770 +3 78 1868 824 +3 1805 1804 1779 +3 1428 1848 1847 +3 56 1053 1168 +3 1168 1131 1144 +3 549 1168 1144 +3 1877 1117 1876 +3 1707 1722 1711 +3 1731 1735 1739 +3 830 1823 1805 +3 830 1822 1823 +3 1859 1873 1145 +3 1869 1859 1145 +3 1131 1101 1144 +3 1814 1813 1790 +3 830 1017 1822 +3 207 562 561 +3 1772 1771 1093 +3 1557 1772 1093 +3 866 1033 1042 +3 1617 1417 1428 +3 1428 1417 1848 +3 1734 1755 1738 +3 1821 1836 1844 +3 1801 1814 1790 +3 895 797 786 +3 787 759 760 +3 1873 961 1145 +3 1145 961 56 +3 1053 1131 1168 +3 1833 1101 1131 +3 1833 710 1101 +3 1853 1871 1852 +3 1689 1690 1698 +3 1772 1275 1771 +3 1848 1417 1859 +3 242 830 1806 +3 1713 1734 1718 +3 1800 1799 1775 +3 1695 1696 1704 +3 1518 1557 1499 +3 1794 1275 1772 +3 1809 1815 1792 +3 1417 1418 1859 +3 961 951 56 +3 56 951 1053 +3 1833 1131 710 +3 1019 1742 1561 +3 1758 1757 1742 +3 1780 1779 1758 +3 1748 1557 1518 +3 1794 1277 1275 +3 1873 1879 961 +3 951 559 1053 +3 1053 559 1131 +3 1876 107 827 +3 1747 1769 1749 +3 1267 1277 1794 +3 1418 1863 1859 +3 1859 1863 1873 +3 1868 815 1867 +3 1766 1772 1557 +3 1748 1766 1557 +3 866 1793 1033 +3 559 1196 1131 +3 1196 1343 1131 +3 1131 1343 710 +3 1766 1794 1772 +3 180 1229 336 +3 415 1879 1873 +3 415 961 1879 +3 1343 577 710 +3 866 865 1793 +3 1362 1557 1093 +3 1789 1794 1766 +3 1873 1863 415 +3 1456 1442 1447 +3 1018 1742 1019 +3 1743 1748 1518 +3 1531 1743 1518 +3 1789 1267 1794 +3 434 961 415 +3 434 951 961 +3 1781 1779 1780 +3 1811 1267 1789 +3 1781 1805 1779 +3 404 522 438 +3 434 736 951 +3 736 559 951 +3 1743 1766 1748 +3 559 736 1196 +3 1722 1739 1747 +3 715 1393 1169 +3 1534 1090 1360 +3 1269 1271 1270 +3 604 1124 272 +3 1358 1531 1500 +3 1824 1268 1267 +3 1811 1824 1267 +3 155 813 1880 +3 736 480 1196 +3 1196 480 1343 +3 1343 480 577 +3 1790 1813 1796 +3 1782 1789 1766 +3 1760 1782 1766 +3 1803 1802 1797 +3 1777 1770 1785 +3 1719 1743 1531 +3 1760 1766 1743 +3 1838 1269 1268 +3 1824 1838 1268 +3 1750 1770 1777 +3 480 578 577 +3 1689 1693 1550 +3 1763 1750 1777 +3 1770 1777 1785 +3 1691 1358 1356 +3 1719 1531 1358 +3 736 1062 480 +3 1813 1831 1817 +3 1549 1689 1550 +3 1756 1763 1785 +3 1691 1356 1355 +3 1085 1691 1355 +3 1761 1760 1743 +3 1744 1761 1743 +3 1807 1811 1789 +3 1838 1271 1269 +3 78 824 79 +3 1876 187 1158 +3 1821 1844 1827 +3 1708 1719 1358 +3 1744 1743 1719 +3 1782 1807 1789 +3 1807 1824 1811 +3 1860 1271 1838 +3 736 451 1062 +3 1756 1790 1769 +3 1725 1740 1724 +3 1698 1705 1711 +3 1510 1691 1085 +3 1708 1358 1691 +3 1761 1782 1760 +3 1818 1824 1807 +3 1860 1272 1271 +3 1718 1717 1696 +3 451 207 480 +3 1062 451 480 +3 1817 1830 1816 +3 1796 1800 1776 +3 1510 1085 1052 +3 1818 1838 1824 +3 1875 1272 1860 +3 1813 1817 1796 +3 1720 1719 1708 +3 1736 1744 1719 +3 1839 1838 1818 +3 96 807 486 +3 1018 1758 1742 +3 1842 1861 1845 +3 1881 814 1872 +3 1781 1780 1758 +3 1867 1881 1872 +3 1692 1691 1510 +3 1720 1736 1719 +3 1783 1782 1761 +3 1839 1860 1838 +3 1875 1661 586 +3 1272 1875 586 +3 1806 1805 1781 +3 1712 1716 1708 +3 1727 1720 1708 +3 1716 1727 1708 +3 1854 1860 1839 +3 1143 1661 1875 +3 1661 99 586 +3 1143 99 1661 +3 1031 60 236 +3 1709 1708 1691 +3 1692 1709 1691 +3 1709 1712 1708 +3 1709 1716 1712 +3 1709 1727 1716 +3 1727 1728 1720 +3 1786 1803 1797 +3 747 120 167 +3 484 207 451 +3 1736 1753 1744 +3 1753 1761 1744 +3 1753 1783 1761 +3 1874 1860 1854 +3 1874 1875 1860 +3 1792 1791 1778 +3 824 1868 1856 +3 1817 1816 1800 +3 520 207 484 +3 1692 1700 1709 +3 1728 1727 1709 +3 1728 1745 1727 +3 1511 1688 1510 +3 1688 1692 1510 +3 1874 1143 1875 +3 1013 1715 1699 +3 1749 1776 1755 +3 1759 1758 1018 +3 1688 1701 1700 +3 1692 1688 1700 +3 1773 1783 1753 +3 1849 1854 1839 +3 813 1143 1874 +3 813 99 1143 +3 1842 1845 1832 +3 1710 1709 1700 +3 1701 1710 1700 +3 1872 804 1878 +3 1825 1842 1832 +3 1853 1852 1830 +3 1730 1749 1734 +3 1689 1698 1697 +3 1805 1806 830 +3 1710 1728 1709 +3 1840 1849 1839 +3 1831 1853 1830 +3 1724 1723 1013 +3 1729 1728 1710 +3 1849 1874 1854 +3 1849 1870 1874 +3 1741 1740 1725 +3 1755 1775 1754 +3 1731 1714 1735 +3 1747 1749 1730 +3 1706 1714 1707 +3 1729 1745 1728 +3 1767 1773 1753 +3 1880 813 1874 +3 1870 1880 1874 +3 865 858 1810 +3 1810 858 259 +3 1861 1866 1845 +3 1790 1796 1769 +3 1755 1754 1738 +3 1739 1735 1747 +3 1686 1688 1511 +3 1439 1686 1511 +3 1746 1745 1729 +3 1774 1773 1767 +3 1834 1849 1840 +3 1016 1690 1548 +3 1788 1787 1765 +3 1551 1016 1548 +3 1686 1702 1701 +3 1688 1686 1701 +3 1703 1710 1701 +3 1702 1703 1701 +3 1795 1798 1773 +3 1825 1832 1813 +3 1697 1713 1696 +3 1762 1745 1746 +3 1762 1768 1745 +3 1795 1773 1774 From 26005a19bde9630c2171d685a610d31c602568ce Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 8 Sep 2013 15:20:02 +0200 Subject: [PATCH 191/205] add license headers --- modules/viz/include/opencv2/viz.hpp | 6 +- modules/viz/include/opencv2/viz/types.hpp | 71 ++- modules/viz/include/opencv2/viz/viz3d.hpp | 62 ++- .../include/opencv2/viz/widget_accessor.hpp | 53 +- modules/viz/include/opencv2/viz/widgets.hpp | 55 ++- modules/viz/src/cloud_widgets.cpp | 314 +++++++----- modules/viz/src/interactor_style.cpp | 459 ++++++++++-------- modules/viz/src/interactor_style.h | 133 ++--- modules/viz/src/precomp.cpp | 50 +- modules/viz/src/precomp.hpp | 53 +- modules/viz/src/shape_widgets.cpp | 298 +++++++----- modules/viz/src/types.cpp | 94 +++- modules/viz/src/viz.cpp | 55 ++- modules/viz/src/viz3d.cpp | 59 ++- modules/viz/src/viz3d_impl.cpp | 286 ++++++----- modules/viz/src/viz3d_impl.hpp | 108 +++-- modules/viz/src/widget.cpp | 48 ++ modules/viz/test/test_precomp.hpp | 48 ++ 18 files changed, 1523 insertions(+), 729 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index df89339dd..61d92e307 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -38,7 +38,7 @@ // the use of this software, even if advised of the possibility of such damage. // // Authors: -// * Ozan Tonkal +// * Ozan Tonkal, ozantonkal@gmail.com // * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com // // OpenCV Viz module is complete rewrite of @@ -49,12 +49,10 @@ #ifndef __OPENCV_VIZ_HPP__ #define __OPENCV_VIZ_HPP__ - #include #include #include - namespace cv { namespace viz @@ -121,6 +119,4 @@ namespace cv } /* namespace viz */ } /* namespace cv */ - #endif /* __OPENCV_VIZ_HPP__ */ - diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 26aa20440..c753945de 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -1,4 +1,53 @@ -#pragma once +/*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*/ + +#ifndef __OPENCV_VIZ_TYPES_HPP__ +#define __OPENCV_VIZ_TYPES_HPP__ #include #include @@ -55,17 +104,17 @@ namespace cv //! Create a keyboard event //! - Note that action is true if key is pressed, false if released - KeyboardEvent (bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); + KeyboardEvent(bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift); - bool isAltPressed () const; - bool isCtrlPressed () const; - bool isShiftPressed () const; + bool isAltPressed() const; + bool isCtrlPressed() const; + bool isShiftPressed() const; - unsigned char getKeyCode () const; + unsigned char getKeyCode() const; - const String& getKeySym () const; - bool keyDown () const; - bool keyUp () const; + const String& getKeySym() const; + bool keyDown() const; + bool keyUp() const; protected: @@ -81,7 +130,7 @@ namespace cv enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ; enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ; - MouseEvent (const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); + MouseEvent(const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift); Type type; MouseButton button; @@ -125,3 +174,5 @@ namespace cv } /* namespace viz */ } /* namespace cv */ + +#endif diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index f118dd6bb..c66aeb43b 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -1,4 +1,53 @@ -#pragma once +/*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*/ + +#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 //#error "Viz is in beta state now. Please define macro above to use it" @@ -38,7 +87,7 @@ namespace cv Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); - void resetCameraViewpoint (const String &id); + void resetCameraViewpoint(const String &id); void resetCamera(); void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); @@ -47,9 +96,9 @@ namespace cv Size getWindowSize() const; void setWindowSize(const Size &window_size); String getWindowName() const; - void saveScreenshot (const String &file); - void setWindowPosition (int x, int y); - void setFullScreen (bool mode); + void saveScreenshot(const String &file); + void setWindowPosition(int x, int y); + void setFullScreen(bool mode); void setBackgroundColor(const Color& color = Color::black()); void spin(); @@ -78,5 +127,4 @@ namespace cv } /* namespace viz */ } /* namespace cv */ - - +#endif diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp index d6c935dd8..394cfa858 100644 --- a/modules/viz/include/opencv2/viz/widget_accessor.hpp +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -1,4 +1,53 @@ -#pragma once +/*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*/ + +#ifndef __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__ +#define __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__ #include #include @@ -19,3 +68,5 @@ namespace cv }; } } + +#endif \ No newline at end of file diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 1216d040a..e96022ccc 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -1,4 +1,53 @@ -#pragma once +/*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*/ + +#ifndef __OPENCV_VIZ_WIDGETS_HPP__ +#define __OPENCV_VIZ_WIDGETS_HPP__ #include @@ -305,4 +354,6 @@ namespace cv template<> CV_EXPORTS MeshWidget Widget::cast(); } /* namespace viz */ -} /* namespace cv */ \ No newline at end of file +} /* namespace cv */ + +#endif diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index adf842a0f..b4ba5b3fe 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -1,3 +1,51 @@ +/*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 @@ -15,10 +63,10 @@ struct cv::viz::CloudWidget::CreateCloudWidget { static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) { - vtkSmartPointer polydata = vtkSmartPointer::New (); - vtkSmartPointer vertices = vtkSmartPointer::New (); + vtkSmartPointer polydata = vtkSmartPointer::New(); + vtkSmartPointer vertices = vtkSmartPointer::New(); - polydata->SetVerts (vertices); + polydata->SetVerts(vertices); vtkSmartPointer points = polydata->GetPoints(); vtkSmartPointer initcells; @@ -26,14 +74,14 @@ struct cv::viz::CloudWidget::CreateCloudWidget if (!points) { - points = vtkSmartPointer::New (); + points = vtkSmartPointer::New(); if (cloud.depth() == CV_32F) points->SetDataTypeToFloat(); else if (cloud.depth() == CV_64F) points->SetDataTypeToDouble(); - polydata->SetPoints (points); + polydata->SetPoints(points); } - points->SetNumberOfPoints (nr_points); + points->SetNumberOfPoints(nr_points); if (cloud.depth() == CV_32F) { @@ -49,51 +97,51 @@ struct cv::viz::CloudWidget::CreateCloudWidget Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); nr_points = data_end - data_beg; } - points->SetNumberOfPoints (nr_points); + points->SetNumberOfPoints(nr_points); // Update cells - vtkSmartPointer cells = vertices->GetData (); + vtkSmartPointer cells = vertices->GetData(); // If no init cells and cells has not been initialized... if (!cells) - cells = vtkSmartPointer::New (); + cells = vtkSmartPointer::New(); // If we have less values then we need to recreate the array - if (cells->GetNumberOfTuples () < nr_points) + if (cells->GetNumberOfTuples() < nr_points) { - cells = vtkSmartPointer::New (); + cells = vtkSmartPointer::New(); // If init cells is given, and there's enough data in it, use it - if (initcells && initcells->GetNumberOfTuples () >= nr_points) + if (initcells && initcells->GetNumberOfTuples() >= nr_points) { - cells->DeepCopy (initcells); - cells->SetNumberOfComponents (2); - cells->SetNumberOfTuples (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); + cells->SetNumberOfComponents(2); + cells->SetNumberOfTuples(nr_points); + vtkIdType *cell = cells->GetPointer(0); // Fill it with 1s - std::fill_n (cell, nr_points * 2, 1); + 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::New (); - initcells->DeepCopy (cells); + initcells = vtkSmartPointer::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); + cells->SetNumberOfComponents(2); + cells->SetNumberOfTuples(nr_points); } // Set the cells and the vertices - vertices->SetCells (nr_points, cells); + vertices->SetCells(nr_points, cells); return polydata; } }; @@ -118,33 +166,33 @@ cv::viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) Vec3b* colors_data = new Vec3b[nr_points]; NanFilter::copyColor(colors, colors_data, cloud); - vtkSmartPointer scalars = vtkSmartPointer::New (); - scalars->SetNumberOfComponents (3); - scalars->SetNumberOfTuples (nr_points); - scalars->SetArray (colors_data->val, 3 * nr_points, 0); + vtkSmartPointer scalars = vtkSmartPointer::New(); + scalars->SetNumberOfComponents(3); + scalars->SetNumberOfTuples(nr_points); + scalars->SetArray(colors_data->val, 3 * nr_points, 0); // Assign the colors - polydata->GetPointData ()->SetScalars (scalars); + polydata->GetPointData()->SetScalars(scalars); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (polydata); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(polydata); Vec3d minmax(scalars->GetRange()); mapper->SetScalarRange(minmax.val); - mapper->SetScalarModeToUsePointData (); + mapper->SetScalarModeToUsePointData(); - bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); + bool interpolation = (polydata && polydata->GetNumberOfCells() != polydata->GetNumberOfVerts()); - mapper->SetInterpolateScalarsBeforeMapping (interpolation); - mapper->ScalarVisibilityOn (); + mapper->SetInterpolateScalarsBeforeMapping(interpolation); + mapper->ScalarVisibilityOn(); - mapper->ImmediateModeRenderingOff (); + mapper->ImmediateModeRenderingOff(); vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); - actor->GetProperty ()->SetInterpolationToFlat (); - actor->GetProperty ()->BackfaceCullingOn (); - actor->SetMapper (mapper); + actor->SetNumberOfCloudPoints(int(std::max(1, polydata->GetNumberOfPoints() / 10))); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); } @@ -157,21 +205,21 @@ cv::viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (polydata); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(polydata); - bool interpolation = (polydata && polydata->GetNumberOfCells () != polydata->GetNumberOfVerts ()); + bool interpolation = (polydata && polydata->GetNumberOfCells() != polydata->GetNumberOfVerts()); - mapper->SetInterpolateScalarsBeforeMapping (interpolation); - mapper->ScalarVisibilityOff (); + mapper->SetInterpolateScalarsBeforeMapping(interpolation); + mapper->ScalarVisibilityOff(); - mapper->ImmediateModeRenderingOff (); + mapper->ImmediateModeRenderingOff(); vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetNumberOfCloudPoints (int (std::max (1, polydata->GetNumberOfPoints () / 10))); - actor->GetProperty ()->SetInterpolationToFlat (); - actor->GetProperty ()->BackfaceCullingOn (); - actor->SetMapper (mapper); + actor->SetNumberOfCloudPoints(int(std::max(1, polydata->GetNumberOfPoints() / 10))); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); setColor(color); @@ -190,10 +238,10 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget { static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) { - vtkSmartPointer polydata = vtkSmartPointer::New (); - vtkSmartPointer vertices = vtkSmartPointer::New (); + vtkSmartPointer polydata = vtkSmartPointer::New(); + vtkSmartPointer vertices = vtkSmartPointer::New(); - polydata->SetVerts (vertices); + polydata->SetVerts(vertices); vtkSmartPointer points = polydata->GetPoints(); vtkSmartPointer initcells; @@ -201,14 +249,14 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget if (!points) { - points = vtkSmartPointer::New (); + points = vtkSmartPointer::New(); if (cloud.depth() == CV_32F) points->SetDataTypeToFloat(); else if (cloud.depth() == CV_64F) points->SetDataTypeToDouble(); - polydata->SetPoints (points); + polydata->SetPoints(points); } - points->SetNumberOfPoints (nr_points); + points->SetNumberOfPoints(nr_points); if (cloud.depth() == CV_32F) { @@ -224,51 +272,51 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget Vec3d *data_end = NanFilter::copy(cloud, data_beg, cloud); nr_points = data_end - data_beg; } - points->SetNumberOfPoints (nr_points); + points->SetNumberOfPoints(nr_points); // Update cells - vtkSmartPointer cells = vertices->GetData (); + vtkSmartPointer cells = vertices->GetData(); // If no init cells and cells has not been initialized... if (!cells) - cells = vtkSmartPointer::New (); + cells = vtkSmartPointer::New(); // If we have less values then we need to recreate the array - if (cells->GetNumberOfTuples () < nr_points) + if (cells->GetNumberOfTuples() < nr_points) { - cells = vtkSmartPointer::New (); + cells = vtkSmartPointer::New(); // If init cells is given, and there's enough data in it, use it - if (initcells && initcells->GetNumberOfTuples () >= nr_points) + if (initcells && initcells->GetNumberOfTuples() >= nr_points) { - cells->DeepCopy (initcells); - cells->SetNumberOfComponents (2); - cells->SetNumberOfTuples (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); + cells->SetNumberOfComponents(2); + cells->SetNumberOfTuples(nr_points); + vtkIdType *cell = cells->GetPointer(0); // Fill it with 1s - std::fill_n (cell, nr_points * 2, 1); + 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::New (); - initcells->DeepCopy (cells); + initcells = vtkSmartPointer::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); + cells->SetNumberOfComponents(2); + cells->SetNumberOfTuples(nr_points); } // Set the cells and the vertices - vertices->SetCells (nr_points, cells); + vertices->SetCells(nr_points, cells); return polydata; } @@ -278,19 +326,19 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget if (!mapper) { // This is the first cloud - vtkSmartPointer mapper_new = vtkSmartPointer::New (); - mapper_new->SetInputConnection (poly_data->GetProducerPort()); + vtkSmartPointer mapper_new = vtkSmartPointer::New(); + mapper_new->SetInputConnection(poly_data->GetProducerPort()); mapper_new->SetScalarRange(minmax.val); - mapper_new->SetScalarModeToUsePointData (); + mapper_new->SetScalarModeToUsePointData(); - bool interpolation = (poly_data && poly_data->GetNumberOfCells () != poly_data->GetNumberOfVerts ()); + bool interpolation = (poly_data && poly_data->GetNumberOfCells() != poly_data->GetNumberOfVerts()); mapper_new->SetInterpolateScalarsBeforeMapping(interpolation); mapper_new->ScalarVisibilityOn(); mapper_new->ImmediateModeRenderingOff(); - actor->SetNumberOfCloudPoints (int (std::max(1, poly_data->GetNumberOfPoints () / 10))); + actor->SetNumberOfCloudPoints(int(std::max(1, poly_data->GetNumberOfPoints() / 10))); actor->GetProperty()->SetInterpolationToFlat(); actor->GetProperty()->BackfaceCullingOn(); actor->SetMapper(mapper_new); @@ -307,7 +355,7 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget // Update the number of cloud points vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); - actor->SetNumberOfCloudPoints (int (std::max(1, old_cloud_points+poly_data->GetNumberOfPoints () / 10))); + actor->SetNumberOfCloudPoints(int(std::max(1, old_cloud_points+poly_data->GetNumberOfPoints() / 10))); } }; @@ -338,13 +386,13 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, InputArray _col Vec3b* colors_data = new Vec3b[nr_points]; NanFilter::copyColor(colors, colors_data, cloud); - vtkSmartPointer scalars = vtkSmartPointer::New (); - scalars->SetNumberOfComponents (3); - scalars->SetNumberOfTuples (nr_points); - scalars->SetArray (colors_data->val, 3 * nr_points, 0); + vtkSmartPointer scalars = vtkSmartPointer::New(); + scalars->SetNumberOfComponents(3); + scalars->SetNumberOfTuples(nr_points); + scalars->SetArray(colors_data->val, 3 * nr_points, 0); // Assign the colors - polydata->GetPointData ()->SetScalars (scalars); + polydata->GetPointData()->SetScalars(scalars); // Transform the poly data based on the pose vtkSmartPointer transform = vtkSmartPointer::New(); @@ -371,15 +419,15 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, const Color &co vtkIdType nr_points; vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); - vtkSmartPointer scalars = vtkSmartPointer::New (); - scalars->SetNumberOfComponents (3); - scalars->SetNumberOfTuples (nr_points); + vtkSmartPointer scalars = vtkSmartPointer::New(); + scalars->SetNumberOfComponents(3); + scalars->SetNumberOfTuples(nr_points); scalars->FillComponent(0, color[2]); scalars->FillComponent(1, color[1]); scalars->FillComponent(2, color[0]); // Assign the colors - polydata->GetPointData ()->SetScalars (scalars); + polydata->GetPointData()->SetScalars(scalars); // Transform the poly data based on the pose vtkSmartPointer transform = vtkSmartPointer::New(); @@ -415,8 +463,8 @@ struct cv::viz::CloudNormalsWidget::ApplyCloudNormals static vtkSmartPointer applyOrganized(const Mat &cloud, const Mat& normals, double level, float scale, _Tp *&pts, vtkIdType &nr_normals) { vtkIdType point_step = static_cast(std::sqrt(level)); - nr_normals = (static_cast ((cloud.cols - 1) / point_step) + 1) * - (static_cast ((cloud.rows - 1) / point_step) + 1); + nr_normals = (static_cast((cloud.cols - 1) / point_step) + 1) * + (static_cast((cloud.rows - 1) / point_step) + 1); vtkSmartPointer lines = vtkSmartPointer::New(); pts = new _Tp[2 * nr_normals * 3]; @@ -436,9 +484,9 @@ struct cv::viz::CloudNormalsWidget::ApplyCloudNormals pts[2 * cell_count * 3 + 4] = prow[x+1] + nrow[x+1] * scale; pts[2 * cell_count * 3 + 5] = prow[x+2] + nrow[x+2] * scale; - lines->InsertNextCell (2); - lines->InsertCellPoint (2 * cell_count); - lines->InsertCellPoint (2 * cell_count + 1); + lines->InsertNextCell(2); + lines->InsertCellPoint(2 * cell_count); + lines->InsertCellPoint(2 * cell_count + 1); cell_count++; } } @@ -464,9 +512,9 @@ struct cv::viz::CloudNormalsWidget::ApplyCloudNormals pts[2 * j * 3 + 4] = p[i+1] + n[i+1] * scale; pts[2 * j * 3 + 5] = p[i+2] + n[i+2] * scale; - lines->InsertNextCell (2); - lines->InsertCellPoint (2 * j); - lines->InsertCellPoint (2 * j + 1); + lines->InsertNextCell(2); + lines->InsertCellPoint(2 * j); + lines->InsertCellPoint(2 * j + 1); } return lines; } @@ -497,33 +545,33 @@ cv::viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _n { points->SetDataTypeToFloat(); - vtkSmartPointer data = vtkSmartPointer::New (); - data->SetNumberOfComponents (3); + vtkSmartPointer data = vtkSmartPointer::New(); + data->SetNumberOfComponents(3); float* pts = 0; lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals); - data->SetArray (&pts[0], 2 * nr_normals * 3, 0); - points->SetData (data); + data->SetArray(&pts[0], 2 * nr_normals * 3, 0); + points->SetData(data); } else { points->SetDataTypeToDouble(); - vtkSmartPointer data = vtkSmartPointer::New (); - data->SetNumberOfComponents (3); + vtkSmartPointer data = vtkSmartPointer::New(); + data->SetNumberOfComponents(3); double* pts = 0; lines = ApplyCloudNormals::apply(cloud, normals, level, scale, pts, nr_normals); - data->SetArray (&pts[0], 2 * nr_normals * 3, 0); - points->SetData (data); + data->SetArray(&pts[0], 2 * nr_normals * 3, 0); + points->SetData(data); } vtkSmartPointer polyData = vtkSmartPointer::New(); - polyData->SetPoints (points); - polyData->SetLines (lines); + polyData->SetPoints(points); + polyData->SetLines(lines); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (polyData); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(polyData); mapper->SetColorModeToMapScalars(); mapper->SetScalarModeToUsePointData(); @@ -558,7 +606,7 @@ struct cv::viz::MeshWidget::CopyImpl const _Tp* srow = source.ptr<_Tp>(0); const _Tp* mrow = nan_mask.ptr<_Tp>(0); - for(int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) + for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) { if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) { @@ -577,11 +625,11 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) CV_Assert(mesh.colors.empty() || (mesh.colors.type() == CV_8UC3 && mesh.cloud.size() == mesh.colors.size())); CV_Assert(!mesh.polygons.empty() && mesh.polygons.type() == CV_32SC1); - vtkSmartPointer points = vtkSmartPointer::New (); + vtkSmartPointer points = vtkSmartPointer::New(); vtkIdType nr_points = mesh.cloud.total(); Mat look_up_mat(1, nr_points, CV_32SC1); int * look_up = look_up_mat.ptr(); - points->SetNumberOfPoints (nr_points); + points->SetNumberOfPoints(nr_points); // Copy data from cloud to vtkPoints if (mesh.cloud.depth() == CV_32F) @@ -607,10 +655,10 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) colors_data = new Vec3b[nr_points]; NanFilter::copyColor(mesh.colors, colors_data, mesh.cloud); - scalars = vtkSmartPointer::New (); - scalars->SetNumberOfComponents (3); - scalars->SetNumberOfTuples (nr_points); - scalars->SetArray (colors_data->val, 3 * nr_points, 0); + scalars = vtkSmartPointer::New(); + scalars->SetNumberOfComponents(3); + scalars->SetNumberOfTuples(nr_points); + scalars->SetArray(colors_data->val, 3 * nr_points, 0); } points->SetNumberOfPoints(nr_points); @@ -633,36 +681,36 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) cell_array->InsertCellPoint(look_up[polygons[i++]]); } vtkSmartPointer polydata = vtkSmartPointer::New(); - cell_array->GetData ()->SetNumberOfValues (idx); - cell_array->Squeeze (); - polydata->SetStrips (cell_array); - polydata->SetPoints (points); + cell_array->GetData()->SetNumberOfValues(idx); + cell_array->Squeeze(); + polydata->SetStrips(cell_array); + polydata->SetPoints(points); if (scalars) - polydata->GetPointData ()->SetScalars (scalars); + polydata->GetPointData()->SetScalars(scalars); data = polydata; } else { // Only one polygon - vtkSmartPointer polygon = vtkSmartPointer::New (); + vtkSmartPointer polygon = vtkSmartPointer::New(); const int * polygons = mesh.polygons.ptr(); int n_points = polygons[0]; polygon->GetPointIds()->SetNumberOfIds(n_points); for (int j = 1; j < n_points+1; ++j) - polygon->GetPointIds ()->SetId (j, look_up[polygons[j]]); + polygon->GetPointIds()->SetId(j, look_up[polygons[j]]); vtkSmartPointer poly_grid = vtkSmartPointer::New(); - poly_grid->Allocate (1, 1); - poly_grid->InsertNextCell (polygon->GetCellType (), polygon->GetPointIds ()); - poly_grid->SetPoints (points); - poly_grid->Update (); + poly_grid->Allocate(1, 1); + poly_grid->InsertNextCell(polygon->GetCellType(), polygon->GetPointIds()); + poly_grid->SetPoints(points); + poly_grid->Update(); if (scalars) - poly_grid->GetPointData ()->SetScalars (scalars); + poly_grid->GetPointData()->SetScalars(scalars); data = poly_grid; } @@ -675,13 +723,13 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) actor->GetProperty()->EdgeVisibilityOff(); actor->GetProperty()->ShadingOff(); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (data); - mapper->ImmediateModeRenderingOff (); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(data); + mapper->ImmediateModeRenderingOff(); vtkIdType numberOfCloudPoints = nr_points * 0.1; - actor->SetNumberOfCloudPoints (int (numberOfCloudPoints > 1 ? numberOfCloudPoints : 1)); - actor->SetMapper (mapper); + actor->SetNumberOfCloudPoints(int(numberOfCloudPoints > 1 ? numberOfCloudPoints : 1)); + actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); } diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 42b3f6b0b..ad446f4c0 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -1,10 +1,58 @@ +/*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" #include "interactor_style.h" using namespace cv; ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::Initialize () +void cv::viz::InteractorStyle::Initialize() { modifier_ = cv::viz::InteractorStyle::KB_MOD_ALT; // Set windows size (width, height) to unknown (-1) @@ -13,9 +61,9 @@ void cv::viz::InteractorStyle::Initialize () max_win_size_ = Vec2i(-1, -1); // Create the image filter and PNG writer objects - wif_ = vtkSmartPointer::New (); - snapshot_writer_ = vtkSmartPointer::New (); - snapshot_writer_->SetInputConnection (wif_->GetOutputPort ()); + wif_ = vtkSmartPointer::New(); + snapshot_writer_ = vtkSmartPointer::New(); + snapshot_writer_->SetInputConnection(wif_->GetOutputPort()); init_ = true; stereo_anaglyph_mask_default_ = true; @@ -30,72 +78,72 @@ void cv::viz::InteractorStyle::Initialize () } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::saveScreenshot (const std::string &file) +void cv::viz::InteractorStyle::saveScreenshot(const std::string &file) { - FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); - wif_->SetInput (Interactor->GetRenderWindow ()); - wif_->Modified (); // Update the WindowToImageFilter - snapshot_writer_->Modified (); - snapshot_writer_->SetFileName (file.c_str ()); - snapshot_writer_->Write (); + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + wif_->SetInput(Interactor->GetRenderWindow()); + wif_->Modified(); // Update the WindowToImageFilter + snapshot_writer_->Modified(); + snapshot_writer_->SetFileName(file.c_str()); + snapshot_writer_->Write(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::zoomIn () +void cv::viz::InteractorStyle::zoomIn() { - FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); // Zoom in - StartDolly (); + StartDolly(); double factor = 10.0 * 0.2 * .5; - Dolly (std::pow (1.1, factor)); - EndDolly (); + Dolly(std::pow(1.1, factor)); + EndDolly(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::zoomOut () +void cv::viz::InteractorStyle::zoomOut() { - FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); // Zoom out - StartDolly (); + StartDolly(); double factor = 10.0 * -0.2 * .5; - Dolly (std::pow (1.1, factor)); - EndDolly (); + Dolly(std::pow(1.1, factor)); + EndDolly(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnChar () +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') + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + if (Interactor->GetKeyCode() >= '0' && Interactor->GetKeyCode() <= '9') return; - std::string key (Interactor->GetKeySym ()); - if (key.find ("XF86ZoomIn") != std::string::npos) - zoomIn (); - else if (key.find ("XF86ZoomOut") != std::string::npos) - zoomOut (); + std::string key(Interactor->GetKeySym()); + if (key.find("XF86ZoomIn") != std::string::npos) + zoomIn(); + else if (key.find("XF86ZoomOut") != std::string::npos) + zoomOut(); int keymod = false; switch (modifier_) { case KB_MOD_ALT: { - keymod = Interactor->GetAltKey (); + keymod = Interactor->GetAltKey(); break; } case KB_MOD_CTRL: { - keymod = Interactor->GetControlKey (); + keymod = Interactor->GetControlKey(); break; } case KB_MOD_SHIFT: { - keymod = Interactor->GetShiftKey (); + keymod = Interactor->GetShiftKey(); break; } } - switch (Interactor->GetKeyCode ()) + switch (Interactor->GetKeyCode()) { // All of the options below simply exit case 'h': case 'H': @@ -118,12 +166,12 @@ void cv::viz::InteractorStyle::OnChar () case 's': case 'S': { if (!keymod) - Superclass::OnChar (); + Superclass::OnChar(); break; } default: { - Superclass::OnChar (); + Superclass::OnChar(); break; } } @@ -147,30 +195,30 @@ void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const K ////////////////////////////////////////////////////////////////////////////////////////////// void -cv::viz::InteractorStyle::OnKeyDown () +cv::viz::InteractorStyle::OnKeyDown() { - CV_Assert("Interactor style not initialized. Please call Initialize () before continuing" && init_); - CV_Assert("No renderer given! Use SetRendererCollection () before continuing." && renderer_); + CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_); + CV_Assert("No renderer given! Use SetRendererCollection() before continuing." && renderer_); - FindPokedRenderer (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1]); + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); - if (wif_->GetInput () == NULL) + if (wif_->GetInput() == NULL) { - wif_->SetInput (Interactor->GetRenderWindow ()); - wif_->Modified (); - snapshot_writer_->Modified (); + wif_->SetInput(Interactor->GetRenderWindow()); + wif_->Modified(); + snapshot_writer_->Modified(); } // Save the initial windows width/height if (win_size_[0] == -1 || win_size_[1] == -1) - win_size_ = Vec2i(Interactor->GetRenderWindow ()->GetSize ()); + win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); // Get the status of special keys (Cltr+Alt+Shift) - bool shift = Interactor->GetShiftKey (); - bool ctrl = Interactor->GetControlKey (); - bool alt = Interactor->GetAltKey (); + bool shift = Interactor->GetShiftKey(); + bool ctrl = Interactor->GetControlKey(); + bool alt = Interactor->GetAltKey(); bool keymod = false; switch (modifier_) @@ -180,13 +228,13 @@ cv::viz::InteractorStyle::OnKeyDown () case KB_MOD_SHIFT: keymod = shift; break; } - std::string key (Interactor->GetKeySym ()); - if (key.find ("XF86ZoomIn") != std::string::npos) - zoomIn (); - else if (key.find ("XF86ZoomOut") != std::string::npos) - zoomOut (); + 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 ()) + switch (Interactor->GetKeyCode()) { case 'h': case 'H': { @@ -218,14 +266,14 @@ cv::viz::InteractorStyle::OnKeyDown () // Switch representation to points case 'p': case 'P': { - vtkSmartPointer ac = CurrentRenderer->GetActors (); + vtkSmartPointer ac = CurrentRenderer->GetActors(); vtkCollectionSimpleIterator ait; - for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) + for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) { - for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) + for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) { - vtkActor* apart = reinterpret_cast (path->GetLastNode ()->GetViewProp ()); - apart->GetProperty ()->SetRepresentationToPoints (); + vtkActor* apart = reinterpret_cast (path->GetLastNode()->GetViewProp()); + apart->GetProperty()->SetRepresentationToPoints(); } } break; @@ -234,27 +282,27 @@ cv::viz::InteractorStyle::OnKeyDown () case 'j': case 'J': { char cam_fn[80], snapshot_fn[80]; - unsigned t = static_cast (time (0)); - sprintf (snapshot_fn, "screenshot-%d.png" , t); - saveScreenshot (snapshot_fn); + unsigned t = static_cast(time(0)); + sprintf(snapshot_fn, "screenshot-%d.png" , t); + saveScreenshot(snapshot_fn); - sprintf (cam_fn, "screenshot-%d.cam", t); + sprintf(cam_fn, "screenshot-%d.cam", t); ofstream ofs_cam; - ofs_cam.open (cam_fn); - vtkSmartPointer cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); + ofs_cam.open(cam_fn); + vtkSmartPointer cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera(); double clip[2], focal[3], pos[3], view[3]; - cam->GetClippingRange (clip); - cam->GetFocalPoint (focal); - cam->GetPosition (pos); - cam->GetViewUp (view); + cam->GetClippingRange(clip); + cam->GetFocalPoint(focal); + cam->GetPosition(pos); + cam->GetViewUp(view); - int *win_pos = Interactor->GetRenderWindow ()->GetPosition (); - int *win_size = Interactor->GetRenderWindow ()->GetSize (); + int *win_pos = Interactor->GetRenderWindow()->GetPosition(); + int *win_size = Interactor->GetRenderWindow()->GetSize(); ofs_cam << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" << pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" << - cam->GetViewAngle () / 180.0 * CV_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] + cam->GetViewAngle() / 180.0 * CV_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1] << endl; - ofs_cam.close (); + ofs_cam.close(); std::cout << "Screenshot (" << snapshot_fn << ") and camera information (" << cam_fn << ") successfully captured." << std::endl; break; @@ -262,14 +310,14 @@ cv::viz::InteractorStyle::OnKeyDown () // display current camera settings/parameters case 'c': case 'C': { - vtkSmartPointer cam = Interactor->GetRenderWindow ()->GetRenderers ()->GetFirstRenderer ()->GetActiveCamera (); + vtkSmartPointer cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera(); Vec2d clip; Vec3d focal, pose, view; - cam->GetClippingRange (clip.val); - cam->GetFocalPoint (focal.val); - cam->GetPosition (pose.val); - cam->GetViewUp (view.val); + cam->GetClippingRange(clip.val); + cam->GetFocalPoint(focal.val); + cam->GetPosition(pose.val); + cam->GetViewUp(view.val); Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition()); Vec2i win_size(Interactor->GetRenderWindow()->GetSize()); @@ -286,20 +334,20 @@ cv::viz::InteractorStyle::OnKeyDown () } case 43: // KEY_PLUS { - if(alt) - zoomIn (); + if (alt) + zoomIn(); else { - vtkSmartPointer ac = CurrentRenderer->GetActors (); + vtkSmartPointer ac = CurrentRenderer->GetActors(); vtkCollectionSimpleIterator ait; - for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) + for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) { - for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) + for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) { - vtkActor* apart = reinterpret_cast (path->GetLastNode ()->GetViewProp ()); - float psize = apart->GetProperty ()->GetPointSize (); + vtkActor* apart = reinterpret_cast (path->GetLastNode()->GetViewProp()); + float psize = apart->GetProperty()->GetPointSize(); if (psize < 63.0f) - apart->GetProperty ()->SetPointSize (psize + 1.0f); + apart->GetProperty()->SetPointSize(psize + 1.0f); } } } @@ -307,20 +355,20 @@ cv::viz::InteractorStyle::OnKeyDown () } case 45: // KEY_MINUS { - if(alt) - zoomOut (); + if (alt) + zoomOut(); else { - vtkSmartPointer ac = CurrentRenderer->GetActors (); + vtkSmartPointer ac = CurrentRenderer->GetActors(); vtkCollectionSimpleIterator ait; - for (ac->InitTraversal (ait); vtkActor* actor = ac->GetNextActor (ait); ) + for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) { - for (actor->InitPathTraversal (); vtkAssemblyPath* path = actor->GetNextPath (); ) + for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) { - vtkActor* apart = static_cast (path->GetLastNode ()->GetViewProp ()); - float psize = apart->GetProperty ()->GetPointSize (); + vtkActor* apart = static_cast(path->GetLastNode()->GetViewProp()); + float psize = apart->GetProperty()->GetPointSize(); if (psize > 1.0f) - apart->GetProperty ()->SetPointSize (psize - 1.0f); + apart->GetProperty()->SetPointSize(psize - 1.0f); } } } @@ -331,39 +379,39 @@ cv::viz::InteractorStyle::OnKeyDown () { if (keymod) { - Vec2i screen_size(Interactor->GetRenderWindow ()->GetScreenSize ()); - Vec2i win_size(Interactor->GetRenderWindow ()->GetSize ()); + 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 (); + 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_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 ()); + Interactor->GetRenderWindow()->SetSize(screen_size.val); + Interactor->GetRenderWindow()->Render(); + Interactor->Render(); + max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); } } else { AnimState = VTKIS_ANIM_ON; vtkAssemblyPath *path = NULL; - Interactor->GetPicker ()->Pick (Interactor->GetEventPosition ()[0], Interactor->GetEventPosition ()[1], 0.0, CurrentRenderer); + Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer); vtkAbstractPropPicker *picker; - if ((picker = vtkAbstractPropPicker::SafeDownCast (Interactor->GetPicker ()))) - path = picker->GetPath (); + if ((picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker()))) + path = picker->GetPath(); if (path != NULL) - Interactor->FlyTo (CurrentRenderer, picker->GetPickPosition ()); + Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition()); AnimState = VTKIS_ANIM_OFF; } break; @@ -373,37 +421,37 @@ cv::viz::InteractorStyle::OnKeyDown () { if (keymod) { - int stereo_render = Interactor->GetRenderWindow ()->GetStereoRender (); + int stereo_render = Interactor->GetRenderWindow()->GetStereoRender(); if (!stereo_render) { if (stereo_anaglyph_mask_default_) { - Interactor->GetRenderWindow ()->SetAnaglyphColorMask (4, 3); + Interactor->GetRenderWindow()->SetAnaglyphColorMask(4, 3); stereo_anaglyph_mask_default_ = false; } else { - Interactor->GetRenderWindow ()->SetAnaglyphColorMask (2, 5); + Interactor->GetRenderWindow()->SetAnaglyphColorMask(2, 5); stereo_anaglyph_mask_default_ = true; } } - Interactor->GetRenderWindow ()->SetStereoRender (!stereo_render); - Interactor->GetRenderWindow ()->Render (); - Interactor->Render (); + Interactor->GetRenderWindow()->SetStereoRender(!stereo_render); + Interactor->GetRenderWindow()->Render(); + Interactor->Render(); } else - Superclass::OnKeyDown (); + Superclass::OnKeyDown(); break; } case 'o': case 'O': { - vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); - int flag = cam->GetParallelProjection (); - cam->SetParallelProjection (!flag); + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + int flag = cam->GetParallelProjection(); + cam->SetParallelProjection(!flag); - CurrentRenderer->SetActiveCamera (cam); - CurrentRenderer->Render (); + CurrentRenderer->SetActiveCamera(cam); + CurrentRenderer->Render(); break; } @@ -412,20 +460,20 @@ cv::viz::InteractorStyle::OnKeyDown () { if (!keymod) { - Superclass::OnKeyDown (); + Superclass::OnKeyDown(); break; } - vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); - static WidgetActorMap::iterator it = widget_actor_map_->begin (); + static 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. bool found_transformation = false; - for (size_t idx = 0; idx < widget_actor_map_->size (); ++idx, ++it) + for (size_t idx = 0; idx < widget_actor_map_->size(); ++idx, ++it) { - if (it == widget_actor_map_->end ()) - it = widget_actor_map_->begin (); + if (it == widget_actor_map_->end()) + it = widget_actor_map_->begin(); vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); if (actor && actor->GetUserMatrix()) @@ -439,219 +487,218 @@ cv::viz::InteractorStyle::OnKeyDown () if (found_transformation) { vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); - cam->SetPosition (actor->GetUserMatrix()->GetElement (0, 3), - actor->GetUserMatrix()->GetElement (1, 3), - actor->GetUserMatrix()->GetElement (2, 3)); + cam->SetPosition(actor->GetUserMatrix()->GetElement(0, 3), + actor->GetUserMatrix()->GetElement(1, 3), + actor->GetUserMatrix()->GetElement(2, 3)); - cam->SetFocalPoint (actor->GetUserMatrix()->GetElement (0, 3) - actor->GetUserMatrix()->GetElement (0, 2), - actor->GetUserMatrix()->GetElement (1, 3) - actor->GetUserMatrix()->GetElement (1, 2), - actor->GetUserMatrix()->GetElement (2, 3) - actor->GetUserMatrix()->GetElement (2, 2)); + cam->SetFocalPoint(actor->GetUserMatrix()->GetElement(0, 3) - actor->GetUserMatrix()->GetElement(0, 2), + actor->GetUserMatrix()->GetElement(1, 3) - actor->GetUserMatrix()->GetElement(1, 2), + actor->GetUserMatrix()->GetElement(2, 3) - actor->GetUserMatrix()->GetElement(2, 2)); - cam->SetViewUp (actor->GetUserMatrix()->GetElement (0, 1), - actor->GetUserMatrix()->GetElement (1, 1), - actor->GetUserMatrix()->GetElement (2, 1)); + cam->SetViewUp(actor->GetUserMatrix()->GetElement(0, 1), + actor->GetUserMatrix()->GetElement(1, 1), + actor->GetUserMatrix()->GetElement(2, 1)); } else { - cam->SetPosition (0, 0, 0); - cam->SetFocalPoint (0, 0, 1); - cam->SetViewUp (0, -1, 0); + 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 ()) + if (it != widget_actor_map_->end()) ++it; else - it = widget_actor_map_->begin (); + it = widget_actor_map_->begin(); - CurrentRenderer->SetActiveCamera (cam); - CurrentRenderer->ResetCameraClippingRange (); - CurrentRenderer->Render (); + CurrentRenderer->SetActiveCamera(cam); + CurrentRenderer->ResetCameraClippingRange(); + CurrentRenderer->Render(); break; } case 'q': case 'Q': { - Interactor->ExitCallback (); + Interactor->ExitCallback(); return; } default: { - Superclass::OnKeyDown (); + Superclass::OnKeyDown(); break; } } - KeyboardEvent event (true, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + KeyboardEvent event(true, Interactor->GetKeySym(), Interactor->GetKeyCode(), Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); // Check if there is a keyboard callback registered if (keyboardCallback_) keyboardCallback_(event, keyboard_callback_cookie_); - renderer_->Render (); - Interactor->Render (); + renderer_->Render(); + Interactor->Render(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnKeyUp () +void cv::viz::InteractorStyle::OnKeyUp() { - KeyboardEvent event (false, Interactor->GetKeySym (), Interactor->GetKeyCode (), Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + KeyboardEvent event(false, Interactor->GetKeySym(), Interactor->GetKeyCode(), Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); // Check if there is a keyboard callback registered if (keyboardCallback_) keyboardCallback_(event, keyboard_callback_cookie_); - Superclass::OnKeyUp (); + Superclass::OnKeyUp(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMouseMove () +void cv::viz::InteractorStyle::OnMouseMove() { Vec2i p(Interactor->GetEventPosition()); - MouseEvent event (MouseEvent::MouseMove, MouseEvent::NoButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnMouseMove (); + Superclass::OnMouseMove(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnLeftButtonDown () +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, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(type, MouseEvent::LeftButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnLeftButtonDown (); + Superclass::OnLeftButtonDown(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnLeftButtonUp () +void cv::viz::InteractorStyle::OnLeftButtonUp() { Vec2i p(Interactor->GetEventPosition()); - MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnLeftButtonUp (); + Superclass::OnLeftButtonUp(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMiddleButtonDown () +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, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(type, MouseEvent::MiddleButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnMiddleButtonDown (); + Superclass::OnMiddleButtonDown(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMiddleButtonUp () +void cv::viz::InteractorStyle::OnMiddleButtonUp() { Vec2i p(Interactor->GetEventPosition()); - MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnMiddleButtonUp (); + Superclass::OnMiddleButtonUp(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnRightButtonDown () +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, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(type, MouseEvent::RightButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnRightButtonDown (); + Superclass::OnRightButtonDown(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnRightButtonUp () +void cv::viz::InteractorStyle::OnRightButtonUp() { Vec2i p(Interactor->GetEventPosition()); - MouseEvent event (MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnRightButtonUp (); + Superclass::OnRightButtonUp(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMouseWheelForward () +void cv::viz::InteractorStyle::OnMouseWheelForward() { Vec2i p(Interactor->GetEventPosition()); - MouseEvent event (MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); // If a mouse callback registered, call it! if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - if (Interactor->GetRepeatCount () && mouseCallback_) + if (Interactor->GetRepeatCount() && mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - if (Interactor->GetAltKey ()) + if (Interactor->GetAltKey()) { // zoom - vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); - double opening_angle = cam->GetViewAngle (); + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + double opening_angle = cam->GetViewAngle(); if (opening_angle > 15.0) opening_angle -= 1.0; - cam->SetViewAngle (opening_angle); - cam->Modified (); - CurrentRenderer->SetActiveCamera (cam); - CurrentRenderer->ResetCameraClippingRange (); - CurrentRenderer->Modified (); - CurrentRenderer->Render (); - renderer_->Render (); - Interactor->Render (); + cam->SetViewAngle(opening_angle); + cam->Modified(); + CurrentRenderer->SetActiveCamera(cam); + CurrentRenderer->ResetCameraClippingRange(); + CurrentRenderer->Modified(); + CurrentRenderer->Render(); + renderer_->Render(); + Interactor->Render(); } else - Superclass::OnMouseWheelForward (); + Superclass::OnMouseWheelForward(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMouseWheelBackward () +void cv::viz::InteractorStyle::OnMouseWheelBackward() { Vec2i p(Interactor->GetEventPosition()); - MouseEvent event (MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, Interactor->GetAltKey (), Interactor->GetControlKey (), Interactor->GetShiftKey ()); + MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey()); // If a mouse callback registered, call it! if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - if (Interactor->GetRepeatCount () && mouseCallback_) + if (Interactor->GetRepeatCount() && mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - if (Interactor->GetAltKey ()) + if (Interactor->GetAltKey()) { // zoom - vtkSmartPointer cam = CurrentRenderer->GetActiveCamera (); - double opening_angle = cam->GetViewAngle (); + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + double opening_angle = cam->GetViewAngle(); if (opening_angle < 170.0) opening_angle += 1.0; - cam->SetViewAngle (opening_angle); - cam->Modified (); - CurrentRenderer->SetActiveCamera (cam); - CurrentRenderer->ResetCameraClippingRange (); - CurrentRenderer->Modified (); - CurrentRenderer->Render (); - renderer_->Render (); - Interactor->Render (); + cam->SetViewAngle(opening_angle); + cam->Modified(); + CurrentRenderer->SetActiveCamera(cam); + CurrentRenderer->ResetCameraClippingRange(); + CurrentRenderer->Modified(); + CurrentRenderer->Render(); + renderer_->Render(); + Interactor->Render(); } else - Superclass::OnMouseWheelBackward (); + Superclass::OnMouseWheelBackward(); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnTimer () +void cv::viz::InteractorStyle::OnTimer() { CV_Assert("Interactor style not initialized." && init_); CV_Assert("Renderer has not been set." && renderer_); - renderer_->Render (); - Interactor->Render (); + renderer_->Render(); + Interactor->Render(); } - namespace cv { namespace viz diff --git a/modules/viz/src/interactor_style.h b/modules/viz/src/interactor_style.h index e48eb3d2c..cc47c87d4 100644 --- a/modules/viz/src/interactor_style.h +++ b/modules/viz/src/interactor_style.h @@ -1,4 +1,53 @@ -#pragma once +/*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*/ + +#ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__ +#define __OPENCV_VIZ_INTERACTOR_STYLE_H__ #include @@ -6,27 +55,6 @@ namespace cv { namespace viz { - /** \brief InteractorStyle defines an unique, custom VTK based interactory style Viz applications. - * Besides defining the rendering style, we also create a list of custom actions - * that are triggered on different keys being pressed: - * - * - p, P : switch to a point-based representation - * - w, W : switch to a wireframe-based representation (where available) - * - s, S : switch to a surface-based representation (where available) - * - j, J : take a .PNG snapshot of the current window view - * - c, C : display current camera/window parameters - * - f, F : fly to point mode - * - e, E : exit the interactor - * - q, Q : stop and call VTK's TerminateApp - * - + / - : increment/decrement overall point size - * - r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}] - * - ALT + s, S : turn stereo mode on/off - * - ALT + f, F : switch between maximized window mode and original size - * - - * - SHIFT + left click : select a point - * - * \author Radu B. Rusu - */ class InteractorStyle : public vtkInteractorStyleTrackballCamera { public: @@ -38,37 +66,31 @@ namespace cv KB_MOD_SHIFT }; - static InteractorStyle *New (); + static InteractorStyle *New(); - InteractorStyle () {} - virtual ~InteractorStyle () {} + InteractorStyle() {} + virtual ~InteractorStyle() {} // this macro defines Superclass, the isA functionality and the safe downcast method - vtkTypeMacro (InteractorStyle, vtkInteractorStyleTrackballCamera) + vtkTypeMacro(InteractorStyle, vtkInteractorStyleTrackballCamera) /** \brief Initialization routine. Must be called before anything else. */ - virtual void Initialize (); + virtual void Initialize(); - inline void setWidgetActorMap (const Ptr& actors) { widget_actor_map_ = actors; } - void setRenderer (vtkSmartPointer& ren) { renderer_ = ren; } + inline void setWidgetActorMap(const Ptr& actors) { widget_actor_map_ = actors; } + void setRenderer(vtkSmartPointer& ren) { renderer_ = ren; } void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0); - void saveScreenshot (const std::string &file); + void saveScreenshot(const std::string &file); - /** \brief Change the default keyboard modified from ALT to a different special key. - * Allowed values are: - * - KB_MOD_ALT - * - KB_MOD_CTRL - * - KB_MOD_SHIFT - * \param[in] modifier the new keyboard modifier - */ - inline void setKeyboardModifier (const KeyboardModifier &modifier) { modifier_ = modifier; } + /** \brief Change the default keyboard modified from ALT to a different special key.*/ + inline void setKeyboardModifier(const KeyboardModifier &modifier) { modifier_ = modifier; } + protected: /** \brief Set to true after initialization is complete. */ bool init_; /** \brief Collection of vtkRenderers stored internally. */ - //vtkSmartPointer rens_; vtkSmartPointer renderer_; /** \brief Actor map stored internally. */ @@ -85,32 +107,33 @@ namespace cv /** \brief A PNG writer for screenshot captures. */ vtkSmartPointer snapshot_writer_; + /** \brief Internal window to image filter. Needed by \a snapshot_writer_. */ vtkSmartPointer wif_; /** \brief Interactor style internal method. Gets called whenever a key is pressed. */ - virtual void OnChar (); + virtual void OnChar(); // Keyboard events - virtual void OnKeyDown (); - virtual void OnKeyUp (); + virtual void OnKeyDown(); + virtual void OnKeyUp(); // mouse button events - virtual void OnMouseMove (); - virtual void OnLeftButtonDown (); - virtual void OnLeftButtonUp (); - virtual void OnMiddleButtonDown (); - virtual void OnMiddleButtonUp (); - virtual void OnRightButtonDown (); - virtual void OnRightButtonUp (); - virtual void OnMouseWheelForward (); - virtual void OnMouseWheelBackward (); + virtual void 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. */ - virtual void OnTimer (); + virtual void OnTimer(); - void zoomIn (); - void zoomOut (); + void zoomIn(); + void zoomOut(); /** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */ bool stereo_anaglyph_mask_default_; @@ -125,3 +148,5 @@ namespace cv }; } } + +#endif diff --git a/modules/viz/src/precomp.cpp b/modules/viz/src/precomp.cpp index 89d145003..834648577 100644 --- a/modules/viz/src/precomp.cpp +++ b/modules/viz/src/precomp.cpp @@ -1 +1,49 @@ -#include "precomp.hpp" \ No newline at end of file +/*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" diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index b2a26b541..23b98d302 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -1,4 +1,53 @@ -#pragma once +/*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*/ + +#ifndef __OPENCV_VIZ_PRECOMP_HPP__ +#define __OPENCV_VIZ_PRECOMP_HPP__ #include #include @@ -89,3 +138,5 @@ namespace cv #include #include #include "opencv2/viz/widget_accessor.hpp" + +#endif diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index f42cebdf0..844347717 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -1,3 +1,51 @@ +/*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 @@ -13,12 +61,12 @@ namespace cv cv::viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) { vtkSmartPointer line = vtkSmartPointer::New(); - line->SetPoint1 (pt1.x, pt1.y, pt1.z); - line->SetPoint2 (pt2.x, pt2.y, pt2.z); - line->Update (); + line->SetPoint1(pt1.x, pt1.y, pt1.z); + line->SetPoint2(pt2.x, pt2.y, pt2.z); + line->Update(); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(line->GetOutput ()); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(line->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -58,15 +106,15 @@ struct cv::viz::PlaneWidget::SetSizeImpl cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color &color) { - vtkSmartPointer plane = vtkSmartPointer::New (); - plane->SetNormal (coefs[0], coefs[1], coefs[2]); + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetNormal(coefs[0], coefs[1], coefs[2]); double norm = cv::norm(Vec3f(coefs.val)); - plane->Push (-coefs[3] / norm); + plane->Push(-coefs[3] / norm); Vec3d p_center; plane->GetOrigin(p_center.val); - vtkSmartPointer mapper = vtkSmartPointer::New (); + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput(SetSizeImpl::setSize(p_center, plane->GetOutput(), size)); vtkSmartPointer actor = vtkSmartPointer::New(); @@ -78,16 +126,16 @@ cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color & cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size, const Color &color) { - vtkSmartPointer plane = vtkSmartPointer::New (); + vtkSmartPointer plane = vtkSmartPointer::New(); Point3f coefs3(coefs[0], coefs[1], coefs[2]); - double norm_sqr = 1.0 / coefs3.dot (coefs3); + double norm_sqr = 1.0 / coefs3.dot(coefs3); plane->SetNormal(coefs[0], coefs[1], coefs[2]); double t = coefs3.dot(pt) + coefs[3]; Vec3f p_center = pt - coefs3 * t * norm_sqr; - plane->SetCenter (p_center[0], p_center[1], p_center[2]); + plane->SetCenter(p_center[0], p_center[1], p_center[2]); - vtkSmartPointer mapper = vtkSmartPointer::New (); + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInput(SetSizeImpl::setSize(p_center, plane->GetOutput(), size)); vtkSmartPointer actor = vtkSmartPointer::New(); @@ -108,16 +156,16 @@ template<> cv::viz::PlaneWidget cv::viz::Widget::cast() cv::viz::SphereWidget::SphereWidget(const Point3f ¢er, float radius, int sphere_resolution, const Color &color) { - vtkSmartPointer sphere = vtkSmartPointer::New (); - sphere->SetRadius (radius); - sphere->SetCenter (center.x, center.y, center.z); - sphere->SetPhiResolution (sphere_resolution); - sphere->SetThetaResolution (sphere_resolution); - sphere->LatLongTessellationOff (); - sphere->Update (); + vtkSmartPointer sphere = vtkSmartPointer::New(); + sphere->SetRadius(radius); + sphere->SetCenter(center.x, center.y, center.z); + sphere->SetPhiResolution(sphere_resolution); + sphere->SetThetaResolution(sphere_resolution); + sphere->LatLongTessellationOff(); + sphere->Update(); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(sphere->GetOutput ()); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(sphere->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -137,7 +185,7 @@ template<> cv::viz::SphereWidget cv::viz::Widget::cast() cv::viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness, const Color &color) { - vtkSmartPointer arrowSource = vtkSmartPointer::New (); + vtkSmartPointer arrowSource = vtkSmartPointer::New(); arrowSource->SetShaftRadius(thickness); // The thickness and radius of the tip are adjusted based on the thickness of the arrow arrowSource->SetTipRadius(thickness * 3.0); @@ -189,8 +237,8 @@ cv::viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, double transformPD->SetTransform(transform); transformPD->SetInputConnection(arrowSource->GetOutputPort()); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(transformPD->GetOutput ()); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(transformPD->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -210,23 +258,23 @@ template<> cv::viz::ArrowWidget cv::viz::Widget::cast() cv::viz::CircleWidget::CircleWidget(const Point3f& pt, double radius, double thickness, const Color& color) { - vtkSmartPointer disk = vtkSmartPointer::New (); + vtkSmartPointer disk = vtkSmartPointer::New(); // Maybe the resolution should be lower e.g. 50 or 25 - disk->SetCircumferentialResolution (50); - disk->SetInnerRadius (radius - thickness); - disk->SetOuterRadius (radius + thickness); + disk->SetCircumferentialResolution(50); + disk->SetInnerRadius(radius - thickness); + disk->SetOuterRadius(radius + thickness); // Set the circle origin - vtkSmartPointer t = vtkSmartPointer::New (); - t->Identity (); - t->Translate (pt.x, pt.y, pt.z); + vtkSmartPointer t = vtkSmartPointer::New(); + t->Identity(); + t->Translate(pt.x, pt.y, pt.z); - vtkSmartPointer tf = vtkSmartPointer::New (); - tf->SetTransform (t); - tf->SetInputConnection (disk->GetOutputPort ()); + vtkSmartPointer tf = vtkSmartPointer::New(); + tf->SetTransform(t); + tf->SetInputConnection(disk->GetOutputPort()); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(tf->GetOutput ()); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(tf->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -247,19 +295,19 @@ template<> cv::viz::CircleWidget cv::viz::Widget::cast() cv::viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides, const Color &color) { const Point3f pt2 = pt_on_axis + axis_direction; - vtkSmartPointer line = vtkSmartPointer::New (); - line->SetPoint1 (pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); - line->SetPoint2 (pt2.x, pt2.y, pt2.z); + vtkSmartPointer line = vtkSmartPointer::New(); + line->SetPoint1(pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); + line->SetPoint2(pt2.x, pt2.y, pt2.z); - vtkSmartPointer tuber = vtkSmartPointer::New (); - tuber->SetInputConnection (line->GetOutputPort ()); - tuber->SetRadius (radius); - tuber->SetNumberOfSides (numsides); + vtkSmartPointer tuber = vtkSmartPointer::New(); + tuber->SetInputConnection(line->GetOutputPort()); + tuber->SetRadius(radius); + tuber->SetNumberOfSides(numsides); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput(tuber->GetOutput ()); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(tuber->GetOutput()); - vtkSmartPointer actor = vtkSmartPointer::New (); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); @@ -277,18 +325,18 @@ template<> cv::viz::CylinderWidget cv::viz::Widget::cast mapper = vtkSmartPointer::New (); + vtkSmartPointer mapper = vtkSmartPointer::New(); if (wire_frame) { vtkSmartPointer cube = vtkSmartPointer::New(); - cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); - mapper->SetInput(cube->GetOutput ()); + cube->SetBounds(pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); + mapper->SetInput(cube->GetOutput()); } else { - vtkSmartPointer cube = vtkSmartPointer::New (); - cube->SetBounds (pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); - mapper->SetInput(cube->GetOutput ()); + vtkSmartPointer cube = vtkSmartPointer::New(); + cube->SetBounds(pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); + mapper->SetInput(cube->GetOutput()); } vtkSmartPointer actor = vtkSmartPointer::New(); @@ -309,31 +357,31 @@ template<> cv::viz::CubeWidget cv::viz::Widget::cast() cv::viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale) { - vtkSmartPointer axes = vtkSmartPointer::New (); - axes->SetOrigin (0, 0, 0); - axes->SetScaleFactor (scale); + vtkSmartPointer axes = vtkSmartPointer::New(); + axes->SetOrigin(0, 0, 0); + axes->SetScaleFactor(scale); - vtkSmartPointer axes_colors = vtkSmartPointer::New (); - axes_colors->Allocate (6); - axes_colors->InsertNextValue (0.0); - axes_colors->InsertNextValue (0.0); - axes_colors->InsertNextValue (0.5); - axes_colors->InsertNextValue (0.5); - axes_colors->InsertNextValue (1.0); - axes_colors->InsertNextValue (1.0); + vtkSmartPointer axes_colors = vtkSmartPointer::New(); + axes_colors->Allocate(6); + axes_colors->InsertNextValue(0.0); + axes_colors->InsertNextValue(0.0); + axes_colors->InsertNextValue(0.5); + axes_colors->InsertNextValue(0.5); + axes_colors->InsertNextValue(1.0); + axes_colors->InsertNextValue(1.0); - vtkSmartPointer axes_data = axes->GetOutput (); - axes_data->Update (); - axes_data->GetPointData ()->SetScalars (axes_colors); + vtkSmartPointer axes_data = axes->GetOutput(); + axes_data->Update(); + axes_data->GetPointData()->SetScalars(axes_colors); - vtkSmartPointer axes_tubes = vtkSmartPointer::New (); - axes_tubes->SetInput (axes_data); - axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); - axes_tubes->SetNumberOfSides (6); + vtkSmartPointer axes_tubes = vtkSmartPointer::New(); + axes_tubes->SetInput(axes_data); + axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); + axes_tubes->SetNumberOfSides(6); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetScalarModeToUsePointData (); - mapper->SetInput(axes_tubes->GetOutput ()); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUsePointData(); + mapper->SetInput(axes_tubes->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -357,11 +405,11 @@ struct cv::viz::PolyLineWidget::CopyImpl { int s_chs = source.channels(); - for(int y = 0, id = 0; y < source.rows; ++y) + for (int y = 0, id = 0; y < source.rows; ++y) { const _Tp* srow = source.ptr<_Tp>(y); - for(int x = 0; x < source.cols; ++x, srow += s_chs, ++id) + for (int x = 0; x < source.cols; ++x, srow += s_chs, ++id) { *output++ = Vec<_Tp, 3>(srow); polyLine->GetPointIds()->SetId(id,id); @@ -376,9 +424,9 @@ cv::viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &colo CV_Assert(pointData.type() == CV_32FC3 || pointData.type() == CV_32FC4 || pointData.type() == CV_64FC3 || pointData.type() == CV_64FC4); vtkIdType nr_points = pointData.total(); - vtkSmartPointer points = vtkSmartPointer::New (); - vtkSmartPointer polyData = vtkSmartPointer::New (); - vtkSmartPointer polyLine = vtkSmartPointer::New (); + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); + vtkSmartPointer polyLine = vtkSmartPointer::New(); if (pointData.depth() == CV_32F) points->SetDataTypeToFloat(); @@ -528,7 +576,7 @@ cv::viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position, textSource->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInputConnection (textSource->GetOutputPort()); + mapper->SetInputConnection(textSource->GetOutputPort()); if (face_camera) { @@ -588,17 +636,17 @@ template<> cv::viz::Text3DWidget cv::viz::Widget::cast() cv::viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) { vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetPosition (pos.x, pos.y); - actor->SetInput (text.c_str ()); + actor->SetPosition(pos.x, pos.y); + actor->SetInput(text.c_str()); - vtkSmartPointer tprop = actor->GetTextProperty (); - tprop->SetFontSize (font_size); - tprop->SetFontFamilyToArial (); - tprop->SetJustificationToLeft (); - tprop->BoldOn (); + vtkSmartPointer tprop = actor->GetTextProperty(); + tprop->SetFontSize(font_size); + tprop->SetFontFamilyToArial(); + tprop->SetJustificationToLeft(); + tprop->BoldOn(); Color c = vtkcolor(color); - tprop->SetColor (c.val); + tprop->SetColor(c.val); WidgetAccessor::setProp(*this, actor); } @@ -938,31 +986,31 @@ struct cv::viz::CameraPositionWidget::ProjectImage cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) { - vtkSmartPointer axes = vtkSmartPointer::New (); - axes->SetOrigin (0, 0, 0); - axes->SetScaleFactor (scale); + vtkSmartPointer axes = vtkSmartPointer::New(); + axes->SetOrigin(0, 0, 0); + axes->SetScaleFactor(scale); - vtkSmartPointer axes_colors = vtkSmartPointer::New (); - axes_colors->Allocate (6); - axes_colors->InsertNextValue (0.0); - axes_colors->InsertNextValue (0.0); - axes_colors->InsertNextValue (0.5); - axes_colors->InsertNextValue (0.5); - axes_colors->InsertNextValue (1.0); - axes_colors->InsertNextValue (1.0); + vtkSmartPointer axes_colors = vtkSmartPointer::New(); + axes_colors->Allocate(6); + axes_colors->InsertNextValue(0.0); + axes_colors->InsertNextValue(0.0); + axes_colors->InsertNextValue(0.5); + axes_colors->InsertNextValue(0.5); + axes_colors->InsertNextValue(1.0); + axes_colors->InsertNextValue(1.0); - vtkSmartPointer axes_data = axes->GetOutput (); - axes_data->Update (); - axes_data->GetPointData ()->SetScalars (axes_colors); + vtkSmartPointer axes_data = axes->GetOutput(); + axes_data->Update(); + axes_data->GetPointData()->SetScalars(axes_colors); - vtkSmartPointer axes_tubes = vtkSmartPointer::New (); - axes_tubes->SetInput (axes_data); - axes_tubes->SetRadius (axes->GetScaleFactor () / 50.0); - axes_tubes->SetNumberOfSides (6); + vtkSmartPointer axes_tubes = vtkSmartPointer::New(); + axes_tubes->SetInput(axes_data); + axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); + axes_tubes->SetNumberOfSides(6); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetScalarModeToUsePointData (); - mapper->SetInput(axes_tubes->GetOutput ()); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUsePointData(); + mapper->SetInput(axes_tubes->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -1122,9 +1170,9 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i // Create a poly line along the path vtkIdType nr_points = path.size(); - vtkSmartPointer points = vtkSmartPointer::New (); - vtkSmartPointer polyData = vtkSmartPointer::New (); - vtkSmartPointer polyLine = vtkSmartPointer::New (); + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer polyData = vtkSmartPointer::New(); + vtkSmartPointer polyLine = vtkSmartPointer::New(); points->SetDataTypeToFloat(); points->SetNumberOfPoints(nr_points); @@ -1161,10 +1209,10 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i { // Create frames and transform along the path vtkSmartPointer axes = vtkSmartPointer::New(); - axes->SetOrigin (0, 0, 0); - axes->SetScaleFactor (scale); + axes->SetOrigin(0, 0, 0); + axes->SetScaleFactor(scale); - vtkSmartPointer axes_colors = vtkSmartPointer::New (); + vtkSmartPointer axes_colors = vtkSmartPointer::New(); axes_colors->SetNumberOfComponents(3); axes_colors->InsertNextTuple3(255,0,0); axes_colors->InsertNextTuple3(255,0,0); @@ -1173,21 +1221,21 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i axes_colors->InsertNextTuple3(0,0,255); axes_colors->InsertNextTuple3(0,0,255); - vtkSmartPointer axes_data = axes->GetOutput (); - axes_data->Update (); - axes_data->GetPointData ()->SetScalars (axes_colors); + vtkSmartPointer axes_data = axes->GetOutput(); + axes_data->Update(); + axes_data->GetPointData()->SetScalars(axes_colors); - vtkSmartPointer axes_tubes = vtkSmartPointer::New (); - axes_tubes->SetInput (axes_data); - axes_tubes->SetRadius (axes->GetScaleFactor() / 50.0); - axes_tubes->SetNumberOfSides (6); + vtkSmartPointer axes_tubes = vtkSmartPointer::New(); + axes_tubes->SetInput(axes_data); + axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); + axes_tubes->SetNumberOfSides(6); axes_tubes->Update(); ApplyPath::applyPath(axes_tubes->GetOutput(), appendFilter, path); } vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetScalarModeToUsePointData (); + mapper->SetScalarModeToUsePointData(); mapper->SetInput(appendFilter->GetOutput()); vtkSmartPointer actor = vtkSmartPointer::New(); @@ -1329,7 +1377,7 @@ cv::viz::SpheresTrajectoryWidget::SpheresTrajectoryWidget(const std::vector sphere_source = vtkSmartPointer::New(); - sphere_source->SetCenter (new_pos.x, new_pos.y, new_pos.z); + sphere_source->SetCenter(new_pos.x, new_pos.y, new_pos.z); if (i == 0) { sphere_source->SetRadius(init_sphere_radius); @@ -1374,4 +1422,4 @@ template<> cv::viz::SpheresTrajectoryWidget cv::viz::Widget::castcast(); return static_cast(widget); -} \ No newline at end of file +} diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index e915207e3..49f6ccee4 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -1,3 +1,51 @@ +/*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" ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -23,8 +71,8 @@ cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); } //////////////////////////////////////////////////////////////////// /// cv::viz::KeyboardEvent -cv::viz::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) - : action_ (_action), modifiers_ (0), key_code_(key), key_sym_ (_key_sym) +cv::viz::KeyboardEvent::KeyboardEvent(bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift) + : action_(_action), modifiers_(0), key_code_(key), key_sym_(_key_sym) { if (alt) modifiers_ = Alt; @@ -36,18 +84,18 @@ cv::viz::KeyboardEvent::KeyboardEvent (bool _action, const std::string& _key_sym modifiers_ |= Shift; } -bool cv::viz::KeyboardEvent::isAltPressed () const { return (modifiers_ & Alt) != 0; } -bool cv::viz::KeyboardEvent::isCtrlPressed () const { return (modifiers_ & Ctrl) != 0; } -bool cv::viz::KeyboardEvent::isShiftPressed () const { return (modifiers_ & Shift) != 0; } -unsigned char cv::viz::KeyboardEvent::getKeyCode () const { return key_code_; } -const cv::String& cv::viz::KeyboardEvent::getKeySym () const { return key_sym_; } -bool cv::viz::KeyboardEvent::keyDown () const { return action_; } -bool cv::viz::KeyboardEvent::keyUp () const { return !action_; } +bool cv::viz::KeyboardEvent::isAltPressed() const { return (modifiers_ & Alt) != 0; } +bool cv::viz::KeyboardEvent::isCtrlPressed() const { return (modifiers_ & Ctrl) != 0; } +bool cv::viz::KeyboardEvent::isShiftPressed() const { return (modifiers_ & Shift) != 0; } +unsigned char cv::viz::KeyboardEvent::getKeyCode() const { return key_code_; } +const cv::String& cv::viz::KeyboardEvent::getKeySym() const { return key_sym_; } +bool cv::viz::KeyboardEvent::keyDown() const { return action_; } +bool cv::viz::KeyboardEvent::keyUp() const { return !action_; } //////////////////////////////////////////////////////////////////// /// cv::viz::MouseEvent -cv::viz::MouseEvent::MouseEvent (const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) +cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift) : type(_type), button(_button), pointer(_p), key_state(0) { if (alt) @@ -73,19 +121,19 @@ struct cv::viz::Mesh3d::loadMeshImpl reader->SetFileName(file.c_str()); reader->Update(); - vtkSmartPointer poly_data = reader->GetOutput (); + vtkSmartPointer poly_data = reader->GetOutput(); CV_Assert("File does not exist or file format is not supported." && poly_data); - vtkSmartPointer mesh_points = poly_data->GetPoints (); - vtkIdType nr_points = mesh_points->GetNumberOfPoints (); + vtkSmartPointer mesh_points = poly_data->GetPoints(); + vtkIdType nr_points = mesh_points->GetNumberOfPoints(); mesh.cloud.create(1, nr_points, CV_32FC3); Vec3f *mesh_cloud = mesh.cloud.ptr(); - for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) + for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++) { Vec3d point; - mesh_points->GetPoint (i, point.val); + mesh_points->GetPoint(i, point.val); mesh_cloud[i] = point; } @@ -94,15 +142,15 @@ struct cv::viz::Mesh3d::loadMeshImpl if (poly_data->GetPointData()) poly_colors = vtkUnsignedCharArray::SafeDownCast(poly_data->GetPointData()->GetScalars()); - if (poly_colors && (poly_colors->GetNumberOfComponents () == 3)) + if (poly_colors && (poly_colors->GetNumberOfComponents() == 3)) { mesh.colors.create(1, nr_points, CV_8UC3); Vec3b *mesh_colors = mesh.colors.ptr(); - for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints (); i++) + for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++) { Vec3b point_color; - poly_colors->GetTupleValue (i, point_color.val); + poly_colors->GetTupleValue(i, point_color.val); std::swap(point_color[0], point_color[2]); // RGB -> BGR mesh_colors[i] = point_color; @@ -114,17 +162,17 @@ struct cv::viz::Mesh3d::loadMeshImpl // Now handle the polygons vtkIdType* cell_points; vtkIdType nr_cell_points; - vtkCellArray * mesh_polygons = poly_data->GetPolys (); - mesh_polygons->InitTraversal (); + vtkCellArray * mesh_polygons = poly_data->GetPolys(); + mesh_polygons->InitTraversal(); mesh.polygons.create(1, mesh_polygons->GetSize(), CV_32SC1); int* polygons = mesh.polygons.ptr(); - while (mesh_polygons->GetNextCell (nr_cell_points, cell_points)) + while (mesh_polygons->GetNextCell(nr_cell_points, cell_points)) { *polygons++ = nr_cell_points; for (int i = 0; i < nr_cell_points; ++i) - *polygons++ = static_cast (cell_points[i]); + *polygons++ = static_cast(cell_points[i]); } return mesh; @@ -257,4 +305,4 @@ cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) K(1,2) = 2.6748068171871557e+02; K(2,2) = 1.0f; return Camera(K, window_size); -} \ No newline at end of file +} diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 8bce61ca2..db109ddd5 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -1,5 +1,52 @@ -#include "precomp.hpp" +/*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" cv::Affine3f cv::viz::makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin) { @@ -44,7 +91,7 @@ cv::Affine3f cv::viz::makeCameraPose(const Vec3f& position, const Vec3f& focal_p return pose_mat; } -vtkSmartPointer cv::viz::convertToVtkMatrix (const cv::Matx44f &m) +vtkSmartPointer cv::viz::convertToVtkMatrix(const cv::Matx44f &m) { vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); for (int i = 0; i < 4; i++) @@ -58,7 +105,7 @@ cv::Matx44f cv::viz::convertToMatx(const vtkSmartPointer& vtk_matr cv::Matx44f m; for (int i = 0; i < 4; i++) for (int k = 0; k < 4; k++) - m(i, k) = vtk_matrix->GetElement (i, k); + m(i, k) = vtk_matrix->GetElement(i, k); return m; } @@ -165,4 +212,4 @@ void cv::viz::VizAccessor::generateWindowName(const String &window_name, String cv::viz::Viz3d cv::viz::get(const String &window_name) { return cv::viz::VizAccessor::getInstance().get(window_name); -} \ No newline at end of file +} diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index eeea94277..c7dcb18a2 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -1,7 +1,54 @@ +/*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 #include "viz3d_impl.hpp" - cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(0) { create(window_name); } cv::viz::Viz3d::Viz3d(const Viz3d& other) : impl_(other.impl_) @@ -45,7 +92,7 @@ void cv::viz::Viz3d::release() } void cv::viz::Viz3d::spin() { impl_->spin(); } -void cv::viz::Viz3d::spinOnce (int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); } +void cv::viz::Viz3d::spinOnce(int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); } bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } void cv::viz::Viz3d::registerKeyboardCallback(KeyboardCallback callback, void* cookie) @@ -67,7 +114,7 @@ cv::viz::Camera cv::viz::Viz3d::getCamera() const { return impl_->getCamera(); } void cv::viz::Viz3d::setViewerPose(const Affine3f &pose) { impl_->setViewerPose(pose); } cv::Affine3f cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } -void cv::viz::Viz3d::resetCameraViewpoint (const String &id) { impl_->resetCameraViewpoint(id); } +void cv::viz::Viz3d::resetCameraViewpoint(const String &id) { impl_->resetCameraViewpoint(id); } void cv::viz::Viz3d::resetCamera() { impl_->resetCamera(); } void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } @@ -76,9 +123,9 @@ void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } -void cv::viz::Viz3d::saveScreenshot (const String &file) { impl_->saveScreenshot(file); } -void cv::viz::Viz3d::setWindowPosition (int x, int y) { impl_->setWindowPosition(x,y); } -void cv::viz::Viz3d::setFullScreen (bool mode) { impl_->setFullScreen(mode); } +void cv::viz::Viz3d::saveScreenshot(const String &file) { impl_->saveScreenshot(file); } +void cv::viz::Viz3d::setWindowPosition(int x, int y) { impl_->setWindowPosition(x,y); } +void cv::viz::Viz3d::setFullScreen(bool mode) { impl_->setFullScreen(mode); } void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double value) { getWidget(id).setRenderingProperty(property, value); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index fd6a82eb4..52c6a45aa 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -1,81 +1,129 @@ +/*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" #include "viz3d_impl.hpp" #include #if 1 || !defined __APPLE__ -vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew () +vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew() { return vtkRenderWindowInteractor::New(); } #endif ///////////////////////////////////////////////////////////////////////////////////////////// -cv::viz::Viz3d::VizImpl::VizImpl (const std::string &name) - : style_ (vtkSmartPointer::New ()) - , widget_actor_map_ (new WidgetActorMap) +cv::viz::Viz3d::VizImpl::VizImpl(const std::string &name) + : style_(vtkSmartPointer::New()) + , widget_actor_map_(new WidgetActorMap) , s_lastDone_(0.0) { - renderer_ = vtkSmartPointer::New (); + renderer_ = vtkSmartPointer::New(); // Create a RendererWindow - window_ = vtkSmartPointer::New (); + window_ = vtkSmartPointer::New(); // Set the window size as 1/2 of the screen size cv::Vec2i window_size = cv::Vec2i(window_->GetScreenSize()) / 2; - window_->SetSize (window_size.val); + window_->SetSize(window_size.val); - window_->AddRenderer (renderer_); + window_->AddRenderer(renderer_); // Create the interactor style - style_->Initialize (); - style_->setRenderer (renderer_); - style_->setWidgetActorMap (widget_actor_map_); - style_->UseTimersOn (); + style_->Initialize(); + style_->setRenderer(renderer_); + style_->setWidgetActorMap(widget_actor_map_); + style_->UseTimersOn(); ///////////////////////////////////////////////// - interactor_ = vtkSmartPointer ::Take (vtkRenderWindowInteractorFixNew ()); + interactor_ = vtkSmartPointer ::Take(vtkRenderWindowInteractorFixNew()); - window_->AlphaBitPlanesOff (); - window_->PointSmoothingOff (); - window_->LineSmoothingOff (); - window_->PolygonSmoothingOff (); - window_->SwapBuffersOn (); - window_->SetStereoTypeToAnaglyph (); + window_->AlphaBitPlanesOff(); + window_->PointSmoothingOff(); + window_->LineSmoothingOff(); + window_->PolygonSmoothingOff(); + window_->SwapBuffersOn(); + window_->SetStereoTypeToAnaglyph(); - interactor_->SetRenderWindow (window_); - interactor_->SetInteractorStyle (style_); - interactor_->SetDesiredUpdateRate (30.0); + interactor_->SetRenderWindow(window_); + interactor_->SetInteractorStyle(style_); + interactor_->SetDesiredUpdateRate(30.0); // Initialize and create timer, also create window - interactor_->Initialize (); - timer_id_ = interactor_->CreateRepeatingTimer (5000L); + interactor_->Initialize(); + timer_id_ = interactor_->CreateRepeatingTimer(5000L); // Set a simple PointPicker - vtkSmartPointer pp = vtkSmartPointer::New (); - pp->SetTolerance (pp->GetTolerance () * 2); - interactor_->SetPicker (pp); + vtkSmartPointer pp = vtkSmartPointer::New(); + pp->SetTolerance(pp->GetTolerance() * 2); + interactor_->SetPicker(pp); - exit_main_loop_timer_callback_ = vtkSmartPointer::New (); + exit_main_loop_timer_callback_ = vtkSmartPointer::New(); exit_main_loop_timer_callback_->viz_ = this; exit_main_loop_timer_callback_->right_timer_id = -1; - interactor_->AddObserver (vtkCommand::TimerEvent, exit_main_loop_timer_callback_); + interactor_->AddObserver(vtkCommand::TimerEvent, exit_main_loop_timer_callback_); - exit_callback_ = vtkSmartPointer::New (); + exit_callback_ = vtkSmartPointer::New(); exit_callback_->viz_ = this; - interactor_->AddObserver (vtkCommand::ExitEvent, exit_callback_); + interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_); - resetStoppedFlag (); + resetStoppedFlag(); ////////////////////////////// String window_name; VizAccessor::generateWindowName(name, window_name); - window_->SetWindowName (window_name.c_str ()); + window_->SetWindowName(window_name.c_str()); } ///////////////////////////////////////////////////////////////////////////////////////////// -cv::viz::Viz3d::VizImpl::~VizImpl () +cv::viz::Viz3d::VizImpl::~VizImpl() { if (interactor_) interactor_->DestroyTimer(timer_id_); @@ -98,7 +146,7 @@ void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, { // If the actor is 3D, apply pose vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); + actor->SetUserMatrix(matrix); actor->Modified(); } // If the actor is a vtkFollower, then it should always face the camera @@ -118,7 +166,7 @@ void cv::viz::Viz3d::VizImpl::removeWidget(const String &id) WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); bool exists = wam_itr != widget_actor_map_->end(); CV_Assert("Widget does not exist." && exists); - CV_Assert("Widget could not be removed." && removeActorFromRenderer (wam_itr->second)); + CV_Assert("Widget could not be removed." && removeActorFromRenderer(wam_itr->second)); widget_actor_map_->erase(wam_itr); } @@ -145,8 +193,8 @@ void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &po CV_Assert("Widget is not 3D." && actor); vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); + actor->SetUserMatrix(matrix); + actor->Modified(); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -169,8 +217,8 @@ void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f Affine3f updated_pose = pose * Affine3f(matrix_cv); matrix = convertToVtkMatrix(updated_pose.matrix); - actor->SetUserMatrix (matrix); - actor->Modified (); + actor->SetUserMatrix(matrix); + actor->Modified(); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -204,7 +252,7 @@ double cv::viz::Viz3d::VizImpl::getDesiredUpdateRate() } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::saveScreenshot (const std::string &file) { style_->saveScreenshot (file); } +void cv::viz::Viz3d::VizImpl::saveScreenshot(const std::string &file) { style_->saveScreenshot(file); } ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void* cookie) @@ -214,33 +262,33 @@ void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(KeyboardCallback callback { style_->registerKeyboardCallback(callback, cookie); } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::spin () +void cv::viz::Viz3d::VizImpl::spin() { - resetStoppedFlag (); - window_->Render (); - interactor_->Start (); + resetStoppedFlag(); + window_->Render(); + interactor_->Start(); } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::spinOnce (int time, bool force_redraw) +void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw) { - resetStoppedFlag (); + resetStoppedFlag(); if (time <= 0) time = 1; if (force_redraw) - interactor_->Render (); + interactor_->Render(); double s_now_ = cv::getTickCount() / cv::getTickFrequency(); if (s_lastDone_ > s_now_) s_lastDone_ = s_now_; - if ((s_now_ - s_lastDone_) > (1.0 / interactor_->GetDesiredUpdateRate ())) + if ((s_now_ - s_lastDone_) > (1.0 / interactor_->GetDesiredUpdateRate())) { - exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer (time); - interactor_->Start (); - interactor_->DestroyTimer (exit_main_loop_timer_callback_->right_timer_id); + exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer(time); + interactor_->Start(); + interactor_->DestroyTimer(exit_main_loop_timer_callback_->right_timer_id); s_lastDone_ = s_now_; } } @@ -253,67 +301,63 @@ void cv::viz::Viz3d::VizImpl::removeAllWidgets() } ///////////////////////////////////////////////////////////////////////////////////////////// -bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer (const vtkSmartPointer &actor) +bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(const vtkSmartPointer &actor) { vtkProp* actor_to_remove = vtkProp::SafeDownCast(actor); - vtkPropCollection* actors = renderer_->GetViewProps (); - actors->InitTraversal (); + vtkPropCollection* actors = renderer_->GetViewProps(); + actors->InitTraversal(); vtkProp* current_actor = NULL; - while ((current_actor = actors->GetNextProp ()) != NULL) + while ((current_actor = actors->GetNextProp()) != NULL) { if (current_actor != actor_to_remove) continue; - renderer_->RemoveActor (actor); + renderer_->RemoveActor(actor); return true; } return false; } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::createActorFromVTKDataSet (const vtkSmartPointer &data, vtkSmartPointer &actor, bool use_scalars) +void cv::viz::Viz3d::VizImpl::createActorFromVTKDataSet(const vtkSmartPointer &data, vtkSmartPointer &actor, bool use_scalars) { if (!actor) - actor = vtkSmartPointer::New (); + actor = vtkSmartPointer::New(); - vtkSmartPointer mapper = vtkSmartPointer::New (); - mapper->SetInput (data); + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInput(data); if (use_scalars) { - vtkSmartPointer scalars = data->GetPointData ()->GetScalars (); + vtkSmartPointer scalars = data->GetPointData()->GetScalars(); if (scalars) { cv::Vec3d minmax(scalars->GetRange()); mapper->SetScalarRange(minmax.val); - mapper->SetScalarModeToUsePointData (); + 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 ()); + vtkPolyData* polyData = vtkPolyData::SafeDownCast(data); + bool interpolation = (polyData && polyData->GetNumberOfCells() != polyData->GetNumberOfVerts()); - mapper->SetInterpolateScalarsBeforeMapping (interpolation); - mapper->ScalarVisibilityOn (); + mapper->SetInterpolateScalarsBeforeMapping(interpolation); + mapper->ScalarVisibilityOn(); } } - mapper->ImmediateModeRenderingOff (); + mapper->ImmediateModeRenderingOff(); - actor->SetNumberOfCloudPoints (int (std::max (1, data->GetNumberOfPoints () / 10))); - actor->GetProperty ()->SetInterpolationToFlat (); + actor->SetNumberOfCloudPoints(int(std::max(1, data->GetNumberOfPoints() / 10))); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); - /// FIXME disabling backface culling due to known VTK bug: vtkTextActors are not - /// shown when there is a vtkActor with backface culling on present in the scene - /// Please see VTK bug tracker for more details: http://www.vtk.org/Bug/view.php?id=12588 - // actor->GetProperty ()->BackfaceCullingOn (); - - actor->SetMapper (mapper); + actor->SetMapper(mapper); } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setBackgroundColor (const Color& color) +void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color) { Color c = vtkcolor(color); - renderer_->SetBackground (c.val); + renderer_->SetBackground(c.val); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -322,7 +366,7 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) vtkCamera& active_camera = *renderer_->GetActiveCamera(); // Set the intrinsic parameters of the camera - window_->SetSize (camera.getWindowSize().width, camera.getWindowSize().height); + window_->SetSize(camera.getWindowSize().width, camera.getWindowSize().height); double aspect_ratio = static_cast(camera.getWindowSize().width)/static_cast(camera.getWindowSize().height); Matx44f proj_mat; @@ -353,18 +397,18 @@ cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) { - vtkCamera& camera = *renderer_->GetActiveCamera (); + vtkCamera& camera = *renderer_->GetActiveCamera(); // Position = extrinsic translation cv::Vec3f pos_vec = pose.translation(); // Rotate the view vector cv::Matx33f rotation = pose.rotation(); - cv::Vec3f y_axis (0.f, 1.f, 0.f); - cv::Vec3f up_vec (rotation * y_axis); + cv::Vec3f y_axis(0.f, 1.f, 0.f); + cv::Vec3f up_vec(rotation * y_axis); // Compute the new focal point - cv::Vec3f z_axis (0.f, 0.f, 1.f); + cv::Vec3f z_axis(0.f, 0.f, 1.f); cv::Vec3f focal_vec = pos_vec + rotation * z_axis; camera.SetPosition(pos_vec[0], pos_vec[1], pos_vec[2]); @@ -373,9 +417,9 @@ void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) } ///////////////////////////////////////////////////////////////////////////////////////////// -cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose () +cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose() { - vtkCamera& camera = *renderer_->GetActiveCamera (); + vtkCamera& camera = *renderer_->GetActiveCamera(); Vec3d pos(camera.GetPosition()); Vec3d view_up(camera.GetViewUp()); @@ -423,11 +467,11 @@ void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d } ///////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const String &id) +void cv::viz::Viz3d::VizImpl::resetCameraViewpoint(const String &id) { vtkSmartPointer camera_pose; - static WidgetActorMap::iterator it = widget_actor_map_->find (id); - if (it != widget_actor_map_->end ()) + static WidgetActorMap::iterator it = widget_actor_map_->find(id); + if (it != widget_actor_map_->end()) { vtkProp3D *actor = vtkProp3D::SafeDownCast(it->second); CV_Assert("Widget is not 3D." && actor); @@ -439,22 +483,22 @@ void cv::viz::Viz3d::VizImpl::resetCameraViewpoint (const String &id) // Prevent a segfault if (!camera_pose) return; - vtkSmartPointer cam = renderer_->GetActiveCamera (); - cam->SetPosition (camera_pose->GetElement (0, 3), - camera_pose->GetElement (1, 3), - camera_pose->GetElement (2, 3)); + vtkSmartPointer cam = renderer_->GetActiveCamera(); + cam->SetPosition(camera_pose->GetElement(0, 3), + camera_pose->GetElement(1, 3), + camera_pose->GetElement(2, 3)); - cam->SetFocalPoint (camera_pose->GetElement (0, 3) - camera_pose->GetElement (0, 2), - camera_pose->GetElement (1, 3) - camera_pose->GetElement (1, 2), - camera_pose->GetElement (2, 3) - camera_pose->GetElement (2, 2)); + cam->SetFocalPoint(camera_pose->GetElement(0, 3) - camera_pose->GetElement(0, 2), + camera_pose->GetElement(1, 3) - camera_pose->GetElement(1, 2), + camera_pose->GetElement(2, 3) - camera_pose->GetElement(2, 2)); - cam->SetViewUp (camera_pose->GetElement (0, 1), - camera_pose->GetElement (1, 1), - camera_pose->GetElement (2, 1)); + cam->SetViewUp(camera_pose->GetElement(0, 1), + camera_pose->GetElement(1, 1), + camera_pose->GetElement(2, 1)); - renderer_->SetActiveCamera (cam); - renderer_->ResetCameraClippingRange (); - renderer_->Render (); + renderer_->SetActiveCamera(cam); + renderer_->ResetCameraClippingRange(); + renderer_->Render(); } /////////////////////////////////////////////////////////////////////////////////// @@ -493,53 +537,53 @@ void cv::viz::Viz3d::VizImpl::setRepresentation(int representation) } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::updateCells (vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points) +void cv::viz::Viz3d::VizImpl::updateCells(vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points) { // If no init cells and cells has not been initialized... if (!cells) - cells = vtkSmartPointer::New (); + cells = vtkSmartPointer::New(); // If we have less values then we need to recreate the array - if (cells->GetNumberOfTuples () < nr_points) + if (cells->GetNumberOfTuples() < nr_points) { - cells = vtkSmartPointer::New (); + cells = vtkSmartPointer::New(); // If init cells is given, and there's enough data in it, use it - if (initcells && initcells->GetNumberOfTuples () >= nr_points) + if (initcells && initcells->GetNumberOfTuples() >= nr_points) { - cells->DeepCopy (initcells); - cells->SetNumberOfComponents (2); - cells->SetNumberOfTuples (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); + cells->SetNumberOfComponents(2); + cells->SetNumberOfTuples(nr_points); + vtkIdType *cell = cells->GetPointer(0); // Fill it with 1s - std::fill_n (cell, nr_points * 2, 1); + 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::New (); - initcells->DeepCopy (cells); + initcells = vtkSmartPointer::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); + cells->SetNumberOfComponents(2); + cells->SetNumberOfTuples(nr_points); } } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setFullScreen (bool mode) +void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode) { if (window_) - window_->SetFullScreen (mode); + window_->SetFullScreen(mode); } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -549,6 +593,6 @@ cv::String cv::viz::Viz3d::VizImpl::getWindowName() const } ////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::Viz3d::VizImpl::setWindowPosition (int x, int y) { window_->SetPosition (x, y); } -void cv::viz::Viz3d::VizImpl::setWindowSize (int xw, int yw) { window_->SetSize (xw, yw); } +void cv::viz::Viz3d::VizImpl::setWindowPosition(int x, int y) { window_->SetPosition(x, y); } +void cv::viz::Viz3d::VizImpl::setWindowSize(int xw, int yw) { window_->SetSize(xw, yw); } cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); } diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 26d817a13..a6d5bd9ca 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -1,4 +1,53 @@ -#pragma once +/*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*/ + +#ifndef __OPENCV_VIZ_VIZ3D_IMPL_HPP__ +#define __OPENCV_VIZ_VIZ3D_IMPL_HPP__ #include #include "interactor_style.h" @@ -12,8 +61,8 @@ public: int ref_counter; - VizImpl (const String &name); - virtual ~VizImpl (); + VizImpl(const String &name); + virtual ~VizImpl(); void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); void removeWidget(const String &id); @@ -28,19 +77,19 @@ public: double getDesiredUpdateRate(); /** \brief Returns true when the user tried to close the window */ - bool wasStopped () const { if (interactor_ != NULL) return (stopped_); else return true; } + bool wasStopped() const { if (interactor_ != NULL) return (stopped_); else return true; } /** \brief Set the stopped flag back to false */ - void resetStoppedFlag () { if (interactor_ != NULL) stopped_ = false; } + void resetStoppedFlag() { if (interactor_ != NULL) stopped_ = false; } /** \brief Stop the interaction and close the visualizaton window. */ - void close () + void close() { stopped_ = true; if (interactor_) { interactor_->GetRenderWindow()->Finalize(); - interactor_->TerminateApp (); // This tends to close the window... + interactor_->TerminateApp(); // This tends to close the window... } } @@ -49,8 +98,7 @@ public: void setCamera(const Camera &camera); Camera getCamera() const; - /** \brief Reset the camera direction from {0, 0, 0} to the center_{x, y, z} of a given dataset. - * \param[in] id the point cloud object id (default: cloud) */ + /** \brief Reset the camera to a given widget */ void resetCameraViewpoint(const String& id); void resetCamera(); @@ -60,16 +108,16 @@ public: void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); - void saveScreenshot (const String &file); - void setWindowPosition (int x, int y); + void saveScreenshot(const String &file); + void setWindowPosition(int x, int y); Size getWindowSize() const; - void setWindowSize (int xw, int yw); - void setFullScreen (bool mode); + void setWindowSize(int xw, int yw); + void setFullScreen(bool mode); String getWindowName() const; - void setBackgroundColor (const Color& color); + void setBackgroundColor(const Color& color); - void spin (); - void spinOnce (int time = 1, bool force_redraw = false); + void spin(); + void spinOnce(int time = 1, bool force_redraw = false); void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); void registerMouseCallback(MouseCallback callback, void* cookie = 0); @@ -88,12 +136,12 @@ private: if (event_id != vtkCommand::TimerEvent) return; - int timer_id = *reinterpret_cast (call_data); + int timer_id = *reinterpret_cast(call_data); if (timer_id != right_timer_id) return; // Stop vtk loop and send notification to app to wake it up - viz_->interactor_->TerminateApp (); + viz_->interactor_->TerminateApp(); } int right_timer_id; VizImpl* viz_; @@ -101,17 +149,17 @@ private: struct ExitCallback : public vtkCommand { - static ExitCallback* New () + static ExitCallback* New() { return new ExitCallback; } - virtual void Execute (vtkObject*, unsigned long event_id, void*) + virtual void Execute(vtkObject*, unsigned long event_id, void*) { if (event_id == vtkCommand::ExitEvent) { viz_->stopped_ = true; viz_->interactor_->GetRenderWindow()->Finalize(); - viz_->interactor_->TerminateApp (); + viz_->interactor_->TerminateApp(); } } VizImpl* viz_; @@ -141,14 +189,14 @@ private: /** \brief Boolean that holds whether or not the camera parameters were manually initialized*/ bool camera_set_; - bool removeActorFromRenderer (const vtkSmartPointer &actor); + bool removeActorFromRenderer(const vtkSmartPointer &actor); /** \brief Internal method. Creates a vtk actor from a vtk polydata object. * \param[in] data the vtk polydata object to create an actor for * \param[out] actor the resultant vtk actor object * \param[in] use_scalars set scalar properties to the mapper if it exists in the data. Default: true. */ - void createActorFromVTKDataSet (const vtkSmartPointer &data, vtkSmartPointer &actor, bool use_scalars = true); + void createActorFromVTKDataSet(const vtkSmartPointer &data, vtkSmartPointer &actor, bool use_scalars = true); /** \brief Updates a set of cells (vtkIdTypeArray) if the number of points in a cloud changes * \param[out] cells the vtkIdTypeArray object (set of cells) to update @@ -158,7 +206,7 @@ private: * \param[in] nr_points the number of points in the new cloud. This dictates how many cells we need to * generate */ - void updateCells (vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points); + void updateCells(vtkSmartPointer &cells, vtkSmartPointer &initcells, vtkIdType nr_points); }; @@ -167,7 +215,7 @@ namespace cv { namespace viz { - vtkSmartPointer convertToVtkMatrix (const cv::Matx44f &m); + vtkSmartPointer convertToVtkMatrix(const cv::Matx44f &m); cv::Matx44f convertToMatx(const vtkSmartPointer& vtk_matrix); struct NanFilter @@ -186,12 +234,12 @@ namespace cv int s_chs = source.channels(); int m_chs = nan_mask.channels(); - for(int y = 0; y < source.rows; ++y) + for (int y = 0; y < source.rows; ++y) { const _Tp* srow = source.ptr<_Tp>(y); const _Msk* mrow = nan_mask.ptr<_Msk>(y); - for(int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) + for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) *output++ = _Out(srow); } @@ -207,12 +255,12 @@ namespace cv int s_chs = source.channels(); int m_chs = nan_mask.channels(); - for(int y = 0; y < source.rows; ++y) + for (int y = 0; y < source.rows; ++y) { const _Tp* srow = source.ptr<_Tp>(y); const _Msk* mrow = nan_mask.ptr<_Msk>(y); - for(int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) + for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) { *output = _Out(srow); @@ -338,6 +386,6 @@ namespace cv } }; } - } +#endif diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 5f52b9281..cdcae8792 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -1,3 +1,51 @@ +/*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" /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/viz/test/test_precomp.hpp b/modules/viz/test/test_precomp.hpp index 0e6b22cc5..9ca98d7b8 100644 --- a/modules/viz/test/test_precomp.hpp +++ b/modules/viz/test/test_precomp.hpp @@ -1,3 +1,51 @@ +/*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*/ + #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" # if defined __clang__ || defined __APPLE__ From 56f9168ac12855763d0d07c4f51c4c586c1904f0 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 8 Sep 2013 18:55:41 +0200 Subject: [PATCH 192/205] support VTK 6.0.0: cmakelist.txt might need to be refactored --- doc/tutorials/viz/creating_widgets.rst | 4 + modules/viz/CMakeLists.txt | 9 +- modules/viz/src/cloud_widgets.cpp | 34 ++++- modules/viz/src/shape_widgets.cpp | 122 ++++++++++++++---- modules/viz/src/viz3d_impl.cpp | 4 + modules/viz/src/viz3d_impl.hpp | 4 + modules/viz/src/widget.cpp | 16 ++- .../tutorial_code/viz/creating_widgets.cpp | 4 + 8 files changed, 168 insertions(+), 29 deletions(-) diff --git a/doc/tutorials/viz/creating_widgets.rst b/doc/tutorials/viz/creating_widgets.rst index a0e9da36c..59f1fdc4b 100644 --- a/doc/tutorials/viz/creating_widgets.rst +++ b/doc/tutorials/viz/creating_widgets.rst @@ -74,7 +74,11 @@ You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/ // Create mapper and actor vtkSmartPointer mapper = vtkSmartPointer::New(); + #if VTK_MAJOR_VERSION <= 5 mapper->SetInput(polyData); + #else + mapper->SetInputData(polyData); + #endif vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 84981f6a0..9a486fb82 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -13,6 +13,9 @@ endmacro() macro(find_vtk) find_package(VTK 5.10.0 REQUIRED) + if(NOT VTK_FOUND) + find_package(VTK 6.0.0 REQUIRED) + endif() if(VTK_FOUND) if (BUILD_SHARED_LIBS OR (NOT BUILD_SHARED_LIBS AND NOT VTK_BUILD_SHARED_LIBS)) find_qvtk() @@ -43,7 +46,11 @@ include_directories(src) ocv_define_module(viz opencv_core) if(DEFINED BUILD_opencv_viz AND BUILD_opencv_viz AND DEFINED HAVE_VTK AND HAVE_VTK) - target_link_libraries(opencv_viz vtkCommon vtkWidgets vtkFiltering vtkRendering) + 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() diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index b4ba5b3fe..ec6c20356 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -175,7 +175,11 @@ cv::viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) polydata->GetPointData()->SetScalars(scalars); vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInput(polydata); +#else + mapper->SetInputData(polydata); +#endif Vec3d minmax(scalars->GetRange()); mapper->SetScalarRange(minmax.val); @@ -206,7 +210,11 @@ cv::viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) vtkSmartPointer polydata = CreateCloudWidget::create(cloud, nr_points); vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInput(polydata); +#else + mapper->SetInputData(polydata); +#endif bool interpolation = (polydata && polydata->GetNumberOfCells() != polydata->GetNumberOfVerts()); @@ -327,7 +335,11 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget { // This is the first cloud vtkSmartPointer mapper_new = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper_new->SetInputConnection(poly_data->GetProducerPort()); +#else + mapper_new->SetInputData(poly_data); +#endif mapper_new->SetScalarRange(minmax.val); mapper_new->SetScalarModeToUsePointData(); @@ -349,8 +361,13 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget CV_Assert("Cloud Widget without data" && data); vtkSmartPointer appendFilter = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); appendFilter->AddInputConnection(poly_data->GetProducerPort()); +#else + appendFilter->AddInputData(data); + appendFilter->AddInputData(poly_data); +#endif mapper->SetInputConnection(appendFilter->GetOutputPort()); // Update the number of cloud points @@ -401,7 +418,11 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, InputArray _col vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); +#if VTK_MAJOR_VERSION <= 5 transform_filter->SetInputConnection(polydata->GetProducerPort()); +#else + transform_filter->SetInputData(polydata); +#endif transform_filter->Update(); vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); @@ -436,7 +457,11 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, const Color &co vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); +#if VTK_MAJOR_VERSION <= 5 transform_filter->SetInputConnection(polydata->GetProducerPort()); +#else + transform_filter->SetInputData(polydata); +#endif transform_filter->Update(); vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); @@ -571,7 +596,11 @@ cv::viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _n polyData->SetLines(lines); vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInput(polyData); +#else + mapper->SetInputData(polyData); +#endif mapper->SetColorModeToMapScalars(); mapper->SetScalarModeToUsePointData(); @@ -707,7 +736,6 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) poly_grid->Allocate(1, 1); poly_grid->InsertNextCell(polygon->GetCellType(), polygon->GetPointIds()); poly_grid->SetPoints(points); - poly_grid->Update(); if (scalars) poly_grid->GetPointData()->SetScalars(scalars); @@ -724,7 +752,11 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) actor->GetProperty()->ShadingOff(); vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInput(data); +#else + mapper->SetInputData(data); +#endif mapper->ImmediateModeRenderingOff(); vtkIdType numberOfCloudPoints = nr_points * 0.1; diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 844347717..45a653de5 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -66,7 +66,7 @@ cv::viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Co line->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(line->GetOutput()); + mapper->SetInputConnection(line->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -87,7 +87,7 @@ template<> cv::viz::LineWidget cv::viz::Widget::cast() struct cv::viz::PlaneWidget::SetSizeImpl { template - static vtkSmartPointer setSize(const Vec<_Tp, 3> ¢er, vtkSmartPointer poly_data, double size) + static vtkSmartPointer setSize(const Vec<_Tp, 3> ¢er, vtkSmartPointer poly_data_port, double size) { vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); @@ -96,11 +96,11 @@ struct cv::viz::PlaneWidget::SetSizeImpl transform->Translate(-center[0], -center[1], -center[2]); vtkSmartPointer transform_filter = vtkSmartPointer::New(); - transform_filter->SetInput(poly_data); + transform_filter->SetInputConnection(poly_data_port); transform_filter->SetTransform(transform); transform_filter->Update(); - return transform_filter->GetOutput(); + return transform_filter; } }; @@ -115,7 +115,7 @@ cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color & plane->GetOrigin(p_center.val); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(SetSizeImpl::setSize(p_center, plane->GetOutput(), size)); + mapper->SetInputConnection(SetSizeImpl::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -136,7 +136,7 @@ cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double plane->SetCenter(p_center[0], p_center[1], p_center[2]); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(SetSizeImpl::setSize(p_center, plane->GetOutput(), size)); + mapper->SetInputConnection(SetSizeImpl::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -165,7 +165,7 @@ cv::viz::SphereWidget::SphereWidget(const Point3f ¢er, float radius, int sph sphere->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(sphere->GetOutput()); + mapper->SetInputConnection(sphere->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -238,7 +238,7 @@ cv::viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, double transformPD->SetInputConnection(arrowSource->GetOutputPort()); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(transformPD->GetOutput()); + mapper->SetInputConnection(transformPD->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -274,7 +274,7 @@ cv::viz::CircleWidget::CircleWidget(const Point3f& pt, double radius, double thi tf->SetInputConnection(disk->GetOutputPort()); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(tf->GetOutput()); + mapper->SetInputConnection(tf->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -305,7 +305,7 @@ cv::viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3f tuber->SetNumberOfSides(numsides); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(tuber->GetOutput()); + mapper->SetInputConnection(tuber->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -330,13 +330,13 @@ cv::viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bo { vtkSmartPointer cube = vtkSmartPointer::New(); cube->SetBounds(pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); - mapper->SetInput(cube->GetOutput()); + mapper->SetInputConnection(cube->GetOutputPort()); } else { vtkSmartPointer cube = vtkSmartPointer::New(); cube->SetBounds(pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); - mapper->SetInput(cube->GetOutput()); + mapper->SetInputConnection(cube->GetOutputPort()); } vtkSmartPointer actor = vtkSmartPointer::New(); @@ -371,17 +371,25 @@ cv::viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale) axes_colors->InsertNextValue(1.0); vtkSmartPointer axes_data = axes->GetOutput(); +#if VTK_MAJOR_VERSION <= 5 axes_data->Update(); +#else + axes->Update(); +#endif axes_data->GetPointData()->SetScalars(axes_colors); vtkSmartPointer axes_tubes = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 axes_tubes->SetInput(axes_data); +#else + axes_tubes->SetInputData(axes_data); +#endif axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); axes_tubes->SetNumberOfSides(6); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUsePointData(); - mapper->SetInput(axes_tubes->GetOutput()); + mapper->SetInputConnection(axes_tubes->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -456,7 +464,11 @@ cv::viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &colo polyData->SetLines(cells); vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInput(polyData); +#else + mapper->SetInputData(polyData); +#endif vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -491,7 +503,11 @@ struct cv::viz::GridWidget::GridImpl // Extract the edges so we have the grid vtkSmartPointer filter = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 filter->SetInputConnection(grid->GetProducerPort()); +#else + filter->SetInputData(grid); +#endif filter->Update(); return filter->GetOutput(); } @@ -502,7 +518,11 @@ cv::viz::GridWidget::GridWidget(const Vec2i &dimensions, const Vec2d &spacing, c vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInputConnection(grid->GetProducerPort()); +#else + mapper->SetInputData(grid); +#endif vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -547,7 +567,11 @@ cv::viz::GridWidget::GridWidget(const Vec4f &coefs, const Vec2i &dimensions, con vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); +#if VTK_MAJOR_VERSION <= 5 transform_filter->SetInputConnection(grid->GetProducerPort()); +#else + transform_filter->SetInputData(grid); +#endif transform_filter->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); @@ -685,7 +709,11 @@ cv::viz::ImageOverlayWidget::ImageOverlayWidget(const Mat &image, const Rect &re // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip +#if VTK_MAJOR_VERSION <= 5 flipFilter->SetInputConnection(vtk_image->GetProducerPort()); +#else + flipFilter->SetInputData(vtk_image); +#endif flipFilter->Update(); // Scale the image based on the Rect @@ -728,7 +756,11 @@ void cv::viz::ImageOverlayWidget::setImage(const Mat &image) // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip +#if VTK_MAJOR_VERSION <= 5 flipFilter->SetInputConnection(vtk_image->GetProducerPort()); +#else + flipFilter->SetInputData(vtk_image); +#endif flipFilter->Update(); mapper->SetInputConnection(flipFilter->GetOutputPort()); @@ -754,7 +786,11 @@ cv::viz::Image3DWidget::Image3DWidget(const Mat &image, const Size &size) // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip +#if VTK_MAJOR_VERSION <= 5 flipFilter->SetInputConnection(vtk_image->GetProducerPort()); +#else + flipFilter->SetInputData(vtk_image); +#endif flipFilter->Update(); Vec3d plane_center(size.width * 0.5, size.height * 0.5, 0.0); @@ -802,7 +838,11 @@ cv::viz::Image3DWidget::Image3DWidget(const Vec3f &position, const Vec3f &normal // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip +#if VTK_MAJOR_VERSION <= 5 flipFilter->SetInputConnection(vtk_image->GetProducerPort()); +#else + flipFilter->SetInputData(vtk_image); +#endif flipFilter->Update(); vtkSmartPointer plane = vtkSmartPointer::New(); @@ -875,7 +915,11 @@ void cv::viz::Image3DWidget::setImage(const Mat &image) // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip +#if VTK_MAJOR_VERSION <= 5 flipFilter->SetInputConnection(vtk_image->GetProducerPort()); +#else + flipFilter->SetInputData(vtk_image); +#endif flipFilter->Update(); // Apply the texture @@ -915,7 +959,11 @@ struct cv::viz::CameraPositionWidget::ProjectImage // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip +#if VTK_MAJOR_VERSION <= 5 flipFilter->SetInputConnection(vtk_image->GetProducerPort()); +#else + flipFilter->SetInputData(vtk_image); +#endif flipFilter->Update(); Vec3d plane_center(0.0, 0.0, scale); @@ -962,7 +1010,7 @@ struct cv::viz::CameraPositionWidget::ProjectImage frustumSource->Update(); vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(frustumSource->GetOutput()); + filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); // Frustum needs to be textured or else it can't be combined with image @@ -1000,17 +1048,25 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) axes_colors->InsertNextValue(1.0); vtkSmartPointer axes_data = axes->GetOutput(); +#if VTK_MAJOR_VERSION <= 5 axes_data->Update(); +#else + axes->Update(); +#endif axes_data->GetPointData()->SetScalars(axes_colors); vtkSmartPointer axes_tubes = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 axes_tubes->SetInput(axes_data); +#else + axes_tubes->SetInputData(axes_data); +#endif axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); axes_tubes->SetNumberOfSides(6); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUsePointData(); - mapper->SetInput(axes_tubes->GetOutput()); + mapper->SetInputConnection(axes_tubes->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -1046,11 +1102,11 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, double sca frustumSource->Update(); vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(frustumSource->GetOutput()); + filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(filter->GetOutput()); + mapper->SetInputConnection(filter->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -1085,11 +1141,11 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double sca // Extract the edges so we have the grid vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(frustumSource->GetOutput()); + filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(filter->GetOutput()); + mapper->SetInputConnection(filter->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -1151,7 +1207,11 @@ struct cv::viz::TrajectoryWidget::ApplyPath transform->SetMatrix(mat_trans); vtkSmartPointer filter = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 filter->SetInput(new_data); +#else + filter->SetInputData(new_data); +#endif filter->SetTransform(transform); filter->Update(); @@ -1202,7 +1262,11 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i colors->FillComponent(2, color[0]); polyData->GetPointData()->SetScalars(colors); +#if VTK_MAJOR_VERSION <= 5 appendFilter->AddInputConnection(polyData->GetProducerPort()); +#else + appendFilter->AddInputData(polyData); +#endif } if ((~display_mode & 3) ^ TrajectoryWidget::DISPLAY_FRAMES) @@ -1222,11 +1286,19 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i axes_colors->InsertNextTuple3(0,0,255); vtkSmartPointer axes_data = axes->GetOutput(); +#if VTK_MAJOR_VERSION <= 5 axes_data->Update(); +#else + axes->Update(); +#endif axes_data->GetPointData()->SetScalars(axes_colors); vtkSmartPointer axes_tubes = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 axes_tubes->SetInput(axes_data); +#else + axes_tubes->SetInputData(axes_data); +#endif axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); axes_tubes->SetNumberOfSides(6); axes_tubes->Update(); @@ -1236,7 +1308,7 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUsePointData(); - mapper->SetInput(appendFilter->GetOutput()); + mapper->SetInputConnection(appendFilter->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -1272,14 +1344,14 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c // Extract the edges vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(frustumSource->GetOutput()); + filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); vtkSmartPointer appendFilter = vtkSmartPointer::New(); ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(appendFilter->GetOutput()); + mapper->SetInputConnection(appendFilter->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -1312,14 +1384,14 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c // Extract the edges vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInput(frustumSource->GetOutput()); + filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); vtkSmartPointer appendFilter = vtkSmartPointer::New(); ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetInput(appendFilter->GetOutput()); + mapper->SetInputConnection(appendFilter->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); @@ -1410,7 +1482,7 @@ cv::viz::SpheresTrajectoryWidget::SpheresTrajectoryWidget(const std::vector mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUseCellData(); - mapper->SetInput(appendFilter->GetOutput()); + mapper->SetInputConnection(appendFilter->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 52c6a45aa..1f01461c7 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -325,7 +325,11 @@ void cv::viz::Viz3d::VizImpl::createActorFromVTKDataSet(const vtkSmartPointer::New(); vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInput(data); +#else + mapper->SetInputData(data); +#endif if (use_scalars) { diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index a6d5bd9ca..7b1ddae6b 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -369,9 +369,13 @@ namespace cv { // Create the vtk image output->SetDimensions(image.cols, image.rows, 1); +#if VTK_MAJOR_VERSION <= 5 output->SetNumberOfScalarComponents(image.channels()); output->SetScalarTypeToUnsignedChar(); output->AllocateScalars(); +#else + output->AllocateScalars(VTK_UNSIGNED_CHAR, image.channels()); +#endif int i_chs = image.channels(); if (i_chs > 1) diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index cdcae8792..1742e854e 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -93,7 +93,11 @@ cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) vtkSmartPointer actor = vtkSmartPointer::New(); vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInput(data); +#else + mapper->SetInputData(data); +#endif vtkSmartPointer scalars = data->GetPointData()->GetScalars(); if (scalars) @@ -183,9 +187,13 @@ void cv::viz::Widget::setRenderingProperty(int property, double value) if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) { vtkSmartPointer normals = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 normals->SetInput(actor->GetMapper()->GetInput()); +#else + normals->SetInputData(actor->GetMapper()->GetInput()); +#endif normals->Update(); - vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInput(normals->GetOutput()); + vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInputConnection(normals->GetOutputPort()); } actor->GetProperty()->SetInterpolationToGouraud(); break; @@ -195,9 +203,13 @@ void cv::viz::Widget::setRenderingProperty(int property, double value) if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) { vtkSmartPointer normals = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 normals->SetInput(actor->GetMapper()->GetInput()); +#else + normals->SetInputData(actor->GetMapper()->GetInput()); +#endif normals->Update(); - vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInput(normals->GetOutput()); + vtkDataSetMapper::SafeDownCast(actor->GetMapper())->SetInputConnection(normals->GetOutputPort()); } actor->GetProperty()->SetInterpolationToPhong(); break; diff --git a/samples/cpp/tutorial_code/viz/creating_widgets.cpp b/samples/cpp/tutorial_code/viz/creating_widgets.cpp index 9d2b5a313..f5fdd92dd 100644 --- a/samples/cpp/tutorial_code/viz/creating_widgets.cpp +++ b/samples/cpp/tutorial_code/viz/creating_widgets.cpp @@ -74,7 +74,11 @@ TriangleWidget::TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Poi // Create mapper and actor vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 mapper->SetInput(polyData); +#else + mapper->SetInputData(polyData); +#endif vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); From 989509352458e08355e6ae2e0cbec40c7de7d2e7 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 8 Sep 2013 19:29:59 +0200 Subject: [PATCH 193/205] check if vtk 5.10.0 exists, if not require 6.0.0 --- modules/viz/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 9a486fb82..fbc41678e 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -12,7 +12,7 @@ macro(find_qvtk) endmacro() macro(find_vtk) - find_package(VTK 5.10.0 REQUIRED) + find_package(VTK 5.10.0) if(NOT VTK_FOUND) find_package(VTK 6.0.0 REQUIRED) endif() From 620d92824ce08ba2bbae80b168739a08e6b450c7 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Wed, 11 Sep 2013 13:23:57 +0200 Subject: [PATCH 194/205] hide VizMap and VizPair from public interface --- modules/viz/include/opencv2/viz.hpp | 7 +++--- modules/viz/src/precomp.hpp | 10 +++++++++ modules/viz/src/viz.cpp | 34 +++++++++++++++++++---------- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 61d92e307..bc0f73f86 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -57,9 +57,6 @@ namespace cv { namespace viz { - typedef std::map VizMap; - typedef std::pair VizPair; - //! takes coordiante frame data and builds transfrom to global coordinate frame CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); @@ -112,7 +109,9 @@ namespace cv static VizAccessor * instance_; static bool is_instantiated_; - static VizMap viz_map_; + + struct VizAccessorImpl; + static VizAccessorImpl * impl_; friend class Viz3d; }; diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 23b98d302..d12011dfd 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -134,6 +134,16 @@ namespace cv } #include "viz3d_impl.hpp" + +namespace cv +{ + namespace viz + { + typedef std::map VizMap; + typedef std::pair VizPair; + } +} + #include #include #include diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index db109ddd5..8941584d6 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -138,11 +138,23 @@ namespace cv cv::viz::VizAccessor * cv::viz::VizAccessor::instance_ = 0; bool cv::viz::VizAccessor::is_instantiated_ = false; -cv::viz::VizMap cv::viz::VizAccessor::viz_map_; +cv::viz::VizAccessor::VizAccessorImpl * cv::viz::VizAccessor::impl_ = 0; -cv::viz::VizAccessor::VizAccessor() {} +struct cv::viz::VizAccessor::VizAccessorImpl +{ + cv::viz::VizMap viz_map; +}; -cv::viz::VizAccessor::~VizAccessor() {} +cv::viz::VizAccessor::VizAccessor() { impl_ = new cv::viz::VizAccessor::VizAccessorImpl;} + +cv::viz::VizAccessor::~VizAccessor() +{ + if(impl_) + { + delete impl_; + impl_ = 0; + } +} cv::viz::VizAccessor & cv::viz::VizAccessor::getInstance() { @@ -170,8 +182,8 @@ cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name) String name; generateWindowName(window_name, name); - VizMap::iterator vm_itr = viz_map_.find(name); - bool exists = vm_itr != viz_map_.end(); + VizMap::iterator vm_itr = impl_->viz_map.find(name); + bool exists = vm_itr != impl_->viz_map.end(); if (exists) return vm_itr->second; else return Viz3d(window_name); } @@ -179,10 +191,10 @@ cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name) void cv::viz::VizAccessor::add(Viz3d window) { String window_name = window.getWindowName(); - VizMap::iterator vm_itr = viz_map_.find(window_name); - bool exists = vm_itr != viz_map_.end(); + VizMap::iterator vm_itr = impl_->viz_map.find(window_name); + bool exists = vm_itr != impl_->viz_map.end(); if (exists) return ; - viz_map_.insert(VizPair(window_name, window)); + impl_->viz_map.insert(VizPair(window_name, window)); } void cv::viz::VizAccessor::remove(const String &window_name) @@ -191,10 +203,10 @@ void cv::viz::VizAccessor::remove(const String &window_name) String name; generateWindowName(window_name, name); - VizMap::iterator vm_itr = viz_map_.find(name); - bool exists = vm_itr != viz_map_.end(); + VizMap::iterator vm_itr = impl_->viz_map.find(name); + bool exists = vm_itr != impl_->viz_map.end(); if (!exists) return ; - viz_map_.erase(vm_itr); + impl_->viz_map.erase(vm_itr); } void cv::viz::VizAccessor::generateWindowName(const String &window_name, String &output) From 3f27ba54e0c134c7ba1c23b9d1d4da4e380fe1bc Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Thu, 12 Sep 2013 19:23:05 +0200 Subject: [PATCH 195/205] re-render the scene after changing camera properties --- modules/viz/src/viz3d_impl.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 1f01461c7..5c91ec72e 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -382,6 +382,9 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) transform->SetMatrix(convertToVtkMatrix(proj_mat * old_proj_mat.inv())); active_camera.SetUserTransform(transform); transform->Delete(); + + renderer_->ResetCameraClippingRange(); + renderer_->Render(); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -418,6 +421,9 @@ void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) camera.SetPosition(pos_vec[0], pos_vec[1], pos_vec[2]); camera.SetFocalPoint(focal_vec[0], focal_vec[1], focal_vec[2]); camera.SetViewUp(up_vec[0], up_vec[1], up_vec[2]); + + renderer_->ResetCameraClippingRange(); + renderer_->Render(); } ///////////////////////////////////////////////////////////////////////////////////////////// From f570b3e18d27d7e5139327890fc274b0933952a6 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 15 Sep 2013 11:24:20 +0200 Subject: [PATCH 196/205] cmake check if VTK version is lower than 5, and give fatal error if it is --- modules/viz/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index fbc41678e..74c9fd116 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -12,9 +12,9 @@ macro(find_qvtk) endmacro() macro(find_vtk) - find_package(VTK 5.10.0) - if(NOT VTK_FOUND) - find_package(VTK 6.0.0 REQUIRED) + 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)) From c31fb8ffff9b5ec033124f5ea9a821d86ff66623 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Sun, 15 Sep 2013 16:26:53 +0200 Subject: [PATCH 197/205] rename widgets from *Widgets to W* --- doc/tutorials/viz/creating_widgets.rst | 18 +- doc/tutorials/viz/transformations.rst | 14 +- doc/tutorials/viz/widget_pose.rst | 20 +- modules/viz/doc/widget.rst | 488 +++++++++--------- modules/viz/include/opencv2/viz/widgets.hpp | 146 +++--- modules/viz/src/cloud_widgets.cpp | 38 +- modules/viz/src/shape_widgets.cpp | 146 +++--- modules/viz/test/test_viz3d.cpp | 309 ++++------- .../tutorial_code/viz/creating_widgets.cpp | 8 +- .../cpp/tutorial_code/viz/transformations.cpp | 8 +- samples/cpp/tutorial_code/viz/widget_pose.cpp | 6 +- 11 files changed, 545 insertions(+), 656 deletions(-) diff --git a/doc/tutorials/viz/creating_widgets.rst b/doc/tutorials/viz/creating_widgets.rst index 59f1fdc4b..fd002a8a2 100644 --- a/doc/tutorials/viz/creating_widgets.rst +++ b/doc/tutorials/viz/creating_widgets.rst @@ -37,19 +37,19 @@ You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/ using namespace std; /** - * @class TriangleWidget + * @class WTriangle * @brief Defining our own 3D Triangle widget */ - class TriangleWidget : public viz::Widget3D + class WTriangle : public viz::Widget3D { public: - TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); }; /** - * @function TriangleWidget::TriangleWidget + * @function WTriangle::WTriangle */ - TriangleWidget::TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color) + WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color) { // Create a triangle vtkSmartPointer points = vtkSmartPointer::New(); @@ -99,7 +99,7 @@ You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/ viz::Viz3d myWindow("Creating Widgets"); /// Create a triangle widget - TriangleWidget tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); + WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); /// Show widget in the visualizer window myWindow.showWidget("TRIANGLE", tw); @@ -119,10 +119,10 @@ Here is the general structure of the program: .. code-block:: cpp - class TriangleWidget : public viz::Widget3D + class WTriangle : public viz::Widget3D { public: - TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); }; * Assign a VTK actor to the widget. @@ -144,7 +144,7 @@ Here is the general structure of the program: .. code-block:: cpp /// Create a triangle widget - TriangleWidget tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); + WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); /// Show widget in the visualizer window myWindow.showWidget("TRIANGLE", tw); diff --git a/doc/tutorials/viz/transformations.rst b/doc/tutorials/viz/transformations.rst index 0639a0d34..0bcc7db60 100644 --- a/doc/tutorials/viz/transformations.rst +++ b/doc/tutorials/viz/transformations.rst @@ -67,7 +67,7 @@ You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/ viz::Viz3d myWindow("Coordinate Frame"); /// Add coordinate axes - myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); /// Let's assume camera has the following properties Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); @@ -81,7 +81,7 @@ You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/ /// Create a cloud widget. Mat bunny_cloud = cvcloud_load(); - viz::CloudWidget cloud_widget(bunny_cloud, viz::Color::green()); + viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); /// Pose of the widget in camera frame Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); @@ -91,8 +91,8 @@ You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/ /// Visualize camera frame if (!camera_pov) { - viz::CameraPositionWidget cpw(0.5); // Coordinate axes - viz::CameraPositionWidget cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + viz::WCameraPosition cpw(0.5); // Coordinate axes + viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum myWindow.showWidget("CPW", cpw, cam_pose); myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); } @@ -147,7 +147,7 @@ Here is the general structure of the program: /// Create a cloud widget. Mat bunny_cloud = cvcloud_load(); - viz::CloudWidget cloud_widget(bunny_cloud, viz::Color::green()); + viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); * Given the pose in camera coordinate system, estimate the global pose. @@ -165,8 +165,8 @@ Here is the general structure of the program: /// Visualize camera frame if (!camera_pov) { - viz::CameraPositionWidget cpw(0.5); // Coordinate axes - viz::CameraPositionWidget cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + viz::WCameraPosition cpw(0.5); // Coordinate axes + viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum myWindow.showWidget("CPW", cpw, cam_pose); myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); } diff --git a/doc/tutorials/viz/widget_pose.rst b/doc/tutorials/viz/widget_pose.rst index 22dfb2867..a0cb00f5f 100644 --- a/doc/tutorials/viz/widget_pose.rst +++ b/doc/tutorials/viz/widget_pose.rst @@ -37,16 +37,16 @@ You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/ viz::Viz3d myWindow("Coordinate Frame"); /// Add coordinate axes - myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); /// Add line to represent (1,1,1) axis - viz::LineWidget axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f)); - axis.setRenderingProperty(viz::VIZ_LINE_WIDTH, 4.0); + 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::CubeWidget cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue()); - cube_widget.setRenderingProperty(viz::VIZ_LINE_WIDTH, 4.0); + 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); @@ -97,15 +97,15 @@ Here is the general structure of the program: .. code-block:: cpp /// Add coordinate axes - myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); * Display a line representing the axis (1,1,1). .. code-block:: cpp /// Add line to represent (1,1,1) axis - viz::LineWidget axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f)); - axis.setRenderingProperty(viz::VIZ_LINE_WIDTH, 4.0); + 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. @@ -113,8 +113,8 @@ Here is the general structure of the program: .. code-block:: cpp /// Construct a cube widget - viz::CubeWidget cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue()); - cube_widget.setRenderingProperty(viz::VIZ_LINE_WIDTH, 4.0); + 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); myWindow.showWidget("Cube Widget", cube_widget); * Create rotation matrix from rodrigues vector diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index ef1e82868..e133eb117 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -14,7 +14,7 @@ and modify the widget without re-adding the widget. ... /// Create a cloud widget - viz::CloudWidget cw(cloud, viz::Color::red()); + viz::WCloud cw(cloud, viz::Color::red()); /// Display it in a window myWindow.showWidget("CloudWidget1", cw); /// Modify it, and it will be modified in the window. @@ -118,9 +118,9 @@ Casts a widget to another. .. code-block:: cpp // Create a sphere widget - viz::SphereWidget sw(Point3f(0.0f,0.0f,0.0f), 0.5f); + viz::WSphere sw(Point3f(0.0f,0.0f,0.0f), 0.5f); // Cast sphere widget to cloud widget - viz::CloudWidget cw = sw.cast(); + viz::WCloud cw = sw.cast(); .. note:: 3D Widgets can only be cast to 3D Widgets. 2D Widgets can only be cast to 2D Widgets. @@ -231,100 +231,100 @@ Sets the color of the widget. :param color: color of type :ocv:class:`Color` -viz::LineWidget ---------------- -.. ocv:class:: LineWidget +viz::WLine +---------- +.. ocv:class:: WLine This 3D Widget defines a finite line. :: - class CV_EXPORTS LineWidget : public Widget3D + class CV_EXPORTS WLine : public Widget3D { public: - LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); }; -viz::LineWidget::LineWidget ---------------------------- -Constructs a LineWidget. +viz::WLine::WLine +----------------- +Constructs a WLine. -.. ocv:function:: LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()) +.. ocv:function:: WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()) :param pt1: Start point of the line. :param pt2: End point of the line. :param color: :ocv:class:`Color` of the line. -viz::PlaneWidget ----------------- -.. ocv:class:: PlaneWidget +viz::WPlane +----------- +.. ocv:class:: WPlane This 3D Widget defines a finite plane. :: - class CV_EXPORTS PlaneWidget : public Widget3D + class CV_EXPORTS WPlane : public Widget3D { public: - PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); - PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); + 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()); private: /* hidden */ }; -viz::PlaneWidget::PlaneWidget ------------------------------ -Constructs a PlaneWidget. +viz::WPlane::WPlane +------------------- +Constructs a WPlane. -.. ocv:function:: PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()) +.. ocv:function:: WPlane(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()) :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. :param size: Size of the plane. :param color: :ocv:class:`Color` of the plane. -.. ocv:function:: PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()) +.. ocv:function:: WPlane(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()) :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. :param pt: Position of the plane. :param size: Size of the plane. :param color: :ocv:class:`Color` of the plane. -viz::SphereWidget ------------------ -.. ocv:class:: SphereWidget +viz::WSphere +------------ +.. ocv:class:: WSphere This 3D Widget defines a sphere. :: - class CV_EXPORTS SphereWidget : public Widget3D + class CV_EXPORTS WSphere : public Widget3D { public: - SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) + WSphere(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) }; -viz::SphereWidget::SphereWidget -------------------------------- -Constructs a SphereWidget. +viz::WSphere::WSphere +--------------------- +Constructs a WSphere. -.. ocv:function:: SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) +.. ocv:function:: WSphere(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()) :param center: Center of the sphere. :param radius: Radius of the sphere. :param sphere_resolution: Resolution of the sphere. :param color: :ocv:class:`Color` of the sphere. -viz::ArrowWidget +viz::WArrow ---------------- -.. ocv:class:: ArrowWidget +.. ocv:class:: WArrow This 3D Widget defines an arrow. :: - class CV_EXPORTS ArrowWidget : public Widget3D + class CV_EXPORTS WArrow : public Widget3D { public: - ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); + WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); }; -viz::ArrowWidget::ArrowWidget +viz::WArrow::WArrow ----------------------------- -Constructs an ArrowWidget. +Constructs an WArrow. -.. ocv:function:: ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()) +.. ocv:function:: WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()) :param pt1: Start point of the arrow. :param pt2: End point of the arrow. @@ -333,46 +333,46 @@ Constructs an ArrowWidget. Arrow head is located at the end point of the arrow. -viz::CircleWidget +viz::WCircle ----------------- -.. ocv:class:: CircleWidget +.. ocv:class:: WCircle This 3D Widget defines a circle. :: - class CV_EXPORTS CircleWidget : public Widget3D + class CV_EXPORTS WCircle : public Widget3D { public: - CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); + WCircle(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); }; -viz::CircleWidget::CircleWidget +viz::WCircle::WCircle ------------------------------- -Constructs a CircleWidget. +Constructs a WCircle. -.. ocv:function:: CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()) +.. ocv:function:: WCircle(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()) :param pt: Center of the circle. :param radius: Radius of the circle. :param thickness: Thickness of the circle. :param color: :ocv:class:`Color` of the circle. -viz::CylinderWidget -------------------- -.. ocv:class:: CylinderWidget +viz::WCylinder +-------------- +.. ocv:class:: WCylinder This 3D Widget defines a cylinder. :: - class CV_EXPORTS CylinderWidget : public Widget3D + class CV_EXPORTS WCylinder : public Widget3D { public: - CylinderWidget(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, double radius, int numsides = 30, const Color &color = Color::white()); }; -viz::CylinderWidget::CylinderWidget +viz::WCylinder::WCylinder ----------------------------------- -Constructs a CylinderWidget. +Constructs a WCylinder. -.. ocv:function:: CylinderWidget(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()) +.. ocv:function:: WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()) :param pt_on_axis: A point on the axis of the cylinder. :param axis_direction: Direction of the axis of the cylinder. @@ -380,23 +380,23 @@ Constructs a CylinderWidget. :param numsides: Resolution of the cylinder. :param color: :ocv:class:`Color` of the cylinder. -viz::CubeWidget ---------------- -.. ocv:class:: CubeWidget +viz::WCube +---------- +.. ocv:class:: WCube This 3D Widget defines a cube. :: - class CV_EXPORTS CubeWidget : public Widget3D + class CV_EXPORTS WCube : public Widget3D { public: - CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); + WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); }; -viz::CubeWidget::CubeWidget +viz::WCube::WCube --------------------------- -Constructs a CudeWidget. +Constructs a WCube. -.. ocv:function:: CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()) +.. ocv:function:: WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()) :param pt_min: Specifies minimum point of the bounding box. :param pt_max: Specifies maximum point of the bounding box. @@ -407,104 +407,104 @@ Constructs a CudeWidget. :alt: Cube Widget :align: center -viz::CoordinateSystemWidget ---------------------------- -.. ocv:class:: CoordinateSystemWidget +viz::WCoordinateSystem +---------------------- +.. ocv:class:: WCoordinateSystem This 3D Widget represents a coordinate system. :: - class CV_EXPORTS CoordinateSystemWidget : public Widget3D + class CV_EXPORTS WCoordinateSystem : public Widget3D { public: - CoordinateSystemWidget(double scale = 1.0); + WCoordinateSystem(double scale = 1.0); }; -viz::CoordinateSystemWidget::CoordinateSystemWidget +viz::WCoordinateSystem::WCoordinateSystem --------------------------------------------------- -Constructs a CoordinateSystemWidget. +Constructs a WCoordinateSystem. -.. ocv:function:: CoordinateSystemWidget(double scale = 1.0) +.. ocv:function:: WCoordinateSystem(double scale = 1.0) :param scale: Determines the size of the axes. -viz::PolyLineWidget -------------------- -.. ocv:class:: PolyLineWidget +viz::WPolyLine +-------------- +.. ocv:class:: WPolyLine This 3D Widget defines a poly line. :: - class CV_EXPORTS PolyLineWidget : public Widget3D + class CV_EXPORTS WPolyLine : public Widget3D { public: - PolyLineWidget(InputArray points, const Color &color = Color::white()); + WPolyLine(InputArray points, const Color &color = Color::white()); private: /* hidden */ }; -viz::PolyLineWidget::PolyLineWidget +viz::WPolyLine::WPolyLine ----------------------------------- -Constructs a PolyLineWidget. +Constructs a WPolyLine. -.. ocv:function:: PolyLineWidget(InputArray points, const Color &color = Color::white()) +.. ocv:function:: WPolyLine(InputArray points, const Color &color = Color::white()) :param points: Point set. :param color: :ocv:class:`Color` of the poly line. -viz::GridWidget ---------------- -.. ocv:class:: GridWidget +viz::WGrid +---------- +.. ocv:class:: WGrid This 3D Widget defines a grid. :: - class CV_EXPORTS GridWidget : public Widget3D + class CV_EXPORTS WGrid : public Widget3D { public: //! Creates grid at the origin - GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); //! Creates grid based on the plane equation - GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); private: /* hidden */ }; -viz::GridWidget::GridWidget +viz::WGrid::WGrid --------------------------- -Constructs a GridWidget. +Constructs a WGrid. -.. ocv:function:: GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) +.. ocv:function:: WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) :param dimensions: Number of columns and rows, respectively. :param spacing: Size of each column and row, respectively. :param color: :ocv:class:`Color` of the grid. -.. ocv:function: GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) +.. ocv:function: WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) :param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. :param dimensions: Number of columns and rows, respectively. :param spacing: Size of each column and row, respectively. :param color: :ocv:class:`Color` of the grid. -viz::Text3DWidget ------------------ -.. ocv:class:: Text3DWidget +viz::WText3D +------------ +.. ocv:class:: WText3D This 3D Widget represents 3D text. The text always faces the camera. :: - class CV_EXPORTS Text3DWidget : public Widget3D + class CV_EXPORTS WText3D : public Widget3D { public: - Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, double face_camera = true, const Color &color = Color::white()); + WText3D(const String &text, const Point3f &position, double text_scale = 1.0, double face_camera = true, const Color &color = Color::white()); void setText(const String &text); String getText() const; }; -viz::Text3DWidget::Text3DWidget +viz::WText3D::WText3D ------------------------------- -Constructs a Text3DWidget. +Constructs a WText3D. -.. ocv:function:: Text3DWidget(const String &text, const Point3f &position, double text_scale = 1.0, double face_camera = true, const Color &color = Color::white()) +.. ocv:function:: WText3D(const String &text, const Point3f &position, double text_scale = 1.0, double face_camera = true, const Color &color = Color::white()) :param text: Text content of the widget. :param position: Position of the text. @@ -512,126 +512,84 @@ Constructs a Text3DWidget. :param face_camera: If true, text always faces the camera. :param color: :ocv:class:`Color` of the text. -viz::Text3DWidget::setText --------------------------- +viz::WText3D::setText +--------------------- Sets the text content of the widget. .. ocv:function:: void setText(const String &text) :param text: Text content of the widget. -viz::Text3DWidget::getText --------------------------- +viz::WText3D::getText +--------------------- Returns the current text content of the widget. .. ocv:function:: String getText() const -viz::TextWidget ---------------- -.. ocv:class:: TextWidget +viz::WText +---------- +.. ocv:class:: WText This 2D Widget represents text overlay. :: - class CV_EXPORTS TextWidget : public Widget2D + class CV_EXPORTS WText : public Widget2D { public: - TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); + WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); void setText(const String &text); String getText() const; }; -viz::TextWidget::TextWidget ---------------------------- -Constructs a TextWidget. +viz::WText::WText +----------------- +Constructs a WText. -.. ocv:function:: TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()) +.. ocv:function:: WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()) :param text: Text content of the widget. :param pos: Position of the text. :param font_size: Font size. :param color: :ocv:class:`Color` of the text. -viz::TextWidget::setText ------------------------- +viz::WText::setText +------------------- Sets the text content of the widget. .. ocv:function:: void setText(const String &text) :param text: Text content of the widget. -viz::TextWidget::getText ------------------------- +viz::WText::getText +------------------- Returns the current text content of the widget. .. ocv:function:: String getText() const -viz::ImageOverlayWidget ------------------------ -.. ocv:class:: ImageOverlayWidget +viz::WImageOverlay +------------------ +.. ocv:class:: WImageOverlay This 2D Widget represents an image overlay. :: - class CV_EXPORTS ImageOverlayWidget : public Widget2D + class CV_EXPORTS WImageOverlay : public Widget2D { public: - ImageOverlayWidget(const Mat &image, const Rect &rect); + WImageOverlay(const Mat &image, const Rect &rect); void setImage(const Mat &image); }; -viz::ImageOverlayWidget::ImageOverlayWidget -------------------------------------------- -Constructs an ImageOverlayWidget. +viz::WImageOverlay::WImageOverlay +--------------------------------- +Constructs an WImageOverlay. -.. ocv:function:: ImageOverlayWidget(const Mat &image, const Rect &rect) +.. ocv:function:: WImageOverlay(const Mat &image, const Rect &rect) :param image: BGR or Gray-Scale image. :param rect: Image is scaled and positioned based on rect. -viz::ImageOverlayWidget::setImage ---------------------------------- -Sets the image content of the widget. - -.. ocv:function:: void setImage(const Mat &image) - - :param image: BGR or Gray-Scale image. - -viz::Image3DWidget ------------------- -.. ocv:class:: Image3DWidget - -This 3D Widget represents an image in 3D space. :: - - class CV_EXPORTS Image3DWidget : public Widget3D - { - public: - //! Creates 3D image at the origin - Image3DWidget(const Mat &image, const Size &size); - //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation - Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); - - void setImage(const Mat &image); - }; - -viz::Image3DWidget::Image3DWidget ---------------------------------- -Constructs an Image3DWidget. - -.. ocv:function:: Image3DWidget(const Mat &image, const Size &size) - - :param image: BGR or Gray-Scale image. - :param size: Size of the image. - -.. ocv:function:: Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) - - :param position: Position of the image. - :param normal: Normal of the plane that represents the image. - :param up_vector: Determines orientation of the image. - :param image: BGR or Gray-Scale image. - :param size: Size of the image. - -viz::Image3DWidget::setImage +viz::WImageOverlay::setImage ---------------------------- Sets the image content of the widget. @@ -639,34 +597,76 @@ Sets the image content of the widget. :param image: BGR or Gray-Scale image. -viz::CameraPositionWidget -------------------------- -.. ocv:class:: CameraPositionWidget +viz::WImage3D +------------- +.. ocv:class:: WImage3D + +This 3D Widget represents an image in 3D space. :: + + class CV_EXPORTS WImage3D : public Widget3D + { + public: + //! Creates 3D image at the origin + WImage3D(const Mat &image, const Size &size); + //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation + WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); + + void setImage(const Mat &image); + }; + +viz::WImage3D::WImage3D +----------------------- +Constructs an WImage3D. + +.. ocv:function:: WImage3D(const Mat &image, const Size &size) + + :param image: BGR or Gray-Scale image. + :param size: Size of the image. + +.. ocv:function:: WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) + + :param position: Position of the image. + :param normal: Normal of the plane that represents the image. + :param up_vector: Determines orientation of the image. + :param image: BGR or Gray-Scale image. + :param size: Size of the image. + +viz::WImage3D::setImage +----------------------- +Sets the image content of the widget. + +.. ocv:function:: void setImage(const Mat &image) + + :param image: BGR or Gray-Scale image. + +viz::WCameraPosition +-------------------- +.. ocv:class:: WCameraPosition This 3D Widget represents camera position in a scene by its axes or viewing frustum. :: - class CV_EXPORTS CameraPositionWidget : public Widget3D + class CV_EXPORTS WCameraPosition : public Widget3D { public: //! Creates camera coordinate frame (axes) at the origin - CameraPositionWidget(double scale = 1.0); + WCameraPosition(double scale = 1.0); //! Creates frustum based on the intrinsic marix K at the origin - CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + WCameraPosition(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); //! Creates frustum based on the field of view at the origin - CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + WCameraPosition(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); //! Creates frustum and display given image at the far plane - CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + WCameraPosition(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); //! Creates frustum and display given image at the far plane - CameraPositionWidget(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + WCameraPosition(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()); }; -viz::CameraPositionWidget::CameraPositionWidget ------------------------------------------------ -Constructs a CameraPositionWidget. +viz::WCameraPosition::WCameraPosition +------------------------------------- +Constructs a WCameraPosition. - **Display camera coordinate frame.** - .. ocv:function:: CameraPositionWidget(double scale = 1.0) + .. ocv:function:: WCameraPosition(double scale = 1.0) Creates camera coordinate frame at the origin. @@ -676,7 +676,7 @@ Constructs a CameraPositionWidget. - **Display the viewing frustum.** - .. ocv:function:: CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) + .. ocv:function:: WCameraPosition(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) :param K: Intrinsic matrix of the camera. :param scale: Scale of the frustum. @@ -684,7 +684,7 @@ Constructs a CameraPositionWidget. Creates viewing frustum of the camera based on its intrinsic matrix K. - .. ocv:function:: CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) + .. ocv:function:: WCameraPosition(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) :param fov: Field of view of the camera (horizontal, vertical). :param scale: Scale of the frustum. @@ -698,7 +698,7 @@ Constructs a CameraPositionWidget. - **Display image on the far plane of the viewing frustum.** - .. ocv:function:: CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()) + .. ocv:function:: WCameraPosition(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()) :param K: Intrinsic matrix of the camera. :param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum. @@ -707,7 +707,7 @@ Constructs a CameraPositionWidget. Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. - .. ocv:function:: CameraPositionWidget(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()) + .. ocv:function:: WCameraPosition(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()) :param fov: Field of view of the camera (horizontal, vertical). :param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum. @@ -720,33 +720,33 @@ Constructs a CameraPositionWidget. :alt: Camera viewing frustum with image :align: center -viz::TrajectoryWidget ---------------------- -.. ocv:class:: TrajectoryWidget +viz::WTrajectory +---------------- +.. ocv:class:: WTrajectory This 3D Widget represents a trajectory. :: - class CV_EXPORTS TrajectoryWidget : public Widget3D + class CV_EXPORTS WTrajectory : public Widget3D { public: enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; //! Displays trajectory of the given path either by coordinate frames or polyline - TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); + WTrajectory(const std::vector &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); //! Displays trajectory of the given path by frustums - TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + WTrajectory(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); //! Displays trajectory of the given path by frustums - TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + WTrajectory(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); private: /* hidden */ }; -viz::TrajectoryWidget::TrajectoryWidget ---------------------------------------- -Constructs a TrajectoryWidget. +viz::WTrajectory::WTrajectory +----------------------------- +Constructs a WTrajectory. -.. ocv:function:: TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0) +.. ocv:function:: WTrajectory(const std::vector &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0) :param path: List of poses on a trajectory. :param display_mode: Display mode. This can be DISPLAY_PATH, DISPLAY_FRAMES, DISPLAY_PATH & DISPLAY_FRAMES. @@ -759,7 +759,7 @@ Constructs a TrajectoryWidget. * DISPLAY_FRAMES : Displays coordinate frames at each pose. * DISPLAY_PATH & DISPLAY_FRAMES : Displays both poly line and coordinate frames. -.. ocv:function:: TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) +.. ocv:function:: WTrajectory(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) :param path: List of poses on a trajectory. :param K: Intrinsic matrix of the camera. @@ -768,7 +768,7 @@ Constructs a TrajectoryWidget. Displays frustums at each pose of the trajectory. -.. ocv:function:: TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) +.. ocv:function:: WTrajectory(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) :param path: List of poses on a trajectory. :param fov: Field of view of the camera (horizontal, vertical). @@ -777,26 +777,26 @@ Constructs a TrajectoryWidget. Displays frustums at each pose of the trajectory. -viz::SpheresTrajectoryWidget ----------------------------- -.. ocv:class:: SpheresTrajectoryWidget +viz::WSpheresTrajectory +----------------------- +.. ocv:class:: WSpheresTrajectory This 3D Widget represents a trajectory using spheres and lines, where spheres represent the positions of the camera, and lines represent the direction from previous position to the current. :: - class CV_EXPORTS SpheresTrajectoryWidget : public Widget3D + class CV_EXPORTS WSpheresTrajectory : public Widget3D { public: - SpheresTrajectoryWidget(const std::vector &path, float line_length = 0.05f, + WSpheresTrajectory(const std::vector &path, float line_length = 0.05f, double init_sphere_radius = 0.021, sphere_radius = 0.007, Color &line_color = Color::white(), const Color &sphere_color = Color::white()); }; -viz::SpheresTrajectoryWidget::SpheresTrajectoryWidget ------------------------------------------------------ -Constructs a SpheresTrajectoryWidget. +viz::WSpheresTrajectory::WSpheresTrajectory +------------------------------------------- +Constructs a WSpheresTrajectory. -.. ocv:function:: SpheresTrajectoryWidget(const std::vector &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()) +.. ocv:function:: WSpheresTrajectory(const std::vector &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()) :param path: List of poses on a trajectory. :param line_length: Length of the lines. @@ -805,36 +805,36 @@ Constructs a SpheresTrajectoryWidget. :param line_color: :ocv:class:`Color` of the lines. :param sphere_color: :ocv:class:`Color` of the spheres. -viz::CloudWidget ----------------- -.. ocv:class:: CloudWidget +viz::WCloud +----------- +.. ocv:class:: WCloud This 3D Widget defines a point cloud. :: - class CV_EXPORTS CloudWidget : public Widget3D + class CV_EXPORTS WCloud : public Widget3D { public: //! Each point in cloud is mapped to a color in colors - CloudWidget(InputArray cloud, InputArray colors); + WCloud(InputArray cloud, InputArray colors); //! All points in cloud have the same color - CloudWidget(InputArray cloud, const Color &color = Color::white()); + WCloud(InputArray cloud, const Color &color = Color::white()); private: /* hidden */ }; -viz::CloudWidget::CloudWidget ------------------------------ -Constructs a CloudWidget. +viz::WCloud::WCloud +------------------- +Constructs a WCloud. -.. ocv:function:: CloudWidget(InputArray cloud, InputArray colors) +.. ocv:function:: WCloud(InputArray cloud, InputArray colors) :param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param colors: Set of colors. It has to be of the same size with cloud. Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). -.. ocv:function:: CloudWidget(InputArray cloud, const Color &color = Color::white()) +.. ocv:function:: WCloud(InputArray cloud, const Color &color = Color::white()) :param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param color: A single :ocv:class:`Color` for the whole cloud. @@ -843,16 +843,16 @@ Constructs a CloudWidget. .. note:: In case there are four channels in the cloud, fourth channel is ignored. -viz::CloudCollectionWidget --------------------------- -.. ocv:class:: CloudCollectionWidget +viz::WCloudCollection +--------------------- +.. ocv:class:: WCloudCollection This 3D Widget defines a collection of clouds. :: - class CV_EXPORTS CloudCollectionWidget : public Widget3D + class CV_EXPORTS WCloudCollection : public Widget3D { public: - CloudCollectionWidget(); + WCloudCollection(); //! Each point in cloud is mapped to a color in colors void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); @@ -863,14 +863,14 @@ This 3D Widget defines a collection of clouds. :: /* hidden */ }; -viz::CloudCollectionWidget::CloudCollectionWidget -------------------------------------------------- -Constructs a CloudCollectionWidget. +viz::WCloudCollection::WCloudCollection +--------------------------------------- +Constructs a WCloudCollection. -.. ocv:function:: CloudCollectionWidget() +.. ocv:function:: WCloudCollection() -viz::CloudCollectionWidget::addCloud ------------------------------------- +viz::WCloudCollection::addCloud +------------------------------- Adds a cloud to the collection. .. ocv:function:: void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()) @@ -891,26 +891,26 @@ Adds a cloud to the collection. .. note:: In case there are four channels in the cloud, fourth channel is ignored. -viz::CloudNormalsWidget ------------------------ -.. ocv:class:: CloudNormalsWidget +viz::WCloudNormals +------------------ +.. ocv:class:: WCloudNormals This 3D Widget represents normals of a point cloud. :: - class CV_EXPORTS CloudNormalsWidget : public Widget3D + class CV_EXPORTS WCloudNormals : public Widget3D { public: - CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); + WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); private: /* hidden */ }; -viz::CloudNormalsWidget::CloudNormalsWidget -------------------------------------------- -Constructs a CloudNormalsWidget. +viz::WCloudNormals::WCloudNormals +--------------------------------- +Constructs a WCloudNormals. -.. ocv:function:: CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()) +.. ocv:function:: WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()) :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param normals: A set of normals that has to be of same type with cloud. @@ -920,26 +920,26 @@ Constructs a CloudNormalsWidget. .. note:: In case there are four channels in the cloud, fourth channel is ignored. -viz::MeshWidget ---------------- -.. ocv:class:: MeshWidget +viz::WMesh +---------- +.. ocv:class:: WMesh This 3D Widget defines a mesh. :: - class CV_EXPORTS MeshWidget : public Widget3D + class CV_EXPORTS WMesh : public Widget3D { public: - MeshWidget(const Mesh3d &mesh); + WMesh(const Mesh3d &mesh); private: /* hidden */ }; -viz::MeshWidget::MeshWidget ---------------------------- -Constructs a MeshWidget. +viz::WMesh::WMesh +----------------- +Constructs a WMesh. -.. ocv:function:: MeshWidget(const Mesh3d &mesh) +.. ocv:function:: WMesh(const Mesh3d &mesh) :param mesh: :ocv:class:`Mesh3d` object that will be displayed. diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index e96022ccc..4d12b7a82 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -134,173 +134,173 @@ namespace cv void setColor(const Color &color); }; - class CV_EXPORTS LineWidget : public Widget3D + class CV_EXPORTS WLine : public Widget3D { public: - LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); }; - class CV_EXPORTS PlaneWidget : public Widget3D + class CV_EXPORTS WPlane : public Widget3D { public: - PlaneWidget(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()); - PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size = 1.0, const Color &color = Color::white()); + 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()); private: struct SetSizeImpl; }; - class CV_EXPORTS SphereWidget : public Widget3D + class CV_EXPORTS WSphere : public Widget3D { public: - SphereWidget(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); + WSphere(const cv::Point3f ¢er, float radius, int sphere_resolution = 10, const Color &color = Color::white()); }; - class CV_EXPORTS ArrowWidget : public Widget3D + class CV_EXPORTS WArrow : public Widget3D { public: - ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); + WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); }; - class CV_EXPORTS CircleWidget : public Widget3D + class CV_EXPORTS WCircle : public Widget3D { public: - CircleWidget(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); + WCircle(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); }; - class CV_EXPORTS CylinderWidget : public Widget3D + class CV_EXPORTS WCylinder : public Widget3D { public: - CylinderWidget(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, double radius, int numsides = 30, const Color &color = Color::white()); }; - class CV_EXPORTS CubeWidget : public Widget3D + class CV_EXPORTS WCube : public Widget3D { public: - CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); + WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); }; - class CV_EXPORTS CoordinateSystemWidget : public Widget3D + class CV_EXPORTS WCoordinateSystem : public Widget3D { public: - CoordinateSystemWidget(double scale = 1.0); + WCoordinateSystem(double scale = 1.0); }; - class CV_EXPORTS PolyLineWidget : public Widget3D + class CV_EXPORTS WPolyLine : public Widget3D { public: - PolyLineWidget(InputArray points, const Color &color = Color::white()); + WPolyLine(InputArray points, const Color &color = Color::white()); private: struct CopyImpl; }; - class CV_EXPORTS GridWidget : public Widget3D + class CV_EXPORTS WGrid : public Widget3D { public: //! Creates grid at the origin - GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); //! Creates grid based on the plane equation - GridWidget(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); + WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); private: struct GridImpl; }; - class CV_EXPORTS Text3DWidget : public Widget3D + class CV_EXPORTS WText3D : public Widget3D { public: - Text3DWidget(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, double text_scale = 1.0, bool face_camera = true, const Color &color = Color::white()); void setText(const String &text); String getText() const; }; - class CV_EXPORTS TextWidget : public Widget2D + class CV_EXPORTS WText : public Widget2D { public: - TextWidget(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); + WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); void setText(const String &text); String getText() const; }; - class CV_EXPORTS ImageOverlayWidget : public Widget2D + class CV_EXPORTS WImageOverlay : public Widget2D { public: - ImageOverlayWidget(const Mat &image, const Rect &rect); + WImageOverlay(const Mat &image, const Rect &rect); void setImage(const Mat &image); }; - class CV_EXPORTS Image3DWidget : public Widget3D + class CV_EXPORTS WImage3D : public Widget3D { public: //! Creates 3D image at the origin - Image3DWidget(const Mat &image, const Size &size); + WImage3D(const Mat &image, const Size &size); //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation - Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); + WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); void setImage(const Mat &image); }; - class CV_EXPORTS CameraPositionWidget : public Widget3D + class CV_EXPORTS WCameraPosition : public Widget3D { public: //! Creates camera coordinate frame (axes) at the origin - CameraPositionWidget(double scale = 1.0); + WCameraPosition(double scale = 1.0); //! Creates frustum based on the intrinsic marix K at the origin - CameraPositionWidget(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + WCameraPosition(const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); //! Creates frustum based on the field of view at the origin - CameraPositionWidget(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + WCameraPosition(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); //! Creates frustum and display given image at the far plane - CameraPositionWidget(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + WCameraPosition(const Matx33f &K, const Mat &img, double scale = 1.0, const Color &color = Color::white()); //! Creates frustum and display given image at the far plane - CameraPositionWidget(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()); + WCameraPosition(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()); private: struct ProjectImage; }; - class CV_EXPORTS TrajectoryWidget : public Widget3D + class CV_EXPORTS WTrajectory : public Widget3D { public: enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; //! Displays trajectory of the given path either by coordinate frames or polyline - TrajectoryWidget(const std::vector &path, int display_mode = TrajectoryWidget::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); + WTrajectory(const std::vector &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); //! Displays trajectory of the given path by frustums - TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); + WTrajectory(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); //! Displays trajectory of the given path by frustums - TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); + WTrajectory(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); private: struct ApplyPath; }; - class CV_EXPORTS SpheresTrajectoryWidget : public Widget3D + class CV_EXPORTS WSpheresTrajectory: public Widget3D { public: - SpheresTrajectoryWidget(const std::vector &path, float line_length = 0.05f, double init_sphere_radius = 0.021, + WSpheresTrajectory(const std::vector &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()); }; - class CV_EXPORTS CloudWidget : public Widget3D + class CV_EXPORTS WCloud: public Widget3D { public: //! Each point in cloud is mapped to a color in colors - CloudWidget(InputArray cloud, InputArray colors); + WCloud(InputArray cloud, InputArray colors); //! All points in cloud have the same color - CloudWidget(InputArray cloud, const Color &color = Color::white()); + WCloud(InputArray cloud, const Color &color = Color::white()); private: struct CreateCloudWidget; }; - class CV_EXPORTS CloudCollectionWidget : public Widget3D + class CV_EXPORTS WCloudCollection : public Widget3D { public: - CloudCollectionWidget(); + WCloudCollection(); //! Each point in cloud is mapped to a color in colors void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); @@ -311,19 +311,19 @@ namespace cv struct CreateCloudWidget; }; - class CV_EXPORTS CloudNormalsWidget : public Widget3D + class CV_EXPORTS WCloudNormals : public Widget3D { public: - CloudNormalsWidget(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); + WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()); private: struct ApplyCloudNormals; }; - class CV_EXPORTS MeshWidget : public Widget3D + class CV_EXPORTS WMesh : public Widget3D { public: - MeshWidget(const Mesh3d &mesh); + WMesh(const Mesh3d &mesh); private: struct CopyImpl; @@ -331,27 +331,27 @@ namespace cv template<> CV_EXPORTS Widget2D Widget::cast(); template<> CV_EXPORTS Widget3D Widget::cast(); - template<> CV_EXPORTS LineWidget Widget::cast(); - template<> CV_EXPORTS PlaneWidget Widget::cast(); - template<> CV_EXPORTS SphereWidget Widget::cast(); - template<> CV_EXPORTS CylinderWidget Widget::cast(); - template<> CV_EXPORTS ArrowWidget Widget::cast(); - template<> CV_EXPORTS CircleWidget Widget::cast(); - template<> CV_EXPORTS CubeWidget Widget::cast(); - template<> CV_EXPORTS CoordinateSystemWidget Widget::cast(); - template<> CV_EXPORTS PolyLineWidget Widget::cast(); - template<> CV_EXPORTS GridWidget Widget::cast(); - template<> CV_EXPORTS Text3DWidget Widget::cast(); - template<> CV_EXPORTS TextWidget Widget::cast(); - template<> CV_EXPORTS ImageOverlayWidget Widget::cast(); - template<> CV_EXPORTS Image3DWidget Widget::cast(); - template<> CV_EXPORTS CameraPositionWidget Widget::cast(); - template<> CV_EXPORTS TrajectoryWidget Widget::cast(); - template<> CV_EXPORTS SpheresTrajectoryWidget Widget::cast(); - template<> CV_EXPORTS CloudWidget Widget::cast(); - template<> CV_EXPORTS CloudCollectionWidget Widget::cast(); - template<> CV_EXPORTS CloudNormalsWidget Widget::cast(); - template<> CV_EXPORTS MeshWidget Widget::cast(); + template<> CV_EXPORTS WLine Widget::cast(); + template<> CV_EXPORTS WPlane Widget::cast(); + template<> CV_EXPORTS WSphere Widget::cast(); + template<> CV_EXPORTS WCylinder Widget::cast(); + template<> CV_EXPORTS WArrow Widget::cast(); + template<> CV_EXPORTS WCircle Widget::cast(); + template<> CV_EXPORTS WCube Widget::cast(); + template<> CV_EXPORTS WCoordinateSystem Widget::cast(); + template<> CV_EXPORTS WPolyLine Widget::cast(); + template<> CV_EXPORTS WGrid Widget::cast(); + template<> CV_EXPORTS WText3D Widget::cast(); + template<> CV_EXPORTS WText Widget::cast(); + template<> CV_EXPORTS WImageOverlay Widget::cast(); + template<> CV_EXPORTS WImage3D Widget::cast(); + template<> CV_EXPORTS WCameraPosition Widget::cast(); + template<> CV_EXPORTS WTrajectory Widget::cast(); + template<> CV_EXPORTS WSpheresTrajectory Widget::cast(); + template<> CV_EXPORTS WCloud Widget::cast(); + template<> CV_EXPORTS WCloudCollection Widget::cast(); + template<> CV_EXPORTS WCloudNormals Widget::cast(); + template<> CV_EXPORTS WMesh Widget::cast(); } /* namespace viz */ } /* namespace cv */ diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index ec6c20356..0149f9033 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -59,7 +59,7 @@ namespace cv /////////////////////////////////////////////////////////////////////////////////////////////// /// Point Cloud Widget implementation -struct cv::viz::CloudWidget::CreateCloudWidget +struct cv::viz::WCloud::CreateCloudWidget { static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) { @@ -146,7 +146,7 @@ struct cv::viz::CloudWidget::CreateCloudWidget } }; -cv::viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) +cv::viz::WCloud::WCloud(InputArray _cloud, InputArray _colors) { Mat cloud = _cloud.getMat(); Mat colors = _colors.getMat(); @@ -201,7 +201,7 @@ cv::viz::CloudWidget::CloudWidget(InputArray _cloud, InputArray _colors) WidgetAccessor::setProp(*this, actor); } -cv::viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) +cv::viz::WCloud::WCloud(InputArray _cloud, const Color &color) { Mat cloud = _cloud.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); @@ -233,16 +233,16 @@ cv::viz::CloudWidget::CloudWidget(InputArray _cloud, const Color &color) setColor(color); } -template<> cv::viz::CloudWidget cv::viz::Widget::cast() +template<> cv::viz::WCloud cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// Cloud Collection Widget implementation -struct cv::viz::CloudCollectionWidget::CreateCloudWidget +struct cv::viz::WCloudCollection::CreateCloudWidget { static inline vtkSmartPointer create(const Mat &cloud, vtkIdType &nr_points) { @@ -376,14 +376,14 @@ struct cv::viz::CloudCollectionWidget::CreateCloudWidget } }; -cv::viz::CloudCollectionWidget::CloudCollectionWidget() +cv::viz::WCloudCollection::WCloudCollection() { // Just create the actor vtkSmartPointer actor = vtkSmartPointer::New(); WidgetAccessor::setProp(*this, actor); } -void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, InputArray _colors, const Affine3f &pose) +void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors, const Affine3f &pose) { Mat cloud = _cloud.getMat(); Mat colors = _colors.getMat(); @@ -432,7 +432,7 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, InputArray _col CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax); } -void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, const Color &color, const Affine3f &pose) +void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color, const Affine3f &pose) { Mat cloud = _cloud.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); @@ -471,16 +471,16 @@ void cv::viz::CloudCollectionWidget::addCloud(InputArray _cloud, const Color &co CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax); } -template<> cv::viz::CloudCollectionWidget cv::viz::Widget::cast() +template<> cv::viz::WCloudCollection cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// Cloud Normals Widget implementation -struct cv::viz::CloudNormalsWidget::ApplyCloudNormals +struct cv::viz::WCloudNormals::ApplyCloudNormals { template struct Impl @@ -555,7 +555,7 @@ struct cv::viz::CloudNormalsWidget::ApplyCloudNormals } }; -cv::viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color) +cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, float scale, const Color &color) { Mat cloud = _cloud.getMat(); Mat normals = _normals.getMat(); @@ -610,16 +610,16 @@ cv::viz::CloudNormalsWidget::CloudNormalsWidget(InputArray _cloud, InputArray _n setColor(color); } -template<> cv::viz::CloudNormalsWidget cv::viz::Widget::cast() +template<> cv::viz::WCloudNormals cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// Mesh Widget implementation -struct cv::viz::MeshWidget::CopyImpl +struct cv::viz::WMesh::CopyImpl { template static Vec<_Tp, 3> * copy(const Mat &source, Vec<_Tp, 3> *output, int *look_up, const Mat &nan_mask) @@ -648,7 +648,7 @@ struct cv::viz::MeshWidget::CopyImpl } }; -cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) +cv::viz::WMesh::WMesh(const Mesh3d &mesh) { CV_Assert(mesh.cloud.rows == 1 && (mesh.cloud.type() == CV_32FC3 || mesh.cloud.type() == CV_64FC3 || mesh.cloud.type() == CV_32FC4 || mesh.cloud.type() == CV_64FC4)); CV_Assert(mesh.colors.empty() || (mesh.colors.type() == CV_8UC3 && mesh.cloud.size() == mesh.colors.size())); @@ -766,8 +766,8 @@ cv::viz::MeshWidget::MeshWidget(const Mesh3d &mesh) WidgetAccessor::setProp(*this, actor); } -template<> CV_EXPORTS cv::viz::MeshWidget cv::viz::Widget::cast() +template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index 45a653de5..b253237c9 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -58,7 +58,7 @@ namespace cv /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation -cv::viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Color &color) +cv::viz::WLine::WLine(const Point3f &pt1, const Point3f &pt2, const Color &color) { vtkSmartPointer line = vtkSmartPointer::New(); line->SetPoint1(pt1.x, pt1.y, pt1.z); @@ -75,16 +75,16 @@ cv::viz::LineWidget::LineWidget(const Point3f &pt1, const Point3f &pt2, const Co setColor(color); } -template<> cv::viz::LineWidget cv::viz::Widget::cast() +template<> cv::viz::WLine cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// plane widget implementation -struct cv::viz::PlaneWidget::SetSizeImpl +struct cv::viz::WPlane::SetSizeImpl { template static vtkSmartPointer setSize(const Vec<_Tp, 3> ¢er, vtkSmartPointer poly_data_port, double size) @@ -104,7 +104,7 @@ struct cv::viz::PlaneWidget::SetSizeImpl } }; -cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color &color) +cv::viz::WPlane::WPlane(const Vec4f& coefs, double size, const Color &color) { vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetNormal(coefs[0], coefs[1], coefs[2]); @@ -124,7 +124,7 @@ cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, double size, const Color & setColor(color); } -cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double size, const Color &color) +cv::viz::WPlane::WPlane(const Vec4f& coefs, const Point3f& pt, double size, const Color &color) { vtkSmartPointer plane = vtkSmartPointer::New(); Point3f coefs3(coefs[0], coefs[1], coefs[2]); @@ -145,16 +145,16 @@ cv::viz::PlaneWidget::PlaneWidget(const Vec4f& coefs, const Point3f& pt, double setColor(color); } -template<> cv::viz::PlaneWidget cv::viz::Widget::cast() +template<> cv::viz::WPlane cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// sphere widget implementation -cv::viz::SphereWidget::SphereWidget(const Point3f ¢er, float radius, int sphere_resolution, const Color &color) +cv::viz::WSphere::WSphere(const Point3f ¢er, float radius, int sphere_resolution, const Color &color) { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(radius); @@ -174,16 +174,16 @@ cv::viz::SphereWidget::SphereWidget(const Point3f ¢er, float radius, int sph setColor(color); } -template<> cv::viz::SphereWidget cv::viz::Widget::cast() +template<> cv::viz::WSphere cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// arrow widget implementation -cv::viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, double thickness, const Color &color) +cv::viz::WArrow::WArrow(const Point3f& pt1, const Point3f& pt2, double thickness, const Color &color) { vtkSmartPointer arrowSource = vtkSmartPointer::New(); arrowSource->SetShaftRadius(thickness); @@ -247,16 +247,16 @@ cv::viz::ArrowWidget::ArrowWidget(const Point3f& pt1, const Point3f& pt2, double setColor(color); } -template<> cv::viz::ArrowWidget cv::viz::Widget::cast() +template<> cv::viz::WArrow cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// circle widget implementation -cv::viz::CircleWidget::CircleWidget(const Point3f& pt, double radius, double thickness, const Color& color) +cv::viz::WCircle::WCircle(const Point3f& pt, double radius, double thickness, const Color& color) { vtkSmartPointer disk = vtkSmartPointer::New(); // Maybe the resolution should be lower e.g. 50 or 25 @@ -283,16 +283,16 @@ cv::viz::CircleWidget::CircleWidget(const Point3f& pt, double radius, double thi setColor(color); } -template<> cv::viz::CircleWidget cv::viz::Widget::cast() +template<> cv::viz::WCircle cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// cylinder widget implementation -cv::viz::CylinderWidget::CylinderWidget(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, double radius, int numsides, const Color &color) { const Point3f pt2 = pt_on_axis + axis_direction; vtkSmartPointer line = vtkSmartPointer::New(); @@ -314,16 +314,16 @@ cv::viz::CylinderWidget::CylinderWidget(const Point3f& pt_on_axis, const Point3f setColor(color); } -template<> cv::viz::CylinderWidget cv::viz::Widget::cast() +template<> cv::viz::WCylinder cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// cylinder widget implementation -cv::viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame, const Color &color) +cv::viz::WCube::WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame, const Color &color) { vtkSmartPointer mapper = vtkSmartPointer::New(); if (wire_frame) @@ -346,16 +346,16 @@ cv::viz::CubeWidget::CubeWidget(const Point3f& pt_min, const Point3f& pt_max, bo setColor(color); } -template<> cv::viz::CubeWidget cv::viz::Widget::cast() +template<> cv::viz::WCube cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// coordinate system widget implementation -cv::viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale) +cv::viz::WCoordinateSystem::WCoordinateSystem(double scale) { vtkSmartPointer axes = vtkSmartPointer::New(); axes->SetOrigin(0, 0, 0); @@ -397,16 +397,16 @@ cv::viz::CoordinateSystemWidget::CoordinateSystemWidget(double scale) WidgetAccessor::setProp(*this, actor); } -template<> cv::viz::CoordinateSystemWidget cv::viz::Widget::cast() +template<> cv::viz::WCoordinateSystem cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// polyline widget implementation -struct cv::viz::PolyLineWidget::CopyImpl +struct cv::viz::WPolyLine::CopyImpl { template static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer polyLine) @@ -426,7 +426,7 @@ struct cv::viz::PolyLineWidget::CopyImpl } }; -cv::viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &color) +cv::viz::WPolyLine::WPolyLine(InputArray _pointData, const Color &color) { Mat pointData = _pointData.getMat(); CV_Assert(pointData.type() == CV_32FC3 || pointData.type() == CV_32FC4 || pointData.type() == CV_64FC3 || pointData.type() == CV_64FC4); @@ -477,16 +477,16 @@ cv::viz::PolyLineWidget::PolyLineWidget(InputArray _pointData, const Color &colo setColor(color); } -template<> cv::viz::PolyLineWidget cv::viz::Widget::cast() +template<> cv::viz::WPolyLine cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// grid widget implementation -struct cv::viz::GridWidget::GridImpl +struct cv::viz::WGrid::GridImpl { static vtkSmartPointer createGrid(const Vec2i &dimensions, const Vec2d &spacing) { @@ -513,7 +513,7 @@ struct cv::viz::GridWidget::GridImpl } }; -cv::viz::GridWidget::GridWidget(const Vec2i &dimensions, const Vec2d &spacing, const Color &color) +cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color) { vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); @@ -531,7 +531,7 @@ cv::viz::GridWidget::GridWidget(const Vec2i &dimensions, const Vec2d &spacing, c setColor(color); } -cv::viz::GridWidget::GridWidget(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color) +cv::viz::WGrid::WGrid(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color) { vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); @@ -584,16 +584,16 @@ cv::viz::GridWidget::GridWidget(const Vec4f &coefs, const Vec2i &dimensions, con setColor(color); } -template<> cv::viz::GridWidget cv::viz::Widget::cast() +template<> cv::viz::WGrid cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// text3D widget implementation -cv::viz::Text3DWidget::Text3DWidget(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, double text_scale, bool face_camera, const Color &color) { vtkSmartPointer textSource = vtkSmartPointer::New(); textSource->SetText(text.c_str()); @@ -622,7 +622,7 @@ cv::viz::Text3DWidget::Text3DWidget(const String &text, const Point3f &position, setColor(color); } -void cv::viz::Text3DWidget::setText(const String &text) +void cv::viz::WText3D::setText(const String &text) { vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("This widget does not support text." && actor); @@ -636,7 +636,7 @@ void cv::viz::Text3DWidget::setText(const String &text) textSource->Update(); } -cv::String cv::viz::Text3DWidget::getText() const +cv::String cv::viz::WText3D::getText() const { vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("This widget does not support text." && actor); @@ -648,16 +648,16 @@ cv::String cv::viz::Text3DWidget::getText() const return textSource->GetText(); } -template<> cv::viz::Text3DWidget cv::viz::Widget::cast() +template<> cv::viz::WText3D cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// text widget implementation -cv::viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font_size, const Color &color) +cv::viz::WText::WText(const String &text, const Point2i &pos, int font_size, const Color &color) { vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetPosition(pos.x, pos.y); @@ -675,20 +675,20 @@ cv::viz::TextWidget::TextWidget(const String &text, const Point2i &pos, int font WidgetAccessor::setProp(*this, actor); } -template<> cv::viz::TextWidget cv::viz::Widget::cast() +template<> cv::viz::WText cv::viz::Widget::cast() { Widget2D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } -void cv::viz::TextWidget::setText(const String &text) +void cv::viz::WText::setText(const String &text) { vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("This widget does not support text." && actor); actor->SetInput(text.c_str()); } -cv::String cv::viz::TextWidget::getText() const +cv::String cv::viz::WText::getText() const { vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("This widget does not support text." && actor); @@ -698,7 +698,7 @@ cv::String cv::viz::TextWidget::getText() const /////////////////////////////////////////////////////////////////////////////////////////////// /// image overlay widget implementation -cv::viz::ImageOverlayWidget::ImageOverlayWidget(const Mat &image, const Rect &rect) +cv::viz::WImageOverlay::WImageOverlay(const Mat &image, const Rect &rect) { CV_Assert(!image.empty() && image.depth() == CV_8U); @@ -739,7 +739,7 @@ cv::viz::ImageOverlayWidget::ImageOverlayWidget(const Mat &image, const Rect &re WidgetAccessor::setProp(*this, actor); } -void cv::viz::ImageOverlayWidget::setImage(const Mat &image) +void cv::viz::WImageOverlay::setImage(const Mat &image) { CV_Assert(!image.empty() && image.depth() == CV_8U); @@ -766,16 +766,16 @@ void cv::viz::ImageOverlayWidget::setImage(const Mat &image) mapper->SetInputConnection(flipFilter->GetOutputPort()); } -template<> cv::viz::ImageOverlayWidget cv::viz::Widget::cast() +template<> cv::viz::WImageOverlay cv::viz::Widget::cast() { Widget2D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// image 3D widget implementation -cv::viz::Image3DWidget::Image3DWidget(const Mat &image, const Size &size) +cv::viz::WImage3D::WImage3D(const Mat &image, const Size &size) { CV_Assert(!image.empty() && image.depth() == CV_8U); @@ -827,7 +827,7 @@ cv::viz::Image3DWidget::Image3DWidget(const Mat &image, const Size &size) WidgetAccessor::setProp(*this, actor); } -cv::viz::Image3DWidget::Image3DWidget(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) +cv::viz::WImage3D::WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) { CV_Assert(!image.empty() && image.depth() == CV_8U); @@ -901,7 +901,7 @@ cv::viz::Image3DWidget::Image3DWidget(const Vec3f &position, const Vec3f &normal WidgetAccessor::setProp(*this, actor); } -void cv::viz::Image3DWidget::setImage(const Mat &image) +void cv::viz::WImage3D::setImage(const Mat &image) { CV_Assert(!image.empty() && image.depth() == CV_8U); @@ -929,16 +929,16 @@ void cv::viz::Image3DWidget::setImage(const Mat &image) actor->SetTexture(texture); } -template<> cv::viz::Image3DWidget cv::viz::Widget::cast() +template<> cv::viz::WImage3D cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// camera position widget implementation -struct cv::viz::CameraPositionWidget::ProjectImage +struct cv::viz::WCameraPosition::ProjectImage { static void projectImage(float fovy, float far_end_height, const Mat &image, double scale, const Color &color, vtkSmartPointer actor) @@ -1032,7 +1032,7 @@ struct cv::viz::CameraPositionWidget::ProjectImage } }; -cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) +cv::viz::WCameraPosition::WCameraPosition(double scale) { vtkSmartPointer axes = vtkSmartPointer::New(); axes->SetOrigin(0, 0, 0); @@ -1074,7 +1074,7 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(double scale) WidgetAccessor::setProp(*this, actor); } -cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, double scale, const Color &color) +cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); float f_x = K(0,0); @@ -1116,7 +1116,7 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, double sca } -cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double scale, const Color &color) +cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); @@ -1154,7 +1154,7 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, double sca setColor(color); } -cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat &image, double scale, const Color &color) +cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, const Mat &image, double scale, const Color &color) { CV_Assert(!image.empty() && image.depth() == CV_8U); float f_y = K(1,1); @@ -1168,7 +1168,7 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Matx33f &K, const Mat WidgetAccessor::setProp(*this, actor); } -cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, const Mat &image, double scale, const Color &color) +cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, const Mat &image, double scale, const Color &color) { CV_Assert(!image.empty() && image.depth() == CV_8U); float fovy = fov[1] * 180.0f / CV_PI; @@ -1179,16 +1179,16 @@ cv::viz::CameraPositionWidget::CameraPositionWidget(const Vec2f &fov, const Mat WidgetAccessor::setProp(*this, actor); } -template<> cv::viz::CameraPositionWidget cv::viz::Widget::cast() +template<> cv::viz::WCameraPosition cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// trajectory widget implementation -struct cv::viz::TrajectoryWidget::ApplyPath +struct cv::viz::WTrajectory::ApplyPath { static void applyPath(vtkSmartPointer poly_data, vtkSmartPointer append_filter, const std::vector &path) { @@ -1220,12 +1220,12 @@ struct cv::viz::TrajectoryWidget::ApplyPath } }; -cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, int display_mode, const Color &color, double scale) +cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display_mode, const Color &color, double scale) { vtkSmartPointer appendFilter = vtkSmartPointer::New(); // Bitwise and with 3 in order to limit the domain to 2 bits - if ((~display_mode & 3) ^ TrajectoryWidget::DISPLAY_PATH) + if ((~display_mode & 3) ^ WTrajectory::DISPLAY_PATH) { // Create a poly line along the path vtkIdType nr_points = path.size(); @@ -1269,7 +1269,7 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i #endif } - if ((~display_mode & 3) ^ TrajectoryWidget::DISPLAY_FRAMES) + if ((~display_mode & 3) ^ WTrajectory::DISPLAY_FRAMES) { // Create frames and transform along the path vtkSmartPointer axes = vtkSmartPointer::New(); @@ -1316,7 +1316,7 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, i WidgetAccessor::setProp(*this, actor); } -cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Matx33f &K, double scale, const Color &color) +cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Matx33f &K, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); float f_x = K(0,0); @@ -1360,7 +1360,7 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c setColor(color); } -cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, const Vec2f &fov, double scale, const Color &color) +cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Vec2f &fov, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); @@ -1400,16 +1400,16 @@ cv::viz::TrajectoryWidget::TrajectoryWidget(const std::vector &path, c setColor(color); } -template<> cv::viz::TrajectoryWidget cv::viz::Widget::cast() +template<> cv::viz::WTrajectory cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } /////////////////////////////////////////////////////////////////////////////////////////////// /// spheres trajectory widget implementation -cv::viz::SpheresTrajectoryWidget::SpheresTrajectoryWidget(const std::vector &path, float line_length, double init_sphere_radius, double sphere_radius, +cv::viz::WSpheresTrajectory::WSpheresTrajectory(const std::vector &path, float line_length, double init_sphere_radius, double sphere_radius, const Color &line_color, const Color &sphere_color) { vtkSmartPointer appendFilter = vtkSmartPointer::New(); @@ -1490,8 +1490,8 @@ cv::viz::SpheresTrajectoryWidget::SpheresTrajectoryWidget(const std::vector cv::viz::SpheresTrajectoryWidget cv::viz::Widget::cast() +template<> cv::viz::WSpheresTrajectory cv::viz::Widget::cast() { Widget3D widget = this->cast(); - return static_cast(widget); + return static_cast(widget); } diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 5e9d13c7b..94804a937 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -41,15 +41,9 @@ //M*/ #include "test_precomp.hpp" #include -#include -#include #include -#include - -#include #include -#include using namespace cv; cv::Mat cvcloud_load() @@ -68,226 +62,121 @@ cv::Mat cvcloud_load() return cloud; } +bool constant_cam = true; +cv::viz::Widget cam_1, cam_coordinates; + +void keyboard_callback(const viz::KeyboardEvent & event, void * cookie) +{ + if (event.keyDown()) + { + if (event.getKeySym() == "space") + { + viz::Viz3d &viz = *((viz::Viz3d *) cookie); + constant_cam = !constant_cam; + if (constant_cam) + { + viz.showWidget("cam_1", cam_1); + viz.showWidget("cam_coordinate", cam_coordinates); + viz.showWidget("cam_text", viz::WText("Global View", Point2i(5,5), 28)); + viz.resetCamera(); + } + else + { + viz.showWidget("cam_text", viz::WText("Cam View", Point2i(5,5), 28)); + viz.removeWidget("cam_1"); + viz.removeWidget("cam_coordinate"); + } + } + } +} + TEST(Viz_viz3d, accuracy) { - cv::Mat cloud = cvcloud_load(); - cv::Mat colors(cloud.size(), CV_8UC3, cv::Scalar(0, 255, 0)); - cv::Mat normals(cloud.size(), cloud.type(), cv::Scalar(0, 10, 0)); - //cv::viz::Mesh3d::Ptr mesh = cv::viz::Mesh3d::mesh_load("/Users/nerei/horse.ply"); - - const Vec4d data[] = { Vec4d(0.0, 0.0, 0.0, 0.0), Vec4d(1.0, 1.0, 1.0, 1.0), cv::Vec4d(0.0, 2.0, 0.0, 0.0), cv::Vec4d(3.0, 4.0, 1.0, 1.0) }; - cv::Mat points(1, sizeof(data)/sizeof(data[0]), CV_64FC4, (void*)data); - points = points.reshape(4, 2); - cv::viz::Viz3d viz("abc"); - viz.setBackgroundColor(); - - Vec3f angle = Vec3f::all(0); - Vec3f pos = Vec3f::all(0); - //viz.addPolygonMesh(*mesh, "pq"); + cv::viz::Mesh3d bunny_mesh = cv::viz::Mesh3d::loadMesh("bunny.ply"); + cv::viz::WMesh bunny_widget(bunny_mesh); + bunny_widget.setColor(cv::viz::Color::cyan()); - viz::Color color = viz::Color::black(); + cam_1 = cv::viz::WCameraPosition(cv::Vec2f(0.6, 0.4), 0.2, cv::viz::Color::green()); + cam_coordinates = cv::viz::WCameraPosition(0.2); - viz::LineWidget lw(Point3f(0, 0, 0), Point3f(4.f, 4.f,4.f), viz::Color::green()); - viz::PlaneWidget pw(Vec4f(0.0,1.0,2.0,3.0)); - viz::PlaneWidget pw2(Vec4f(0.0,1.0,2.0,3.0), 2.0, viz::Color::red()); - viz::PlaneWidget pw3(Vec4f(0.0,1.0,2.0,3.0), 3.0, viz::Color::blue()); - viz::SphereWidget sw(Point3f(0, 0, 0), 0.2); - viz::ArrowWidget aw(Point3f(0, 0, 0), Point3f(1, 1, 1), 0.01, viz::Color::red()); - viz::CircleWidget cw(Point3f(0, 0, 0), 0.5, 0.01, viz::Color::green()); - viz::CylinderWidget cyw(Point3f(0, 0, 0), Point3f(-1, -1, -1), 0.5, 30, viz::Color::green()); - viz::CubeWidget cuw(Point3f(-2, -2, -2), Point3f(-1, -1, -1)); - viz::CoordinateSystemWidget csw; - viz::TextWidget tw("TEST", Point(100, 100), 20); - viz::CloudWidget pcw(cloud, colors); -// pcw.setRenderingProperty(VIZ_LINE_WIDTH)); - viz::CloudWidget pcw2(cloud, viz::Color::magenta()); - -// viz.showWidget("line", lw); - viz.showWidget("plane", pw); - viz.showWidget("plane2", pw2); - viz.showWidget("plane3", pw3); -// viz.showWidget("sphere", sw); -// viz.showWidget("arrow", aw); -// viz.showWidget("circle", cw); -// viz.showWidget("cylinder", cyw); -// viz.showWidget("cube", cuw); - viz.showWidget("coordinateSystem", csw); -// viz.showWidget("coordinateSystem2", viz::CoordinateSystemWidget(2.0), Affine3f().translate(Vec3f(2, 0, 0))); -// viz.showWidget("text",tw); -// viz.showWidget("pcw",pcw); -// viz.showWidget("pcw2",pcw2); - -// viz::LineWidget lw2 = lw; -// v.showPointCloud("cld",cloud, colors); + viz.showWidget("bunny", bunny_widget); + viz.showWidget("cam_1", cam_1, viz::makeCameraPose(Point3f(1.0,0.0,0.0), Point3f(0.0,0.0,0.0), Point3f(0.0,1.0,0.0))); + viz.showWidget("cam_coordinate", cam_coordinates, viz::makeCameraPose(Point3f(1.0,0.0,0.0), Point3f(0.0,0.0,0.0), Point3f(0.0,1.0,0.0))); -// v.addPointCloudNormals(cloud, normals, 100, 0.02, "n"); - //viz::CloudNormalsWidget cnw(cloud, normals); - //v.showWidget("n", cnw); + std::vector cam_path; - -// lw = v.getWidget("n").cast(); -// pw = v.getWidget("n").cast(); - - - viz::PolyLineWidget plw(points, viz::Color::green()); -// viz.showWidget("polyline", plw); -// lw = v.getWidget("polyline").cast(); - - viz::Mesh3d mesh = cv::viz::Mesh3d::loadMesh("/Users/nerei/horse.ply"); - -// viz::MeshWidget mw(mesh); -// viz.showWidget("mesh", mw); - - Mat img = imread("opencv.png"); -// resize(img, img, Size(50,50)); -// viz.showWidget("img", viz::ImageOverlayWidget(img, Point2i(50,50))); - - Matx33f K(657, 0, 320, - 0, 657, 240, - 0, 0, 1); - - //viz::CameraPositionWidget cpw(Vec3f(0.5, 0.5, 3.0), Vec3f(0.0,0.0,0.0), Vec3f(0.0,-1.0,0.0), 0.5); - viz::CameraPositionWidget cpw2(0.5); - viz::CameraPositionWidget frustum(K, 2.0, viz::Color::green()); -// viz::CameraPositionWidget frustum2(K, 4.0, viz::Color::red()); - viz::CameraPositionWidget frustum2(K, 4.0, viz::Color::red()); - viz::CameraPositionWidget frustum3(Vec2f(CV_PI, CV_PI/2), 4.0); - viz::Text3DWidget t3w1("Camera1", Point3f(0.4, 0.6, 3.0), 0.1); - viz::Text3DWidget t3w2("Camera2", Point3f(0,0,0), 0.1); - -// viz.showWidget("CameraPositionWidget", cpw); -// viz.showWidget("CameraPositionWidget2", cpw2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); -// viz.showWidget("camera_label", t3w1); -// viz.showWidget("camera_label2", t3w2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); -// viz.showWidget("frustrum", frustum, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); -// viz.showWidget("frustrum2", frustum2, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); -// viz.showWidget("frustum3", frustum3, Affine3f(0.524, 0, 0, Vec3f(-1.0, 0.5, 0.5))); - - std::vector trajectory; - - trajectory.push_back(Affine3f().translate(Vec3f(0.5,0.5,0.5))); - trajectory.push_back(Affine3f().translate(Vec3f(1.0,0.0,0.0))); - trajectory.push_back(Affine3f().translate(Vec3f(2.0,0.5,0.0))); - trajectory.push_back(Affine3f(0.5, 0.0, 0.0, Vec3f(1.0,0.0,1.0))); -// - //viz.showWidget("trajectory1", viz::TrajectoryWidget(trajectory, viz::Color(0,255,255), true, 0.5)); - viz.showWidget("trajectory2", viz::TrajectoryWidget(trajectory, K, 1.0, viz::Color(255,0,255))); - -// cv::Rodrigues2(Vec3f(), Mat()); - - -// viz.showWidget("trajectory1", viz::TrajectoryWidget(trajectory/*, viz::Color::yellow()*/)); - -// viz.showWidget("CameraPositionWidget2", cpw2); -// viz.showWidget("CameraPositionWidget3", cpw3); - - viz.spin(); + for (int i = 0, j = 0; i <= 360; ++i, j+=5) + { + cam_path.push_back(viz::makeCameraPose(Point3f(0.5*cos(double(i)*CV_PI/180.0), 0.5*sin(double(j)*CV_PI/180.0), 0.5*sin(double(i)*CV_PI/180.0)), + Point3f(0.0,0.0,0.0), Point3f(0.0,1.0,0.0))); + } + + int path_counter = 0; + int cam_path_size = cam_path.size(); - //viz::GridWidget gw(viz::Vec2i(100,100), viz::Vec2d(1,1)); - //v.showWidget("grid", gw); -// lw = viz.getWidget("grid").cast(); + // OTHER WIDGETS + cv::Mat img = imread("opencv.png"); - //viz::Text3DWidget t3w("OpenCV", cv::Point3f(0.0, 2.0, 0.0), 1.0, viz::Color(255,255,0)); - //v.showWidget("txt3d", t3w); + int downSample = 4; + + int row_max = img.rows/downSample; + int col_max = img.cols/downSample; + + cv::Mat clouds[img.cols/downSample]; + cv::Mat colors[img.cols/downSample]; + + for (int col = 0; col < col_max; ++col) + { + clouds[col] = Mat::zeros(img.rows/downSample, 1, CV_32FC3); + colors[col] = Mat::zeros(img.rows/downSample, 1, CV_8UC3); + for (int row = 0; row < row_max; ++row) + { + clouds[col].at(row) = Vec3f(downSample * float(col) / img.cols, 1.0-(downSample * float(row) / img.rows), 0.0); + colors[col].at(row) = img.at(row*downSample,col*downSample); + } + } + + for (int col = 0; col < col_max; ++col) + { + std::stringstream strstrm; + strstrm << "cloud_" << col; + viz.showWidget(strstrm.str(), viz::WCloud(clouds[col], colors[col])); + viz.getWidget(strstrm.str()).setRenderingProperty(viz::POINT_SIZE, 3.0); + viz.getWidget(strstrm.str()).setRenderingProperty(viz::OPACITY, 0.45); + } + + viz.showWidget("trajectory", viz::WTrajectory(cam_path, viz::WTrajectory::DISPLAY_PATH, viz::Color::yellow())); + viz.showWidget("cam_text", viz::WText("Global View", Point2i(5,5), 28)); + viz.registerKeyboardCallback(keyboard_callback, (void *) &viz); -// float grid_x_angle = 0.0; - + int angle = 0; while(!viz.wasStopped()) { - // Creating new point cloud with id cloud1 - cv::Affine3f cloudPosition(angle, pos); - cv::Affine3f cloudPosition2(angle, pos + Vec3f(0.2f, 0.2f, 0.2f)); + if (path_counter == cam_path_size) + { + path_counter = 0; + } - lw.setColor(color); -// lw.setLineWidth(pos_x * 10); + if (!constant_cam) + { + viz.setViewerPose(cam_path[path_counter]); + } - //plw.setColor(viz::Color(col_blue, col_green, col_red)); - -// sw.setPose(cloudPosition); -// pw.setPose(cloudPosition); - aw.setPose(cloudPosition); - cw.setPose(cloudPosition); - cyw.setPose(cloudPosition); - - frustum.setPose(cloudPosition); -// lw.setPose(cloudPosition); -// cpw.updatePose(Affine3f(0.1,0.0,0.0, cv::Vec3f(0.0,0.0,0.0))); -// cpw.setPose(cloudPosition); -// cnw.setPose(cloudPosition); -// v.showWidget("pcw",pcw, cloudPosition); -// v.showWidget("pcw2",pcw2, cloudPosition2); -// v.showWidget("plane", pw, cloudPosition); - -// v.setWidgetPose("n",cloudPosition); -// v.setWidgetPose("pcw2", cloudPosition); - //cnw.setColor(viz::Color(col_blue, col_green, col_red)); - //pcw2.setColor(viz::Color(col_blue, col_green, col_red)); - - //gw.updatePose(viz::Affine3f(0.0, 0.1, 0.0, cv::Vec3f(0.0,0.0,0.0))); - - angle[0] += 0.1f; - angle[1] -= 0.1f; - angle[2] += 0.1f; - pos[0] = std::sin(angle[0]); - pos[1] = std::sin(angle[1]); - pos[2] = std::sin(angle[2]); + if (angle == 360) angle = 0; - color[0] = int(angle[0] * 10) % 256; - color[1] = int(angle[0] * 20) % 256; - color[2] = int(angle[0] * 30) % 256; - - viz.spinOnce(1, true); + cam_1.cast().setPose(cam_path[path_counter]); + cam_coordinates.cast().setPose(cam_path[path_counter++]); + + for (int i = 0; i < col_max; ++i) + { + std::stringstream strstrm; + strstrm << "cloud_" << i; + viz.setWidgetPose(strstrm.str(), Affine3f().translate(Vec3f(-0.5,0.0, -0.7 + 0.2*sin((angle+i*10)*CV_PI / 180.0)))); + } + angle += 10; + viz.spinOnce(42, true); } - - -// -// -// viz::ModelCoefficients mc; -// mc.values.resize(4); -// mc.values[0] = mc.values[1] = mc.values[2] = mc.values[3] = 1; -// v.addPlane(mc); -// -// -// viz::Mesh3d::Ptr mesh = viz::mesh_load("horse.ply"); -// v.addPolygonMesh(*mesh, "pq"); -// -// v.spinOnce(1000, true); -// -// v.removeCoordinateSystem(); -// -// for(int i = 0; i < mesh->cloud.cols; ++i) -// mesh->cloud.ptr()[i] += cv::Point3f(1, 1, 1); -// -// v.updatePolygonMesh(*mesh, "pq"); -// -// -// for(int i = 0; i < mesh->cloud.cols; ++i) -// mesh->cloud.ptr()[i] -= cv::Point3f(2, 2, 2); -// v.addPolylineFromPolygonMesh(*mesh); -// -// -// v.addText("===Abd sadfljsadlk", 100, 100, cv::Scalar(255, 0, 0), 15); -// for(int i = 0; i < cloud.cols; ++i) -// cloud.ptr()[i].x *=2; -// -// colors.setTo(cv::Scalar(255, 0, 0)); -// -// v.addSphere(cv::Point3f(0, 0, 0), 0.3, viz::Color::blue()); -// -// cv::Mat cvpoly(1, 5, CV_32FC3); -// cv::Point3f* pdata = cvpoly.ptr(); -// pdata[0] = cv::Point3f(0, 0, 0); -// pdata[1] = cv::Point3f(0, 1, 1); -// pdata[2] = cv::Point3f(3, 1, 2); -// pdata[3] = cv::Point3f(0, 2, 4); -// pdata[4] = cv::Point3f(7, 2, 3); -// v.addPolygon(cvpoly, viz::Color::white()); -// -// // Updating cloud1 -// v.showPointCloud("cloud1", cloud, colors); -// v.spin(); } - diff --git a/samples/cpp/tutorial_code/viz/creating_widgets.cpp b/samples/cpp/tutorial_code/viz/creating_widgets.cpp index f5fdd92dd..636650252 100644 --- a/samples/cpp/tutorial_code/viz/creating_widgets.cpp +++ b/samples/cpp/tutorial_code/viz/creating_widgets.cpp @@ -39,17 +39,17 @@ void help() * @class TriangleWidget * @brief Defining our own 3D Triangle widget */ -class TriangleWidget : public viz::Widget3D +class WTriangle : public viz::Widget3D { public: - TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); }; /** * @function TriangleWidget::TriangleWidget * @brief Constructor */ -TriangleWidget::TriangleWidget(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color) +WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color) { // Create a triangle vtkSmartPointer points = vtkSmartPointer::New(); @@ -101,7 +101,7 @@ int main() viz::Viz3d myWindow("Creating Widgets"); /// Create a triangle widget - TriangleWidget tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); + WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); /// Show widget in the visualizer window myWindow.showWidget("TRIANGLE", tw); diff --git a/samples/cpp/tutorial_code/viz/transformations.cpp b/samples/cpp/tutorial_code/viz/transformations.cpp index d357f4abf..1748cd5d1 100644 --- a/samples/cpp/tutorial_code/viz/transformations.cpp +++ b/samples/cpp/tutorial_code/viz/transformations.cpp @@ -68,7 +68,7 @@ int main(int argn, char **argv) viz::Viz3d myWindow("Coordinate Frame"); /// Add coordinate axes - myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); /// Let's assume camera has the following properties Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); @@ -82,7 +82,7 @@ int main(int argn, char **argv) /// Create a cloud widget. Mat bunny_cloud = cvcloud_load(); - viz::CloudWidget cloud_widget(bunny_cloud, viz::Color::green()); + viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); /// Pose of the widget in camera frame Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); @@ -92,8 +92,8 @@ int main(int argn, char **argv) /// Visualize camera frame if (!camera_pov) { - viz::CameraPositionWidget cpw(0.5); // Coordinate axes - viz::CameraPositionWidget cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + viz::WCameraPosition cpw(0.5); // Coordinate axes + viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum myWindow.showWidget("CPW", cpw, cam_pose); myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); } diff --git a/samples/cpp/tutorial_code/viz/widget_pose.cpp b/samples/cpp/tutorial_code/viz/widget_pose.cpp index d83ac6b2e..03c88109f 100644 --- a/samples/cpp/tutorial_code/viz/widget_pose.cpp +++ b/samples/cpp/tutorial_code/viz/widget_pose.cpp @@ -37,15 +37,15 @@ int main() viz::Viz3d myWindow("Coordinate Frame"); /// Add coordinate axes - myWindow.showWidget("Coordinate Widget", viz::CoordinateSystemWidget()); + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); /// Add line to represent (1,1,1) axis - viz::LineWidget axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f)); + 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::CubeWidget cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue()); + 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); myWindow.showWidget("Cube Widget", cube_widget); From a117400577d4d02db283936c9df97ce1dca8a496 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Tue, 17 Sep 2013 18:55:10 +0200 Subject: [PATCH 198/205] ignore viz tutorials when BUILD_opencv_viz is not set --- modules/viz/test/test_viz3d.cpp | 4 ++-- samples/cpp/CMakeLists.txt | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 94804a937..19d9f7300 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -124,8 +124,8 @@ TEST(Viz_viz3d, accuracy) int row_max = img.rows/downSample; int col_max = img.cols/downSample; - cv::Mat clouds[img.cols/downSample]; - cv::Mat colors[img.cols/downSample]; + cv::Mat *clouds = new cv::Mat[img.cols/downSample]; + cv::Mat *colors = new cv::Mat[img.cols/downSample]; for (int col = 0; col < col_max; ++col) { diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index 4115bf9fc..d5302fc86 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -28,6 +28,9 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) if(HAVE_opencv_gpufilters) ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpufilters/include") endif() + if(HAVE_opencv_viz) + ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/viz/include") + endif() if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") @@ -55,6 +58,10 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) if("${srcs}" MATCHES "gpu/") target_link_libraries(${the_target} opencv_gpuarithm opencv_gpufilters) endif() + + if(HAVE_opencv_viz) + target_link_libraries(${the_target} opencv_viz) + endif() set_target_properties(${the_target} PROPERTIES OUTPUT_NAME "cpp-${sample_kind}-${name}" @@ -82,6 +89,10 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) if(NOT HAVE_opencv_gpuarithm OR NOT HAVE_opencv_gpufilters) ocv_list_filterout(cpp_samples "/gpu/") endif() + + if(NOT HAVE_opencv_viz) + ocv_list_filterout(cpp_samples "viz") + endif() foreach(sample_filename ${cpp_samples}) get_filename_component(sample ${sample_filename} NAME_WE) From 223fb39d94a728e7f2510203b5ab3a750be54f1a Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Tue, 17 Sep 2013 20:17:13 +0200 Subject: [PATCH 199/205] include viz tutorials in the main tutorials file. ignore viz samples --- doc/tutorials/images/viz.jpg | Bin 0 -> 31804 bytes doc/tutorials/tutorials.rst | 16 +++ .../creating_widgets.rst | 2 +- .../images/red_triangle.png | Bin .../images/window_demo.png | Bin .../viz/{ => launching_viz}/launching_viz.rst | 2 +- .../images/facedetect.jpg | Bin 0 -> 17902 bytes .../images/image_effects.png | Bin 0 -> 29966 bytes .../viz/table_of_content_viz/images/intro.png | Bin 0 -> 2584 bytes .../table_of_content_viz.rst | 94 ++++++++++++++++++ .../images/camera_view_point.png | Bin .../images/global_view_point.png | Bin .../{ => transformations}/transformations.rst | 2 +- .../viz/widget_pose/images/widgetpose.png | Bin 0 -> 40892 bytes .../viz/{ => widget_pose}/widget_pose.rst | 2 +- samples/cpp/CMakeLists.txt | 11 +- 16 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 doc/tutorials/images/viz.jpg rename doc/tutorials/viz/{ => creating_widgets}/creating_widgets.rst (97%) rename doc/tutorials/viz/{ => creating_widgets}/images/red_triangle.png (100%) rename doc/tutorials/viz/{ => launching_viz}/images/window_demo.png (100%) rename doc/tutorials/viz/{ => launching_viz}/launching_viz.rst (96%) create mode 100644 doc/tutorials/viz/table_of_content_viz/images/facedetect.jpg create mode 100755 doc/tutorials/viz/table_of_content_viz/images/image_effects.png create mode 100644 doc/tutorials/viz/table_of_content_viz/images/intro.png create mode 100644 doc/tutorials/viz/table_of_content_viz/table_of_content_viz.rst rename doc/tutorials/viz/{ => transformations}/images/camera_view_point.png (100%) rename doc/tutorials/viz/{ => transformations}/images/global_view_point.png (100%) rename doc/tutorials/viz/{ => transformations}/transformations.rst (98%) create mode 100644 doc/tutorials/viz/widget_pose/images/widgetpose.png rename doc/tutorials/viz/{ => widget_pose}/widget_pose.rst (97%) diff --git a/doc/tutorials/images/viz.jpg b/doc/tutorials/images/viz.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ac8f3ed8d641d2332755e8c9196517f1438b616 GIT binary patch literal 31804 zcmcF~Wl$VZ)9x;dC0KBmun-a~!F3^o;OV% zR5Y|S|62+0-=i4l7`T|2xHLrgL^S{7@wXj-j|n^gZh?UG02F*62p{;j3qS<`0)S}$ zy#2oe9SA~2!$86OC)Ile0D?d$|6E7I1Yu!fy!dxF%0DSS!E1Cv4h(uR6=Nb!2VY|F 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 Za{J9|C-wgpr~fA2NBO^g0R8Xc{{oslWW)df literal 0 HcmV?d00001 diff --git a/doc/tutorials/tutorials.rst b/doc/tutorials/tutorials.rst index 07bc515d5..d5d6d4f1e 100644 --- a/doc/tutorials/tutorials.rst +++ b/doc/tutorials/tutorials.rst @@ -186,6 +186,21 @@ As always, we would be happy to hear your comments and receive your contribution :width: 80pt :alt: gpu icon +* :ref:`Table-Of-Content-Viz` + + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + =========== ======================================================= + |Viz| These tutorials show how to use Viz module effectively. + + =========== ======================================================= + + .. |Viz| image:: images/viz.jpg + :height: 80pt + :width: 80pt + :alt: viz icon + * :ref:`Table-Of-Content-General` .. tabularcolumns:: m{100pt} m{300pt} @@ -221,4 +236,5 @@ As always, we would be happy to hear your comments and receive your contribution gpu/table_of_content_gpu/table_of_content_gpu bioinspired/table_of_content_bioinspired/table_of_content_bioinspired ios/table_of_content_ios/table_of_content_ios + viz/table_of_content_viz/table_of_content_viz general/table_of_content_general/table_of_content_general diff --git a/doc/tutorials/viz/creating_widgets.rst b/doc/tutorials/viz/creating_widgets/creating_widgets.rst similarity index 97% rename from doc/tutorials/viz/creating_widgets.rst rename to doc/tutorials/viz/creating_widgets/creating_widgets.rst index fd002a8a2..0d9b288c3 100644 --- a/doc/tutorials/viz/creating_widgets.rst +++ b/doc/tutorials/viz/creating_widgets/creating_widgets.rst @@ -16,7 +16,7 @@ In this tutorial you will learn how to Code ==== -You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/creating_widgets.cpp>`_. +You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/creating_widgets.cpp>`. .. code-block:: cpp diff --git a/doc/tutorials/viz/images/red_triangle.png b/doc/tutorials/viz/creating_widgets/images/red_triangle.png similarity index 100% rename from doc/tutorials/viz/images/red_triangle.png rename to doc/tutorials/viz/creating_widgets/images/red_triangle.png diff --git a/doc/tutorials/viz/images/window_demo.png b/doc/tutorials/viz/launching_viz/images/window_demo.png similarity index 100% rename from doc/tutorials/viz/images/window_demo.png rename to doc/tutorials/viz/launching_viz/images/window_demo.png diff --git a/doc/tutorials/viz/launching_viz.rst b/doc/tutorials/viz/launching_viz/launching_viz.rst similarity index 96% rename from doc/tutorials/viz/launching_viz.rst rename to doc/tutorials/viz/launching_viz/launching_viz.rst index 4b8bd5f93..56526ef4e 100644 --- a/doc/tutorials/viz/launching_viz.rst +++ b/doc/tutorials/viz/launching_viz/launching_viz.rst @@ -18,7 +18,7 @@ In this tutorial you will learn how to Code ==== -You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/launching_viz.cpp>`_. +You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/launching_viz.cpp>`. .. code-block:: cpp diff --git a/doc/tutorials/viz/table_of_content_viz/images/facedetect.jpg b/doc/tutorials/viz/table_of_content_viz/images/facedetect.jpg new file mode 100644 index 0000000000000000000000000000000000000000..788b7d8262b75bc416edc75495663d592fa1d4e2 GIT binary patch literal 17902 zcmeIZcUTn5*Dl(_07FJ{WT0D(Y&D*6Z9 zt`IbuM>hJyJqv006;9OLzC@7w` z_HtLy)_w&1FT>dsfYt;6~AN)r*xhJ}UXdLzj+y9Nz{$Q)Wars{|PjnU0GR**hLtts?X%7JS{pfTi zUu%1`9{f!-zVB+|=!&+V8jWSG9V~6o_!%1Cb8&I|gI}UCr`3PaWB*^UrKQ!sIxQ{j z|HXgXg1!@7@Iyy0_ve-Ye_i~4d2o5|gKn?C0welJ;N`5Rfj-ls+sxnEQc3S0>|m?* zr_cUMclUmv`ww>XR(tXfcJNWv{|Eax>nr?&o!vD4m3Oszto2X2wU;8g?f=#p=8AUyyqB-uzv+PvijV)1ak5nZ)8Bv9&C(N%{s*>wuJUiW?%vw}*37j(&_E_|Q$QOK1cU%lKm=d{^Z+G57f?eV(bC?w{^)T90E%wz0iKTb4&F=( z=$T-9k4eqdn(rQy;C%r>;Lp7JBLe`(Gk?t&5GBrk(!6E>Kw208Fa`gUW&#C(Pb~m& zC;mTa>L}6p#Ys(KS>Dw16jo zAz%hr0}g--;0gEv!N3b33Wx=gfOH@m$Onpna-b6U4AcY7KnKtZ3<0CSBrpdo0qejH zfB?>bEA&DF0TF`8Kr|pIhz-O85(J5ZWI;-xM<890A;vA= zdJn1wHG(=o1E3$EpP*&X7U&3ci2=qSz#zw9z+lJV#}LO*z|g>Wf?@C7C|CK)CZCNHKGrYfdBrZuJqW+-MHW;SLyW*ufX<~ZguCIS!FR+D!_UJ1gx`<9jDJBuO2AE^NMJ(XLy$mFM$k_1li-+;kdU2Fp3sQU zn=pa!Jz*E&0wI!!jEIj&jmU-wMwCNTM>IyXPmD{>_$p?}Fl1)+wDLbhWsSW8%(qhss(p54r84H;r znKfAiSqWJW**ZBkIS08Kxf6LTc_sNUIf8@CROi%m)biA})G^d>>PhNL8YUVg8fThhntGaFw3xKqv^unY zw0X2Ww7YcVbW(KIbTM?F>1OFM=(*{2>4WHt>A%sRGB7fzFt{_kVd!GmWu#=3XLMpr zV{B#If|5aHp^nfrXd85!iGoRi={ZvtQ#TWWnVwmd*@wB1d6@a?F2`N{yWw}?cYm?q zv52$Sv81tdvLINYteULBtQD-YY`ARVYz}OhY<+C!>>TU{?9uG??3*0a9BLea92Fe% zoP?ZmoF1G-oD*EwT;g2LT)AAM+!)*<+z#A1+#@^~Jfb{~Jh?nS?qS`NxaWGW=-xCh z0j~nDFK-3!G9M-1BffCHdcJ*rR(>P?Wd1&W)P0fr&+nJqpA#SzP!|XnXc9OQ;_%0h4H!xR4Z;^p^ZAc_76rTQsTiWz{t*07`={py4-HZbmY(rH3wbtVNNeb5*kA-PdTLZ^bZV?* zoNl~sB4QF{GG)qP>Tfz=Mr-!mti_zz+|vAu1(t<@#RrRPOD)SH%Tp^gtG8ANYenl! z>m3_;n>3p(TN&FF+YLJzyA-=kdl~yw`z;4KhYW{ZM@7eM$3rJor+lY#XD#P4=iBE7 z&*3gOE*370uB5KcuH9~oZvJjR+f8o*JH|ULY@1uLf^&G=cf%!|4<0 zv+OJDo8yc0d+PVapTytQ|62fe!0UjGK;^)9L6||-L7lK?CH%V`$el zS#3-ms4k!mQSVT{)L_`~qfx!Fvq`F{_AB4lvS#MyoED0f#8$l4m#w#Lfo-Sl?(MrB z_8qI8=ACn0&$=eMb-IUpG3BnKJ?#Ruz$M2G6WiF~X5F7my0 zSai5JpL4(FK>pwx;u&K7(DU&2DDIf%xa>sur1Mn!bm7e9 z?CLxQNrNoE5WncVG`QTj^1FsyXWek!G@&$5^S3Uyx9*mnmVa>pF#3pLX9oaBWdJ~E zh~^5T0DwpIH}CyR0`xamN8>-7{ZIT8{u}Ff3IIj&0HBYKn(Y8k5C#D3=tzQ& z+VTMKL>|Bp68bj+e+Mr+A;G^82)`apO)_q8kI`Ha!UX^~)3>)*^|!Y-rD%RW3jpnB zfAj4>(ne@r8_f9!4SJ_J{5k*EaJvkIDfv61ZPU~QxY0Q{02YW8_+#;3Hi2l-9O!RL z)IoIrVqFmD|B%4|fM`eH4_W$Str0r@34b`_pXZ6O4t0iEao`2s$6YB*7wO7Er(@)3Joy^&l5~kz9zw z@}RndLiY!PRmjRS92bw0ikgO&jh%y&i(6PkR7_k#Qt_dZvWlvjy51B0rv_+xYHed{ zXYb(X*pU381XVPD*Dyyn3UAC^o-1`H`ztSCGSeh%HMzZ{H3P0uD+qMsk5uQ zr?;3- z-4p1JK-&ev@cUyp2__b^05++D4#d)f?5^Mo9P$Urh1DInEJC^n3MWt+`#y2QbI}Mz=xNQyc~5!E zT~oo%yrD?0{5|Es9Z8y7puz7Jus6$}LbP^_JqbC>Z1D@aG@3=JWS&ZEbSqbUydVqR zOV6FG4ccmZe}k!bxVS=|)aAhuE?qirMfvSB)z@sXa4xI3Rs75pyQi*r-Nb?I=85Jc zdm9r6If_@R8MDLw&#`I-lVp1x3kef!Fh8V@udTFUwJraK)pE!kN{rqD2-92O=Xl~Z z`OsM@ATTAYSyqVpzH*S?8-#s=jOxE=uT52|gw!ah@F`K+Tyal?x z%Q`D); zw=Uo`4W+M2x`25a^=HgC;=>+h$4hc_&XSogYKHdI_=sxPzrAz&l*q%=R4BemK%pwW zcE|am6kR}e=tS;+3Mi37=*i8-9r?r)-vU@|H|Zj*S#Rl7PTH2*D3Kpl7S2(mDXkU) z!n!!YsSTwznvD|ru3$f?`W|eV6}kvthocy6uXJFe)(>uh4!2vtR^?iH=&a}#DCmv6 z1;Q6mgSC}LB2E(JM~g)>!|5~+xCQ+}MmGCa7GtiR?R^kcJDrj>qtEJNz2{7=#unyP zT|btjlDdYL$6!B8XxuX+M0l;Z^}Y_au5>_gO}$H1ZAe*|tYuLCxo*BknW}UA^rt+d zE>6)Gm&$bNUNsN%SLiN0=AVs4MbJ{A@L^ZnCvH(~b<=wzhcLq&1*D&4=?)d5AO*(r z_({Sq+;&IS0E}{u(#Ma9gkpx?(0YD3IfBKQ*HA>Zb=gd~)dr35of}*|s+-y)XsYcF zyzC%QdP1Rpg=?=pqg(J6!E>V7tX!BwN?;#@@($%fP01m&iNkm7<+^2{8si`N>4u_E zQk?rt$?e07f)Y4{aflfX2m_&i-+ynTNY)n}`4eT=tPxiyuufIEHuE9#|1Oh=49MJ5 zx&;*C@&E2ASsOlOm~K8Ih4|pdEr82}x`FY+{%7OmmVcYqQr%z+^Iucm0%uRWnAYr1 zx&9W0{<(4bX!;f)7Q88M+Y~5-E!E!wpNs!*Jt|1_PdU^1!H*6@3$2&)Yqz?z(^nf` z4N<0fNGBgBmF>h$9~=I6UGLD79X+}{MdAsdSJ>zp=%?H6IS%4!ie@+cGXHS=a5$}u zihM7$Y@e@i6-JB9>)laBOtcD)`ebS&wvAp!7AHDlhKruEFoig8yI~{qO<{POknTd| zCf+2Iq@VZNtv$|}FhU04zYS1~&R4pyQRj!~arkE$(fl))LMO~ms7Kon#^_0HAPXiy zJjs=qOjik7Fun|=u|$j)5~*npoZD~w3JJO5^M^k`7(~Gwv`BU&6N;^Q>!WumXICF) z;J_nVE9^?-?Vg%FsXIu^{o3RMPaBT^$kpX&5Ozroz2;I*{utKo=vQ#R0|T<=b5a#i zb0d5UL|!bx@UHJ6O;?ETIAx=1X1|59Wvq62;!Efm8MNeaDwkdfQZpyA>HC{!((8}V zIetMVE*s47-{W2RQF*UfxK5JRiPCE``|4vx(na8tF58}W-4(3yd@JtKOFjM~7opy{ zHeqy+TDV(4k;ofvYx@;4a&0n{rJfHfw(RW z3M}dg_b;2FpV5mPFX|iYL;?xB1t0^rKo5Gf64YM_+ybK;%eTNal;aklGEas5l&rr2 zyWRo^L+G|+9;?-v*8F-4wDF@Tc3~fdO@v1%>8C#v-M>$;*Z;05!S>;)CuQ)8fOv=Pr7V59W1 z>nMerL}OIA?Rnd=oB?b(;})=!yQIICy9FZFZh@7ZlbkaFqznSyWrlIco{AX01s=7g zIoY`=JLA_jJ+E@7eCvtJ|~ zTG5KUoPrl@kC$aiJK|ICCwUv*wXAKIKH`am=IHhQIMeCsB|2}ay#-i(ECnyKoZcQ) za`8MrK-r&49A++4b-9rs!MdZeyc(s({yf@wIClB^4aN>BS_0}M%q-3rf;bX8=1^D{ zDXc?IZqpCphN3{P8GSs5QmgrU0#{0?A3SABhvwZ)dBvrMVsG5a6rInUZ9;RdOF$ad zaoHC`S5kTscY8OWrvq)B&3fZ<#Ro_$EhNXr4H1g)7U(R5A=jaZ?tFyS$R)!y9lE>F ztN-C3%3bgAM9J_FT}I!zmGup``EI;D>V;q1Il7lS!{mzd|F@KQv{j$xUt%rX0*leN z0G{0cbOoRiV9T%Nmh$sYq>y6hZ1kVZYWjuVRnRrdO};D%a=K&Iyd6d{vt1End#|as zDktP@#)Vq&)vHtvtQWymu$PRdh>bJZFSmgF*TpNuEwHS16aNu5%6*KwmP2YorrL0Q zav|DC&1GIPZNz!B=2Xt1O4sgDzg2DH#NGn0LW#!f8R##9yWz@{{oj?YOuMH8;V+~$ z%D)HMuE;!{I@rsjn&5YVv;LTp3TL^iDzBXqW%VI|4tMius}8DfDm)!E)H3_nV@+1* zB53^gxX4blpjO%90M}AYvTEP)-7rDUO8#9JYt##a{J+{Q@xNY#$tje6iPG;X|24DP zVk7P1#*xV#-$HSS9$Y)q#_P8LQJ{CZO>Ke=7boWZeNOP3nKD-H)h!)rm2+&_^iXHD zduuFG1#&)#Zq}Md1MQf0VM5;&t2z=3N&|S_E?G0ChZHki{?1un@)SQQz++V9*iRhH z9_6vwqbUBgMxZxEL_|J{Wh$vAeAQo7L|-^Sy)6}U?y!4LTCqfxS*iQ=1W{D8txKSN zqSO90^T%BFjs7=nKT236b{)Xq%f?;38J-Q^ovTI6`}74Kh{(_`_DJe3{`^o?=Gxc} z4Qv5-&uT{1TC>gDQrejIBp%`&?UCuZ5S>3ywIhZb0js)fDKxz7uXw^0`mf?q6aywk z&1C&?IU$MGW*czF45Q|)atBQ5G2(@8h|y}T8?jUQi+$mN^YW_>+`&;uMmtoqRqYdj zAT)=iB~auGYxz6*0eX4^<{-D<4||l|-JhK58HYl1^Z2>7PG9#4gBq9^eB*AoJ?^Zo zLl6~Aek{TTjAon1TUboYz~sEP2c@2k`r!Z*|tsS+bAz_*Z1&nm$U( zRKEM(lWj@3xL~>8b)9`WWFNK7d$!L&?1Op&Qthn5`y5Vaqg8s7|2vUQD8B5&v~jiC z(pq5PlhDWhJEsLitYzPDItm_YA!0Vm#zU4G9f?#L3;i34VP!n?&Hek zI=%|)s}=7i_w;y?=Kz)(?C9mL-5sz8n`oR^g8{5g|jY(4%JQ;#a=S%^sykEnUa}X{=i5>ySLj z3esdWEpCpWxpp=|D)y?;DV_;YyXL8{9-kKAuXfAQA@Z_mm0y|e^`%7w+0UQB`5KVp z?+4ruA1uwS?e=e7oSjuAY%KRBY!Fp<&q)lQ&_|f0_jNJ^*z>c!CLRd+AZ3s}^0F`{GUDSk7_++?Du^-Su(%yTs1GmWaN4 z+Wo$kpOiVl#W+J<7{u?y;adh)c~V)J22RXv3SqnV>2~xf9eTPmydnr^ed4bYwS!^+ zyWy7a%w`@2aSv}~oJ8euPEW}}1~k~I3<2-gsJR7Y4z=@EV*pE*!vmd-8I(Rp!RmB2 zu~{1EO$pLZ4e>pLcLh{El=tk)z_P%>uRfmldzVOMS_C_jZwBMXApI8pN1A%NH=BeM ztvHIKsiWE3@cq@KfwI|8B;7qGi7PDAvtiPgrf!{6vlWgBsS42ov90=kLC0^srr-IX z9!-7tJQ#e%GG+@EytE-IUijpbk3YLZ5{0P}82d7dQ{v2WKFC0(#5p@Z!j(#M(!y`N zg(minRE^E4xz2<(q$De?oF__GoaOCQ@MVBURwj{L^i=&`QQgUQp4l!xlVST;j8!LK#!tZS;MeTDfl1KtmvISX4-s=Se)F)ui+YA{j>2%xBO zmp=M}b-xo|I$D|&oDvcla*ilI)1KJ(_7Ao`wA+)WTgCy>d0jiWq z$mz~}TX%;CG6q6L#J(QJmSkpmym?w8=3A8-A3 z64LjqSI)aeqMy1H2h$_sbmzI4YrpG=N#%jKi8%_k<$Q_T9)m+7VOo+<13G}tqMzMa)jo8mPLv`iw0OVEAB2mxVY0;*H zT#?*sn+hcllK6>pOxla$-dW|scOT7MSLrpgT+=-B&7E#OLg}udtFZzF*DeUn%9~;v zzS=US=xDi~n&7VOG6b9%`Q?gvZbz0rvj+yLeR!x9X|Mae?BHo0b01FE0ZD3-dl$nd z_(( zI}%f6F<$xnU7m9p30sYWT2gg8^+CS+4VK>W;!Ni9!<1(#jy{Le-J`wlpKn$PcgrM5 za)+y-jzKf-pyH+cs6`@}%`d^ZZdtx7su)=rGt$v#N_@zgQ5DN;Ch&Pb!OzYmgFIwc zA0t09w!E%*CFHSV(Si{^8>@mVv5nc=z*9Ia!q{nnDet%^kF7QD>e<9QAx$68o;+ol zopBqx3lanHgm(cRK4wyq>V?b)g@FxL@GQK8Y|uT3==9!GOxZEDc?XQ|Uk7R|f`5IT z9FbIFvaooXo}LJNI_rC9()6iYspyct68J)g9j(fPj2uC4Oro@;~v*sy=?Rq9g z;=uLaPv>#OpQD%d6Sr=D%wU0=FWwC5bQ=a6M6%_f!6<3^h$H8;-Xi4$*+F6Q0#l{RJG{VL1sS=8XZhK$pX?z;1& z+^Pg31x$nHV0i>A>K1SriF{wQBStv|t>KSk&TxjrKb6~if`9HAdL%{zT*pVmX+zdq z^MeRaYlJ$l>N%yoVnPK{uPgF@2=i)mPG2rYoepW_@H#(kaNzq`l~gg;-%PXY z4&eJgE8ZJuKS94J_zgE4cyIK1Zq8JwaM>y=AS^^GM%N%kStimChSx0KDtUMwB~54h zThp(?w1of6XTfC&BG}(o6e-`wde#>RT#229j-J4yU_?G`vt%n69js4Z{n(u9kKpHI z1BV3)z>-6-joPG}{Z@1BR}A7^o0TfJ?G8*Q_=JRbf~yl^Vj!R=7R2w+&*u*QeGevr z6^ereYo-@Q+RaE_SfB>Rv-Vq>01O;6RV9#0qZ6{L^Xb!Bc%t{51_N8o6&=&(oB#s? zgA|&Ukv3t_X;o6Pqh!dta+Ch#4=9;!l|#m4XSr0L&{9vqC-jk3R6W@hGY=Jou-!w$ z42C2(VnoQB*~f4n#i)sIcoY!V^(6$$#%Y^%OSI3=3{++G^;}|pBY`iICEqN^TsKcj zE0&krrMv1Jr^vHpFT2VzIp1mM>0X|=F5_U*hU`i1h??p4XX+#sms|F~)AXfz@$%bO zj}C?ocwY$JN_`BeL#LA%cR}KcxSWo;$+Z+RQnu2bYK}wBF)lgo^!!pAGHWHJ=2znh zO6dHkY)w*bB@}a*%ipc*eVkQDU*|MA9h0&s(Euc_@b+?o#}4@JY8%dQ>P#5m2Lz`= z#JBw!c7_jRxg6a4KbbkV(C35S7tzZ6e2v2D533Zovf^6rQB%> zn!2hRCESOBuD9&#Tm4g9T=#@SWLkHbq8oE&K;x(Hm-NSZha3?~MTSEit<8+KzecVq zrsd2B!?+nl_tz9TUe}VmGaQuHz_)H)vD{SMI-$6vyW*SOlp~UbUh5)9d`cL29*usS z9c~{4Ye=ON40omA+C|FC_|YOGy0VqVG(_LIIG<5>rd+mGU(LOd`5_lQCzl@b?sm{^p=rCr|{}w&`Z|5uNv1L>RWvo!LN72%38-RMzGio$E~R-D{4$d0@!L z=kv?$Jd^Be$~PV2M=2i0P<(ISTi|6^H*MPR5kVgNVM?OzMB?nN`AFO4 z78M;IW2O%k=M^t&kU>6PA!p84j+pn{zhE+_ov{W6O^+?&NXvvQ?;xM94=F*3V9iq6 z5I>HWwK)vJ-+w9_MtLQ^^Vf#IwTVoZAjVz7pg7dh6QlJRH&k7$7;kr2O;7o~<4Iu8A8V zFIXM)2rpsm6BoI3xzcl%Gl3GYT5$y+q<-*%>l{E67>4zwN4WO2&ip^s8|NltnYKz&Ee z-#kn%7YGe7MYeT|{ivDsP0J949p6;+--T)un@=^WOjfb_1~i9w{m#?+`P>#w$(J}9 zDi^Cac{pYn>EfTB9G}HbbL2lix&H8@tyTA-?^%CtlFC~=;NV_OP|7Xf9K&9{IITM= z7v#ls3s_3>8k0F(3e|SwjBoRv!}&(uFy8{+zSlf&o2Oi>jJ;G1WFGs`c4T-yOX;p} zEFe}ujkQixvc+)WWN+(7iFys#F{_N)OiwM=Yksdw4nX*IBymQWLgi&$N)$;{8jAQ9 zepz{(Tu%1{K3s=(%_)Ny+lhiuCkE3{gm!@FwHcy;BVrlZb`m@RI+PZw&Jb*r-e9af z-RMf@anK$T$8e733$m_1fhXRx#rGgtjToJt3nhwtUZcs)XBeFRJb9c&ZYoT2U~lCO z(F&0a&&w(AYHzms7@ZUeWg6_S@1I;e-wv=wKaVhkKlm0AdjDD6C}hMaG2HFtktRK< zH3uR23#XQ{$XYfFwq_D`*&PXMvpqkuVQQ8=!anj0GwS#(4N)7*QSqfva?o!bq@CSS z22Z0gdeg}-iqvReodT)N9(m9s3zOx9Zm|iH3+HmF)?+v`v#?E|Ixtge= z-7x=)$a#&Q)&VvvW}7WD_jrj|{W7-uvPAc1iOxWLi#(j7Np&Mbvn*MjQNUw~j%RCX zdwUO0l$y1@+}tvOr#l#iXuWo#`m%LcU7s9*`#g&wf<9bwdiJa?S&b@Lnt3lrI{94F z>$2>Hb<$TO)qX9dVU=6JC`^{~M>AQaW2bR{N#4&V!4a&Ka_Tz|oWwj7D9h~ZxD^Zq z!g&_i5WJ%n3^Q>@Aolu`18hE)_)65{<#KTE2|lIY6V;r=1ETazxE%*> z8r|vZ3wmRvjoiR!K3*Y^RgM-`mzz>Ahg1Tdk`%3)Nnw<(ej172UljBS{cigAUlCNiu=kKcd^cm2Q)>mfSY5nX;$dL+-%+CJ7 zOa^HidBmqRM=E(Jl2jYgF`E}Hn)zWn(B{X75nC_b=9n_>j|or0LIk;!Yk*aZ7NOp{ z#zT1A@c3{=K;KPW;CgG{UVd+wI928+>AXprRQF-voV_}#jL!Wr-FV@LBlB`7EMjgd zOlq=4)W|hAglH;bcG*rlfG+*Bpo}0^Nbwbn&iR-5(m|Y6nwo6m@`{armM|+1OI4@L zZ`X|ico<9Dag9d9s73G35xAmxfjPxQu`oHgd;AKy+Ha3zZt%v!jh{U$2zGgaEw^;HRTq)pu0^56)^gV3f&IoU zX~8)6s2Bb_RJy6{!kgm)?Y}67E z{NaP&i-a0rA_iyvFhy#@FK|LM`9+Grw&b*gUsZ`A2%+`JK!C?&TZQ!dXVL&W@dCo$ z>Cy>1JCh6f)r8Y8wl1vSspmD?LOUB(tGvH+Ygh^ou(d89^@bu&s@_Q3miGC(GV7}f zgvHBK%d*sG&)0bJO?7Z=nW^}d<8w`#dQzWK?Bp>W^45J3oAoSwu*)G%4QHJys%i02 zWt|Tsm9h(y%Ee^cwYHdt56Gss3a`A(wBs5jG1&;en>T%~O9b?;F0?#1DrOC!`Sl&} zh}P6xUB{AfI`I`?XPprvn*72B&oFisjd;Q)$ZUme@QEB0Ti#oi+pv>;3?p?gpA~Wx z4f3P0aa5JtP2ia@efT|MKqg+&MRHJTC*Z(!wXUwd-pbD`4?D^)+=90r=PLkXG79Ff#n${c|(KbW6gw?FY-_-Gk-tBsajJ# z{ib?Vqod!((RNY>UX9i-w!SL|vsg82RLe&#S}Q%v*I3>`j$%G!G3wyNvX-EW z{v1;v&9Lk#=(Ex{(W~qLUh&N^u76e(Kg9S#Su;>BDwG&`&|OJhZ79+b>(kJ}ejidk z!rr=vsPA+G`zu&ys8(9Ok(ehpc?4ThiL4B9TPX{>rYCT(Z2FZzv2Q$_m4BuUQ;=uW zTGIOYRipa#yQ#It34(~<3RhV|r_#yhLD!Hm?|^2C)sdI?St;Lp;G6#JaB6tA2vQsI zooA6-n{Ll;>w}UwWqJ@o)zf%HDNP?{9Z3d%D(8bSo4R#{7_9I|g|Z{{Rv3$e+=VOD zx=f6RJBM+ZEbEj=j=mqIDDM)y=mCtTLz(>by2Mgvw1QbDSMA~}EwCNy!QrBDc||3S zjcThg>pID<ULqQ}?K zeT{I&Ny~`cQ8jxf-o5k(C3thqwe&tR4j5UvNv?WFmrq50A=q+)yxR5jZJH!3aN9SX zX;t{S_C}`3LB-C`&!+*23$;D%V8!tR7Q{)aW6W=dUYOrh-96TrQLX@pbVg-t?&D5p zU$uAI(X~KmpxVj^)Zy~;Map*{o00r4!&%g4G8I#-hs9c$TGgw31!-P``Rb=`cN}La zcKVaMXp*%E3W%J0gH?+5Q-{L#n5?-a^Nj$*W(%g;Hw#wf#jL3&Q!fq$g(vP$`SCV3 zWV%5RWpnveBt2Ft1$cq+z18B~Nyu6xynv4EgkAnf$Xl!hcTodIhCw)4zVR@xH_ zvB12^brja<-BD}&-;~K0ta(K(f)8D;rf&@QYZKA)EMQ%PJfQa)?Mrn8t~lb7C6<0^k=(8mozoi*C+6fsV+ZA*buo?xq4^< z?@W9NgUAwYRdwm9PU}t-0WP7q7JVG4EP2sL83E(`FZsK*<*C6@}#D(%~xV;)$BCu++PzEsL);)yDCF;LuN)H8~dql zWysbA+`A1=S|c&2*JM7d`ZN02(P=N867lShUuuZd){{7S z`c>)zd=Il{hFtZCzUY%1TJY4f)ZtvzXEBLO{jbJPTVMBd$BPWUea*)9`dZWep+x6W zzSFPjD42k$dH((j^egWP7_P{7mc9kTR;0kn#ScCbd`AN!#=({S-W8*86>B-KqQiiK`&H5}U5SF}`2z={OPVjM%ZcUJfAY(

!hSsQX88nw2ji{CH+NdP%9mjx%thfd-`3$}5*|bw*#Q=r24I)2_6! z2hE#P2tTif2=z#=RjtX47#*(`A;&f6>qVvNV6Iy^c3pA8ZfK+Vs!#50gKSnf)|E`&S zj8hEG-tsnOD@_vp2G`35PDUcl@N)Ev=XX5uG%@^{#JY7Cr99~Rn> z1Z3%iQHi5!8PcR$4sW+&&3b>PN9Q!d`ZoO^#@!8a^P%W zEtuEQ&DrC9FSCv(D^nx=s*KQufs08EbQ8tgNYnYau#Mh82ZT>wS@{$cgOu7^D1v3-@lXs;U**)(CoX#M#yaouW< z?sN1J&l_vtBwXYF&y(24$F)WQ^Nj1+qW@l%}aZ_)m zc4e?aUu{7l`yUDVr#{VgOLs8z)GYdo-v1WefPVb!%4a~0wbeYWEZ4MLStQ#IRLTkd z?3f`C5{Yr;vWD{6M7s*Le);I{)t$$ExR4wmWTxowijUQr+3E;G|Ffq8o+n{w(X}l? zr6X30V0#>Spi$kHF~z&^L>qNDe4jk;+xIw<2=n|rnlEF)LT(|>%X?hHS9I@#r|K7M zI7X?Y(a&C&SK6uV&>EMQ8FfcLk$x)(#hOo@P9XW^S65w$=a~#W!2+vr5E9-&`+X{N zCI0Tp;EEV`N>e`f68OA0G>+Je$M0E`D&O5n;n?@Qa4Yxa!ldHfu3{b{1xQN}M|7K` zbBKnfECji+JaH%%P0h`AdAD-1-sM+4W4>UztJLo>S+nY7tF8Ej$f6vSWl`52rD`kYVJLyR$=zqUv$BOuG5%VZ;>drIkUiZ*hqyQ@&_hSDQi&OUC}`RaZj z7K}}jW1IkOcsM88QW~ z!PF0WYT(GGc%)9LfQ+dd6l3x0<-~|8W7M5}d^lKI6D`5;fi8{ofl49a1#NneHa5eF zEx*e?xhHTVciCJ2q96N<59bgLJ-y{8t*Od~eM6dkztOw&$blkMM<`xxbwkskTo0X^ zYjND?xvk_(0{JCZS=6L`7xeRa_{rC(q*%u~M%v$^Z&44+Z+I3{F74`5I6sqJwFv2L zFHEBNHi8N}sRR^PacVPp=xBxeIN`5R^RF*keVbg-5|T+HFDP^e1mFl9fre zd2KrD{+vXgY;ErrZO_8H59Uspf|(gBb^zK>2-I1AhVeBWD<|MUo+kUHnfK!l-S>y- z#+u8t+n$;4UPiVqmA$5lFq`&pwR!b9aRDZI1Sj3v@ua`cCFqGu4ziY?s3l~-BsAzU znwXldUQTfii1TDVW68ce=#;BD@5T{6EcLH{G=8mVbq%fWrsyB>#2!xwgooB%EZdi> zS$a;5tW(zx7U}YIe|;+w8*Lnvu(e-amP3Nzjl6aO6z`ph&kHBd@^w0ah+`pctNMZM6T#*WWZb?tXOFRuMu4T(IR@2la0 z)YNI&$?jnNiO`;{habz5hk09SnG+w z@C=ODGS~E{JRi&kz8|gGwaOv(c7V5+wC5xEJJ=F;r8dF)-Q4|=T7&XEvd!j?4&NeJ zEz}yxiIba1%<@Zid;^;?jQv1O!p{TrfujCy^|n zxrFDEeH;nitR*M`4!VprHSyzH^1$f_vWLG7xQU2moGwqk^P`u{i!HRXVpE5l5Iz0V z+E*QHufGR8G$%(f+Hf73#w6k|B<5pDo`b3WofNf> zUTjYA#uYZB`bAjqAdi}%bvpzvXc|)HpQ@>PS8cyhAIvTW9YZ?~F0=g*NURSBmdM=@ z1w<>jp_~0@6(|dCWeJ(@0rR0;KeS(*El~s#qW!2sg6#`WoPQu$V3B~gf$xA|p2UF} z?Biy?8lC^?N!5#Hg91{ViB!fM<7@8pk=Mewo>-S8`|&9ByS+?WeiL?&MRMaU=zT2t zk#|00PO~&#bte{it;VoOR>`U;`pjmNpklOU729`$dl&u;{cwdbmoreWK(B|%dfO{$ z$(K~EdZ)^LN0qOF^_IHHHB!)CgSeucArIhrQs3gJkFV3C{IDf*sj&yci}t$!M5V!)}(h zWz!FT!MhJ2Ttmp1d153L(m;W@#~d69Mv(^T-vTe7hyvm@{Bw7;@LvmB@s_Q5sMuEYTIK#DC2LfLP@=~n2$Po+IvH5(atJ_ zEC?Y~jBfKgLU5&mm-w124_6nP3oWbCWu#I1B2WW528n#;?AH8kU zmIgYP`~PMCkK5q^awv%VV|TSUAf{&;StGgkO@lkU;0RpDvjUBR-LaUI4q0}QL8pv&rDKt{KhMM)Zq8*CGgFxBi6|eigme*3y&Ar>- zgO`1~K8|llyg$f2*15httTr$>z2nTYwR0pLyDNEqK90I7-j%!s{s8z#6s^DLZ~S~( znk;b`p_9Yc;>}*Nh*P*IdQ*<_7C;5TR`YKHuc+PYiPS%CUGYcF9%~q1kHq9tdfelB zP*#hCm$7=+HYf5U&RnglqL+}S_?03fut|y zelWC$Q}w06?`DJO4vXre&Lv0BPA+HPIT!Paxxz~ru9e5kZmW26h?(O+%e@peDR1K~ zuZv%YL}e97J>!XHsTI0_kF`0tkM!mqx%YQnBrKg%#G^eD(BGDf^r2)-(ckDC_cZaN z9e^D|#2$@3Q2PM0FqSR3Yayy?rkT?=d(?@dh7ZG#Mx^K)zQPs?esYC_(( zI245u*NRm_o!pE#3&4AtJ1Vm|Q!$*tm0sYFv(nR|7(n)aS1{ObT#?mFkwr!LISm6Y zmg?G_pgYbdbjt_V#|75LFY#81x>TC>_hO2{-$2wt)(yQOoJCEa z8s?R8>mRs^&9C)XxFaVr?&3Y2-3V+$=oy!vKSv5VeSM)6L~Os5_@H;r-oF)%6s>G zuBb8E$fZA!@smZkI1|EotTrFXE7mjDg16nJgw$IeB6L~hVtmg#@#R&5?0ISp28>=u z$-}C;_Ap+(xiNdk7Nz1!g{6r3)4Tx04R}-Ro!pfR1`mnZ(O7nKcKOW4i$^9Ra0BJ8yc;~21%2p=|UR0&DbiW z$#rfTQ`a`O(`{9s_5yDV_yd5l2Of}kLK+Oj_Ok5(v`JGz71bo9J#^YYXp{DWs&KBa zQ@dTpxRI}aIp=pi@6k0t$5)!;m`NF6-tt{FpOKHBn3g+MAqmexC-gw4rh87hTrL7G z#)U`L!(So6-Zux@>;H3gR;i~0B%VTSS3P|m@o9jRsXML@Al^p#@G0Lx-0?i(9WEw_ zSYddU<1E8793KxjQ|c&UmW!mTC>k>?{om1c9S zUx<6_jj_!T&^M{wWM#>IBbOSf*xP<^F{$j$aOQ5Y{cT zROCL1M7^NKKL z&(yA}mSw#iM0^;IB{ZO5!wl{^Sg-*ysE~&Yz8!E;Qv(A`lu*=Clo*MpVGd>OdF6n^ zam1Jntk;<}MrqIC5$=Q>n{*R}?8oOIDUw5En2dl--Xw34!z7E+5pr-OgyQ-soSab)C%saskMla`aQLVzg0+MZf20tJU&K{hZoBrUc+U4e9&3o zw|KmGEe4#xz17wBu{f`SS_4i66?j31EjY7n{zGfhONK~c+td!TS#B}JoR}5UAd7p& z5phTyXSkK0xCeD3xaYP^o&J~#Xp9xFb0C;HHml5fA<%h1eR|qw7wxF+oNL9T1Aits?sKNIwvGaN)^WO$I^cUV)HzL_| z1K?{9p!>B*)`xfEv!4N6IG{J&h49W#Bz^(#YWw%`e_a{8n{G9m5AeR~_yl0%<7V@p zp-RKpbss|+tQI79| z>p4gPB>~k^&a~Jdvx=FOuMpZA;-P!!h6xT;e4!9Jqd;LDC_mL>`rT&QF= zYV;5Voye)Jal*LQjI^5vfR*iDnR90YU*Lo9+`oKX%#v^GcwqNHGy zS(H~I&vOux&FzFz;NuBJTBH~uPyj+fn-9MGDXqPx<@C_|}Qqtn?V*BKaaq$JWYrpVENaC~H8FmHFObU`91TS>LmB1;SQ zyL(hx4af}rL7(sb%1*}=G^Hc)9ViC|X$t(3i_I)f=u#%7?sPa144FCt+fD)^Bm^Ao zlF0%g6_>yG42$nS#l*7Uz^!MwXx2FzRcOmTX|IP@DI+!q1i4FbBt&lP;kGp*bnuT( zQ&x3u>|Ei@!Q1hGs&&alfka^dfg(n;M!`NQH=cfslc#SczqCu%5-iA>j(W$z=A*ch zTGhuIgXj53A+Z*cyg&$tz*R_-Qy7a-k}OlW2(->IQX&v2$3Yhbhi*B>Hy?itZ=%9} zdxsgfK`ty#*+&%M1|fMA6O_xKEP0eru2$&}`|R(x$th^nCo$GgC`+gUtW-FTht3Ox zE3widl>}=MSX?2A`Xlaq;4TgU+88>U)dg+?GiNwU-+awwH8 z+9;wTXsqS=oNhyyjfz| z#qkVqnH*xuWr-|u0qpvZG(Kl-x? zh|tOcV-?0qED|Lh+yKxLr4;GNFu$}*EF&CI!$TniWLR2L?s}X8x0`Ep2GooS4*APl}5uQQHPNGXs&niZr*Vy!?b zDAEFnK<5Sri7?Pwn4%oi$&{w*2ABdy$pGI884UJGb&53>LWOT!RMjQT3$!s*OBJkv zdaZ@y1tdvArB9~^EwZv%luC5YqcgThjy2#10jNC{P z<6s?$L7-d*gkm)4kY(cmsSP+DXbVDyAPTS=Eesau-q=7leFn?xbcM$B+SrDRFC?R; zOIY^USy@L-y6EK&u2&|kOt5=(mn4g*Z41aELO+07ndtHwa$$-@WSG2QD{a#^2?jx6 z6gA;6Z$mC;%M?08^b?{eCEo7fOw_A1s~MxDAT0T8?e+jgAO%6$L-Zr0>yV@wRZmiQ zIm3~{xDYrFg)Jy_!St~MY;0~YDk7@Gkd8>0nyGO2;sHMNkvnkI%{=hI5A(@K{yAIQ zZOV;0SW7zUON?ONST~eI_Pa^ag$QcJ_#3jdDGL*u@owRDjhTf>M(x(qx&$^9-Q}>w5>7nHk~R zj9415l8tlcI8!=>+KH&#eg@O_`PxhK{LypQanc2(KZ)Icf$#gVdzpwX;(7wNS)tp# z#)m%geLQpRc^17I7uH|qs5*e_1spkhGlR|^(b_K6g`?~xf?=UC`y*QQGMn8^E|v`M z@lLUP?mUgTY38R|te(Gw+}+!w(3+ws#`?@!ln`jEaU6vZ5=S`%zC)u{rW}G57Ac_6 z8U&a^GaL;;skc>?I-Ok{p{ThfNOIyhL0iyKPO?8B?vKcYA*VpN0xB-MgI)UlF5B%L_BvhC zD8(YMT42&Xy3pj&8je$=$OTyrQh_Z52AA%pN3lO7PZW-IkwQ_SOtaY}Xicy^+T_o_ zp7F-x1!m}z=PptII*xRC_#AQvWR#8n0oR+2WaTtA1G z7c8DQOk4LE(&y6UbCgWo}TWoZ_9?_GCdbdD5;{k<+n z7Y~u^u?jRrK`BtAX-=zNCK?QJ9f?qaAnLTwi0ay+dFW$4{MRYipf}#w?K@^1+8b z$O8}D&%ng=qKKlC;N*tMsY#q#na1=4y*MUIa{Aebw8+VH21XJMhxm@m)Z7f(K#|2* zN1}C(mKCDzK0*P~!3srYEy*ZHhB^LZNFG|UK}veL$3#Ab5O78A&^9Gjp4Y6u{w!J2 zCCOs!XdC5M8Lo_|RwkI3Uf|lbR}f1r23J;@z5Og(>z61UJ;cSQUqfAwIni2V*bpSm z0I?pi(2<;&IYHemvy%_G++V>jg_y(;lpKDnbk+9yi|cEaEs0y08oeLppoA__Yc%t!bpE$ddxA6_|uH_V7a= zMUD<#`YTW4S1U;W7JMAEwd{6ETwE@gK70YUK7noq420qmIe+r0bC|ueY+U>bVSN_I ztsrcURz8|4e#@g@t+RIF89sXZLwx

x5ax<_qW0y#dAIh~p33!OG=L*8bsD9JfGY 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 Syng=>03dFf8`QyFV*UrqR@d7A literal 0 HcmV?d00001 diff --git a/doc/tutorials/viz/table_of_content_viz/table_of_content_viz.rst b/doc/tutorials/viz/table_of_content_viz/table_of_content_viz.rst new file mode 100644 index 000000000..c3d08fe17 --- /dev/null +++ b/doc/tutorials/viz/table_of_content_viz/table_of_content_viz.rst @@ -0,0 +1,94 @@ +.. _Table-Of-Content-Viz: + +**OpenCV Viz** +----------------------------------------------------------- + +.. include:: ../../definitions/tocDefinitions.rst + ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================== =============================================================================== + |VizLaunchingViz| **Title:** :ref:`launching_viz` + + *Compatibility:* > OpenCV 3.0.0 + + *Author:* Ozan Tonkal + + You will learn how to launch a viz window. + + ================== =============================================================================== + + .. |VizLaunchingViz| image:: ../launching_viz/images/window_demo.png + :height: 120pt + :width: 90pt + ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================ ============================================================================ + |WidgetPose| **Title:** :ref:`widget_pose` + + *Compatibility:* > OpenCV 3.0.0 + + *Author:* Ozan Tonkal + + You will learn how to change pose of a widget. + + ================ ============================================================================ + + .. |WidgetPose| image:: ../widget_pose/images/widgetpose.png + :height: 90pt + :width: 90pt + ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================== ============================================================================ + |Transformations| **Title:** :ref:`transformations` + + *Compatibility:* > OpenCV 3.0.0 + + *Author:* Ozan Tonkal + + You will learn how to transform between global and camera frames. + + ================== ============================================================================ + + .. |Transformations| image:: ../transformations/images/global_view_point.png + :height: 120pt + :width: 90pt + ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================== ============================================================================ + |CreatingWidgets| **Title:** :ref:`creating_widgets` + + *Compatibility:* > OpenCV 3.0.0 + + *Author:* Ozan Tonkal + + You will learn how to create your own widgets. + + ================== ============================================================================ + + .. |CreatingWidgets| image:: ../creating_widgets/images/red_triangle.png + :height: 120pt + :width: 90pt + +.. raw:: latex + + \pagebreak + +.. toctree:: + :hidden: + + ../launching_viz/launching_viz + ../widget_pose/widget_pose + ../transformations/transformations + ../creating_widgets/creating_widgets diff --git a/doc/tutorials/viz/images/camera_view_point.png b/doc/tutorials/viz/transformations/images/camera_view_point.png similarity index 100% rename from doc/tutorials/viz/images/camera_view_point.png rename to doc/tutorials/viz/transformations/images/camera_view_point.png diff --git a/doc/tutorials/viz/images/global_view_point.png b/doc/tutorials/viz/transformations/images/global_view_point.png similarity index 100% rename from doc/tutorials/viz/images/global_view_point.png rename to doc/tutorials/viz/transformations/images/global_view_point.png diff --git a/doc/tutorials/viz/transformations.rst b/doc/tutorials/viz/transformations/transformations.rst similarity index 98% rename from doc/tutorials/viz/transformations.rst rename to doc/tutorials/viz/transformations/transformations.rst index 0bcc7db60..fd7cafe71 100644 --- a/doc/tutorials/viz/transformations.rst +++ b/doc/tutorials/viz/transformations/transformations.rst @@ -17,7 +17,7 @@ In this tutorial you will learn how to Code ==== -You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/transformations.cpp>`_. +You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/transformations.cpp>`. .. code-block:: cpp diff --git a/doc/tutorials/viz/widget_pose/images/widgetpose.png b/doc/tutorials/viz/widget_pose/images/widgetpose.png new file mode 100644 index 0000000000000000000000000000000000000000..ef8a5937f9c3e18507acdefc758102919c2efdb8 GIT binary patch literal 40892 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 LUA9izJp6wE?|M7Z literal 0 HcmV?d00001 diff --git a/doc/tutorials/viz/widget_pose.rst b/doc/tutorials/viz/widget_pose/widget_pose.rst similarity index 97% rename from doc/tutorials/viz/widget_pose.rst rename to doc/tutorials/viz/widget_pose/widget_pose.rst index a0cb00f5f..18df97033 100644 --- a/doc/tutorials/viz/widget_pose.rst +++ b/doc/tutorials/viz/widget_pose/widget_pose.rst @@ -17,7 +17,7 @@ In this tutorial you will learn how to Code ==== -You can download the code from `here <../../../../samples/cpp/tutorial_code/viz/widget_pose.cpp>`_. +You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/widget_pose.cpp>`. .. code-block:: cpp diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index d5302fc86..ad7ca7f8b 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -28,9 +28,6 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) if(HAVE_opencv_gpufilters) ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpufilters/include") endif() - if(HAVE_opencv_viz) - ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/viz/include") - endif() if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") @@ -58,10 +55,6 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) if("${srcs}" MATCHES "gpu/") target_link_libraries(${the_target} opencv_gpuarithm opencv_gpufilters) endif() - - if(HAVE_opencv_viz) - target_link_libraries(${the_target} opencv_viz) - endif() set_target_properties(${the_target} PROPERTIES OUTPUT_NAME "cpp-${sample_kind}-${name}" @@ -90,9 +83,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) ocv_list_filterout(cpp_samples "/gpu/") endif() - if(NOT HAVE_opencv_viz) - ocv_list_filterout(cpp_samples "viz") - endif() + ocv_list_filterout(cpp_samples "viz") foreach(sample_filename ${cpp_samples}) get_filename_component(sample ${sample_filename} NAME_WE) From 8de46e1f81dce5efd54fbdbdf8455bf7984f4504 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Wed, 18 Sep 2013 12:50:55 +0100 Subject: [PATCH 200/205] removed trailing spaces --- .../viz/creating_widgets/creating_widgets.rst | 44 +- .../viz/launching_viz/launching_viz.rst | 30 +- .../viz/transformations/transformations.rst | 56 +- doc/tutorials/viz/widget_pose/widget_pose.rst | 58 +- modules/viz/CMakeLists.txt | 6 +- modules/viz/doc/viz.rst | 2 +- modules/viz/doc/viz3d.rst | 122 +- modules/viz/doc/widget.rst | 202 +- modules/viz/include/opencv2/viz.hpp | 18 +- modules/viz/include/opencv2/viz/types.hpp | 20 +- modules/viz/include/opencv2/viz/viz3d.hpp | 16 +- modules/viz/include/opencv2/viz/widgets.hpp | 40 +- modules/viz/src/cloud_widgets.cpp | 68 +- modules/viz/src/interactor_style.cpp | 14 +- modules/viz/src/interactor_style.h | 6 +- modules/viz/src/shape_widgets.cpp | 398 +- modules/viz/src/types.cpp | 50 +- modules/viz/src/viz.cpp | 12 +- modules/viz/src/viz3d.cpp | 2 +- modules/viz/src/viz3d_impl.cpp | 28 +- modules/viz/src/viz3d_impl.hpp | 30 +- modules/viz/src/widget.cpp | 30 +- modules/viz/test/test_viz3d.cpp | 24 +- samples/cpp/CMakeLists.txt | 2 +- samples/cpp/tutorial_code/viz/bunny.ply | 11480 ++++++++-------- .../tutorial_code/viz/creating_widgets.cpp | 30 +- .../cpp/tutorial_code/viz/launching_viz.cpp | 16 +- .../cpp/tutorial_code/viz/transformations.cpp | 30 +- samples/cpp/tutorial_code/viz/widget_pose.cpp | 26 +- 29 files changed, 6430 insertions(+), 6430 deletions(-) diff --git a/doc/tutorials/viz/creating_widgets/creating_widgets.rst b/doc/tutorials/viz/creating_widgets/creating_widgets.rst index 0d9b288c3..4646d7519 100644 --- a/doc/tutorials/viz/creating_widgets/creating_widgets.rst +++ b/doc/tutorials/viz/creating_widgets/creating_widgets.rst @@ -21,7 +21,7 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial .. code-block:: cpp #include - #include + #include #include #include @@ -43,7 +43,7 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial class WTriangle : public viz::Widget3D { public: - WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); }; /** @@ -56,22 +56,22 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial points->InsertNextPoint(pt1.x, pt1.y, pt1.z); points->InsertNextPoint(pt2.x, pt2.y, pt2.z); points->InsertNextPoint(pt3.x, pt3.y, pt3.z); - + vtkSmartPointer triangle = vtkSmartPointer::New(); triangle->GetPointIds()->SetId(0,0); triangle->GetPointIds()->SetId(1,1); triangle->GetPointIds()->SetId(2,2); - + vtkSmartPointer cells = vtkSmartPointer::New(); cells->InsertNextCell(triangle); - + // Create a polydata object vtkSmartPointer polyData = vtkSmartPointer::New(); - + // Add the geometry and topology to the polydata polyData->SetPoints(points); polyData->SetPolys(cells); - + // Create mapper and actor vtkSmartPointer mapper = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 @@ -79,13 +79,13 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial #else mapper->SetInputData(polyData); #endif - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + // Store this actor in the widget in order that visualizer can access it viz::WidgetAccessor::setProp(*this, actor); - + // Set the color of the widget. This has to be called after WidgetAccessor. setColor(color); } @@ -94,22 +94,22 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial * @function main */ int main() - { + { /// Create a window viz::Viz3d myWindow("Creating Widgets"); - + /// Create a triangle widget WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); - + /// Show widget in the visualizer window myWindow.showWidget("TRIANGLE", tw); - + /// Start event loop myWindow.spin(); - + return 0; } - + Explanation =========== @@ -122,33 +122,33 @@ Here is the general structure of the program: class WTriangle : public viz::Widget3D { public: - WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); }; - + * Assign a VTK actor to the widget. .. code-block:: cpp // Store this actor in the widget in order that visualizer can access it viz::WidgetAccessor::setProp(*this, actor); - + * Set color of the widget. .. code-block:: cpp // Set the color of the widget. This has to be called after WidgetAccessor. setColor(color); - + * Construct a triangle widget and display it in the window. .. code-block:: cpp /// Create a triangle widget WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); - + /// Show widget in the visualizer window myWindow.showWidget("TRIANGLE", tw); - + Results ======= diff --git a/doc/tutorials/viz/launching_viz/launching_viz.rst b/doc/tutorials/viz/launching_viz/launching_viz.rst index 56526ef4e..0bf31977d 100644 --- a/doc/tutorials/viz/launching_viz/launching_viz.rst +++ b/doc/tutorials/viz/launching_viz/launching_viz.rst @@ -27,7 +27,7 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial using namespace cv; using namespace std; - + /** * @function main */ @@ -35,38 +35,38 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial { /// Create a window viz::Viz3d myWindow("Viz Demo"); - + /// Start event loop myWindow.spin(); - + /// Event loop is over when pressed q, Q, e, E cout << "First event loop is over" << endl; - + /// Access window via its name viz::Viz3d sameWindow = viz::get("Viz Demo"); - + /// Start event loop sameWindow.spin(); - + /// Event loop is over when pressed q, Q, e, E cout << "Second event loop is over" << endl; - + /// Event loop is over when pressed q, Q, e, E /// Start event loop once for 1 millisecond sameWindow.spinOnce(1, true); while(!sameWindow.wasStopped()) { /// Interact with window - + /// Event loop for 1 millisecond sameWindow.spinOnce(1, true); } - + /// Once more event loop is stopped cout << "Last event loop is over" << endl; return 0; } - + Explanation =========== @@ -78,21 +78,21 @@ Here is the general structure of the program: /// Create a window viz::Viz3d myWindow("Viz Demo"); - + * Start event loop. This event loop will run until user terminates it by pressing **e**, **E**, **q**, **Q**. .. code-block:: cpp /// Start event loop myWindow.spin(); - + * Access same window via its name. Since windows are implicitly shared, **sameWindow** is exactly the same with **myWindow**. If the name does not exist, a new window is created. .. code-block:: cpp /// Access window via its name viz::Viz3d sameWindow = viz::get("Viz Demo"); - + * Start a controlled event loop. Once it starts, **wasStopped** is set to false. Inside the while loop, in each iteration, **spinOnce** is called to prevent event loop from completely stopping. Inside the while loop, user can execute other statements including those which interact with the window. .. code-block:: cpp @@ -103,11 +103,11 @@ Here is the general structure of the program: while(!sameWindow.wasStopped()) { /// Interact with window - + /// Event loop for 1 millisecond sameWindow.spinOnce(1, true); } - + Results ======= diff --git a/doc/tutorials/viz/transformations/transformations.rst b/doc/tutorials/viz/transformations/transformations.rst index fd7cafe71..e4d72c6f6 100644 --- a/doc/tutorials/viz/transformations/transformations.rst +++ b/doc/tutorials/viz/transformations/transformations.rst @@ -45,7 +45,7 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial float dummy1, dummy2; for(size_t i = 0; i < 1889; ++i) ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2; - + cloud *= 5.0f; return cloud; } @@ -54,40 +54,40 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial * @function main */ int main(int argn, char **argv) - { + { if (argn < 2) { cout << "Usage: " << endl << "./transformations [ G | C ]" << endl; return 1; } - + bool camera_pov = (argv[1][0] == 'C'); - + /// Create a window viz::Viz3d myWindow("Coordinate Frame"); - + /// Add coordinate axes myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); - + /// Let's assume camera has the following properties Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); - + /// We can get the pose of the cam using makeCameraPose Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); - + /// We can get the transformation matrix from camera coordinate system to global using /// - makeTransformToGlobal. We need the axes of the camera Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); - + /// Create a cloud widget. Mat bunny_cloud = cvcloud_load(); viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); - + /// Pose of the widget in camera frame Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); /// Pose of the widget in global frame Affine3f cloud_pose_global = transform * cloud_pose; - + /// Visualize camera frame if (!camera_pov) { @@ -96,21 +96,21 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial myWindow.showWidget("CPW", cpw, cam_pose); myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); } - + /// Visualize widget myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); - + /// Set the viewer pose to that of camera if (camera_pov) myWindow.setViewerPose(cam_pose); - + /// Start event loop. myWindow.spin(); - + return 0; } - + Explanation =========== @@ -122,17 +122,17 @@ Here is the general structure of the program: /// Create a window viz::Viz3d myWindow("Transformations"); - + * Get camera pose from camera position, camera focal point and y direction. .. code-block:: cpp /// Let's assume camera has the following properties Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); - + /// We can get the pose of the cam using makeCameraPose Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); - + * Obtain transform matrix knowing the axes of camera coordinate system. .. code-block:: cpp @@ -140,7 +140,7 @@ Here is the general structure of the program: /// We can get the transformation matrix from camera coordinate system to global using /// - makeTransformToGlobal. We need the axes of the camera Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); - + * Create a cloud widget from bunny.ply file .. code-block:: cpp @@ -148,16 +148,16 @@ Here is the general structure of the program: /// Create a cloud widget. Mat bunny_cloud = cvcloud_load(); viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); - + * Given the pose in camera coordinate system, estimate the global pose. - + .. code-block:: cpp /// Pose of the widget in camera frame Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); /// Pose of the widget in global frame Affine3f cloud_pose_global = transform * cloud_pose; - + * If the view point is set to be global, visualize camera coordinate frame and viewing frustum. .. code-block:: cpp @@ -170,22 +170,22 @@ Here is the general structure of the program: myWindow.showWidget("CPW", cpw, cam_pose); myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); } - + * Visualize the cloud widget with the estimated global pose - + .. code-block:: cpp /// Visualize widget myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); - + * If the view point is set to be camera's, set viewer pose to **cam_pose**. - + .. code-block:: cpp /// Set the viewer pose to that of camera if (camera_pov) myWindow.setViewerPose(cam_pose); - + Results ======= diff --git a/doc/tutorials/viz/widget_pose/widget_pose.rst b/doc/tutorials/viz/widget_pose/widget_pose.rst index 18df97033..8e1cfb7c9 100644 --- a/doc/tutorials/viz/widget_pose/widget_pose.rst +++ b/doc/tutorials/viz/widget_pose/widget_pose.rst @@ -35,22 +35,22 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial { /// 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); - + 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; @@ -61,25 +61,25 @@ You can download the code from :download:`here <../../../../samples/cpp/tutorial rot_vec.at(0,0) += CV_PI * 0.01f; rot_vec.at(0,1) += CV_PI * 0.01f; rot_vec.at(0,2) += CV_PI * 0.01f; - + /// Shift on (1,1,1) translation_phase += CV_PI * 0.01f; translation = sin(translation_phase); - + Mat rot_mat; - Rodrigues(rot_vec, rot_mat); - + Rodrigues(rot_vec, rot_mat); + /// Construct pose Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); - + myWindow.setWidgetPose("Cube Widget", pose); - + myWindow.spinOnce(1, true); } - + return 0; } - + Explanation =========== @@ -91,14 +91,14 @@ Here is the general structure of the program: /// Create a window viz::Viz3d myWindow("Coordinate Frame"); - + * Show coordinate axes in the window using CoordinateSystemWidget. .. code-block:: cpp /// Add coordinate axes myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); - + * Display a line representing the axis (1,1,1). .. code-block:: cpp @@ -107,7 +107,7 @@ Here is the general structure of the program: 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. .. code-block:: cpp @@ -115,8 +115,8 @@ Here is the general structure of the program: /// 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); - myWindow.showWidget("Cube Widget", cube_widget); - + myWindow.showWidget("Cube Widget", cube_widget); + * Create rotation matrix from rodrigues vector .. code-block:: cpp @@ -125,20 +125,20 @@ Here is the general structure of the program: rot_vec.at(0,0) += CV_PI * 0.01f; rot_vec.at(0,1) += CV_PI * 0.01f; rot_vec.at(0,2) += CV_PI * 0.01f; - - ... - - Mat rot_mat; - Rodrigues(rot_vec, rot_mat); -* Use Affine3f to set pose of the cube. + ... + + Mat rot_mat; + Rodrigues(rot_vec, rot_mat); + +* Use Affine3f to set pose of the cube. .. code-block:: cpp - + /// Construct pose Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); myWindow.setWidgetPose("Cube Widget", pose); - + * Animate the rotation using wasStopped and spinOnce .. code-block:: cpp @@ -146,10 +146,10 @@ Here is the general structure of the program: while(!myWindow.wasStopped()) { ... - + myWindow.spinOnce(1, true); } - + Results ======= diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 74c9fd116..140f916f9 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -3,7 +3,7 @@ macro(find_qvtk) 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) + 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}) @@ -22,7 +22,7 @@ macro(find_vtk) 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) + 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!") @@ -39,7 +39,7 @@ if(DEFINED HAVE_VTK AND HAVE_VTK) include (${VTK_USE_FILE}) add_definitions(-DHAVE_VTK) endif() - + set(the_description "Viz") set(BUILD_opencv_viz_INIT OFF) include_directories(src) diff --git a/modules/viz/doc/viz.rst b/modules/viz/doc/viz.rst index 2f1bf0456..3cf550253 100644 --- a/modules/viz/doc/viz.rst +++ b/modules/viz/doc/viz.rst @@ -4,6 +4,6 @@ viz. 3D Visualizer .. toctree:: :maxdepth: 2 - + viz3d.rst widget.rst diff --git a/modules/viz/doc/viz3d.rst b/modules/viz/doc/viz3d.rst index 1aff05150..dbe243890 100644 --- a/modules/viz/doc/viz3d.rst +++ b/modules/viz/doc/viz3d.rst @@ -4,7 +4,7 @@ Viz .. highlight:: cpp This section describes 3D visualization window as well as classes and methods -that are used to interact with it. +that are used to interact with it. 3D visualization window (see :ocv:class:`Viz3d`) is used to display widgets (see :ocv:class:`Widget`), and it provides several methods to interact with scene and widgets. @@ -21,17 +21,17 @@ Takes coordinate frame data and builds transform to global coordinate frame. :param origin: Origin of the coordinate frame in global coordinate frame. This function returns affine transform that describes transformation between global coordinate frame and a given coordinate frame. - + viz::makeCameraPose ------------------- Constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation). - + .. ocv:function:: Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir) :param position: Position of the camera in global coordinate frame. :param focal_point: Focal point of the camera in global coordinate frame. :param y_dir: Up vector of the camera in global coordinate frame. - + This function returns pose of the camera in global coordinate frame. viz::get @@ -41,15 +41,15 @@ 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. + +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"); @@ -75,7 +75,7 @@ Checks **point** for nan .. ocv:function:: bool isNan(const Point3_<_Tp>& p) :param p: return true if **any** of the elements of the point is *nan*. - + viz::VizAccessor ---------------- .. ocv:class:: VizAccessor @@ -87,16 +87,16 @@ A singleton class that provides access by name infrastructure for 3D visualizati 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. @@ -116,15 +116,15 @@ 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. + +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"); @@ -134,7 +134,7 @@ 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 @@ -164,18 +164,18 @@ The Viz3d class represents a 3D visualizer window. This class is implicitly shar void setWidgetPose(const String &id, const Affine3f &pose); void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; - + void setCamera(const Camera &camera); Camera getCamera() const; Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); - + void resetCameraViewpoint (const String &id); void resetCamera(); - + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); - + Size getWindowSize() const; void setWindowSize(const Size &window_size); String getWindowName() const; @@ -190,13 +190,13 @@ The Viz3d class represents a 3D visualizer window. This class is implicitly shar void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); void registerMouseCallback(MouseCallback callback, void* cookie = 0); - + void setRenderingProperty(const String &id, int property, double value); double getRenderingProperty(const String &id, int property); - + void setDesiredUpdateRate(double rate); double getDesiredUpdateRate(); - + void setRepresentation(int representation); private: /* hidden */ @@ -219,7 +219,7 @@ Shows a widget in the window. :param id: A unique id for the widget. :param widget: The widget to be displayed in the window. :param pose: Pose of the widget. - + viz::Viz3d::removeWidget ------------------------ Removes a widget from the window. @@ -227,17 +227,17 @@ Removes a widget from the window. .. ocv:function:: void removeWidget(const String &id) :param id: The id of the widget that will be removed. - + viz::Viz3d::getWidget --------------------- Retrieves a widget from the window. A widget is implicitly shared; -that is, if the returned widget is modified, the changes will be +that is, if the returned widget is modified, the changes will be immediately visible in the window. .. ocv:function:: Widget getWidget(const String &id) const :param id: The id of the widget that will be returned. - + viz::Viz3d::removeAllWidgets ---------------------------- Removes all widgets from the window. @@ -305,7 +305,7 @@ Resets camera viewpoint to a 3D widget in the scene. .. ocv:function:: void resetCameraViewpoint (const String &id) :param pose: Id of a 3D widget. - + viz::Viz3d::resetCamera ----------------------- Resets camera. @@ -320,7 +320,7 @@ Transforms a point in world coordinate system to window coordinate system. :param pt: Point in world coordinate system. :param window_coord: Output point in window coordinate system. - + viz::Viz3d::converTo3DRay ------------------------- Transforms a point in window coordinate system to a 3D ray in world coordinate system. @@ -330,7 +330,7 @@ Transforms a point in window coordinate system to a 3D ray in world coordinate s :param window_coord: Point in window coordinate system. :param origin: Output origin of the ray. :param direction: Output direction of the ray. - + viz::Viz3d::getWindowSize ------------------------- Returns the current size of the window. @@ -344,7 +344,7 @@ Sets the size of the window. .. ocv:function:: void setWindowSize(const Size &window_size) :param window_size: New size of the window. - + viz::Viz3d::getWindowName ------------------------- Returns the name of the window which has been set in the constructor. @@ -358,7 +358,7 @@ Saves screenshot of the current scene. .. ocv:function:: void saveScreenshot(const String &file) :param file: Name of the file. - + viz::Viz3d::setWindowPosition ----------------------------- Sets the position of the window in the screen. @@ -367,7 +367,7 @@ Sets the position of the window in the screen. :param x: x coordinate of the window :param y: y coordinate of the window - + viz::Viz3d::setFullScreen ------------------------- Sets or unsets full-screen rendering mode. @@ -375,7 +375,7 @@ Sets or unsets full-screen rendering mode. .. ocv:function:: void setFullScreen(bool mode) :param mode: If true, window will use full-screen mode. - + viz::Viz3d::setBackgroundColor ------------------------------ Sets background color. @@ -411,7 +411,7 @@ Sets keyboard handler. :param callback: Keyboard callback ``(void (*KeyboardCallbackFunction(const KeyboardEvent&, void*))``. :param cookie: The optional parameter passed to the callback. - + viz::Viz3d::registerMouseCallback --------------------------------- Sets mouse handler. @@ -430,9 +430,9 @@ Sets rendering property of a widget. :param id: Id of the widget. :param property: Property that will be modified. :param value: The new value of the property. - + **Rendering property** can be one of the following: - + * **POINT_SIZE** * **OPACITY** * **LINE_WIDTH** @@ -441,14 +441,14 @@ Sets rendering property of a widget. * **REPRESENTATION_POINTS** * **REPRESENTATION_WIREFRAME** * **REPRESENTATION_SURFACE** - * **IMMEDIATE_RENDERING**: + * **IMMEDIATE_RENDERING**: * Turn on immediate rendering by setting the value to ``1``. * Turn off immediate rendering by setting the value to ``0``. * **SHADING**: Expected values are * **SHADING_FLAT** * **SHADING_GOURAUD** * **SHADING_PHONG** - + viz::Viz3d::getRenderingProperty -------------------------------- Returns rendering property of a widget. @@ -457,9 +457,9 @@ Returns rendering property of a widget. :param id: Id of the widget. :param property: Property. - + **Rendering property** can be one of the following: - + * **POINT_SIZE** * **OPACITY** * **LINE_WIDTH** @@ -468,7 +468,7 @@ Returns rendering property of a widget. * **REPRESENTATION_POINTS** * **REPRESENTATION_WIREFRAME** * **REPRESENTATION_SURFACE** - * **IMMEDIATE_RENDERING**: + * **IMMEDIATE_RENDERING**: * Turn on immediate rendering by setting the value to ``1``. * Turn off immediate rendering by setting the value to ``0``. * **SHADING**: Expected values are @@ -483,7 +483,7 @@ Sets desired update rate of the window. .. ocv:function:: void setDesiredUpdateRate(double rate) :param rate: Desired update rate. The default is 30. - + viz::Viz3d::getDesiredUpdateRate -------------------------------- Returns desired update rate of the window. @@ -497,11 +497,11 @@ Sets geometry representation of the widgets to surface, wireframe or points. .. ocv:function:: void setRepresentation(int representation) :param representation: Geometry representation which can be one of the following: - + * **REPRESENTATION_POINTS** * **REPRESENTATION_WIREFRAME** * **REPRESENTATION_SURFACE** - + viz::Color ---------- .. ocv:class:: Color @@ -545,11 +545,11 @@ This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. :: //! Loads mesh from a given ply file static Mesh3d loadMesh(const String& file); - + private: /* hidden */ }; - + viz::Mesh3d::loadMesh --------------------- Loads a mesh from a ``ply`` file. @@ -557,8 +557,8 @@ Loads a mesh from a ``ply`` file. .. ocv:function:: static Mesh3d loadMesh(const String& file) :param file: File name. - - + + viz::KeyboardEvent ------------------ .. ocv:class:: KeyboardEvent @@ -602,7 +602,7 @@ Constructs a KeyboardEvent. :param alt: If true, ``alt`` is pressed. :param ctrl: If true, ``ctrl`` is pressed. :param shift: If true, ``shift`` is pressed. - + viz::MouseEvent --------------- .. ocv:class:: MouseEvent @@ -622,7 +622,7 @@ This class represents a mouse event. :: Point pointer; unsigned int key_state; }; - + viz::MouseEvent::MouseEvent --------------------------- Constructs a MouseEvent. @@ -635,7 +635,7 @@ Constructs a MouseEvent. :param alt: If true, ``alt`` is pressed. :param ctrl: If true, ``ctrl`` is pressed. :param shift: If true, ``shift`` is pressed. - + viz::Camera ----------- .. ocv:class:: Camera @@ -651,23 +651,23 @@ that can extract the intrinsic parameters from ``field of view``, ``intrinsic ma Camera(const Vec2f &fov, const Size &window_size); Camera(const cv::Matx33f &K, const Size &window_size); Camera(const cv::Matx44f &proj, const Size &window_size); - + inline const Vec2d & getClip() const { return clip_; } inline void setClip(const Vec2d &clip) { clip_ = clip; } - + inline const Size & getWindowSize() const { return window_size_; } void setWindowSize(const Size &window_size); - + inline const Vec2f & getFov() const { return fov_; } inline void setFov(const Vec2f & fov) { fov_ = fov; } - + inline const Vec2f & getPrincipalPoint() const { return principal_point_; } inline const Vec2f & getFocalLength() const { return focal_; } - + void computeProjectionMatrix(Matx44f &proj) const; - + static Camera KinectCamera(const Size &window_size); - + private: /* hidden */ }; @@ -690,7 +690,7 @@ Constructs a Camera. :param window_size: Size of the window. Principal point is at the center of the window by default. - + .. ocv:function:: Camera(const cv::Matx33f &K, const Size &window_size) :param K: Intrinsic matrix of the camera. @@ -708,7 +708,7 @@ Computes projection matrix using intrinsic parameters of the camera. .. ocv:function:: void computeProjectionMatrix(Matx44f &proj) const :param proj: Output projection matrix. - + viz::Camera::KinectCamera ------------------------- Creates a Kinect Camera. diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index e133eb117..4986b3ac3 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -1,13 +1,13 @@ Widget ====== - + .. highlight:: cpp In this section, the widget framework is explained. Widgets represent -2D or 3D objects, varying from simple ones such as lines to complex one such as +2D or 3D objects, varying from simple ones such as lines to complex one such as point clouds and meshes. -Widgets are **implicitly shared**. Therefore, one can add a widget to the scene, +Widgets are **implicitly shared**. Therefore, one can add a widget to the scene, and modify the widget without re-adding the widget. .. code-block:: cpp @@ -34,10 +34,10 @@ Base class of all widgets. Widget is implicitly shared. :: Widget(const Widget& other); Widget& operator=(const Widget& other); ~Widget(); - + //! Create a widget directly from ply file static Widget fromPlyFile(const String &file_name); - + //! Rendering properties of this particular widget void setRenderingProperty(int property, double value); double getRenderingProperty(int property) const; @@ -55,7 +55,7 @@ Creates a widget from ply file. .. ocv:function:: static Widget fromPlyFile(const String &file_name) :param file_name: Ply file name. - + viz::Widget::setRenderingProperty --------------------------------- Sets rendering property of the widget. @@ -64,9 +64,9 @@ Sets rendering property of the widget. :param property: Property that will be modified. :param value: The new value of the property. - + **Rendering property** can be one of the following: - + * **POINT_SIZE** * **OPACITY** * **LINE_WIDTH** @@ -75,14 +75,14 @@ Sets rendering property of the widget. * **REPRESENTATION_POINTS** * **REPRESENTATION_WIREFRAME** * **REPRESENTATION_SURFACE** - * **IMMEDIATE_RENDERING**: + * **IMMEDIATE_RENDERING**: * Turn on immediate rendering by setting the value to ``1``. * Turn off immediate rendering by setting the value to ``0``. * **SHADING**: Expected values are * **SHADING_FLAT** * **SHADING_GOURAUD** * **SHADING_PHONG** - + viz::Widget::getRenderingProperty --------------------------------- Returns rendering property of the widget. @@ -90,9 +90,9 @@ Returns rendering property of the widget. .. ocv:function:: double getRenderingProperty(int property) const :param property: Property. - + **Rendering property** can be one of the following: - + * **POINT_SIZE** * **OPACITY** * **LINE_WIDTH** @@ -101,14 +101,14 @@ Returns rendering property of the widget. * **REPRESENTATION_POINTS** * **REPRESENTATION_WIREFRAME** * **REPRESENTATION_SURFACE** - * **IMMEDIATE_RENDERING**: + * **IMMEDIATE_RENDERING**: * Turn on immediate rendering by setting the value to ``1``. * Turn off immediate rendering by setting the value to ``0``. * **SHADING**: Expected values are * **SHADING_FLAT** * **SHADING_GOURAUD** * **SHADING_PHONG** - + viz::Widget::cast ----------------- Casts a widget to another. @@ -135,7 +135,7 @@ This class is for users who want to develop their own widgets using VTK library static vtkSmartPointer getProp(const Widget &widget); static void setProp(Widget &widget, vtkSmartPointer prop); }; - + viz::WidgetAccessor::getProp ---------------------------- Returns ``vtkProp`` of a given widget. @@ -147,9 +147,9 @@ Returns ``vtkProp`` of a given widget. .. note:: vtkProp has to be down cast appropriately to be modified. .. code-block:: cpp - + vtkActor * actor = vtkActor::SafeDownCast(viz::WidgetAccessor::getProp(widget)); - + viz::WidgetAccessor::setProp ---------------------------- Sets ``vtkProp`` of a given widget. @@ -158,7 +158,7 @@ Sets ``vtkProp`` of a given widget. :param widget: Widget whose ``vtkProp`` is to be set. :param prop: A ``vtkProp``. - + viz::Widget3D ------------- .. ocv:class:: Widget3D @@ -186,7 +186,7 @@ Sets pose of the widget. .. ocv:function:: void setPose(const Affine3f &pose) :param pose: The new pose of the widget. - + viz::Widget3D::updateWidgetPose ------------------------------- Updates pose of the widget by pre-multiplying its current pose. @@ -207,8 +207,8 @@ Sets the color of the widget. .. ocv:function:: void setColor(const Color &color) - :param color: color of type :ocv:class:`Color` - + :param color: color of type :ocv:class:`Color` + viz::Widget2D ------------- .. ocv:class:: Widget2D @@ -222,7 +222,7 @@ Base class of all 2D widgets. :: void setColor(const Color &color); }; - + viz::Widget2D::setColor ----------------------- Sets the color of the widget. @@ -242,7 +242,7 @@ This 3D Widget defines a finite line. :: public: WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); }; - + viz::WLine::WLine ----------------- Constructs a WLine. @@ -252,7 +252,7 @@ Constructs a WLine. :param pt1: Start point of the line. :param pt2: End point of the line. :param color: :ocv:class:`Color` of the line. - + viz::WPlane ----------- .. ocv:class:: WPlane @@ -267,13 +267,13 @@ This 3D Widget defines a finite plane. :: private: /* hidden */ }; - + viz::WPlane::WPlane ------------------- Constructs a WPlane. .. ocv:function:: WPlane(const Vec4f& coefs, double size = 1.0, const Color &color = Color::white()) - + :param coefs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. :param size: Size of the plane. :param color: :ocv:class:`Color` of the plane. @@ -284,7 +284,7 @@ Constructs a WPlane. :param pt: Position of the plane. :param size: Size of the plane. :param color: :ocv:class:`Color` of the plane. - + viz::WSphere ------------ .. ocv:class:: WSphere @@ -319,7 +319,7 @@ This 3D Widget defines an arrow. :: public: WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); }; - + viz::WArrow::WArrow ----------------------------- Constructs an WArrow. @@ -330,9 +330,9 @@ Constructs an WArrow. :param pt2: End point of the arrow. :param thickness: Thickness of the arrow. Thickness of arrow head is also adjusted accordingly. :param color: :ocv:class:`Color` of the arrow. - + Arrow head is located at the end point of the arrow. - + viz::WCircle ----------------- .. ocv:class:: WCircle @@ -344,7 +344,7 @@ This 3D Widget defines a circle. :: public: WCircle(const Point3f& pt, double radius, double thickness = 0.01, const Color &color = Color::white()); }; - + viz::WCircle::WCircle ------------------------------- Constructs a WCircle. @@ -355,7 +355,7 @@ Constructs a WCircle. :param radius: Radius of the circle. :param thickness: Thickness of the circle. :param color: :ocv:class:`Color` of the circle. - + viz::WCylinder -------------- .. ocv:class:: WCylinder @@ -379,7 +379,7 @@ Constructs a WCylinder. :param radius: Radius of the cylinder. :param numsides: Resolution of the cylinder. :param color: :ocv:class:`Color` of the cylinder. - + viz::WCube ---------- .. ocv:class:: WCube @@ -391,7 +391,7 @@ This 3D Widget defines a cube. :: public: WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); }; - + viz::WCube::WCube --------------------------- Constructs a WCube. @@ -402,11 +402,11 @@ Constructs a WCube. :param pt_max: Specifies maximum point of the bounding box. :param wire_frame: If true, cube is represented as wireframe. :param color: :ocv:class:`Color` of the cube. - + .. image:: images/cube_widget.png :alt: Cube Widget :align: center - + viz::WCoordinateSystem ---------------------- .. ocv:class:: WCoordinateSystem @@ -418,7 +418,7 @@ This 3D Widget represents a coordinate system. :: public: WCoordinateSystem(double scale = 1.0); }; - + viz::WCoordinateSystem::WCoordinateSystem --------------------------------------------------- Constructs a WCoordinateSystem. @@ -426,7 +426,7 @@ Constructs a WCoordinateSystem. .. ocv:function:: WCoordinateSystem(double scale = 1.0) :param scale: Determines the size of the axes. - + viz::WPolyLine -------------- .. ocv:class:: WPolyLine @@ -447,10 +447,10 @@ viz::WPolyLine::WPolyLine Constructs a WPolyLine. .. ocv:function:: WPolyLine(InputArray points, const Color &color = Color::white()) - + :param points: Point set. :param color: :ocv:class:`Color` of the poly line. - + viz::WGrid ---------- .. ocv:class:: WGrid @@ -467,7 +467,7 @@ This 3D Widget defines a grid. :: private: /* hidden */ }; - + viz::WGrid::WGrid --------------------------- Constructs a WGrid. @@ -477,14 +477,14 @@ Constructs a WGrid. :param dimensions: Number of columns and rows, respectively. :param spacing: Size of each column and row, respectively. :param color: :ocv:class:`Color` of the grid. - + .. ocv:function: WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()) - + :param coeffs: Plane coefficients as in (A,B,C,D) where Ax + By + Cz + D = 0. :param dimensions: Number of columns and rows, respectively. :param spacing: Size of each column and row, respectively. :param color: :ocv:class:`Color` of the grid. - + viz::WText3D ------------ .. ocv:class:: WText3D @@ -499,7 +499,7 @@ This 3D Widget represents 3D text. The text always faces the camera. :: void setText(const String &text); String getText() const; }; - + viz::WText3D::WText3D ------------------------------- Constructs a WText3D. @@ -511,7 +511,7 @@ Constructs a WText3D. :param text_scale: Size of the text. :param face_camera: If true, text always faces the camera. :param color: :ocv:class:`Color` of the text. - + viz::WText3D::setText --------------------- Sets the text content of the widget. @@ -540,7 +540,7 @@ This 2D Widget represents text overlay. :: void setText(const String &text); String getText() const; }; - + viz::WText::WText ----------------- Constructs a WText. @@ -551,7 +551,7 @@ Constructs a WText. :param pos: Position of the text. :param font_size: Font size. :param color: :ocv:class:`Color` of the text. - + viz::WText::setText ------------------- Sets the text content of the widget. @@ -576,10 +576,10 @@ This 2D Widget represents an image overlay. :: { public: WImageOverlay(const Mat &image, const Rect &rect); - + void setImage(const Mat &image); }; - + viz::WImageOverlay::WImageOverlay --------------------------------- Constructs an WImageOverlay. @@ -588,7 +588,7 @@ Constructs an WImageOverlay. :param image: BGR or Gray-Scale image. :param rect: Image is scaled and positioned based on rect. - + viz::WImageOverlay::setImage ---------------------------- Sets the image content of the widget. @@ -596,7 +596,7 @@ Sets the image content of the widget. .. ocv:function:: void setImage(const Mat &image) :param image: BGR or Gray-Scale image. - + viz::WImage3D ------------- .. ocv:class:: WImage3D @@ -610,7 +610,7 @@ This 3D Widget represents an image in 3D space. :: WImage3D(const Mat &image, const Size &size); //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); - + void setImage(const Mat &image); }; @@ -619,10 +619,10 @@ viz::WImage3D::WImage3D Constructs an WImage3D. .. ocv:function:: WImage3D(const Mat &image, const Size &size) - + :param image: BGR or Gray-Scale image. :param size: Size of the image. - + .. ocv:function:: WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) :param position: Position of the image. @@ -630,7 +630,7 @@ Constructs an WImage3D. :param up_vector: Determines orientation of the image. :param image: BGR or Gray-Scale image. :param size: Size of the image. - + viz::WImage3D::setImage ----------------------- Sets the image content of the widget. @@ -638,7 +638,7 @@ Sets the image content of the widget. .. ocv:function:: void setImage(const Mat &image) :param image: BGR or Gray-Scale image. - + viz::WCameraPosition -------------------- .. ocv:class:: WCameraPosition @@ -659,7 +659,7 @@ This 3D Widget represents camera position in a scene by its axes or viewing frus //! 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()); }; - + viz::WCameraPosition::WCameraPosition ------------------------------------- Constructs a WCameraPosition. @@ -669,7 +669,7 @@ Constructs a WCameraPosition. .. ocv:function:: WCameraPosition(double scale = 1.0) Creates camera coordinate frame at the origin. - + .. image:: images/cpw1.png :alt: Camera coordinate frame :align: center @@ -681,15 +681,15 @@ Constructs a WCameraPosition. :param K: Intrinsic matrix of the camera. :param scale: Scale of the frustum. :param color: :ocv:class:`Color` of the frustum. - + Creates viewing frustum of the camera based on its intrinsic matrix K. - + .. ocv:function:: WCameraPosition(const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) :param fov: Field of view of the camera (horizontal, vertical). :param scale: Scale of the frustum. :param color: :ocv:class:`Color` of the frustum. - + Creates viewing frustum of the camera based on its field of view fov. .. image:: images/cpw2.png @@ -704,7 +704,7 @@ Constructs a WCameraPosition. :param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum. :param scale: Scale of the frustum and image. :param color: :ocv:class:`Color` of the frustum. - + Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. .. ocv:function:: WCameraPosition(const Vec2f &fov, const Mat &img, double scale = 1.0, const Color &color = Color::white()) @@ -713,9 +713,9 @@ Constructs a WCameraPosition. :param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum. :param scale: Scale of the frustum and image. :param color: :ocv:class:`Color` of the frustum. - + Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. - + .. image:: images/cpw3.png :alt: Camera viewing frustum with image :align: center @@ -730,18 +730,18 @@ This 3D Widget represents a trajectory. :: { public: enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; - + //! Displays trajectory of the given path either by coordinate frames or polyline WTrajectory(const std::vector &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); //! Displays trajectory of the given path by frustums WTrajectory(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); //! Displays trajectory of the given path by frustums WTrajectory(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); - + private: /* hidden */ }; - + viz::WTrajectory::WTrajectory ----------------------------- Constructs a WTrajectory. @@ -752,29 +752,29 @@ Constructs a WTrajectory. :param display_mode: Display mode. This can be DISPLAY_PATH, DISPLAY_FRAMES, DISPLAY_PATH & DISPLAY_FRAMES. :param color: :ocv:class:`Color` of the polyline that represents path. Frames are not affected. :param scale: Scale of the frames. Polyline is not affected. - + Displays trajectory of the given path as follows: - + * DISPLAY_PATH : Displays a poly line that represents the path. * DISPLAY_FRAMES : Displays coordinate frames at each pose. * DISPLAY_PATH & DISPLAY_FRAMES : Displays both poly line and coordinate frames. - + .. ocv:function:: WTrajectory(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()) :param path: List of poses on a trajectory. :param K: Intrinsic matrix of the camera. :param scale: Scale of the frustums. :param color: :ocv:class:`Color` of the frustums. - + Displays frustums at each pose of the trajectory. - + .. ocv:function:: WTrajectory(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()) :param path: List of poses on a trajectory. :param fov: Field of view of the camera (horizontal, vertical). :param scale: Scale of the frustums. :param color: :ocv:class:`Color` of the frustums. - + Displays frustums at each pose of the trajectory. viz::WSpheresTrajectory @@ -787,24 +787,24 @@ represent the direction from previous position to the current. :: class CV_EXPORTS WSpheresTrajectory : public Widget3D { public: - WSpheresTrajectory(const std::vector &path, float line_length = 0.05f, - double init_sphere_radius = 0.021, sphere_radius = 0.007, + WSpheresTrajectory(const std::vector &path, float line_length = 0.05f, + double init_sphere_radius = 0.021, sphere_radius = 0.007, Color &line_color = Color::white(), const Color &sphere_color = Color::white()); }; - + viz::WSpheresTrajectory::WSpheresTrajectory ------------------------------------------- Constructs a WSpheresTrajectory. .. ocv:function:: WSpheresTrajectory(const std::vector &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()) - + :param path: List of poses on a trajectory. :param line_length: Length of the lines. :param init_sphere_radius: Radius of the first sphere which represents the initial position of the camera. :param sphere_radius: Radius of the rest of the spheres. :param line_color: :ocv:class:`Color` of the lines. :param sphere_color: :ocv:class:`Color` of the spheres. - + viz::WCloud ----------- .. ocv:class:: WCloud @@ -822,7 +822,7 @@ This 3D Widget defines a point cloud. :: private: /* hidden */ }; - + viz::WCloud::WCloud ------------------- Constructs a WCloud. @@ -831,16 +831,16 @@ Constructs a WCloud. :param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param colors: Set of colors. It has to be of the same size with cloud. - - Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). .. ocv:function:: WCloud(InputArray cloud, const Color &color = Color::white()) - + :param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param color: A single :ocv:class:`Color` for the whole cloud. - Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). - + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + .. note:: In case there are four channels in the cloud, fourth channel is ignored. viz::WCloudCollection @@ -853,16 +853,16 @@ This 3D Widget defines a collection of clouds. :: { public: WCloudCollection(); - + //! Each point in cloud is mapped to a color in colors void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); //! All points in cloud have the same color void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3f &pose = Affine3f::Identity()); - + private: /* hidden */ }; - + viz::WCloudCollection::WCloudCollection --------------------------------------- Constructs a WCloudCollection. @@ -878,19 +878,19 @@ Adds a cloud to the collection. :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param colors: Set of colors. It has to be of the same size with cloud. :param pose: Pose of the cloud. - - Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). - + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + .. ocv:function:: void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity()) :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param colors: A single :ocv:class:`Color` for the whole cloud. :param pose: Pose of the cloud. - - Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). .. note:: In case there are four channels in the cloud, fourth channel is ignored. - + viz::WCloudNormals ------------------ .. ocv:class:: WCloudNormals @@ -905,36 +905,36 @@ This 3D Widget represents normals of a point cloud. :: private: /* hidden */ }; - + viz::WCloudNormals::WCloudNormals --------------------------------- Constructs a WCloudNormals. .. ocv:function:: WCloudNormals(InputArray cloud, InputArray normals, int level = 100, float scale = 0.02f, const Color &color = Color::white()) - + :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. :param normals: A set of normals that has to be of same type with cloud. :param level: Display only every ``level`` th normal. :param scale: Scale of the arrows that represent normals. :param color: :ocv:class:`Color` of the arrows that represent normals. - + .. note:: In case there are four channels in the cloud, fourth channel is ignored. - + viz::WMesh ---------- .. ocv:class:: WMesh This 3D Widget defines a mesh. :: - + class CV_EXPORTS WMesh : public Widget3D { public: WMesh(const Mesh3d &mesh); - + private: /* hidden */ }; - + viz::WMesh::WMesh ----------------- Constructs a WMesh. diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index bc0f73f86..f6dc882c3 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -56,7 +56,7 @@ namespace cv { namespace viz - { + { //! takes coordiante frame data and builds transfrom to global coordinate frame CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); @@ -87,32 +87,32 @@ namespace cv //! checks point for Nans template 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_; static bool is_instantiated_; - + struct VizAccessorImpl; static VizAccessorImpl * impl_; - + friend class Viz3d; }; } /* namespace viz */ diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index 60200eb66..5a3667b82 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -88,7 +88,7 @@ namespace cv //! Loads mesh from a given ply file static cv::viz::Mesh3d loadMesh(const String& file); - + private: struct loadMeshImpl; }; @@ -135,7 +135,7 @@ namespace cv Point pointer; unsigned int key_state; }; - + class CV_EXPORTS Camera { public: @@ -143,26 +143,26 @@ namespace cv Camera(const Vec2f &fov, const Size &window_size); Camera(const cv::Matx33f &K, const Size &window_size); Camera(const cv::Matx44f &proj, const Size &window_size); - + inline const Vec2d & getClip() const { return clip_; } inline void setClip(const Vec2d &clip) { clip_ = clip; } - + inline const Size & getWindowSize() const { return window_size_; } void setWindowSize(const Size &window_size); - + inline const Vec2f & getFov() const { return fov_; } inline void setFov(const Vec2f & fov) { fov_ = fov; } - + inline const Vec2f & getPrincipalPoint() const { return principal_point_; } inline const Vec2f & getFocalLength() const { return focal_; } - + void computeProjectionMatrix(Matx44f &proj) const; - + static Camera KinectCamera(const Size &window_size); - + private: void init(float f_x, float f_y, float c_x, float c_y, const Size &window_size); - + Vec2d clip_; Vec2f fov_; Size window_size_; diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index c66aeb43b..b12147274 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -81,18 +81,18 @@ namespace cv void setWidgetPose(const String &id, const Affine3f &pose); void updateWidgetPose(const String &id, const Affine3f &pose); Affine3f getWidgetPose(const String &id) const; - + void setCamera(const Camera &camera); Camera getCamera() const; Affine3f getViewerPose(); void setViewerPose(const Affine3f &pose); - + void resetCameraViewpoint(const String &id); void resetCamera(); - + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); - + Size getWindowSize() const; void setWindowSize(const Size &window_size); String getWindowName() const; @@ -107,19 +107,19 @@ namespace cv void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); void registerMouseCallback(MouseCallback callback, void* cookie = 0); - + void setRenderingProperty(const String &id, int property, double value); double getRenderingProperty(const String &id, int property); - + void setDesiredUpdateRate(double rate); double getDesiredUpdateRate(); - + void setRepresentation(int representation); private: struct VizImpl; VizImpl* impl_; - + void create(const String &window_name); void release(); }; diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 4d12b7a82..9a2c5ecbf 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -81,7 +81,7 @@ namespace cv SHADING_GOURAUD, SHADING_PHONG }; - + ///////////////////////////////////////////////////////////////////////////// /// The base class for all widgets class CV_EXPORTS Widget @@ -91,10 +91,10 @@ namespace cv Widget(const Widget& other); Widget& operator=(const Widget& other); ~Widget(); - + //! Create a widget directly from ply file static Widget fromPlyFile(const String &file_name); - + //! Rendering properties of this particular widget void setRenderingProperty(int property, double value); double getRenderingProperty(int property) const; @@ -201,10 +201,10 @@ namespace cv WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); //! Creates grid based on the plane equation WGrid(const Vec4f &coeffs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color = Color::white()); - + private: struct GridImpl; - + }; class CV_EXPORTS WText3D : public Widget3D @@ -224,15 +224,15 @@ namespace cv void setText(const String &text); String getText() const; }; - + class CV_EXPORTS WImageOverlay : public Widget2D { public: WImageOverlay(const Mat &image, const Rect &rect); - + void setImage(const Mat &image); }; - + class CV_EXPORTS WImage3D : public Widget3D { public: @@ -240,10 +240,10 @@ namespace cv WImage3D(const Mat &image, const Size &size); //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size); - + void setImage(const Mat &image); }; - + class CV_EXPORTS WCameraPosition : public Widget3D { public: @@ -257,27 +257,27 @@ namespace cv WCameraPosition(const Matx33f &K, const Mat &img, double scale = 1.0, 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()); - + private: struct ProjectImage; }; - + class CV_EXPORTS WTrajectory : public Widget3D { public: enum {DISPLAY_FRAMES = 1, DISPLAY_PATH = 2}; - + //! Displays trajectory of the given path either by coordinate frames or polyline WTrajectory(const std::vector &path, int display_mode = WTrajectory::DISPLAY_PATH, const Color &color = Color::white(), double scale = 1.0); //! Displays trajectory of the given path by frustums WTrajectory(const std::vector &path, const Matx33f &K, double scale = 1.0, const Color &color = Color::white()); //! Displays trajectory of the given path by frustums WTrajectory(const std::vector &path, const Vec2f &fov, double scale = 1.0, const Color &color = Color::white()); - + private: struct ApplyPath; }; - + class CV_EXPORTS WSpheresTrajectory: public Widget3D { public: @@ -301,16 +301,16 @@ namespace cv { public: WCloudCollection(); - + //! Each point in cloud is mapped to a color in colors void addCloud(InputArray cloud, InputArray colors, const Affine3f &pose = Affine3f::Identity()); //! All points in cloud have the same color void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3f &pose = Affine3f::Identity()); - + private: struct CreateCloudWidget; }; - + class CV_EXPORTS WCloudNormals : public Widget3D { public: @@ -319,12 +319,12 @@ namespace cv private: struct ApplyCloudNormals; }; - + class CV_EXPORTS WMesh : public Widget3D { public: WMesh(const Mesh3d &mesh); - + private: struct CopyImpl; }; diff --git a/modules/viz/src/cloud_widgets.cpp b/modules/viz/src/cloud_widgets.cpp index 0149f9033..73cc26201 100644 --- a/modules/viz/src/cloud_widgets.cpp +++ b/modules/viz/src/cloud_widgets.cpp @@ -327,7 +327,7 @@ struct cv::viz::WCloudCollection::CreateCloudWidget vertices->SetCells(nr_points, cells); return polydata; } - + static void createMapper(vtkSmartPointer actor, vtkSmartPointer poly_data, Vec3d& minmax) { vtkDataSetMapper *mapper = vtkDataSetMapper::SafeDownCast(actor->GetMapper()); @@ -349,17 +349,17 @@ struct cv::viz::WCloudCollection::CreateCloudWidget mapper_new->SetInterpolateScalarsBeforeMapping(interpolation); mapper_new->ScalarVisibilityOn(); mapper_new->ImmediateModeRenderingOff(); - + actor->SetNumberOfCloudPoints(int(std::max(1, poly_data->GetNumberOfPoints() / 10))); actor->GetProperty()->SetInterpolationToFlat(); actor->GetProperty()->BackfaceCullingOn(); actor->SetMapper(mapper_new); return ; } - + vtkPolyData *data = vtkPolyData::SafeDownCast(mapper->GetInput()); CV_Assert("Cloud Widget without data" && data); - + vtkSmartPointer appendFilter = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 appendFilter->AddInputConnection(mapper->GetInput()->GetProducerPort()); @@ -369,7 +369,7 @@ struct cv::viz::WCloudCollection::CreateCloudWidget appendFilter->AddInputData(poly_data); #endif mapper->SetInputConnection(appendFilter->GetOutputPort()); - + // Update the number of cloud points vtkIdType old_cloud_points = actor->GetNumberOfCloudPoints(); actor->SetNumberOfCloudPoints(int(std::max(1, old_cloud_points+poly_data->GetNumberOfPoints() / 10))); @@ -389,7 +389,7 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors, Mat colors = _colors.getMat(); CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); CV_Assert(colors.type() == CV_8UC3 && cloud.size() == colors.size()); - + if (cloud.isContinuous() && colors.isContinuous()) { cloud.reshape(cloud.channels(), 1); @@ -410,12 +410,12 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors, // Assign the colors polydata->GetPointData()->SetScalars(scalars); - + // Transform the poly data based on the pose vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); transform->SetMatrix(convertToVtkMatrix(pose.matrix)); - + vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); #if VTK_MAJOR_VERSION <= 5 @@ -424,10 +424,10 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, InputArray _colors, transform_filter->SetInputData(polydata); #endif transform_filter->Update(); - + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Incompatible widget type." && actor); - + Vec3d minmax(scalars->GetRange()); CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax); } @@ -449,12 +449,12 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color, // Assign the colors polydata->GetPointData()->SetScalars(scalars); - + // Transform the poly data based on the pose vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); transform->SetMatrix(convertToVtkMatrix(pose.matrix)); - + vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); #if VTK_MAJOR_VERSION <= 5 @@ -463,10 +463,10 @@ void cv::viz::WCloudCollection::addCloud(InputArray _cloud, const Color &color, transform_filter->SetInputData(polydata); #endif transform_filter->Update(); - + vtkLODActor *actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Incompatible widget type." && actor); - + Vec3d minmax(scalars->GetRange()); CreateCloudWidget::createMapper(actor, transform_filter->GetOutput(), minmax); } @@ -634,7 +634,7 @@ struct cv::viz::WMesh::CopyImpl int index = 0; const _Tp* srow = source.ptr<_Tp>(0); const _Tp* mrow = nan_mask.ptr<_Tp>(0); - + for (int x = 0; x < source.cols; ++x, srow += s_chs, mrow += m_chs) { if (!isNan(mrow[0]) && !isNan(mrow[1]) && !isNan(mrow[2])) @@ -653,13 +653,13 @@ cv::viz::WMesh::WMesh(const Mesh3d &mesh) CV_Assert(mesh.cloud.rows == 1 && (mesh.cloud.type() == CV_32FC3 || mesh.cloud.type() == CV_64FC3 || mesh.cloud.type() == CV_32FC4 || mesh.cloud.type() == CV_64FC4)); CV_Assert(mesh.colors.empty() || (mesh.colors.type() == CV_8UC3 && mesh.cloud.size() == mesh.colors.size())); CV_Assert(!mesh.polygons.empty() && mesh.polygons.type() == CV_32SC1); - + vtkSmartPointer points = vtkSmartPointer::New(); vtkIdType nr_points = mesh.cloud.total(); Mat look_up_mat(1, nr_points, CV_32SC1); int * look_up = look_up_mat.ptr(); points->SetNumberOfPoints(nr_points); - + // Copy data from cloud to vtkPoints if (mesh.cloud.depth() == CV_32F) { @@ -675,36 +675,36 @@ cv::viz::WMesh::WMesh(const Mesh3d &mesh) Vec3d *data_end = CopyImpl::copy(mesh.cloud, data_beg, look_up, mesh.cloud); nr_points = data_end - data_beg; } - + vtkSmartPointer scalars; - + if (!mesh.colors.empty()) { Vec3b * colors_data = 0; colors_data = new Vec3b[nr_points]; NanFilter::copyColor(mesh.colors, colors_data, mesh.cloud); - + scalars = vtkSmartPointer::New(); scalars->SetNumberOfComponents(3); scalars->SetNumberOfTuples(nr_points); scalars->SetArray(colors_data->val, 3 * nr_points, 0); } - + points->SetNumberOfPoints(nr_points); - + vtkSmartPointer data; - + if (mesh.polygons.size().area() > 1) { vtkSmartPointer cell_array = vtkSmartPointer::New(); const int * polygons = mesh.polygons.ptr(); - + int idx = 0; int poly_size = mesh.polygons.total(); for (int i = 0; i < poly_size; ++idx) { int n_points = polygons[i++]; - + cell_array->InsertNextCell(n_points); for (int j = 0; j < n_points; ++j, ++idx) cell_array->InsertCellPoint(look_up[polygons[i++]]); @@ -717,7 +717,7 @@ cv::viz::WMesh::WMesh(const Mesh3d &mesh) if (scalars) polydata->GetPointData()->SetScalars(scalars); - + data = polydata; } else @@ -726,20 +726,20 @@ cv::viz::WMesh::WMesh(const Mesh3d &mesh) vtkSmartPointer polygon = vtkSmartPointer::New(); const int * polygons = mesh.polygons.ptr(); int n_points = polygons[0]; - + polygon->GetPointIds()->SetNumberOfIds(n_points); - + for (int j = 1; j < n_points+1; ++j) polygon->GetPointIds()->SetId(j, look_up[polygons[j]]); - + vtkSmartPointer poly_grid = vtkSmartPointer::New(); poly_grid->Allocate(1, 1); poly_grid->InsertNextCell(polygon->GetCellType(), polygon->GetPointIds()); poly_grid->SetPoints(points); - + if (scalars) poly_grid->GetPointData()->SetScalars(scalars); - + data = poly_grid; } @@ -750,7 +750,7 @@ cv::viz::WMesh::WMesh(const Mesh3d &mesh) actor->GetProperty()->SetInterpolationToFlat(); actor->GetProperty()->EdgeVisibilityOff(); actor->GetProperty()->ShadingOff(); - + vtkSmartPointer mapper = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 mapper->SetInput(data); @@ -758,11 +758,11 @@ cv::viz::WMesh::WMesh(const Mesh3d &mesh) mapper->SetInputData(data); #endif mapper->ImmediateModeRenderingOff(); - + vtkIdType numberOfCloudPoints = nr_points * 0.1; actor->SetNumberOfCloudPoints(int(numberOfCloudPoints > 1 ? numberOfCloudPoints : 1)); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); } diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 312f68616..8abc46880 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -67,11 +67,11 @@ void cv::viz::InteractorStyle::Initialize() 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; @@ -197,7 +197,7 @@ void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const K void cv::viz::InteractorStyle::OnKeyDown() { - + CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_); CV_Assert("No renderer given! Use SetRendererCollection() before continuing." && renderer_); @@ -482,7 +482,7 @@ cv::viz::InteractorStyle::OnKeyDown() { if (it == widget_actor_map_->end()) it = widget_actor_map_->begin(); - + vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); if (actor && actor->GetUserMatrix()) { @@ -554,7 +554,7 @@ void cv::viz::InteractorStyle::OnKeyUp() // Check if there is a keyboard callback registered if (keyboardCallback_) keyboardCallback_(event, keyboard_callback_cookie_); - + Superclass::OnKeyUp(); } @@ -673,10 +673,10 @@ void cv::viz::InteractorStyle::OnMouseWheelBackward() // If a mouse callback registered, call it! if (mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - + if (Interactor->GetRepeatCount() && mouseCallback_) mouseCallback_(event, mouse_callback_cookie_); - + if (Interactor->GetAltKey()) { // zoom diff --git a/modules/viz/src/interactor_style.h b/modules/viz/src/interactor_style.h index cc47c87d4..7b80ee94b 100644 --- a/modules/viz/src/interactor_style.h +++ b/modules/viz/src/interactor_style.h @@ -85,7 +85,7 @@ namespace cv /** \brief Change the default keyboard modified from ALT to a different special key.*/ inline void setKeyboardModifier(const KeyboardModifier &modifier) { modifier_ = modifier; } - + protected: /** \brief Set to true after initialization is complete. */ bool init_; @@ -95,7 +95,7 @@ namespace cv /** \brief Actor map stored internally. */ cv::Ptr widget_actor_map_; - + /** \brief The current window width/height. */ Vec2i win_size_; @@ -107,7 +107,7 @@ namespace cv /** \brief A PNG writer for screenshot captures. */ vtkSmartPointer snapshot_writer_; - + /** \brief Internal window to image filter. Needed by \a snapshot_writer_. */ vtkSmartPointer wif_; diff --git a/modules/viz/src/shape_widgets.cpp b/modules/viz/src/shape_widgets.cpp index b253237c9..2e062d52d 100644 --- a/modules/viz/src/shape_widgets.cpp +++ b/modules/viz/src/shape_widgets.cpp @@ -59,7 +59,7 @@ namespace cv /////////////////////////////////////////////////////////////////////////////////////////////// /// line widget implementation cv::viz::WLine::WLine(const Point3f &pt1, const Point3f &pt2, const Color &color) -{ +{ vtkSmartPointer line = vtkSmartPointer::New(); line->SetPoint1(pt1.x, pt1.y, pt1.z); line->SetPoint2(pt2.x, pt2.y, pt2.z); @@ -94,32 +94,32 @@ struct cv::viz::WPlane::SetSizeImpl transform->Translate(center[0], center[1], center[2]); transform->Scale(size, size, size); transform->Translate(-center[0], -center[1], -center[2]); - + vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetInputConnection(poly_data_port); transform_filter->SetTransform(transform); transform_filter->Update(); - + return transform_filter; } }; cv::viz::WPlane::WPlane(const Vec4f& coefs, double size, const Color &color) -{ +{ vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetNormal(coefs[0], coefs[1], coefs[2]); double norm = cv::norm(Vec3f(coefs.val)); plane->Push(-coefs[3] / norm); - + Vec3d p_center; plane->GetOrigin(p_center.val); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(SetSizeImpl::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -134,13 +134,13 @@ cv::viz::WPlane::WPlane(const Vec4f& coefs, const Point3f& pt, double size, cons double t = coefs3.dot(pt) + coefs[3]; Vec3f p_center = pt - coefs3 * t * norm_sqr; plane->SetCenter(p_center[0], p_center[1], p_center[2]); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(SetSizeImpl::setSize(p_center, plane->GetOutputPort(), size)->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -163,7 +163,7 @@ cv::viz::WSphere::WSphere(const Point3f ¢er, float radius, int sphere_resolu sphere->SetThetaResolution(sphere_resolution); sphere->LatLongTessellationOff(); sphere->Update(); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(sphere->GetOutputPort()); @@ -190,7 +190,7 @@ cv::viz::WArrow::WArrow(const Point3f& pt1, const Point3f& pt2, double thickness // The thickness and radius of the tip are adjusted based on the thickness of the arrow arrowSource->SetTipRadius(thickness * 3.0); arrowSource->SetTipLength(thickness * 10.0); - + float startPoint[3], endPoint[3]; startPoint[0] = pt1.x; startPoint[1] = pt1.y; @@ -199,7 +199,7 @@ cv::viz::WArrow::WArrow(const Point3f& pt1, const Point3f& pt2, double thickness endPoint[1] = pt2.y; endPoint[2] = pt2.z; float normalizedX[3], normalizedY[3], normalizedZ[3]; - + // The X axis is a vector from start to end vtkMath::Subtract(endPoint, startPoint, normalizedX); float length = vtkMath::Norm(normalizedX); @@ -224,7 +224,7 @@ cv::viz::WArrow::WArrow(const Point3f& pt1, const Point3f& pt2, double thickness matrix->SetElement(i, 0, normalizedX[i]); matrix->SetElement(i, 1, normalizedY[i]); matrix->SetElement(i, 2, normalizedZ[i]); - } + } // Apply the transforms vtkSmartPointer transform = vtkSmartPointer::New(); @@ -236,13 +236,13 @@ cv::viz::WArrow::WArrow(const Point3f& pt1, const Point3f& pt2, double thickness vtkSmartPointer transformPD = vtkSmartPointer::New(); transformPD->SetTransform(transform); transformPD->SetInputConnection(arrowSource->GetOutputPort()); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(transformPD->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -272,13 +272,13 @@ cv::viz::WCircle::WCircle(const Point3f& pt, double radius, double thickness, co vtkSmartPointer tf = vtkSmartPointer::New(); tf->SetTransform(t); tf->SetInputConnection(disk->GetOutputPort()); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(tf->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -293,23 +293,23 @@ template<> cv::viz::WCircle cv::viz::Widget::cast() /// cylinder widget implementation cv::viz::WCylinder::WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides, const Color &color) -{ +{ const Point3f pt2 = pt_on_axis + axis_direction; vtkSmartPointer line = vtkSmartPointer::New(); line->SetPoint1(pt_on_axis.x, pt_on_axis.y, pt_on_axis.z); line->SetPoint2(pt2.x, pt2.y, pt2.z); - + vtkSmartPointer tuber = vtkSmartPointer::New(); tuber->SetInputConnection(line->GetOutputPort()); tuber->SetRadius(radius); tuber->SetNumberOfSides(numsides); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(tuber->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -324,8 +324,8 @@ template<> cv::viz::WCylinder cv::viz::Widget::cast() /// cylinder widget implementation cv::viz::WCube::WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame, const Color &color) -{ - vtkSmartPointer mapper = vtkSmartPointer::New(); +{ + vtkSmartPointer mapper = vtkSmartPointer::New(); if (wire_frame) { vtkSmartPointer cube = vtkSmartPointer::New(); @@ -338,10 +338,10 @@ cv::viz::WCube::WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_fr cube->SetBounds(pt_min.x, pt_max.x, pt_min.y, pt_max.y, pt_min.z, pt_max.z); mapper->SetInputConnection(cube->GetOutputPort()); } - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -386,14 +386,14 @@ cv::viz::WCoordinateSystem::WCoordinateSystem(double scale) #endif axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); axes_tubes->SetNumberOfSides(6); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUsePointData(); mapper->SetInputConnection(axes_tubes->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); } @@ -407,7 +407,7 @@ template<> cv::viz::WCoordinateSystem cv::viz::Widget::cast static void copy(const Mat& source, Vec<_Tp, 3> *output, vtkSmartPointer polyLine) { @@ -430,20 +430,20 @@ cv::viz::WPolyLine::WPolyLine(InputArray _pointData, const Color &color) { Mat pointData = _pointData.getMat(); CV_Assert(pointData.type() == CV_32FC3 || pointData.type() == CV_32FC4 || pointData.type() == CV_64FC3 || pointData.type() == CV_64FC4); - vtkIdType nr_points = pointData.total(); - + vtkIdType nr_points = pointData.total(); + vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer polyData = vtkSmartPointer::New(); vtkSmartPointer polyLine = vtkSmartPointer::New(); - + if (pointData.depth() == CV_32F) points->SetDataTypeToFloat(); else points->SetDataTypeToDouble(); - + points->SetNumberOfPoints(nr_points); polyLine->GetPointIds()->SetNumberOfIds(nr_points); - + if (pointData.depth() == CV_32F) { // Get a pointer to the beginning of the data array @@ -456,23 +456,23 @@ cv::viz::WPolyLine::WPolyLine(InputArray _pointData, const Color &color) Vec3d *data_beg = vtkpoints_data(points); CopyImpl::copy(pointData, data_beg, polyLine); } - + vtkSmartPointer cells = vtkSmartPointer::New(); cells->InsertNextCell(polyLine); - + polyData->SetPoints(points); polyData->SetLines(cells); - + vtkSmartPointer mapper = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 mapper->SetInput(polyData); #else mapper->SetInputData(polyData); #endif - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -492,15 +492,15 @@ struct cv::viz::WGrid::GridImpl { // Create the grid using image data vtkSmartPointer grid = vtkSmartPointer::New(); - + // Add 1 to dimensions because in ImageData dimensions is the number of lines // - however here it means number of cells grid->SetDimensions(dimensions[0]+1, dimensions[1]+1, 1); grid->SetSpacing(spacing[0], spacing[1], 0.); - + // Set origin of the grid to be the middle of the grid grid->SetOrigin(dimensions[0] * spacing[0] * (-0.5), dimensions[1] * spacing[1] * (-0.5), 0); - + // Extract the edges so we have the grid vtkSmartPointer filter = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 @@ -516,17 +516,17 @@ struct cv::viz::WGrid::GridImpl cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color &color) { vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); - + vtkSmartPointer mapper = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 mapper->SetInputConnection(grid->GetProducerPort()); #else mapper->SetInputData(grid); #endif - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -534,7 +534,7 @@ cv::viz::WGrid::WGrid(const Vec2i &dimensions, const Vec2d &spacing, const Color cv::viz::WGrid::WGrid(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d &spacing, const Color &color) { vtkSmartPointer grid = GridImpl::createGrid(dimensions, spacing); - + // Estimate the transform to set the normal based on the coefficients Vec3f normal(coefs[0], coefs[1], coefs[2]); Vec3f up_vector(0.0f, 1.0f, 0.0f); // Just set as default @@ -543,7 +543,7 @@ cv::viz::WGrid::WGrid(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d & n = normalize(normal); u = normalize(up_vector.cross(n)); v = n.cross(u); - + vtkSmartPointer mat_trans = vtkSmartPointer::New(); mat_trans->SetElement(0,0,u[0]); mat_trans->SetElement(0,1,u[1]); @@ -560,11 +560,11 @@ cv::viz::WGrid::WGrid(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d & mat_trans->SetElement(1,3,n[1] * push_distance); mat_trans->SetElement(2,3,n[2] * push_distance); mat_trans->SetElement(3,3,1); - + vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); transform->SetMatrix(mat_trans); - + vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); #if VTK_MAJOR_VERSION <= 5 @@ -573,13 +573,13 @@ cv::viz::WGrid::WGrid(const Vec4f &coefs, const Vec2i &dimensions, const Vec2d & transform_filter->SetInputData(grid); #endif transform_filter->Update(); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(transform_filter->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -601,7 +601,7 @@ cv::viz::WText3D::WText3D(const String &text, const Point3f &position, double te vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(textSource->GetOutputPort()); - + if (face_camera) { vtkSmartPointer actor = vtkSmartPointer::New(); @@ -618,7 +618,7 @@ cv::viz::WText3D::WText3D(const String &text, const Point3f &position, double te actor->SetScale(text_scale); WidgetAccessor::setProp(*this, actor); } - + setColor(color); } @@ -626,12 +626,12 @@ void cv::viz::WText3D::setText(const String &text) { vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("This widget does not support text." && actor); - + // Update text source vtkPolyDataMapper *mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); vtkVectorText * textSource = vtkVectorText::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); CV_Assert("This widget does not support text." && textSource); - + textSource->SetText(text.c_str()); textSource->Update(); } @@ -640,11 +640,11 @@ cv::String cv::viz::WText3D::getText() const { vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("This widget does not support text." && actor); - + vtkPolyDataMapper *mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); vtkVectorText * textSource = vtkVectorText::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); CV_Assert("This widget does not support text." && textSource); - + return textSource->GetText(); } @@ -671,7 +671,7 @@ cv::viz::WText::WText(const String &text, const Point2i &pos, int font_size, con Color c = vtkcolor(color); tprop->SetColor(c.val); - + WidgetAccessor::setProp(*this, actor); } @@ -701,11 +701,11 @@ cv::String cv::viz::WText::getText() const cv::viz::WImageOverlay::WImageOverlay(const Mat &image, const Rect &rect) { CV_Assert(!image.empty() && image.depth() == CV_8U); - + // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); ConvertToVtkImage::convert(image, vtk_image); - + // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip @@ -715,44 +715,44 @@ cv::viz::WImageOverlay::WImageOverlay(const Mat &image, const Rect &rect) flipFilter->SetInputData(vtk_image); #endif flipFilter->Update(); - + // Scale the image based on the Rect vtkSmartPointer transform = vtkSmartPointer::New(); transform->Scale(double(image.cols)/rect.width,double(image.rows)/rect.height,1.0); - + vtkSmartPointer image_reslice = vtkSmartPointer::New(); image_reslice->SetResliceTransform(transform); image_reslice->SetInputConnection(flipFilter->GetOutputPort()); image_reslice->SetOutputDimensionality(2); image_reslice->InterpolateOn(); - image_reslice->AutoCropOutputOn(); - + image_reslice->AutoCropOutputOn(); + vtkSmartPointer imageMapper = vtkSmartPointer::New(); imageMapper->SetInputConnection(image_reslice->GetOutputPort()); imageMapper->SetColorWindow(255); // OpenCV color - imageMapper->SetColorLevel(127.5); - + imageMapper->SetColorLevel(127.5); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(imageMapper); actor->SetPosition(rect.x, rect.y); - + WidgetAccessor::setProp(*this, actor); } void cv::viz::WImageOverlay::setImage(const Mat &image) { CV_Assert(!image.empty() && image.depth() == CV_8U); - + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("This widget does not support overlay image." && actor); - + vtkImageMapper *mapper = vtkImageMapper::SafeDownCast(actor->GetMapper()); CV_Assert("This widget does not support overlay image." && mapper); - + // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); ConvertToVtkImage::convert(image, vtk_image); - + // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip @@ -762,7 +762,7 @@ void cv::viz::WImageOverlay::setImage(const Mat &image) flipFilter->SetInputData(vtk_image); #endif flipFilter->Update(); - + mapper->SetInputConnection(flipFilter->GetOutputPort()); } @@ -778,11 +778,11 @@ template<> cv::viz::WImageOverlay cv::viz::Widget::cast( cv::viz::WImage3D::WImage3D(const Mat &image, const Size &size) { CV_Assert(!image.empty() && image.depth() == CV_8U); - + // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); ConvertToVtkImage::convert(image, vtk_image); - + // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip @@ -792,49 +792,49 @@ cv::viz::WImage3D::WImage3D(const Mat &image, const Size &size) flipFilter->SetInputData(vtk_image); #endif flipFilter->Update(); - + Vec3d plane_center(size.width * 0.5, size.height * 0.5, 0.0); - + vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); plane->SetNormal(0.0, 0.0, 1.0); - + vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); transform->Translate(plane_center[0], plane_center[1], plane_center[2]); transform->Scale(size.width, size.height, 1.0); transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); - + vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); transform_filter->SetInputConnection(plane->GetOutputPort()); transform_filter->Update(); - + // Apply the texture vtkSmartPointer texture = vtkSmartPointer::New(); texture->SetInputConnection(flipFilter->GetOutputPort()); - + vtkSmartPointer texturePlane = vtkSmartPointer::New(); texturePlane->SetInputConnection(transform_filter->GetOutputPort()); - + vtkSmartPointer planeMapper = vtkSmartPointer::New(); planeMapper->SetInputConnection(texturePlane->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(planeMapper); actor->SetTexture(texture); - + WidgetAccessor::setProp(*this, actor); } cv::viz::WImage3D::WImage3D(const Vec3f &position, const Vec3f &normal, const Vec3f &up_vector, const Mat &image, const Size &size) { CV_Assert(!image.empty() && image.depth() == CV_8U); - + // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); ConvertToVtkImage::convert(image, vtk_image); - + // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip @@ -844,17 +844,17 @@ cv::viz::WImage3D::WImage3D(const Vec3f &position, const Vec3f &normal, const Ve flipFilter->SetInputData(vtk_image); #endif flipFilter->Update(); - + vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetCenter(0.0, 0.0, 0.0); - plane->SetNormal(0.0, 0.0, 1.0); - + plane->SetNormal(0.0, 0.0, 1.0); + // Compute the transformation matrix for drawing the camera frame in a scene Vec3f u,v,n; n = normalize(normal); u = normalize(up_vector.cross(n)); v = n.cross(u); - + vtkSmartPointer mat_trans = vtkSmartPointer::New(); mat_trans->SetElement(0,0,u[0]); mat_trans->SetElement(0,1,u[1]); @@ -866,52 +866,52 @@ cv::viz::WImage3D::WImage3D(const Vec3f &position, const Vec3f &normal, const Ve mat_trans->SetElement(2,1,n[1]); mat_trans->SetElement(2,2,n[2]); // Inverse rotation (orthogonal, so just take transpose) - mat_trans->Transpose(); + mat_trans->Transpose(); // Then translate the coordinate frame to camera position mat_trans->SetElement(0,3,position[0]); mat_trans->SetElement(1,3,position[1]); mat_trans->SetElement(2,3,position[2]); mat_trans->SetElement(3,3,1); - + // Apply the texture vtkSmartPointer texture = vtkSmartPointer::New(); texture->SetInputConnection(flipFilter->GetOutputPort()); - + vtkSmartPointer texturePlane = vtkSmartPointer::New(); texturePlane->SetInputConnection(plane->GetOutputPort()); - + // Apply the transform after texture mapping vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); transform->SetMatrix(mat_trans); transform->Scale(size.width, size.height, 1.0); - + vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); transform_filter->SetInputConnection(texturePlane->GetOutputPort()); transform_filter->Update(); - + vtkSmartPointer planeMapper = vtkSmartPointer::New(); planeMapper->SetInputConnection(transform_filter->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(planeMapper); actor->SetTexture(texture); - + WidgetAccessor::setProp(*this, actor); } void cv::viz::WImage3D::setImage(const Mat &image) { CV_Assert(!image.empty() && image.depth() == CV_8U); - + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("This widget does not support 3D image." && actor); - + // Create the vtk image and set its parameters based on input image vtkSmartPointer vtk_image = vtkSmartPointer::New(); ConvertToVtkImage::convert(image, vtk_image); - + // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip @@ -921,11 +921,11 @@ void cv::viz::WImage3D::setImage(const Mat &image) flipFilter->SetInputData(vtk_image); #endif flipFilter->Update(); - + // Apply the texture vtkSmartPointer texture = vtkSmartPointer::New(); texture->SetInputConnection(flipFilter->GetOutputPort()); - + actor->SetTexture(texture); } @@ -940,22 +940,22 @@ template<> cv::viz::WImage3D cv::viz::Widget::cast() struct cv::viz::WCameraPosition::ProjectImage { - static void projectImage(float fovy, float far_end_height, const Mat &image, + static void projectImage(float fovy, float far_end_height, const Mat &image, double scale, const Color &color, vtkSmartPointer actor) { // Create a camera vtkSmartPointer camera = vtkSmartPointer::New(); float aspect_ratio = float(image.cols)/float(image.rows); - + // Create the vtk image vtkSmartPointer vtk_image = vtkSmartPointer::New(); ConvertToVtkImage::convert(image, vtk_image); - + // Adjust a pixel of the vtk_image vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 0, color[2]); vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 1, color[1]); vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 2, color[0]); - + // Need to flip the image as the coordinates are different in OpenCV and VTK vtkSmartPointer flipFilter = vtkSmartPointer::New(); flipFilter->SetFilteredAxis(1); // Vertical flip @@ -965,68 +965,68 @@ struct cv::viz::WCameraPosition::ProjectImage flipFilter->SetInputData(vtk_image); #endif flipFilter->Update(); - + Vec3d plane_center(0.0, 0.0, scale); - + vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); plane->SetNormal(0.0, 0.0, 1.0); - + vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); transform->Translate(plane_center[0], plane_center[1], plane_center[2]); transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0); transform->RotateY(180.0); transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); - + // Apply the texture vtkSmartPointer texture = vtkSmartPointer::New(); texture->SetInputConnection(flipFilter->GetOutputPort()); - + vtkSmartPointer texturePlane = vtkSmartPointer::New(); texturePlane->SetInputConnection(plane->GetOutputPort()); - + vtkSmartPointer transform_filter = vtkSmartPointer::New(); transform_filter->SetTransform(transform); transform_filter->SetInputConnection(texturePlane->GetOutputPort()); transform_filter->Update(); - + // Create frustum camera->SetViewAngle(fovy); camera->SetPosition(0.0,0.0,0.0); camera->SetViewUp(0.0,1.0,0.0); camera->SetFocalPoint(0.0,0.0,1.0); camera->SetClippingRange(0.01, scale); - + double planesArray[24]; camera->GetFrustumPlanes(aspect_ratio, planesArray); - + vtkSmartPointer planes = vtkSmartPointer::New(); planes->SetFrustumPlanes(planesArray); - + vtkSmartPointer frustumSource = vtkSmartPointer::New(); frustumSource->SetPlanes(planes); frustumSource->Update(); - + vtkSmartPointer filter = vtkSmartPointer::New(); filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); - + // Frustum needs to be textured or else it can't be combined with image vtkSmartPointer frustum_texture = vtkSmartPointer::New(); frustum_texture->SetInputConnection(filter->GetOutputPort()); // Texture mapping with only one pixel from the image to have constant color - frustum_texture->SetSRange(0.0, 0.0); + frustum_texture->SetSRange(0.0, 0.0); frustum_texture->SetTRange(0.0, 0.0); - + vtkSmartPointer appendFilter = vtkSmartPointer::New(); appendFilter->AddInputConnection(frustum_texture->GetOutputPort()); appendFilter->AddInputConnection(transform_filter->GetOutputPort()); - + vtkSmartPointer planeMapper = vtkSmartPointer::New(); planeMapper->SetInputConnection(appendFilter->GetOutputPort()); - + actor->SetMapper(planeMapper); actor->SetTexture(texture); } @@ -1037,7 +1037,7 @@ cv::viz::WCameraPosition::WCameraPosition(double scale) vtkSmartPointer axes = vtkSmartPointer::New(); axes->SetOrigin(0, 0, 0); axes->SetScaleFactor(scale); - + vtkSmartPointer axes_colors = vtkSmartPointer::New(); axes_colors->Allocate(6); axes_colors->InsertNextValue(0.0); @@ -1054,7 +1054,7 @@ cv::viz::WCameraPosition::WCameraPosition(double scale) axes->Update(); #endif axes_data->GetPointData()->SetScalars(axes_colors); - + vtkSmartPointer axes_tubes = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 axes_tubes->SetInput(axes_data); @@ -1063,14 +1063,14 @@ cv::viz::WCameraPosition::WCameraPosition(double scale) #endif axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); axes_tubes->SetNumberOfSides(6); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUsePointData(); mapper->SetInputConnection(axes_tubes->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); } @@ -1083,19 +1083,19 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, double scale, const float aspect_ratio = f_y / f_x; // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) float fovy = 2.0f * atan2(c_y,f_y) * 180 / CV_PI; - + camera->SetViewAngle(fovy); camera->SetPosition(0.0,0.0,0.0); camera->SetViewUp(0.0,1.0,0.0); camera->SetFocalPoint(0.0,0.0,1.0); camera->SetClippingRange(0.01, scale); - + double planesArray[24]; camera->GetFrustumPlanes(aspect_ratio, planesArray); - + vtkSmartPointer planes = vtkSmartPointer::New(); planes->SetFrustumPlanes(planesArray); - + vtkSmartPointer frustumSource = vtkSmartPointer::New(); frustumSource->SetPlanes(planes); @@ -1104,13 +1104,13 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, double scale, const vtkSmartPointer filter = vtkSmartPointer::New(); filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(filter->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -1119,21 +1119,21 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, double scale, const cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); - + camera->SetViewAngle(fov[1] * 180 / CV_PI); // Vertical field of view camera->SetPosition(0.0,0.0,0.0); camera->SetViewUp(0.0,1.0,0.0); camera->SetFocalPoint(0.0,0.0,1.0); camera->SetClippingRange(0.01, scale); - + double aspect_ratio = tan(fov[0] * 0.5) / tan(fov[1] * 0.5); - + double planesArray[24]; camera->GetFrustumPlanes(aspect_ratio, planesArray); - + vtkSmartPointer planes = vtkSmartPointer::New(); planes->SetFrustumPlanes(planesArray); - + vtkSmartPointer frustumSource = vtkSmartPointer::New(); frustumSource->SetPlanes(planes); @@ -1142,14 +1142,14 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, double scale, const // Extract the edges so we have the grid vtkSmartPointer filter = vtkSmartPointer::New(); filter->SetInputConnection(frustumSource->GetOutputPort()); - filter->Update(); - + filter->Update(); + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(filter->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -1162,7 +1162,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33f &K, const Mat &image, do // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) float fovy = 2.0f * atan2(c_y,f_y) * 180.0f / CV_PI; float far_end_height = 2.0f * c_y * scale / f_y; - + vtkSmartPointer actor = vtkSmartPointer::New(); ProjectImage::projectImage(fovy, far_end_height, image, scale, color, actor); WidgetAccessor::setProp(*this, actor); @@ -1173,7 +1173,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2f &fov, const Mat &image, do CV_Assert(!image.empty() && image.depth() == CV_8U); float fovy = fov[1] * 180.0f / CV_PI; float far_end_height = 2.0 * scale * tan(fov[1] * 0.5); - + vtkSmartPointer actor = vtkSmartPointer::New(); ProjectImage::projectImage(fovy, far_end_height, image, scale, color, actor); WidgetAccessor::setProp(*this, actor); @@ -1191,21 +1191,21 @@ template<> cv::viz::WCameraPosition cv::viz::Widget::cast poly_data, vtkSmartPointer append_filter, const std::vector &path) - { + { vtkIdType nr_points = path.size(); - + for (vtkIdType i = 0; i < nr_points; ++i) { vtkSmartPointer new_data = vtkSmartPointer::New(); new_data->DeepCopy(poly_data); - + // Transform the default coordinate frame vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); vtkSmartPointer mat_trans = vtkSmartPointer::New(); mat_trans = convertToVtkMatrix(path[i].matrix); transform->SetMatrix(mat_trans); - + vtkSmartPointer filter = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 filter->SetInput(new_data); @@ -1214,7 +1214,7 @@ struct cv::viz::WTrajectory::ApplyPath #endif filter->SetTransform(transform); filter->Update(); - + append_filter->AddInputConnection(filter->GetOutputPort()); } } @@ -1223,36 +1223,36 @@ struct cv::viz::WTrajectory::ApplyPath cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display_mode, const Color &color, double scale) { vtkSmartPointer appendFilter = vtkSmartPointer::New(); - + // Bitwise and with 3 in order to limit the domain to 2 bits if ((~display_mode & 3) ^ WTrajectory::DISPLAY_PATH) { // Create a poly line along the path - vtkIdType nr_points = path.size(); - + vtkIdType nr_points = path.size(); + vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer polyData = vtkSmartPointer::New(); vtkSmartPointer polyLine = vtkSmartPointer::New(); - + points->SetDataTypeToFloat(); points->SetNumberOfPoints(nr_points); polyLine->GetPointIds()->SetNumberOfIds(nr_points); - + Vec3f *data_beg = vtkpoints_data(points); - + for (vtkIdType i = 0; i < nr_points; ++i) { Vec3f cam_pose = path[i].translation(); *data_beg++ = cam_pose; polyLine->GetPointIds()->SetId(i,i); } - + vtkSmartPointer cells = vtkSmartPointer::New(); cells->InsertNextCell(polyLine); - + polyData->SetPoints(points); polyData->SetLines(cells); - + // Set the color for polyData vtkSmartPointer colors = vtkSmartPointer::New(); colors->SetNumberOfComponents(3); @@ -1260,7 +1260,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display colors->FillComponent(0, color[2]); colors->FillComponent(1, color[1]); colors->FillComponent(2, color[0]); - + polyData->GetPointData()->SetScalars(colors); #if VTK_MAJOR_VERSION <= 5 appendFilter->AddInputConnection(polyData->GetProducerPort()); @@ -1268,14 +1268,14 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display appendFilter->AddInputData(polyData); #endif } - + if ((~display_mode & 3) ^ WTrajectory::DISPLAY_FRAMES) { // Create frames and transform along the path vtkSmartPointer axes = vtkSmartPointer::New(); axes->SetOrigin(0, 0, 0); axes->SetScaleFactor(scale); - + vtkSmartPointer axes_colors = vtkSmartPointer::New(); axes_colors->SetNumberOfComponents(3); axes_colors->InsertNextTuple3(255,0,0); @@ -1284,7 +1284,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display axes_colors->InsertNextTuple3(0,255,0); axes_colors->InsertNextTuple3(0,0,255); axes_colors->InsertNextTuple3(0,0,255); - + vtkSmartPointer axes_data = axes->GetOutput(); #if VTK_MAJOR_VERSION <= 5 axes_data->Update(); @@ -1292,7 +1292,7 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display axes->Update(); #endif axes_data->GetPointData()->SetScalars(axes_colors); - + vtkSmartPointer axes_tubes = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 axes_tubes->SetInput(axes_data); @@ -1302,22 +1302,22 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, int display axes_tubes->SetRadius(axes->GetScaleFactor() / 50.0); axes_tubes->SetNumberOfSides(6); axes_tubes->Update(); - + ApplyPath::applyPath(axes_tubes->GetOutput(), appendFilter, path); } - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUsePointData(); mapper->SetInputConnection(appendFilter->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); } cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Matx33f &K, double scale, const Color &color) -{ +{ vtkSmartPointer camera = vtkSmartPointer::New(); float f_x = K(0,0); float f_y = K(1,1); @@ -1325,19 +1325,19 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Matx3 float aspect_ratio = f_y / f_x; // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) float fovy = 2.0f * atan2(c_y,f_y) * 180 / CV_PI; - + camera->SetViewAngle(fovy); camera->SetPosition(0.0,0.0,0.0); camera->SetViewUp(0.0,1.0,0.0); camera->SetFocalPoint(0.0,0.0,1.0); camera->SetClippingRange(0.01, scale); - + double planesArray[24]; camera->GetFrustumPlanes(aspect_ratio, planesArray); - + vtkSmartPointer planes = vtkSmartPointer::New(); planes->SetFrustumPlanes(planesArray); - + vtkSmartPointer frustumSource = vtkSmartPointer::New(); frustumSource->SetPlanes(planes); frustumSource->Update(); @@ -1346,16 +1346,16 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Matx3 vtkSmartPointer filter = vtkSmartPointer::New(); filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); - + vtkSmartPointer appendFilter = vtkSmartPointer::New(); ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(appendFilter->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -1363,21 +1363,21 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Matx3 cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Vec2f &fov, double scale, const Color &color) { vtkSmartPointer camera = vtkSmartPointer::New(); - + camera->SetViewAngle(fov[1] * 180 / CV_PI); // Vertical field of view camera->SetPosition(0.0,0.0,0.0); camera->SetViewUp(0.0,1.0,0.0); camera->SetFocalPoint(0.0,0.0,1.0); camera->SetClippingRange(0.01, scale); - + double aspect_ratio = tan(fov[0] * 0.5) / tan(fov[1] * 0.5); - + double planesArray[24]; camera->GetFrustumPlanes(aspect_ratio, planesArray); - + vtkSmartPointer planes = vtkSmartPointer::New(); planes->SetFrustumPlanes(planesArray); - + vtkSmartPointer frustumSource = vtkSmartPointer::New(); frustumSource->SetPlanes(planes); frustumSource->Update(); @@ -1386,16 +1386,16 @@ cv::viz::WTrajectory::WTrajectory(const std::vector &path, const Vec2f vtkSmartPointer filter = vtkSmartPointer::New(); filter->SetInputConnection(frustumSource->GetOutputPort()); filter->Update(); - + vtkSmartPointer appendFilter = vtkSmartPointer::New(); ApplyPath::applyPath(filter->GetOutput(), appendFilter, path); - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(appendFilter->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); setColor(color); } @@ -1409,17 +1409,17 @@ template<> cv::viz::WTrajectory cv::viz::Widget::cast() /////////////////////////////////////////////////////////////////////////////////////////////// /// spheres trajectory widget implementation -cv::viz::WSpheresTrajectory::WSpheresTrajectory(const std::vector &path, float line_length, double init_sphere_radius, double sphere_radius, +cv::viz::WSpheresTrajectory::WSpheresTrajectory(const std::vector &path, float line_length, double init_sphere_radius, double sphere_radius, const Color &line_color, const Color &sphere_color) { vtkSmartPointer appendFilter = vtkSmartPointer::New(); vtkIdType nr_poses = path.size(); - + // Create color arrays vtkSmartPointer line_scalars = vtkSmartPointer::New(); line_scalars->SetNumberOfComponents(3); line_scalars->InsertNextTuple3(line_color[2], line_color[1], line_color[0]); - + // Create color array for sphere vtkSphereSource * dummy_sphere = vtkSphereSource::New(); // Create the array for big sphere @@ -1442,12 +1442,12 @@ cv::viz::WSpheresTrajectory::WSpheresTrajectory(const std::vector &pat sphere_scalars->FillComponent(0, sphere_color[2]); sphere_scalars->FillComponent(1, sphere_color[1]); sphere_scalars->FillComponent(2, sphere_color[0]); - dummy_sphere->Delete(); - + dummy_sphere->Delete(); + for (vtkIdType i = 0; i < nr_poses; ++i) { Point3f new_pos = path[i].translation(); - + vtkSmartPointer sphere_source = vtkSmartPointer::New(); sphere_source->SetCenter(new_pos.x, new_pos.y, new_pos.z); if (i == 0) @@ -1465,28 +1465,28 @@ cv::viz::WSpheresTrajectory::WSpheresTrajectory(const std::vector &pat sphere_source->GetOutput()->GetCellData()->SetScalars(sphere_scalars); appendFilter->AddInputConnection(sphere_source->GetOutputPort()); } - - + + Affine3f relativeAffine = path[i].inv() * path[i-1]; Vec3f v = path[i].rotation() * relativeAffine.translation(); v = normalize(v) * line_length; - + vtkSmartPointer line_source = vtkSmartPointer::New(); line_source->SetPoint1(new_pos.x + v[0], new_pos.y + v[1], new_pos.z + v[2]); line_source->SetPoint2(new_pos.x, new_pos.y, new_pos.z); line_source->Update(); line_source->GetOutput()->GetCellData()->SetScalars(line_scalars); - + appendFilter->AddInputConnection(line_source->GetOutputPort()); } - + vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetScalarModeToUseCellData(); mapper->SetInputConnection(appendFilter->GetOutputPort()); - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + WidgetAccessor::setProp(*this, actor); } diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp index 31a469933..5528fbcfc 100644 --- a/modules/viz/src/types.cpp +++ b/modules/viz/src/types.cpp @@ -120,10 +120,10 @@ struct cv::viz::Mesh3d::loadMeshImpl vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(file.c_str()); reader->Update(); - + vtkSmartPointer poly_data = reader->GetOutput(); CV_Assert("File does not exist or file format is not supported." && poly_data); - + vtkSmartPointer mesh_points = poly_data->GetPoints(); vtkIdType nr_points = mesh_points->GetNumberOfPoints(); @@ -141,7 +141,7 @@ struct cv::viz::Mesh3d::loadMeshImpl vtkUnsignedCharArray* poly_colors = 0; if (poly_data->GetPointData()) poly_colors = vtkUnsignedCharArray::SafeDownCast(poly_data->GetPointData()->GetScalars()); - + if (poly_colors && (poly_colors->GetNumberOfComponents() == 3)) { mesh.colors.create(1, nr_points, CV_8UC3); @@ -164,9 +164,9 @@ struct cv::viz::Mesh3d::loadMeshImpl vtkIdType nr_cell_points; vtkCellArray * mesh_polygons = poly_data->GetPolys(); mesh_polygons->InitTraversal(); - + mesh.polygons.create(1, mesh_polygons->GetSize(), CV_32SC1); - + int* polygons = mesh.polygons.ptr(); while (mesh_polygons->GetNextCell(nr_cell_points, cell_points)) { @@ -213,30 +213,30 @@ cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size) } cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size) -{ +{ CV_Assert(window_size.width > 0 && window_size.height > 0); - + double near = proj(2,3) / (proj(2,2) - 1.0); double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0); double left = near * (proj(0,2)-1) / proj(0,0); double right = 2.0 * near / proj(0,0) + left; double bottom = near * (proj(1,2)-1) / proj(1,1); double top = 2.0 * near / proj(1,1) + bottom; - + double epsilon = 2.2204460492503131e-16; - + if (fabs(left-right) < epsilon) principal_point_[0] = static_cast(window_size.width) * 0.5f; - else principal_point_[0] = (left * static_cast(window_size.width)) / (left - right); + else principal_point_[0] = (left * static_cast(window_size.width)) / (left - right); focal_[0] = -near * principal_point_[0] / left; - - if (fabs(top-bottom) < epsilon) principal_point_[1] = static_cast(window_size.height) * 0.5f; - else principal_point_[1] = (top * static_cast(window_size.height)) / (top - bottom); + + if (fabs(top-bottom) < epsilon) principal_point_[1] = static_cast(window_size.height) * 0.5f; + else principal_point_[1] = (top * static_cast(window_size.height)) / (top - bottom); focal_[1] = near * principal_point_[1] / top; - + setClip(Vec2d(near, far)); fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); fov_[1] = (atan2(principal_point_[1],focal_[1]) + atan2(window_size.height-principal_point_[1],focal_[1])); - + window_size_ = window_size; } @@ -244,33 +244,33 @@ void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Siz { CV_Assert(window_size.width > 0 && window_size.height > 0); setClip(Vec2d(0.01, 1000.01));// Default clipping - + fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x)); fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y)); - + principal_point_[0] = c_x; principal_point_[1] = c_y; - + focal_[0] = f_x; focal_[1] = f_y; - + window_size_ = window_size; } void cv::viz::Camera::setWindowSize(const Size &window_size) { CV_Assert(window_size.width > 0 && window_size.height > 0); - + // Get the scale factor and update the principal points float scalex = static_cast(window_size.width) / static_cast(window_size_.width); float scaley = static_cast(window_size.height) / static_cast(window_size_.height); - + principal_point_[0] *= scalex; principal_point_[1] *= scaley; focal_ *= scaley; // Vertical field of view is fixed! Update horizontal field of view fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); - + window_size_ = window_size; } @@ -280,12 +280,12 @@ void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const double left = -clip_[0] * principal_point_[0] / focal_[0]; double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0]; double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1]; - + double temp1 = 2.0 * clip_[0]; double temp2 = 1.0 / (right - left); double temp3 = 1.0 / (top - bottom); double temp4 = 1.0 / (clip_[0] - clip_[1]); - + proj = Matx44d::zeros(); proj(0,0) = temp1 * temp2; proj(1,1) = temp1 * temp3; @@ -300,7 +300,7 @@ cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) { // Without distortion, RGB Camera // Received from http://nicolas.burrus.name/index.php/Research/KinectCalibration - Matx33f K = Matx33f::zeros(); + Matx33f K = Matx33f::zeros(); K(0,0) = 5.2921508098293293e+02; K(0,2) = 3.2894272028759258e+02; K(1,1) = 5.2556393630057437e+02; diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 8941584d6..2517d138a 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -72,7 +72,7 @@ cv::Affine3f cv::viz::makeCameraPose(const Vec3f& position, const Vec3f& focal_p Vec3f n = normalize(focal_point - position); Vec3f u = normalize(y_dir.cross(n)); Vec3f v = n.cross(u); - + Matx44f pose_mat = Matx44f::zeros(); pose_mat(0,0) = u[0]; pose_mat(0,1) = u[1]; @@ -147,9 +147,9 @@ struct cv::viz::VizAccessor::VizAccessorImpl cv::viz::VizAccessor::VizAccessor() { impl_ = new cv::viz::VizAccessor::VizAccessorImpl;} -cv::viz::VizAccessor::~VizAccessor() -{ - if(impl_) +cv::viz::VizAccessor::~VizAccessor() +{ + if(impl_) { delete impl_; impl_ = 0; @@ -202,7 +202,7 @@ void cv::viz::VizAccessor::remove(const String &window_name) // Add the prefix Viz String name; generateWindowName(window_name, name); - + VizMap::iterator vm_itr = impl_->viz_map.find(name); bool exists = vm_itr != impl_->viz_map.end(); if (!exists) return ; @@ -214,7 +214,7 @@ void cv::viz::VizAccessor::generateWindowName(const String &window_name, String output = "Viz"; // Already is Viz if (window_name == output) return; - + String prefixed = output + " - "; if (window_name.substr(0, prefixed.length()) == prefixed) output = window_name; // Already has "Viz - " else if (window_name.substr(0, output.length()) == output) output = prefixed + window_name; // Doesn't have prefix diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index c7dcb18a2..f1714cf09 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -51,7 +51,7 @@ cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(0) { create(window_name); } -cv::viz::Viz3d::Viz3d(const Viz3d& other) : impl_(other.impl_) +cv::viz::Viz3d::Viz3d(const Viz3d& other) : impl_(other.impl_) { if (impl_) CV_XADD(&impl_->ref_counter, 1); } diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index 456b3d62c..cf5a90580 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -125,7 +125,7 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name) ///////////////////////////////////////////////////////////////////////////////////////////// cv::viz::Viz3d::VizImpl::~VizImpl() { - if (interactor_) + if (interactor_) interactor_->DestroyTimer(timer_id_); if (renderer_) renderer_->Clear(); } @@ -368,11 +368,11 @@ void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color) void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) { vtkCamera& active_camera = *renderer_->GetActiveCamera(); - + // Set the intrinsic parameters of the camera window_->SetSize(camera.getWindowSize().width, camera.getWindowSize().height); double aspect_ratio = static_cast(camera.getWindowSize().width)/static_cast(camera.getWindowSize().height); - + Matx44f proj_mat; camera.computeProjectionMatrix(proj_mat); // Use the intrinsic parameters of the camera to simulate more realistically @@ -382,7 +382,7 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) transform->SetMatrix(convertToVtkMatrix(proj_mat * old_proj_mat.inv())); active_camera.SetUserTransform(transform); transform->Delete(); - + renderer_->ResetCameraClippingRange(); renderer_->Render(); } @@ -391,11 +391,11 @@ void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const { vtkCamera& active_camera = *renderer_->GetActiveCamera(); - + Size window_size(renderer_->GetRenderWindow()->GetSize()[0], renderer_->GetRenderWindow()->GetSize()[1]); double aspect_ratio = static_cast(window_size.width) / static_cast(window_size.height); - + Matx44f proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f)); Camera camera(proj_matrix, window_size); return camera; @@ -405,7 +405,7 @@ cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) { vtkCamera& camera = *renderer_->GetActiveCamera(); - + // Position = extrinsic translation cv::Vec3f pos_vec = pose.translation(); @@ -417,11 +417,11 @@ void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose) // Compute the new focal point cv::Vec3f z_axis(0.f, 0.f, 1.f); cv::Vec3f focal_vec = pos_vec + rotation * z_axis; - + camera.SetPosition(pos_vec[0], pos_vec[1], pos_vec[2]); camera.SetFocalPoint(focal_vec[0], focal_vec[1], focal_vec[2]); camera.SetViewUp(up_vec[0], up_vec[1], up_vec[2]); - + renderer_->ResetCameraClippingRange(); renderer_->Render(); } @@ -465,10 +465,10 @@ void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3d &pt, Poin ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) -{ +{ Vec4d world_pt; vtkInteractorObserver::ComputeDisplayToWorld(renderer_, window_coord.x, window_coord.y, window_coord.z, world_pt.val); - + vtkCamera &active_camera = *renderer_->GetActiveCamera(); Vec3d cam_pos; active_camera.GetPosition(cam_pos.val); @@ -525,19 +525,19 @@ void cv::viz::Viz3d::VizImpl::setRepresentation(int representation) vtkActor * actor; switch (representation) { - case REPRESENTATION_POINTS: + case REPRESENTATION_POINTS: { while ((actor = actors->GetNextActor()) != NULL) actor->GetProperty()->SetRepresentationToPoints(); break; } - case REPRESENTATION_SURFACE: + case REPRESENTATION_SURFACE: { while ((actor = actors->GetNextActor()) != NULL) actor->GetProperty()->SetRepresentationToSurface(); break; } - case REPRESENTATION_WIREFRAME: + case REPRESENTATION_WIREFRAME: { while ((actor = actors->GetNextActor()) != NULL) actor->GetProperty()->SetRepresentationToWireframe(); diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index 7b1ddae6b..e94b7361f 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -58,20 +58,20 @@ public: typedef cv::Ptr Ptr; typedef Viz3d::KeyboardCallback KeyboardCallback; typedef Viz3d::MouseCallback MouseCallback; - + int ref_counter; VizImpl(const String &name); virtual ~VizImpl(); - + void showWidget(const String &id, const Widget &widget, const Affine3f &pose = Affine3f::Identity()); void removeWidget(const String &id); Widget getWidget(const String &id) const; void removeAllWidgets(); - + void setWidgetPose(const String &id, const Affine3f &pose); void updateWidgetPose(const String &id, const Affine3f &pose); - Affine3f getWidgetPose(const String &id) const; + Affine3f getWidgetPose(const String &id) const; void setDesiredUpdateRate(double rate); double getDesiredUpdateRate(); @@ -86,7 +86,7 @@ public: void close() { stopped_ = true; - if (interactor_) + if (interactor_) { interactor_->GetRenderWindow()->Finalize(); interactor_->TerminateApp(); // This tends to close the window... @@ -94,14 +94,14 @@ public: } void setRepresentation(int representation); - + void setCamera(const Camera &camera); Camera getCamera() const; /** \brief Reset the camera to a given widget */ void resetCameraViewpoint(const String& id); void resetCamera(); - + void setViewerPose(const Affine3f &pose); Affine3f getViewerPose(); @@ -182,7 +182,7 @@ private: /** \brief The render window interactor style. */ vtkSmartPointer style_; - + /** \brief Internal list with actor pointers and name IDs for all widget actors */ cv::Ptr widget_actor_map_; @@ -245,7 +245,7 @@ namespace cv } return output; } - + static _Out* copyColor(const Mat& source, _Out* output, const Mat& nan_mask) { CV_Assert(DataDepth<_Tp>::value == source.depth() && source.size() == nan_mask.size()); @@ -282,7 +282,7 @@ namespace cv return table[nan_mask.depth() - 5](source, output, nan_mask); } - + template static inline Vec<_Tp, 3>* copyColor(const Mat& source, Vec<_Tp, 3>* output, const Mat& nan_mask) { @@ -328,7 +328,7 @@ namespace cv inline Vec3d vtkpoint(const Point3f& point) { return Vec3d(point.x, point.y, point.z); } template inline _Tp normalized(const _Tp& v) { return v * 1/cv::norm(v); } - + struct ConvertToVtkImage { struct Impl @@ -336,7 +336,7 @@ namespace cv static void copyImageMultiChannel(const Mat &image, vtkSmartPointer output) { int i_chs = image.channels(); - + for (int i = 0; i < image.rows; ++i) { const unsigned char * irows = image.ptr(i); @@ -349,7 +349,7 @@ namespace cv } output->Modified(); } - + static void copyImageSingleChannel(const Mat &image, vtkSmartPointer output) { for (int i = 0; i < image.rows; ++i) @@ -364,7 +364,7 @@ namespace cv output->Modified(); } }; - + static void convert(const Mat &image, vtkSmartPointer output) { // Create the vtk image @@ -376,7 +376,7 @@ namespace cv #else output->AllocateScalars(VTK_UNSIGNED_CHAR, image.channels()); #endif - + int i_chs = image.channels(); if (i_chs > 1) { diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp index 1742e854e..04abdcf7a 100644 --- a/modules/viz/src/widget.cpp +++ b/modules/viz/src/widget.cpp @@ -55,14 +55,14 @@ class cv::viz::Widget::Impl { public: vtkSmartPointer prop; - + Impl() : prop(0) {} }; cv::viz::Widget::Widget() : impl_( new Impl() ) { } cv::viz::Widget::Widget(const Widget& other) : impl_( new Impl() ) -{ +{ if (other.impl_ && other.impl_->prop) impl_->prop = other.impl_->prop; } @@ -73,8 +73,8 @@ cv::viz::Widget& cv::viz::Widget::operator=(const Widget& other) return *this; } -cv::viz::Widget::~Widget() -{ +cv::viz::Widget::~Widget() +{ if (impl_) { delete impl_; @@ -86,7 +86,7 @@ cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) { vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(file_name.c_str()); - + vtkSmartPointer data = reader->GetOutput(); CV_Assert("File does not exist or file format is not supported." && data); @@ -120,7 +120,7 @@ cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) actor->GetProperty()->BackfaceCullingOn(); actor->SetMapper(mapper); - + Widget widget; widget.impl_->prop = actor; return widget; @@ -130,7 +130,7 @@ void cv::viz::Widget::setRenderingProperty(int property, double value) { vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Widget type is not supported." && actor); - + switch (property) { case POINT_SIZE: @@ -218,8 +218,8 @@ void cv::viz::Widget::setRenderingProperty(int property, double value) actor->Modified(); break; } - - + + default: CV_Assert("setPointCloudRenderingProperties: Unknown property"); } @@ -229,7 +229,7 @@ double cv::viz::Widget::getRenderingProperty(int property) const { vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Widget type is not supported." && actor); - + double value = 0.0; switch (property) { @@ -313,7 +313,7 @@ struct cv::viz::Widget3D::MatrixConverter m(i, k) = vtk_matrix->GetElement(i, k); return m; } - + static vtkSmartPointer convertToVtkMatrix(const Matx44f& m) { vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); @@ -328,7 +328,7 @@ void cv::viz::Widget3D::setPose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Widget is not 3D." && actor); - + vtkSmartPointer matrix = convertToVtkMatrix(pose.matrix); actor->SetUserMatrix(matrix); actor->Modified(); @@ -338,7 +338,7 @@ void cv::viz::Widget3D::updatePose(const Affine3f &pose) { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Widget is not 3D." && actor); - + vtkSmartPointer matrix = actor->GetUserMatrix(); if (!matrix) { @@ -358,7 +358,7 @@ cv::Affine3f cv::viz::Widget3D::getPose() const { vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Widget is not 3D." && actor); - + vtkSmartPointer matrix = actor->GetUserMatrix(); Matx44f matrix_cv = MatrixConverter::convertToMatx(matrix); return Affine3f(matrix_cv); @@ -369,7 +369,7 @@ void cv::viz::Widget3D::setColor(const Color &color) // Cast to actor instead of prop3d since prop3d doesn't provide getproperty vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); CV_Assert("Widget type is not supported." && actor); - + Color c = vtkcolor(color); actor->GetMapper()->ScalarVisibilityOff(); actor->GetProperty()->SetColor(c.val); diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 19d9f7300..ef21c9df7 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -110,23 +110,23 @@ TEST(Viz_viz3d, accuracy) for (int i = 0, j = 0; i <= 360; ++i, j+=5) { cam_path.push_back(viz::makeCameraPose(Point3f(0.5*cos(double(i)*CV_PI/180.0), 0.5*sin(double(j)*CV_PI/180.0), 0.5*sin(double(i)*CV_PI/180.0)), - Point3f(0.0,0.0,0.0), Point3f(0.0,1.0,0.0))); + Point3f(0.0,0.0,0.0), Point3f(0.0,1.0,0.0))); } - + int path_counter = 0; int cam_path_size = cam_path.size(); // OTHER WIDGETS cv::Mat img = imread("opencv.png"); - + int downSample = 4; - + int row_max = img.rows/downSample; int col_max = img.cols/downSample; - + cv::Mat *clouds = new cv::Mat[img.cols/downSample]; cv::Mat *colors = new cv::Mat[img.cols/downSample]; - + for (int col = 0; col < col_max; ++col) { clouds[col] = Mat::zeros(img.rows/downSample, 1, CV_32FC3); @@ -137,7 +137,7 @@ TEST(Viz_viz3d, accuracy) colors[col].at(row) = img.at(row*downSample,col*downSample); } } - + for (int col = 0; col < col_max; ++col) { std::stringstream strstrm; @@ -146,16 +146,16 @@ TEST(Viz_viz3d, accuracy) viz.getWidget(strstrm.str()).setRenderingProperty(viz::POINT_SIZE, 3.0); viz.getWidget(strstrm.str()).setRenderingProperty(viz::OPACITY, 0.45); } - + viz.showWidget("trajectory", viz::WTrajectory(cam_path, viz::WTrajectory::DISPLAY_PATH, viz::Color::yellow())); viz.showWidget("cam_text", viz::WText("Global View", Point2i(5,5), 28)); viz.registerKeyboardCallback(keyboard_callback, (void *) &viz); int angle = 0; - + while(!viz.wasStopped()) { - if (path_counter == cam_path_size) + if (path_counter == cam_path_size) { path_counter = 0; } @@ -164,12 +164,12 @@ TEST(Viz_viz3d, accuracy) { viz.setViewerPose(cam_path[path_counter]); } - + if (angle == 360) angle = 0; cam_1.cast().setPose(cam_path[path_counter]); cam_coordinates.cast().setPose(cam_path[path_counter++]); - + for (int i = 0; i < col_max; ++i) { std::stringstream strstrm; diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index ad7ca7f8b..a82dddcea 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -82,7 +82,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) if(NOT HAVE_opencv_gpuarithm OR NOT HAVE_opencv_gpufilters) ocv_list_filterout(cpp_samples "/gpu/") endif() - + ocv_list_filterout(cpp_samples "viz") foreach(sample_filename ${cpp_samples}) diff --git a/samples/cpp/tutorial_code/viz/bunny.ply b/samples/cpp/tutorial_code/viz/bunny.ply index 10ae64fc3..7d3423339 100644 --- a/samples/cpp/tutorial_code/viz/bunny.ply +++ b/samples/cpp/tutorial_code/viz/bunny.ply @@ -10,5743 +10,5743 @@ property float intensity element face 3851 property list uchar int vertex_indices end_header --0.0369122 0.127512 0.00276757 0.850855 0.5 --0.0457707 0.130327 0.00306785 0.900159 0.5 --0.0708847 0.149834 0.0388672 0.398443 0.5 --0.00331557 0.130403 0.0212208 0.85268 0.5 --0.0211979 0.1272 0.00915278 0.675938 0.5 --0.0265255 0.12592 0.00874866 0.711533 0.5 -0.0339261 0.112038 0.0269672 0.652757 0.5 -0.0376485 0.110455 0.0145481 0.708171 0.5 --0.0259368 0.111118 0.0379115 0.454541 0.437538 -0.027952 0.120939 0.0215377 0.533079 0.5 --0.0628308 0.155987 -0.0150105 0.404517 0.5 -0.0390029 0.106711 0.0215202 0.535542 0.5 -0.0447976 0.0950477 0.00866471 0.579563 0.425995 --0.0330636 0.173619 -0.0031267 0.365607 0.5 --0.0808069 0.136243 0.0495014 0.499575 0.5 --0.0705086 0.12445 0.0526685 0.564827 0.5 -0.00874873 0.131225 0.0145345 0.748371 0.5 -0.0401015 0.106711 0.00874166 0.680399 0.5 -0.0379483 0.100145 -0.00827134 0.600054 0.5 --0.0906538 0.137201 0.0207305 0.824561 0.5 --0.0841655 0.110667 0.0275273 0.690889 0.5 --0.0705214 0.156214 0.0144536 0.807492 0.5 --0.083872 0.15212 0.0282652 0.248168 0.41865 -0.00305028 0.12432 0.0332425 0.555044 0.354559 -0.00870828 0.124165 0.0330348 0.653433 0.5 --0.0328896 0.12613 0.00300653 0.898771 0.5 --0.0506302 0.143065 0.0150611 0.691477 0.5 --0.0757863 0.13637 0.050172 0.566256 0.5 --0.0027191 0.128962 0.0264678 0.271491 0.462815 --0.0460961 0.125118 0.0263142 0.539149 0.5 --0.0785104 0.0942728 -0.0109192 0.710999 0.5 -0.0216915 0.125373 0.0211452 0.530957 0.5 --0.0888469 0.124305 0.00237041 0.635593 0.5 -0.040386 0.100825 -0.00303043 0.574857 0.5 --0.0884145 0.117791 0.00268555 0.487167 0.430737 --0.0319074 0.177421 -0.00491879 0.269231 0.447035 --0.0765825 0.143224 0.0455148 0.414139 0.5 --0.0209748 0.112544 0.0388613 0.482541 0.5 --0.020836 0.179425 -0.0221622 0.341071 0.440034 --0.0377039 0.167987 -0.0130391 0.396317 0.473039 --0.0331765 0.12681 0.00839958 0.896274 0.5 -0.00893926 0.127114 0.0292916 0.350014 0.41288 --0.044944 0.131083 0.0147963 0.599596 0.5 --0.0266041 0.12515 0.00282384 0.73687 0.5 -0.0144285 0.12328 0.0319185 0.625269 0.5 -0.019244 0.122284 0.0308314 0.611204 0.34486 --0.0390225 0.167317 0.00215527 0.413994 0.469929 --0.08808 0.129976 0.00206377 0.625486 0.5 --0.0537203 0.142608 0.0266058 0.696873 0.5 -0.043095 0.0980072 0.0191617 0.665192 0.5 -0.0432138 0.100117 0.00866473 0.691828 0.5 -0.0415448 0.0944954 0.0275695 0.671611 0.5 --0.0578726 0.155337 0.0149245 0.394763 0.437313 --0.0231577 0.157375 -0.0046304 0.136389 0.380194 --0.0683123 0.145735 0.0420568 0.751812 0.5 --0.0708351 0.142847 0.0451248 0.627973 0.5 --0.070664 0.0642894 0.0209789 0.413051 0.5 --0.0761519 0.130581 0.0525324 0.629117 0.5 --0.0640036 0.161784 -0.0208118 0.449093 0.5 --0.0706461 0.155711 0.00252406 0.855717 0.5 --0.0924366 0.118434 0.0399838 0.673877 0.5 --0.0635349 0.156052 0.0148814 0.798496 0.5 -0.0282675 0.118192 0.0274382 0.635485 0.5 -0.0392736 0.0938857 -0.00915453 0.585857 0.459742 --0.0695973 0.164844 -0.0174846 0.548789 0.5 --0.00892354 0.123904 0.0330319 0.602316 0.374044 -0.0269099 0.0942476 0.0444911 0.649753 0.5 --0.0146258 0.162377 -0.0144398 0.338176 0.5 --0.0450983 0.167072 0.00289327 0.449091 0.5 --0.0761536 0.172742 -0.0384391 0.256591 0.4298 --0.0858274 0.105458 0.00472318 0.523819 0.297125 -0.0370431 0.110443 0.0207229 0.52623 0.448558 -0.0321593 0.0994027 0.0380657 0.733041 0.5 --0.075287 0.146433 0.0428582 0.424358 0.5 --0.0395145 0.171107 0.000531747 0.452893 0.5 --0.0839586 0.11215 0.00148754 0.436727 0.419097 -0.0446848 0.0883378 0.0216285 0.487783 0.481728 -0.0161783 0.127819 0.0220535 0.481793 0.5 --0.00251635 0.0397232 0.0474087 0.280725 0.5 -0.00303163 0.0406968 0.0460422 0.331809 0.5 --0.0143059 0.128197 0.00333856 0.693854 0.5 --0.0526117 0.155596 0.0109972 0.561042 0.5 --0.0332043 0.17776 -0.00906223 0.212789 0.5 -0.0394391 0.106654 0.00306577 0.522321 0.489889 --0.0923799 0.1249 0.0327641 0.848517 0.5 -0.0454681 0.0882959 0.0146642 0.575503 0.5 --0.0274495 0.179802 -0.00925837 0.258799 0.457369 --0.072504 0.146297 0.0429682 0.549207 0.5 --0.0579959 0.129793 0.0383118 0.658867 0.444043 -0.043117 0.0923689 0.0251649 0.622686 0.5 --0.00865718 0.130323 0.0149721 0.633691 0.5 --0.0141304 0.129188 0.0147431 0.547632 0.5 --0.0707877 0.15583 0.00921954 0.739059 0.5 --0.00952731 0.127041 0.0281475 0.375412 0.377874 --0.0646289 0.153404 0.0329146 0.855321 0.5 --0.0706939 0.15347 0.0328596 0.444959 0.455263 -0.0208126 0.118434 0.0336393 0.519282 0.5 --0.0396566 0.173008 -0.00299705 0.274377 0.177706 --0.0442176 0.170815 -0.00391429 0.245926 0.5 --0.0582565 0.0395149 0.0457796 0.417977 0.459314 --0.0523033 0.0401501 0.04623 0.454776 0.456044 --0.0760211 0.161274 -0.0145891 0.267801 0.372187 --0.0693983 0.163016 -0.0140293 0.403228 0.45768 -0.0399663 0.106491 0.014952 0.713602 0.5 -0.041536 0.0950084 -0.00475737 0.490139 0.464008 --0.0470079 0.163779 0.00528295 0.432857 0.486946 --0.0402546 0.161678 0.00298655 0.447592 0.5 --0.0386569 0.0389805 0.0441153 0.509262 0.5 --0.0704175 0.166991 -0.0216976 0.332592 0.447054 --0.0254201 0.0886622 0.0503827 0.608282 0.5 --0.0886334 0.137429 0.00876953 0.549009 0.5 --0.014179 0.12627 0.0266417 0.420759 0.5 --0.0360017 0.17408 -0.0118959 0.409753 0.289042 --0.0886251 0.0937834 0.00823534 0.753697 0.5 --0.0648672 0.155874 -0.00891497 0.595216 0.5 --0.0704508 0.137752 -0.00774011 0.446131 0.5 --0.0750154 0.166247 -0.0219558 0.263106 0.5 -0.0299465 0.114869 0.0300239 0.642356 0.5 -0.0398138 0.0998788 0.0273101 0.51725 0.5 --0.015242 0.111698 0.0407424 0.605597 0.5 --0.0700387 0.118219 0.0524379 0.585543 0.5 -0.0149973 0.112399 0.0386082 0.669811 0.5 --0.036487 0.171225 0.000545037 0.438578 0.5 --0.0641664 0.118551 -0.00968333 0.569796 0.5 --0.071817 0.166979 -0.0463822 0.381568 0.451091 --0.0913559 0.14534 0.0246937 0.648478 0.5 -0.00903703 0.112569 0.0396571 0.549283 0.408623 -0.0324674 0.0997396 -0.0141603 0.732658 0.5 -0.0417911 0.101845 0.00188609 0.547756 0.5 -0.00302992 0.112517 0.0415434 0.592572 0.5 --0.0650368 0.148485 0.0382561 0.62562 0.5 --0.0706519 0.13063 0.0502497 0.563116 0.5 --0.0144471 0.128935 0.00903509 0.682121 0.5 -0.00292575 0.131541 0.00912318 0.795238 0.5 --0.0625682 0.151125 0.035875 0.463512 0.5 -0.0349829 0.113328 0.0214487 0.620597 0.5 -0.021327 0.0385664 0.0392992 0.259499 0.426724 -0.0145125 0.093771 0.0501571 0.654705 0.5 --0.00923752 0.112849 0.0413907 0.615633 0.5 -0.0415329 0.100906 0.0210277 0.662312 0.5 -0.0422859 0.101486 0.0146614 0.569693 0.490777 --0.0773783 0.112839 -0.00448759 0.505277 0.5 --0.078035 0.137641 -0.00517379 0.466714 0.5 -0.00873437 0.106347 -0.0202193 0.792948 0.5 -0.0090324 0.13035 0.0211569 0.465873 0.5 -0.00301322 0.130902 0.0206741 0.592486 0.5 --0.00286342 0.13115 0.0147367 0.587804 0.5 --0.0391578 0.12569 0.0207996 0.438744 0.464814 --0.0205725 0.123523 0.0265579 0.445477 0.415699 --0.0644194 0.155634 0.00928477 0.611624 0.331941 --0.0463385 0.131411 0.0207671 0.674928 0.5 --0.0532034 0.0439067 0.044658 0.417403 0.440199 --0.00297651 0.131046 0.00884967 0.738924 0.5 --0.089664 0.137755 0.0263925 0.80362 0.5 --0.00888731 0.124273 -0.00880284 0.767738 0.284429 --0.0460971 0.0385107 0.0446891 0.654962 0.5 --0.0649255 0.178874 -0.0579325 0.245129 0.411885 --0.0329347 0.124601 0.0211235 0.32811 0.5 --0.0831301 0.149901 0.0334123 0.331963 0.314683 --0.0895652 0.093948 0.0149303 0.603378 0.5 --0.0328901 0.124518 -0.00282055 0.63839 0.5 --0.0845271 0.106161 0.00204328 0.338681 0.43162 --0.0469341 0.155816 0.00872921 0.470367 0.484595 -0.0206202 0.123943 0.0267275 0.477255 0.5 --0.026256 0.117499 0.0321672 0.543293 0.5 --0.021392 0.118632 0.0336445 0.468887 0.429556 --0.0195069 0.116132 0.0368525 0.534732 0.411301 --0.0761618 0.118382 0.0520923 0.490413 0.5 -0.00889281 0.0395765 0.0451727 0.476347 0.38769 --0.0534736 0.159548 0.00753828 0.476667 0.5 --0.0469464 0.161226 0.00680216 0.495992 0.483766 --0.0574886 0.154862 0.0204748 0.677314 0.5 -0.0317199 0.117635 0.0202007 0.579556 0.5 -0.0378683 0.105514 -0.00259159 0.588286 0.5 --0.0811847 0.137693 -0.00253994 0.641736 0.5 --0.0764348 0.124515 0.0528345 0.65366 0.5 -0.0343816 0.106104 -0.00900254 0.534403 0.5 -0.0457922 0.088316 0.00867097 0.586292 0.439394 --0.0703288 0.0944195 -0.0159143 0.511499 0.5 --0.0756048 0.0937947 -0.0135536 0.429902 0.5 --0.058657 0.156369 0.0093256 0.31374 0.5 --0.0637335 0.153848 0.00222718 0.478676 0.5 --0.0777278 0.0960024 0.0363437 0.678588 0.5 --0.0868519 0.136556 0.00309926 0.517441 0.5 --0.0455299 0.0432404 0.0432162 0.712662 0.5 --0.0402011 0.045749 0.0408051 0.669165 0.320516 --0.0654123 0.160403 -0.0149066 0.335302 0.5 --0.0318898 0.0387174 0.0510004 0.553401 0.5 --0.0267997 0.0453977 0.0509311 0.501112 0.5 --0.0271043 0.0396972 0.0535379 0.487956 0.5 --0.0215575 0.0460868 0.0517209 0.709553 0.5 --0.0143078 0.0445295 0.0504368 0.575852 0.5 --0.00981594 0.043264 0.0493162 0.448927 0.393067 --0.00348436 0.044054 0.0472086 0.598081 0.5 -0.009577 0.0458139 0.0465877 0.519814 0.433928 -0.02048 0.111086 0.0379569 0.681163 0.5 --0.0141831 0.128547 0.0200007 0.293349 0.5 --0.0526702 0.144108 0.0210347 0.639643 0.5 --0.0634838 0.17384 -0.0527131 0.549906 0.5 --0.0366553 0.171999 -0.0125745 0.436075 0.5 --0.0525548 0.131228 0.0328277 0.727547 0.5 --0.0659567 0.132023 0.0442925 0.724494 0.5 --0.0921726 0.11832 0.0267606 0.794672 0.5 -0.0452792 0.0882737 0.00268175 0.507794 0.5 --0.00305651 0.112889 0.0417789 0.635396 0.5 --0.0451955 0.161396 -0.00871567 0.424682 0.5 --0.0402914 0.160933 -0.0115368 0.411895 0.405943 --0.0521414 0.0701165 0.0389584 0.682177 0.456916 --0.0383315 0.093604 -0.0232581 0.72469 0.5 --0.0690556 0.137374 0.046352 0.61723 0.5 --0.0695996 0.167401 -0.0516299 0.518552 0.5 --0.00246047 0.124102 0.0337609 0.444043 0.5 --0.0398624 0.128204 0.00299348 0.864483 0.5 --0.0753331 0.149032 0.0395625 0.432149 0.5 --0.0701432 0.160618 -0.00917801 0.464361 0.5 --0.0589378 0.0440425 0.0434222 0.437887 0.447715 --0.0207164 0.126445 0.00312493 0.710427 0.5 --0.00850666 0.0467286 0.0481052 0.613173 0.5 -0.00300323 0.0450308 0.0469911 0.464978 0.5 --0.0802174 0.148665 0.0379438 0.47939 0.5 --0.0819961 0.130698 0.0513437 0.54405 0.5 -0.00273088 0.106333 -0.0209927 0.733954 0.5 --0.0757273 0.0885687 -0.0138399 0.397424 0.5 --0.0698477 0.0882875 -0.0167823 0.420617 0.5 --0.0668508 0.159243 -0.0102161 0.42216 0.440727 --0.0226988 0.0885773 0.0536309 0.546444 0.5 --0.00281419 0.0990077 0.0505614 0.455087 0.5 -0.0452902 0.0696213 0.0253974 0.33948 0.5 --0.0525629 0.0472823 0.040482 0.279548 0.5 --0.046959 0.0466581 0.0408127 0.43714 0.5 --0.0691348 0.156682 -0.00276369 0.629099 0.5 --0.0897599 0.150073 0.0220744 0.276354 0.5 --0.0702883 0.155637 0.0263654 0.47565 0.441038 --0.0765031 0.154893 0.0266005 0.799832 0.5 --0.00804843 0.0987379 0.0505998 0.327523 0.438474 -0.0300791 0.11567 -0.00430465 0.66246 0.5 --0.0923054 0.117757 0.0334441 0.476916 0.5 --0.0331192 0.0449511 0.0462474 0.432059 0.466683 --0.0337794 0.113308 0.034612 0.683562 0.5 --0.0521291 0.113769 0.0349566 0.515399 0.5 -0.0437636 0.0825382 -0.0027974 0.568535 0.5 --0.0202819 0.126016 0.0210507 0.374818 0.437592 -0.0327872 0.043925 0.0295904 0.650152 0.5 --0.0453372 0.155266 -0.0075525 0.386286 0.5 --0.0284609 0.173987 -0.0175958 0.379432 0.418735 -0.0268448 0.0881755 -0.0223077 0.715629 0.5 --0.0308231 0.0923023 -0.0246377 0.474586 0.431409 --0.0899732 0.149975 0.0141115 0.257143 0.5 -0.0381804 0.105121 0.0266947 0.534482 0.490368 -0.00842001 0.12907 0.0258154 0.374593 0.448613 --0.0266549 0.0942999 -0.0265555 0.294426 0.332222 --0.0279896 0.0475815 0.0485532 0.381268 0.5 --0.0150037 0.048073 0.0483203 0.576068 0.5 --0.00298993 0.0473817 0.0491102 0.446744 0.431743 -0.00376754 0.0477551 0.0502037 0.495901 0.44823 -0.00748504 0.0473851 0.0493363 0.494952 0.5 --0.0581651 0.149751 0.032858 0.470966 0.5 --0.0720688 0.136456 0.0490662 0.625357 0.5 --0.0810638 0.0939541 -0.0082617 0.685573 0.5 -0.0380863 0.0458646 0.0307423 0.807573 0.5 --0.0253234 0.182998 -0.0108168 0.245054 0.5 --0.0230508 0.183235 -0.0110157 0.246322 0.458572 -0.00323317 0.129146 0.0263855 0.347796 0.441746 --0.0626125 0.149788 -0.00343342 0.691705 0.5 --0.0591471 0.0466998 0.0395843 0.0883466 0.213805 --0.0353862 0.0471292 0.0414241 0.656538 0.5 --0.0194948 0.0486404 0.0485565 0.373069 0.5 --0.00849455 0.0521633 0.0517688 0.61481 0.5 --0.00296485 0.051429 0.0527827 0.53012 0.5 -0.00279019 0.0517664 0.0528352 0.560812 0.423049 -0.00904034 0.0517165 0.051222 0.558244 0.5 -0.0443839 0.0943042 0.00268377 0.582116 0.455816 --0.0886145 0.111113 0.0148415 0.604102 0.5 --0.0885219 0.144027 0.0329221 0.623335 0.5 -0.0440719 0.0937787 0.0206165 0.493368 0.454688 -0.0436531 0.0980341 0.0146596 0.668233 0.5 --0.0650976 0.153799 -0.00285808 0.715743 0.5 --0.0517297 0.0490759 0.0371355 0 0 --0.0331222 0.0518259 0.0385377 0.676102 0.5 --0.0377352 0.127448 0.0152358 0.612182 0.5 --0.00906608 0.100701 0.0460122 0.338462 0.5 --0.0410683 0.128416 0.0134054 0.417331 0.5 --0.0712056 0.158724 -0.00521868 0.246338 0.5 --0.0266313 0.0501544 0.044695 0.182016 0.5 --0.0211065 0.0519946 0.0455753 0.195646 0.404388 --0.0168667 0.0505241 0.0476889 0.520032 0.5 --0.0147601 0.0527687 0.050103 0.451613 0.5 --0.0626395 0.149972 -0.00897733 0.363787 0.461156 --0.090861 0.124732 0.00627835 0.587249 0.5 --0.0255786 0.0923499 -0.0315595 0.294527 0.5 --0.0709738 0.172947 -0.052768 0.460427 0.5 --0.0588974 0.143232 -0.00327646 0.48145 0.5 --0.0943643 0.12436 0.0216467 0.570519 0.5 -0.0337044 0.112449 -0.00269877 0.532211 0.5 --0.0515051 0.136557 0.0263185 0.72719 0.5 --0.00886593 0.121199 0.0360577 0.614897 0.5 --0.061729 0.155665 -0.0259512 0.690546 0.5 --0.0862637 0.10567 0.0206042 0.519516 0.5 --0.0895584 0.138606 0.032689 0.685876 0.5 --0.0268168 0.123904 0.0208113 0.428255 0.5 -0.0341937 0.0515433 0.033081 0.609925 0.5 -0.0401268 0.0512743 0.0322702 0.669803 0.5 -0.0449306 0.0526595 0.0319582 0.655209 0.5 --0.0405348 0.117168 0.0319438 0.657986 0.5 --0.0636902 0.155546 -0.0390642 0.523327 0.5 -0.0278663 0.100401 0.0410064 0.689793 0.5 --0.0275828 0.179275 -0.0157605 0.314049 0.5 --0.0758871 0.0942302 0.0383961 0.647987 0.457049 -0.0138371 0.129201 0.0203961 0.412341 0.5 --0.0152723 0.0998429 0.0451638 0.271215 0.427554 --0.00916763 0.129718 0.0206646 0.438679 0.430152 --0.0512444 0.0516901 0.0334801 0.192432 0.5 --0.0461563 0.0523184 0.0379981 0.311543 0.5 --0.0410001 0.05272 0.0393793 0.629588 0.477809 --0.0270993 0.0526642 0.0393104 0.155274 0.5 -0.0434924 0.0931097 -0.00154028 0.576953 0.480183 --0.0823819 0.112683 0.045427 0.438131 0.5 --0.092066 0.118055 0.00909937 0.325678 0.5 --0.00448884 0.121713 0.0362976 0.591545 0.5 -0.0147346 0.129423 0.0143146 0.840212 0.5 --0.0158113 0.161888 -0.00973584 0.202865 0.5 --0.0778838 0.149704 -0.00337488 0.403345 0.5 --0.0865357 0.12477 -0.00166991 0.677311 0.5 -0.0153656 0.126058 0.0275381 0.479299 0.429147 --0.0388913 0.123761 0.0249778 0.514489 0.5 --0.0390351 0.121238 0.0283673 0.510424 0.470651 --0.0324963 0.120237 0.0283344 0.568849 0.348087 --0.0149052 0.12311 0.0316417 0.446842 0.5 --0.0582873 0.117688 0.0386719 0.634635 0.5 --0.0626536 0.161861 -0.0264031 0.685413 0.5 --0.0818147 0.141639 0.0444825 0.392929 0.5 -0.0350734 0.100071 0.0345975 0.716199 0.5 -0.0311856 0.11215 0.0310216 0.689434 0.5 --0.0335778 0.11743 0.031458 0.525408 0.5 --0.059637 0.153475 0.031348 0.93076 0.5 --0.0481256 0.0536625 0.0362191 0.58186 0.5 --0.059026 0.156388 0.00269852 0.133166 0.5 --0.0211187 0.0578754 0.0461125 0.660553 0.5 --0.082738 0.124721 0.050554 0.665202 0.5 --0.0466997 0.11363 0.0348133 0.568902 0.5 --0.0107262 0.179662 -0.0277472 0.400699 0.458536 -0.0347725 0.0894441 -0.0170339 0.702331 0.5 --0.0891825 0.100351 0.0148945 0.574286 0.477791 -0.0257275 0.122894 0.0207337 0.498278 0.5 --0.0883949 0.100277 0.00841226 0.477822 0.5 --0.0649858 0.155518 0.0263367 0.864791 0.5 --0.0768402 0.154073 0.00257877 0.57436 0.5 --0.0576877 0.154146 0.0262123 0.402162 0.5 --0.0266966 0.125729 0.0145923 0.393422 0.5 --0.076376 0.155782 0.0208875 0.505065 0.5 --0.0763295 0.167188 -0.039594 0.405226 0.426366 --0.0771877 0.100229 -0.0103313 0.528684 0.5 --0.0153681 0.0590839 0.0519909 0.652683 0.5 --0.010206 0.0576345 0.0535443 0.781548 0.413019 --0.00350044 0.0578672 0.0543757 0.774384 0.5 -0.00300818 0.0568916 0.0538692 0.704357 0.5 -0.0088308 0.0580497 0.0529859 0.692645 0.5 -0.0410915 0.0820775 -0.00893411 0.500391 0.430286 -0.0395449 0.0576373 0.0318985 0.612032 0.4505 --0.0762443 0.139336 0.0484763 0.588653 0.42756 --0.0324306 0.120379 -0.00955344 0.656019 0.5 --0.0194451 0.0881559 0.0557639 0.449983 0.473992 --0.074787 0.159471 -0.00898201 0.281303 0.5 --0.0639935 0.15611 0.0210031 0.687157 0.5 --0.0762438 0.153101 0.0322442 0.323875 0.45561 --0.00876679 0.128727 0.025102 0.735708 0.5 -0.0282216 0.112237 -0.00983067 0.567922 0.385391 --0.0451341 0.0593225 0.0387559 0.511245 0.5 --0.0405005 0.0579499 0.040202 0.540369 0.5 --0.033993 0.0584028 0.038704 0.646744 0.5 --0.0272756 0.0585468 0.0382285 0.571263 0.5 --0.0248608 0.122913 0.0245429 0.379391 0.5 --0.0825276 0.154355 0.0206132 0.385494 0.444119 --0.00884271 0.129403 0.00305159 0.702319 0.5 -0.0207587 0.126654 0.0147646 0.624434 0.5 --0.0394868 0.173351 -0.00839443 0.199648 0.251821 --0.028421 0.114019 0.0347746 0.603313 0.5 --0.0193575 0.122009 0.0306737 0.55532 0.5 --0.0691626 0.161675 -0.0514614 0.38665 0.5 --0.0516736 0.15006 0.0148119 0.716684 0.5 --0.0156325 0.120151 0.0349054 0.470635 0.336572 -0.0467454 0.0582319 0.0314404 0.576429 0.5 --0.0770165 0.0685425 0.0147863 0.703257 0.5 --0.00967101 0.173225 -0.0264945 0.379771 0.5 --0.0213141 0.184813 -0.0151112 0.186313 0.403961 --0.0766524 0.0882188 0.0382876 0.650646 0.5 --0.0540219 0.0521463 0.0110698 0.270787 0.5 --0.0219451 0.126821 0.0155536 0.534695 0.5 --0.0820391 0.153392 0.0264506 0.292051 0.4047 --0.0213183 0.124468 -0.00290836 0.782181 0.5 --0.0268364 0.123465 -0.00321538 0.727949 0.5 --0.0312035 0.177796 -0.0133521 0.371348 0.5 --0.00749945 0.0598042 0.0553302 0.778631 0.5 --0.00108951 0.0601245 0.0554892 0.776353 0.5 -0.00280202 0.0599746 0.0555283 0.768603 0.5 --0.051797 0.118119 0.033678 0.677092 0.438456 -0.00302464 0.131618 0.0149353 0.692956 0.5 -0.0446005 0.0942619 0.0151198 0.554026 0.5 --0.0880636 0.111855 0.00852285 0.304511 0.3924 --0.0704321 0.144096 -0.0148369 0.130446 0.5 --0.0820967 0.0943634 0.0322765 0.629357 0.5 --0.0269642 0.120812 0.0275676 0.345323 0.386314 --0.0540164 0.149968 0.0253393 0.49489 0.5 --0.0800337 0.0995053 -0.00770139 0.499264 0.5 -0.00922138 0.12038 0.0360924 0.562107 0.5 -0.00286056 0.117968 0.0387331 0.649494 0.5 --0.0936229 0.118494 0.0206524 0.664933 0.5 --0.0409923 0.113229 0.035109 0.667726 0.5 --0.0822185 0.154488 0.0146661 0.500539 0.5 --0.0625956 0.155202 -0.0329876 0.814083 0.5 --0.0462511 0.124621 -0.00898124 0.590842 0.5 --0.0220336 0.160676 -0.00426008 0.309766 0.47069 --0.065621 0.172767 -0.0466049 0.613718 0.5 --0.0762614 0.155884 0.0148687 0.717415 0.5 --0.0644988 0.149044 -0.0265159 0.690046 0.5 --0.0581979 0.0593456 0.0210895 0.079935 0 --0.0335439 0.122618 0.0254024 0.514037 0.5 --0.0826578 0.153434 0.00921403 0.601617 0.5 --0.049999 0.132417 0.0286961 0.650903 0.5 -0.0088217 0.131096 0.00864908 0.834131 0.5 --0.0154842 0.0644282 0.0533754 0.608033 0.445048 --0.00871951 0.065015 0.0556827 0.650491 0.470895 --0.00324815 0.0640003 0.0562816 0.762387 0.5 -0.00292601 0.0643094 0.0563956 0.748671 0.5 -0.00738462 0.0651614 0.0553402 0.488299 0.46872 --0.0143174 0.116971 0.037836 0.441459 0.5 --0.00299223 0.118083 0.0390751 0.65526 0.5 --0.00864301 0.117816 0.0385662 0.681198 0.5 --0.0532884 0.0571719 0.0206631 0.106703 0 --0.0882588 0.100387 0.0210097 0.535268 0.5 --0.0324377 0.099703 -0.0227313 0.620611 0.5 -0.0425072 0.0603725 0.0302275 0.744481 0.5 -0.0523383 0.0580401 0.0290457 0.405493 0.41666 -0.0413612 0.0877503 -0.00929235 0.635782 0.5 --0.0581547 0.0620148 0.0270981 0.448705 0.5 --0.0530328 0.0590503 0.0266933 0.136202 0.5 --0.0477227 0.135526 0.0148654 0.740469 0.5 -0.00323512 0.0983053 0.0504424 0.395048 0.366076 -0.0150627 0.119642 0.034806 0.696033 0.374342 --0.0453373 0.0643061 0.0391142 0.587502 0.5 --0.0394097 0.0644278 0.0414133 0.715885 0.5 --0.033068 0.0642666 0.0396407 0.650585 0.5 --0.0270237 0.0644489 0.0395335 0.617817 0.5 --0.0881604 0.149479 0.0268507 0.265855 0.5 --0.0640727 0.143434 -0.00894036 0.668887 0.5 -0.00286033 0.121151 0.036139 0.623932 0.5 --0.0827306 0.138152 0.0466993 0.412428 0.5 --0.00261511 0.127006 0.030132 0.335862 0.5 -0.0355841 0.108498 -0.00452523 0.461807 0.466834 -0.0219203 0.114136 0.0356941 0.554683 0.5 --0.0379555 0.161954 -0.0128021 0.499753 0.5 --0.0526362 0.0643632 0.0340621 0.277414 0.5 -0.025874 0.123374 0.0143811 0.506732 0.5 --0.0451406 0.131184 0.00901599 0.493237 0.5 --0.075778 0.155361 -0.00310678 0.708579 0.5 --0.0739145 0.156437 -0.0274945 0.645327 0.5 --0.0833056 0.100778 -0.00354288 0.490806 0.397415 --0.0767099 0.173942 -0.0452732 0.259897 0.5 -0.00846106 0.116985 0.038033 0.66824 0.5 --0.0200899 0.184788 -0.020546 0.237973 0.106197 --0.046571 0.120413 0.0285524 0.752764 0.5 --0.0515313 0.123718 -0.0088569 0.538005 0.5 -0.0212116 0.105804 -0.0171101 0.576137 0.468722 --0.0938613 0.124487 0.0151416 0.737559 0.5 -0.0414591 0.064577 0.0290352 0.617794 0.5 -0.0466725 0.0643471 0.0285539 0.486488 0.5 -0.0526423 0.0634018 0.0283831 0.501229 0.5 --0.0468141 0.168322 -0.00285433 0.371444 0.5 --0.0869152 0.0944156 0.00293118 0.494536 0.346642 --0.0773713 0.161559 -0.0267238 0.476378 0.5 --0.0396095 0.126677 -0.00334699 0.853498 0.5 --0.0271315 0.0764239 0.0455715 0.693464 0.5 --0.0587953 0.107012 -0.0177177 0.484023 0.5 --0.0748314 0.11156 -0.00720996 0.44421 0.5 --0.0642623 0.0888181 -0.018733 0.676741 0.5 --0.0325172 0.0881157 -0.0255424 0.370176 0.330832 -0.00325654 0.0700086 0.0561047 0.731659 0.5 -0.0103151 0.0636713 0.0537558 0.477793 0.458716 -0.0432701 0.0979967 0.00267804 0.544182 0.465461 --0.0708223 0.156244 0.021207 0.768676 0.5 --0.0584176 0.0702277 0.0384322 0.673529 0.5 --0.0703207 0.112305 -0.00963846 0.530989 0.5 --0.0581653 0.0881983 -0.0208369 0.619673 0.5 --0.0443038 0.0877156 -0.0218942 0.693083 0.5 --0.0488091 0.0660127 0.0373959 0.829801 0.5 -0.00269411 0.126911 0.030114 0.419275 0.5 -0.0239692 0.12105 0.0288706 0.523768 0.5 --0.0469203 0.117468 0.0314407 0.649888 0.5 --0.091552 0.143361 0.0201623 0.515231 0.5 --0.0907563 0.143859 0.0263089 0.504684 0.469425 --0.0495713 0.144022 0.00976642 0.636632 0.45621 --0.0770934 0.15583 -0.0147903 0.519503 0.5 --0.0868322 0.105634 0.00887573 0.731519 0.5 --0.082848 0.131648 -0.00299747 0.386393 0.5 --0.0384249 0.106407 -0.0201393 0.79815 0.5 --0.0823953 0.118841 -0.00336022 0.540306 0.5 --0.0102333 0.0876697 -0.0375101 0.564234 0.5 --0.00789361 0.089842 -0.0363492 0.755212 0.5 --0.0579097 0.111769 -0.0161856 0.463258 0.5 -0.0140074 0.105793 -0.0193841 0.554632 0.5 --0.00328561 0.105435 -0.0225198 0.740261 0.5 --0.0409613 0.070972 0.0419904 0.795206 0.5 --0.033501 0.0710512 0.0409793 0.706864 0.5 --0.0272732 0.0701361 0.0410332 0.726443 0.5 --0.0161963 0.127121 0.0228897 0.305628 0.5 --0.0190644 0.127936 0.0133818 0.519435 0.5 --0.0149926 0.0694778 0.0545159 0.595577 0.5 --0.00932719 0.0707313 0.0562936 0.785998 0.5 --0.002994 0.0710941 0.0575426 0.779773 0.5 -0.00838831 0.0714267 0.0556585 0.671976 0.5 -0.0102531 0.0693533 0.0547665 0.525573 0.5 --0.0323939 0.153399 -0.00240332 0.209483 0.5 -0.0435981 0.0881514 0.0254203 0.603121 0.478265 --0.0586529 0.124882 -0.00781093 0.700525 0.5 --0.0204287 0.107045 -0.022046 0.723165 0.5 --0.0382961 0.0879422 -0.0229335 0.629507 0.5 --0.081573 0.113394 -0.00173083 0.508624 0.426711 --0.0380811 0.154778 -0.00889149 0.748063 0.5 --0.00212588 0.0889926 -0.0354677 0.782073 0.5 -0.00904065 0.100193 -0.0222794 0.54652 0.5 --0.0467068 0.0700493 0.0405769 0.710023 0.5 --0.0779974 0.151244 0.0352264 0.347296 0.5 -0.0149019 0.116126 0.0367849 0.635361 0.5 --0.07603 0.106301 -0.0087688 0.520423 0.5 --0.0885261 0.137839 0.0393964 0.651389 0.5 --0.0703112 0.131278 -0.00857724 0.737784 0.5 -0.0419377 0.0703605 0.0288832 0.54196 0.5 -0.0514194 0.0684326 0.0256968 0.512602 0.5 --0.0922548 0.124813 0.0393757 0.806636 0.5 -0.0135035 0.128105 0.0250558 0.487288 0.424656 --0.0704618 0.125421 -0.00881334 0.801453 0.5 --0.0703931 0.118731 -0.00840961 0.381625 0.5 --0.0719685 0.106305 -0.0114493 0.499561 0.5 --0.0646972 0.161498 -0.0573125 0.41682 0.5 -0.0463693 0.0715128 0.0216754 0.461473 0.448797 --0.0538246 0.153497 0.0152346 0.602795 0.402362 --0.0142869 0.0724666 0.0554243 0.617853 0.5 --0.0394057 0.118512 -0.01336 0.602235 0.5 --0.0280509 0.0880065 -0.0330858 0.33771 0.5 --0.00957701 0.168254 -0.0212321 0.359593 0.5 --0.0445856 0.167324 -0.00782662 0.413138 0.327414 --0.0513101 0.161594 -0.00355965 0.292939 0.5 --0.0702356 0.179304 -0.0569867 0.253404 0.5 --0.0644695 0.168402 -0.0398946 0.676128 0.5 --0.0089459 0.130139 0.00911776 0.703889 0.5 -0.00219503 0.0880369 -0.0342201 0.75972 0.5 --0.0268891 0.16726 -0.0174204 0.847505 0.5 --0.0525985 0.155054 -0.00368706 0.37123 0.419006 --0.0761618 0.131736 -0.00696723 0.42394 0.44361 --0.0759576 0.07099 0.0265672 0.757943 0.5 --0.00875341 0.10588 -0.02285 0.71177 0.5 --0.0519242 0.1493 -0.00277595 0.483301 0.5 --0.016371 0.18465 -0.0214272 0.271878 0.5 --0.020548 0.0705632 0.0520411 0.601639 0.5 --0.0813371 0.120073 0.049533 0.662828 0.5 --0.0625087 0.149934 -0.0150319 0.415531 0.480025 --0.0831098 0.10651 0.0273461 0.515033 0.5 --0.011119 0.163582 -0.018751 0.17813 0.5 --0.00291057 0.101147 0.0456419 0.307462 0.5 --0.0635467 0.0660523 0.0318653 0.49936 0.45677 --0.0511979 0.0873878 -0.0217212 0.75515 0.5 --0.0530335 0.0740367 0.0417219 0.727079 0.5 --0.0465007 0.0756701 0.0421325 0.696934 0.5 --0.022314 0.0760359 0.0530306 0.607912 0.5 --0.0151351 0.0764056 0.0563566 0.616605 0.5 --0.00900601 0.0766621 0.0575852 0.791265 0.5 --0.00299732 0.0767339 0.0584651 0.678647 0.450838 -0.00347424 0.0769755 0.0565905 0.523043 0.5 -0.00860763 0.0767538 0.0557293 0.612782 0.5 --0.0271239 0.156216 -0.00302734 0.139755 0.329034 --0.0633091 0.16738 -0.0580906 0.358909 0.45373 --0.0873943 0.144225 0.00902371 0.583528 0.5 --0.0626891 0.162297 -0.0470925 0.70746 0.5 -0.0370111 0.110397 0.00265294 0.516602 0.481774 --0.0744006 0.144062 -0.00864565 0.417075 0.5 --0.0244124 0.183841 -0.0135068 0.166659 0.5 --0.0803381 0.0715473 0.0150483 0.5669 0.5 --0.0644528 0.0761561 0.040638 0.610448 0.476331 --0.0588413 0.0753794 0.0421022 0.634349 0.5 --0.0524294 0.077372 0.0433357 0.774603 0.5 --0.0484981 0.0769334 0.043281 0.674446 0.5 --0.0414954 0.0773856 0.0429005 0.752035 0.5 --0.0395008 0.0754808 0.0425134 0.72256 0.5 --0.033488 0.0764759 0.0414605 0.748994 0.5 --0.0627838 0.162163 -0.0530538 0.691143 0.5 -0.0381456 0.0881056 -0.0138675 0.676152 0.5 --0.0642837 0.0396418 0.039624 0.532543 0.5 --0.0526672 0.121335 -0.010917 0.523608 0.5 --0.0738104 0.162942 -0.037093 0.458525 0.324439 --0.0490869 0.13938 0.00889895 0.657159 0.5 --0.0495771 0.166027 -0.00171113 0.322064 0.5 --0.0709736 0.161609 -0.0450808 0.365011 0.420984 -0.0251847 0.12195 0.0254854 0.524179 0.5 --0.0193615 0.0781018 0.0558163 0.595703 0.4544 --0.0265458 0.120645 -0.00911332 0.52669 0.5 --0.061796 0.155741 -0.0207923 0.443336 0.5 --0.082476 0.110295 0.0324103 0.745977 0.5 --0.0691674 0.156314 -0.050857 0.360984 0.5 --0.0622848 0.16236 -0.0396288 0.427869 0.464762 --0.088248 0.113803 0.0264606 0.595923 0.5 --0.0575392 0.0787026 0.0436363 0.801201 0.5 --0.0298439 0.0782596 0.0421168 0.771067 0.5 --0.0677617 0.0876701 0.0434928 0.59211 0.5 --0.0921939 0.131884 0.015227 0.781723 0.5 --0.0878987 0.111742 0.0209206 0.698028 0.5 --0.049353 0.139298 0.0147955 0.761861 0.5 --0.0327071 0.173321 -0.0149209 0.384317 0.5 --0.0866298 0.152851 0.0149144 0.267781 0.5 --0.0779646 0.100025 0.035185 0.697079 0.5 --0.0935537 0.118404 0.0151524 0.667612 0.5 --0.084908 0.10801 0.0228537 0.694681 0.5 --0.0210677 0.0821213 0.0562096 0.557699 0.5 --0.0149957 0.082187 0.0572635 0.665194 0.5 --0.00899671 0.0822178 0.0576875 0.71377 0.5 --0.00299966 0.0822055 0.0574653 0.668024 0.472979 -0.0034748 0.0817533 0.0567544 0.69456 0.5 -0.00824833 0.082992 0.0556315 0.615627 0.5 -0.0102414 0.0812949 0.0546523 0.424956 0.485927 --0.0398496 0.123966 -0.00878898 0.60318 0.5 --0.092257 0.124769 0.00902091 0.309094 0.468872 --0.0436728 0.126191 0.0209533 0.472028 0.413108 --0.0820425 0.105873 -0.00271871 0.341089 0.347157 --0.0663016 0.0807623 0.0424437 0.632223 0.5 --0.0639939 0.0836688 0.0439754 0.778832 0.5 --0.058539 0.0825906 0.0439671 0.770991 0.5 --0.0521209 0.0822523 0.0446262 0.782751 0.5 --0.0467559 0.0828569 0.0439458 0.699516 0.399968 --0.0424962 0.0810729 0.0423266 0.617938 0.5 --0.0404903 0.0830123 0.0430984 0.712874 0.5 --0.0365108 0.0825773 0.0434355 0.675696 0.5 --0.032204 0.0824171 0.0421121 0.529763 0.5 --0.0864005 0.152981 0.0204492 0.250247 0.416029 --0.0235661 0.115415 0.0353667 0.518805 0.471584 --0.0764871 0.111685 0.0461598 0.498936 0.5 --0.0763895 0.14977 -0.00829972 0.604451 0.5 --0.0754801 0.161855 -0.0327796 0.39691 0.5 --0.0285733 0.0828247 0.0462702 0.636794 0.5 --0.0862819 0.100797 0.0028483 0.65379 0.5 -0.021088 0.08242 0.0504086 0.491924 0.475524 --0.0801892 0.143128 -0.00230055 0.641961 0.5 -0.00844098 0.124407 -0.00878569 0.555015 0.5 -0.0147552 0.0825883 0.0529115 0.480476 0.5 --0.061995 0.161169 -0.032654 0.499509 0.5 --0.0807571 0.1525 0.0307996 0.295115 0.454522 --0.00295953 0.130272 0.00279699 0.742188 0.5 --0.0153619 0.0884791 0.0565599 0.818561 0.5 --0.00899729 0.0878977 0.0570287 0.818958 0.5 --0.00299611 0.0880658 0.0568489 0.695384 0.5 -0.00301457 0.0885291 0.0562756 0.81087 0.5 -0.00834267 0.0873808 0.0555541 0.577038 0.479545 --0.00897481 0.0941651 -0.0338408 0.678465 0.5 -0.0314278 0.11673 0.0250113 0.597807 0.5 --0.0760602 0.155337 0.0093949 0.68566 0.5 -0.0257808 0.116776 -0.00728909 0.54747 0.36626 --0.0646577 0.0882843 0.0447113 0.69894 0.5 --0.058996 0.0882997 0.0449149 0.778337 0.5 --0.0529958 0.0883132 0.0451395 0.696869 0.45083 --0.0465421 0.0881579 0.0443187 0.605881 0.5 --0.0404961 0.0876863 0.0430941 0.556958 0.5 --0.0331792 0.0885648 0.04366 0.668172 0.5 --0.0280482 0.0879652 0.046363 0.699915 0.5 -0.0150626 0.0881784 0.0517745 0.702815 0.5 -0.0205955 0.087113 0.0492325 0.678548 0.5 --0.0702712 0.0823874 0.0409431 0.628092 0.5 --0.0296926 0.0896882 -0.0286839 0.317989 0.390463 --0.0236137 0.179242 -0.0115629 0.264741 0.5 --0.0809391 0.100029 0.0323433 0.683272 0.5 --0.0928336 0.130683 0.0207107 0.62518 0.472282 --0.0761771 0.156201 -0.0204165 0.612769 0.5 -0.0146577 0.129396 0.00843576 0.595962 0.5 -0.0104845 0.089766 0.0542005 0.46622 0.5 --0.072579 0.161253 -0.0389447 0.482103 0.5 --0.0322741 0.110391 -0.0184574 0.809584 0.5 --0.0550172 0.150108 0.027792 0.412797 0.5 --0.071635 0.0883254 0.0414652 0.604622 0.463567 --0.0424904 0.0895336 0.0426086 0.959715 0.5 -0.0207945 0.0897491 0.0484315 0.669841 0.5 -0.0273189 0.118845 -0.00265658 0.615055 0.5 -0.0285218 0.121112 0.0162366 0.593248 0.434231 --0.00899735 0.0930598 0.0559298 0.639163 0.5 --0.00291176 0.118727 -0.0144021 0.826286 0.5 --0.0885191 0.113233 0.0327948 0.447552 0.461926 --0.0713744 0.0938304 0.0415269 0.544171 0.444972 --0.0641029 0.0935514 0.0439488 0.597795 0.395518 --0.0584965 0.0944146 0.0446213 0.678752 0.5 --0.0515853 0.0939836 0.0442383 0.634435 0.477778 --0.0465591 0.0937901 0.0436103 0.714507 0.5 --0.0414914 0.0942416 0.0425268 0.490492 0.46307 --0.0377723 0.0933327 0.0434889 0.620752 0.5 --0.0332864 0.0945766 0.0443868 0.723538 0.5 --0.0263807 0.094318 0.0450568 0.620324 0.5 --0.0141606 0.0929618 0.0553898 0.503825 0.5 --0.00319641 0.0930898 0.0557853 0.624082 0.5 -0.00150357 0.0931879 0.0551544 0.492015 0.5 -0.00367616 0.0950752 0.0535295 0.508462 0.5 -0.00915739 0.0941794 0.0519212 0.597357 0.452723 -0.0216553 0.0937794 0.0473202 0.671835 0.5 --0.0702968 0.174481 -0.045888 0.43732 0.455145 --0.0305889 0.168899 -0.00702359 0.59106 0.5 --0.0528191 0.162649 0.00296711 0.343566 0.5 --0.0890968 0.0940104 0.0208024 0.539357 0.478012 --0.0626249 0.173112 -0.0586131 0.353011 0.447085 --0.0443835 0.105923 -0.0201903 0.683228 0.5 --0.0664958 0.0951776 0.0424531 0.672396 0.5 --0.0324384 0.126415 0.0146752 0.445893 0.463327 --0.0152469 0.0961657 0.0518098 0.323594 0.5 --0.0097537 0.0960506 0.0535818 0.446732 0.426556 --0.00304601 0.0963367 0.0537791 0.579525 0.5 -0.01642 0.0957081 0.0480381 0.687032 0.5 --0.0876548 0.105191 0.0148253 0.774556 0.5 --0.0699417 0.0763232 0.0381496 0.596573 0.5 -0.0358078 0.0958594 -0.0120328 0.738943 0.5 -0.0374966 0.100154 0.031249 0.720944 0.5 --0.0530195 0.150059 0.0207323 0.696139 0.5 --0.0905911 0.131765 0.0328667 0.816274 0.5 --0.0709717 0.147309 -0.0268389 0.224341 0.389051 --0.0443321 0.0935075 -0.0222668 0.709831 0.5 --0.0400911 0.128618 0.00909496 0.81345 0.5 --0.0710054 0.100275 0.0398128 0.481571 0.5 --0.0653063 0.100124 0.0417262 0.670525 0.470095 --0.0589969 0.0980495 0.0430328 0.779482 0.5 --0.0529938 0.0980631 0.0432952 0.836255 0.5 --0.0469951 0.0980659 0.043235 0.637806 0.5 --0.0408476 0.100401 0.0414668 0.648927 0.395789 --0.0323344 0.0988071 0.0435216 0.652032 0.5 --0.0259464 0.0998425 0.0438947 0.737424 0.5 --0.0212066 0.0999849 0.0444194 0.576924 0.5 -0.00749586 0.09835 0.0488255 0.46146 0.5 -0.0090271 0.101109 0.0469975 0.470012 0.5 -0.0153076 0.100008 0.0472449 0.600016 0.5 -0.0208175 0.100067 0.0453866 0.595024 0.46889 --0.0648326 0.131509 -0.00838673 0.790869 0.5 --0.0740297 0.150832 -0.0323367 0.406089 0.5 --0.0932444 0.124885 0.026841 0.802537 0.5 --0.0633239 0.169093 -0.0610358 0.362406 0.5 --0.0771158 0.162488 -0.0202679 0.465605 0.5 --0.0585669 0.0647555 0.0323611 0.494963 0.328305 -0.0377689 0.110383 0.00969065 0.710008 0.5 --0.0503559 0.0935892 -0.0218956 0.807094 0.5 --0.0589961 0.101543 0.042437 0.529374 0.5 --0.0516647 0.101981 0.0417488 0.647378 0.5 --0.0469248 0.101325 0.0421166 0.608323 0.5 --0.0352173 0.101965 0.0413638 0.751982 0.5 -0.00285015 0.100935 0.0464433 0.395489 0.5 --0.075479 0.150312 -0.0143808 0.730394 0.5 --0.078936 0.108126 -0.00525459 0.540251 0.381971 --0.0251472 0.168981 -0.0187156 0.757996 0.5 --0.071457 0.113692 0.0499983 0.429195 0.5 --0.0747771 0.0997536 0.0377868 0.551123 0.5 --0.0902919 0.137212 0.0146286 0.495279 0.5 --0.0264568 0.105883 0.0411765 0.58994 0.471484 --0.0209966 0.1044 0.0429589 0.797197 0.5 --0.0145208 0.105597 0.0430511 0.780555 0.5 --0.00899316 0.10622 0.0435541 0.510194 0.5 --0.00289533 0.105882 0.0438861 0.384284 0.5 -0.00245231 0.105621 0.0429868 0.332307 0.5 -0.00945613 0.104903 0.0439002 0.435482 0.5 -0.0149913 0.104769 0.0443348 0.548532 0.5 --0.0772186 0.106139 0.0350601 0.430274 0.367589 --0.0708601 0.106945 0.0381598 0.402417 0.5 --0.0652985 0.106577 0.0390805 0.558067 0.398761 --0.0583896 0.105623 0.0405326 0.594554 0.5 --0.0529341 0.106445 0.0398435 0.644542 0.398207 --0.0461638 0.105797 0.0404843 0.759883 0.5 --0.0400204 0.106789 0.0388993 0.653599 0.5 --0.03311 0.106322 0.0394461 0.532024 0.5 -0.0193026 0.10477 0.0431964 0.486674 0.480281 --0.0501412 0.13774 0.00286739 0.569746 0.5 -0.0266104 0.105911 0.0384052 0.650339 0.5 -0.0438719 0.088439 -0.0031027 0.506353 0.478726 --0.0590381 0.113203 0.0362299 0.87726 0.5 --0.021499 0.107851 0.0414162 0.584043 0.5 --0.0164951 0.107881 0.0420289 0.633836 0.5 -0.00450524 0.107918 0.0419336 0.79888 0.5 -0.00856234 0.108229 0.0410531 0.820786 0.5 -0.0149994 0.10779 0.0412845 0.598409 0.5 -0.0213049 0.106041 0.0409433 0.561561 0.479574 --0.0336665 0.167843 -0.00338268 0.478764 0.5 --0.0587789 0.131705 -0.00671001 0.673026 0.5 --0.0443517 0.100306 -0.0215281 0.825942 0.5 --0.0147306 0.179604 -0.0266222 0.40888 0.5 -0.0159582 0.108177 -0.0177822 0.564672 0.468958 --0.0638447 0.138119 -0.00733006 0.633194 0.5 --0.0330953 0.167861 -0.0155539 0.527374 0.428366 --0.0643684 0.125359 -0.00876153 0.813046 0.5 --0.032583 0.161992 -0.0142418 0.852313 0.5 --0.068568 0.110392 0.0392194 0.353622 0.364353 --0.0643494 0.112195 0.0388907 0.34696 0.5 --0.0593722 0.112082 0.0373875 0.588374 0.5 --0.0529986 0.110472 0.0373551 0.513233 0.408461 --0.0468613 0.11028 0.0378862 0.569336 0.5 --0.040984 0.110496 0.0370883 0.553647 0.5 --0.0320055 0.110468 0.0370438 0.565129 0.5 --0.0074871 0.110717 0.042649 0.617568 0.5 --0.00449218 0.110714 0.0426582 0.621679 0.5 -0.0250033 0.110611 0.0368459 0.631257 0.5 -0.025919 0.0995286 -0.0189206 0.684181 0.5 --0.06973 0.112153 0.0457184 0.746569 0.5 --0.045604 0.148834 -0.00329924 0.521986 0.5 --0.0653006 0.0947889 -0.0177657 0.582853 0.5 --0.0906677 0.13318 0.0277848 0.773217 0.5 --0.0331508 0.094474 -0.0237799 0.742 0.5 --0.0575764 0.0941613 -0.0208023 0.703326 0.5 --0.0200586 0.0397198 0.0532237 0.447203 0.5 --0.0203685 0.0352888 0.051184 0.291685 0.457265 --0.0764163 0.125947 -0.00745144 0.524375 0.5 --0.0205906 0.167551 -0.0139677 0.809186 0.5 -0.025858 0.116851 0.0315289 0.660225 0.5 --0.0139279 0.167191 -0.021044 0.669958 0.5 --0.0587481 0.149802 -0.00133886 0.562881 0.5 -0.0144191 0.0395247 0.0443396 0.266796 0.5 -0.0332953 0.105473 0.0329627 0.721815 0.5 --0.0647461 0.114313 -0.0115219 0.592211 0.5 --0.0520818 0.0353771 0.0449331 0.341981 0.5 --0.015004 0.0392095 0.0513548 0.312679 0.5 --0.0094925 0.0384962 0.049554 0.302651 0.5 --0.0638496 0.117631 0.0454477 0.559641 0.5 --0.0573025 0.136864 0.033162 0.554568 0.5 -0.0189101 0.0400942 0.0428502 0.270107 0.5 --0.0508192 0.124393 0.0332635 0.581555 0.5 --0.0182623 0.180885 -0.017743 0.594618 0.5 --0.0651271 0.150343 -0.0325707 0.505808 0.5 -0.0332966 0.0936886 0.0400216 0.637373 0.5 --0.0463011 0.149493 0.00833001 0.611316 0.5 -0.00260773 0.0354887 0.0450013 0.261253 0.345588 --0.0780807 0.10971 0.0423535 0.916894 0.5 --0.0542262 0.124756 0.0369858 0.64506 0.5 --0.0402584 0.0361447 0.0436625 0.193197 0.5 --0.00317483 0.0942874 -0.0331049 0.71511 0.325502 --0.0151032 0.179716 -0.0207621 0.731902 0.5 -0.026141 0.0403246 0.0327265 0.294647 0.339561 --0.0640247 0.111376 -0.0136272 0.608847 0.5 -0.027817 0.112309 0.0339118 0.692282 0.5 --0.0586332 0.142774 0.0334953 0.761767 0.5 --0.0146622 0.167501 -0.0154455 0.61604 0.5 --0.0270893 0.167298 -0.00866399 0.642638 0.5 -0.0152056 0.045813 0.0442638 0.487785 0.5 -0.0190988 0.0442996 0.0429 0.362689 0.463942 -0.0215694 0.0456112 0.041209 0.479281 0.5 -0.0257452 0.0459137 0.0381185 0.444171 0.5 -0.0387365 0.0944447 0.0327088 0.718127 0.5 -0.0287308 0.0456722 0.0347466 0.335561 0.431941 --0.0151805 0.173809 -0.0213305 0.730436 0.5 --0.0658903 0.118253 0.0498126 0.307185 0.5 --0.0628345 0.093206 -0.0188544 0.659442 0.5 --0.0643065 0.142451 0.0394123 0.621016 0.5 --0.040079 0.150283 0.00280951 0.491474 0.5 --0.026851 0.173268 -0.00983852 0.620534 0.5 --0.0207913 0.173767 -0.0147826 0.653794 0.5 --0.0582334 0.124238 0.0403406 0.70004 0.5 --0.0683337 0.131545 0.0479709 0.732904 0.5 --0.0693547 0.10637 -0.012803 0.472443 0.5 --0.0428668 0.157627 0.0050419 0.670804 0.5 --0.0476449 0.130368 0.0258834 0.623828 0.5 -0.0379451 0.0817167 -0.0141547 0.644934 0.5 -0.0312298 0.0470286 0.0324465 0.426433 0.5 --0.0662284 0.138149 0.042896 0.72515 0.5 --0.0644094 0.105575 -0.0158634 0.566501 0.5 -0.0411271 0.0443713 0.0285474 0.466284 0.5 --0.0830031 0.0762361 0.0150296 0.67606 0.5 --0.0660167 0.123488 0.0501643 0.718404 0.5 --0.0416352 0.155329 0.00636435 0.466436 0.5 --0.0388456 0.155994 0.00477206 0.438555 0.402124 --0.0551732 0.116538 0.0359195 0.457649 0.5 --0.0600069 0.134082 0.0369434 0.682472 0.5 -0.0452816 0.0453284 0.0263124 0.471094 0.5 -0.0513161 0.0463154 0.0204963 0.342211 0.398387 --0.0106687 0.172847 -0.0215627 0.69267 0.5 --0.0147735 0.18419 -0.0259341 0.309641 0.5 -0.0301064 0.106776 0.0358091 0.72383 0.5 --0.063709 0.125122 0.0457451 0.712215 0.420475 -0.0473431 0.0499217 0.0295077 0.554948 0.5 -0.0497106 0.0482066 0.0259506 0.48379 0.5 -0.0518484 0.0518415 0.0267161 0.416499 0.5 --0.0162732 0.172938 -0.0174582 0.719256 0.5 -0.0355097 0.107304 0.0291151 0.718782 0.5 --0.0552656 0.143077 0.0300537 0.622521 0.5 --0.0637191 0.136482 0.0388176 0.603354 0.5 --0.0199086 0.161072 -0.00863325 0.350317 0.5 --0.0209172 0.179282 -0.0148523 0.455842 0.5 -0.014511 0.0513519 0.0474271 0.589102 0.5 --0.0610259 0.126912 0.0416133 0.698375 0.5 -0.0539905 0.0494141 0.0219114 0.418448 0.5 -0.00925922 0.118865 -0.0148674 0.54369 0.457314 --0.0268384 0.162091 -0.00836699 0.546076 0.486591 --0.0367024 0.163198 -0.00107067 0.680811 0.5 --0.0336432 0.155948 0.00188963 0.445666 0.44081 --0.0280966 0.159587 0.000483069 0.431301 0.5 --0.026491 0.16163 -0.00321758 0.537982 0.323001 -0.0206613 0.0528733 0.0451655 0.647628 0.324331 -0.0231576 0.0513069 0.0414753 0.507052 0.5 -0.0266044 0.0526516 0.039853 0.635463 0.446542 -0.0309772 0.0527823 0.0371348 0.671735 0.5 -0.0239371 0.103424 0.0418106 0.654526 0.5 -0.0568895 0.0527484 0.0209204 0.474964 0.5 --0.0664209 0.11329 0.0441331 0.212624 0.5 --0.0326789 0.162384 -0.00243762 0.543585 0.5 -0.0145199 0.0932586 -0.026363 0.546403 0.5 --0.0543983 0.119186 0.0365781 0.502204 0.44785 --0.0564272 0.132376 0.0357966 0.720059 0.5 --0.0501636 0.142911 0.00230897 0.376445 0.5 --0.043714 0.147707 0.0038501 0.245798 0.5 --0.0291346 0.177171 -0.00534178 0.371295 0.5 -0.0357304 0.100363 -0.0111604 0.61591 0.5 -0.0133943 0.0541536 0.0499521 0.532724 0.5 -0.0551089 0.0545007 0.0253961 0.545646 0.5 -0.0291033 0.0572886 0.0407089 0.633826 0.5 -0.0585723 0.0583402 0.0214893 0.549998 0.477428 --0.0740322 0.0656952 0.0144875 0.594594 0.5 --0.0749844 0.179305 -0.0518221 0.216638 0.5 -0.0145778 0.0585769 0.0501691 0.387785 0.5 -0.0214876 0.058332 0.0470549 0.596242 0.5 -0.0259507 0.0590004 0.0437762 0.663038 0.5 -0.032833 0.0585633 0.0387158 0.630786 0.5 -0.0358218 0.0578374 0.0350365 0.591179 0.5 -0.0360585 0.0951301 0.0364902 0.726421 0.5 --0.0886806 0.118283 0.0459142 0.444358 0.5 -0.0562736 0.0586365 0.0253398 0.57284 0.5 -0.0303311 0.0951295 0.0419589 0.717458 0.5 --0.0222315 0.167389 -0.0110472 0.688671 0.5 --0.0543257 0.136577 0.0307959 0.688078 0.5 --0.0500074 0.150447 0.0117579 0.563476 0.5 --0.0616289 0.137406 0.0354744 0.592141 0.5 --0.0319367 0.159507 0.00191749 0.44862 0.5 --0.0634458 0.132148 0.0406867 0.731705 0.5 -0.0368678 0.0921989 0.0367449 0.708135 0.5 --0.0728433 0.156137 -0.0339112 0.713518 0.5 -0.0389872 0.0640689 0.0330299 0.521361 0.5 --0.0636611 0.1488 -0.0205996 0.618447 0.5 -0.0153938 0.0648444 0.0513036 0.554385 0.463079 -0.0213958 0.0645506 0.0473078 0.414803 0.412252 -0.0265105 0.0649235 0.0439721 0.611901 0.5 -0.0302364 0.0650657 0.0415975 0.600683 0.487653 -0.0331295 0.0642221 0.0397381 0.500385 0.490901 -0.0367885 0.065027 0.0366867 0.593561 0.5 -0.0563131 0.0650782 0.0252208 0.639437 0.5 -0.0591364 0.0644742 0.0211357 0.550839 0.448044 --0.0110683 0.167098 -0.0167807 0.360187 0.5 --0.0605202 0.146205 0.0366666 0.591479 0.5 -0.0194528 0.0665736 0.0491642 0.603282 0.5 --0.0286777 0.158132 0.000508817 0.402765 0.431383 -0.0253025 0.0989569 0.0434277 0.623394 0.5 --0.0349979 0.152158 8.20736e-05 0.217633 0.5 -0.014665 0.070627 0.0528306 0.52613 0.5 -0.0202908 0.071041 0.0498828 0.634288 0.435356 -0.0230702 0.0702991 0.0473835 0.571849 0.5 -0.0263693 0.0706238 0.0441789 0.622852 0.474797 -0.0328306 0.0707606 0.0401362 0.612279 0.409693 -0.0368832 0.070672 0.0365953 0.662199 0.5 -0.0398878 0.0705632 0.0325808 0.656566 0.5 -0.0579544 0.0694794 0.0198345 0.6125 0.5 --0.0641704 0.063724 0.0268682 0.425507 0.418571 --0.0919499 0.114216 0.0149265 0.530043 0.5 -0.0351624 0.0819076 -0.0172502 0.760295 0.5 --0.0862408 0.119271 -0.00117534 0.455279 0.5 --0.0294401 0.174958 -0.00579982 0.562984 0.5 --0.0175288 0.165418 -0.0114925 0.675539 0.5 --0.0617869 0.117789 0.0409144 0.40334 0.5 -0.0301891 0.0723658 0.0418804 0.606777 0.5 --0.0822099 0.149486 0.00288044 0.385889 0.468811 --0.0760271 0.175704 -0.0506937 0.340571 0.5 --0.0652343 0.0614738 0.0211346 0.414933 0.425841 --0.0266574 0.110394 -0.019007 0.783101 0.5 --0.0813538 0.0779161 0.0268055 0.756683 0.5 -0.021417 0.118723 -0.00893569 0.549 0.5 -0.0149346 0.0759297 0.0536191 0.48671 0.476705 -0.0209886 0.0761609 0.0506055 0.575091 0.5 -0.0268396 0.0762089 0.0459193 0.572664 0.5 -0.0336785 0.0760737 0.0405166 0.630563 0.5 -0.0373422 0.0760306 0.0366776 0.505468 0.5 -0.0400324 0.0763062 0.0328345 0.645662 0.5 -0.0419048 0.076876 0.0296092 0.673034 0.5 -0.0438094 0.0763805 0.0258638 0.624347 0.5 --0.0452412 0.118472 -0.0142046 0.833781 0.5 -0.0456773 0.0768089 0.0208187 0.458504 0.467907 --0.050165 0.137714 0.0207618 0.606401 0.481088 --0.00327054 0.111563 -0.0203549 0.551699 0.482404 --0.0483236 0.145111 0.00757835 0.59165 0.5 -0.0310833 0.0775315 0.0432282 0.624343 0.5 --0.046855 0.145222 0.00288431 0.195425 0.432502 --0.0141716 0.10541 -0.0225802 0.672132 0.5 -0.0470348 0.0753979 0.0148736 0.455861 0.5 --0.0611433 0.140542 0.0356184 0.646306 0.5 -0.0272779 0.0823714 0.0459243 0.61663 0.478488 -0.0309212 0.08255 0.0430252 0.611382 0.5 -0.0343037 0.0825412 0.0402907 0.613309 0.465282 -0.0370354 0.0824663 0.0369099 0.642585 0.5 --0.0799946 0.147989 -0.000835337 0.484293 0.5 --0.0774435 0.0690153 0.00961977 0.704234 0.277826 -0.0404363 0.0826995 0.0326021 0.686672 0.5 -0.0417479 0.0827335 0.0302524 0.63553 0.5 -0.0436887 0.0825508 0.0263844 0.61829 0.5 -0.0454407 0.0825465 0.0207137 0.601475 0.480065 --0.0822812 0.116295 0.0482855 0.66926 0.5 --0.0844726 0.0947391 -0.00345192 0.592061 0.5 --0.020271 0.168003 -0.0193935 0.821267 0.5 --0.0742716 0.0668501 0.0190414 0.706894 0.5 -0.026747 0.0882417 0.0458314 0.539865 0.389736 -0.0308722 0.0882572 0.0430146 0.948814 0.5 -0.0344922 0.0883047 0.0403697 0.638338 0.5 -0.0372481 0.0881263 0.0366393 0.643327 0.5 -0.039927 0.088094 0.0326668 0.711283 0.5 -0.0419027 0.0877782 0.0290815 0.667656 0.5 -0.00264738 0.112302 -0.019871 0.766242 0.5 --0.0703315 0.1455 -0.0205576 0.136819 0.239158 --0.0749446 0.137879 -0.00653312 0.459033 0.397283 --0.0266967 0.114299 -0.0159903 0.856895 0.5 --0.0869924 0.113518 0.00410409 0.344807 0.5 --0.0142186 0.174013 -0.0259807 0.439072 0.5 --0.0221564 0.157852 -0.00861651 0.254248 0.5 --0.011587 0.164129 -0.0163045 0.228563 0.367524 --0.00997381 0.169338 -0.0247765 0.42189 0.5 --0.082875 0.143405 0.00186692 0.494272 0.5 -0.0203757 0.0354405 -0.00287175 0 0 -0.0191274 0.0363337 -0.00917714 0.174536 0.5 -0.0184456 0.036388 -0.013479 0.173751 0.5 -0.0149535 0.0347732 -0.0154937 0.144529 0.253209 -0.0221204 0.0372026 0.0342324 0.156956 0.287305 -0.039271 0.0382866 0.00854708 0.245023 0.5 -0.0397549 0.0398545 0.002614 0.276002 0.5 -0.0221892 0.0380614 -0.00446361 0.173629 0.5 -0.0179901 0.0369066 -0.0161835 0.336518 0.5 -0.0154148 0.0392444 -0.0212861 0.367832 0.5 -0.0208023 0.100118 -0.0213392 0.648293 0.46589 -0.0446004 0.0409064 0.00927401 0.208963 0.5 -0.0435625 0.0411355 0.00427044 0.357471 0.452104 -0.0381381 0.0411139 -0.00147908 0.514406 0.5 --0.0478807 0.135207 0.00885778 0.482359 0.5 -0.0217274 0.0404287 -0.00964433 0.311593 0.5 -0.0206744 0.0405956 -0.0144437 0.473825 0.5 -0.0192578 0.0411681 -0.0195074 0.414351 0.5 --0.0885736 0.112913 0.0395856 0.488806 0.5 --0.026793 0.106457 -0.0218501 0.617481 0.5 -0.0481487 0.0428585 0.0145594 0.265572 0.5 -0.0521212 0.0461655 0.0089655 0.199267 0.5 -0.0480438 0.0430647 0.00724585 0.412258 0.5 -0.0460936 0.0434131 0.00284357 0.566688 0.5 -0.0285003 0.100485 -0.0168103 0.728425 0.5 -0.0269462 0.0395833 -0.00334578 0.464947 0.5 --0.0907856 0.117838 0.00647331 0.421552 0.5 --0.062721 0.167567 -0.0470628 0.645866 0.5 --0.0799532 0.106813 0.0316838 0.420249 0.5 -0.0527437 0.0462125 0.0139554 0.286197 0.5 -0.0504533 0.0466263 0.00264513 0.57721 0.5 --0.0322581 0.117324 -0.0133273 0.811815 0.5 -0.0272475 0.0455966 -0.00927071 0.533119 0.5 --0.0146455 0.0942084 -0.0337341 0.520871 0.5 --0.0411545 0.16722 -0.010818 0.48116 0.5 --0.0721385 0.156112 -0.0384102 0.511983 0.468875 -0.0456803 0.0474217 -0.00311192 0.412576 0.5 -0.0239407 0.0433254 -0.00969837 0.651864 0.5 -0.021084 0.0462585 -0.0205303 0.476548 0.5 --0.0348527 0.0351549 -0.0307351 0.16856 0.5 --0.0699867 0.0663066 0.0259153 0.590849 0.43032 --0.0747071 0.149891 -0.0201453 0.5851 0.5 --0.0845448 0.13725 0.000743181 0.580039 0.5 -0.0549514 0.0484178 0.0163982 0.295573 0.5 -0.0264565 0.0466261 -0.0141039 0.515417 0.5 -0.0225276 0.0444655 -0.0157683 0.505631 0.5 -0.0330538 0.0938135 -0.0160538 0.699679 0.5 -0.0526476 0.0694992 0.00297306 0.629664 0.372945 -0.0528544 0.0581339 -0.00277966 0.592036 0.5 --0.0571464 0.0671799 0.0361705 0.503626 0.472266 --0.0651544 0.157167 -0.0515491 0.708429 0.5 --0.0493189 0.133682 0.00119868 0.355836 0.438333 --0.032962 0.10595 -0.0206729 0.810434 0.5 --0.0649538 0.155656 -0.045631 0.820472 0.5 --0.0390456 0.150445 -0.00354536 0.204281 0.5 -0.0574365 0.051618 0.0145183 0.351624 0.5 -0.0574129 0.0522531 0.00903377 0.511629 0.5 -0.0536112 0.0500965 0.00204174 0.768402 0.5 -0.0512204 0.0520121 -0.00218354 0.534755 0.5 -0.0471226 0.0515811 -0.00481298 0.434179 0.5 -0.033443 0.047576 -0.0063817 0.557462 0.465257 -0.00280933 0.118297 -0.0158208 0.570337 0.473222 --0.0147841 0.10125 -0.0238408 0.771507 0.5 --0.0620037 0.167422 -0.0527165 0.538383 0.466596 -0.0559147 0.0528382 0.00339683 0.824166 0.5 -0.0334801 0.0518506 -0.00825293 0.591066 0.5 -0.0287814 0.0501171 -0.0157926 0.574224 0.5 -0.0256197 0.0485542 -0.0190548 0.421586 0.5 --0.00863537 0.118406 -0.0146114 0.827086 0.5 --0.0148322 0.117675 -0.014701 0.559736 0.5 --0.0615138 0.145712 -0.00481276 0.466074 0.5 -0.0232531 0.12083 -0.00456186 0.617393 0.5 --0.0401535 0.0342718 -0.0275149 0.0979878 0.5 -0.0302657 0.0496868 -0.0107289 0.647285 0.5 -0.0320066 0.111334 -0.00737407 0.536101 0.5 --0.0211003 0.120417 -0.0102482 0.732965 0.5 --0.0204991 0.117125 -0.0140803 0.767014 0.5 --0.00910263 0.0383602 -0.025776 0.274297 0.5 --0.0525144 0.11229 -0.0171034 0.442719 0.484227 -0.0202353 0.123713 -0.00247094 0.59012 0.5 --0.0701749 0.0347541 -0.0017891 0.135623 0.5 --0.00340266 0.114844 -0.0176928 0.826111 0.5 -0.0310248 0.053713 -0.0140522 0.572913 0.5 -0.0268191 0.0528482 -0.020339 0.412387 0.455219 --0.0147458 0.120673 -0.0105853 0.653192 0.5 -0.0270905 0.106214 -0.0146756 0.603346 0.5 -0.0465541 0.0697991 0.00228503 0.590477 0.5 --0.00300122 0.100676 -0.0235814 0.77298 0.5 --0.0755874 0.076212 0.033468 0.651011 0.5 -0.059738 0.0572998 0.0151736 0.624329 0.5 -0.0595394 0.0578717 0.00861672 0.650231 0.5 -0.0572091 0.0580526 0.00253507 0.577167 0.5 --0.0142907 0.123147 -0.00746744 0.689207 0.5 -0.0211831 0.112303 -0.0140834 0.636933 0.5 -0.0347455 0.0565046 -0.010714 0.517615 0.5 -0.0249138 0.0825163 -0.0245877 0.759593 0.5 --0.0382227 0.114521 -0.016178 0.845616 0.5 --0.0819485 0.0761672 0.0208322 0.76776 0.5 --0.0269557 0.0392251 -0.0293943 0.537642 0.5 -0.0377037 0.0593401 -0.00852013 0.537798 0.5 -0.0330295 0.0586306 -0.014729 0.60439 0.5 -0.0218121 0.0515865 -0.0236492 0.56032 0.5 --0.0204953 0.0935908 -0.0331675 0.485557 0.5 --0.0872217 0.113521 0.0440666 0.448078 0.427651 --0.0271537 0.0351608 0.0509267 0.96808 0.5 --0.0503825 0.106302 -0.0194598 0.649024 0.5 -0.0266611 0.0585067 -0.0219134 0.622435 0.5 -0.00975018 0.0945932 -0.0280451 0.504262 0.457756 --0.0205524 0.122391 -0.00754739 0.498583 0.5 --0.0668021 0.0909191 -0.0174744 0.566525 0.5 --0.0856155 0.0942099 -0.00109094 0.420789 0.436678 --0.0915274 0.11444 0.0204492 0.759207 0.5 --0.0909048 0.131701 0.00809159 0.558083 0.5 -0.0404851 0.0578886 -0.0051698 0.425865 0.437223 -0.0295964 0.0580473 -0.0178274 0.608291 0.460655 -0.0266986 0.0941359 -0.0205949 0.662934 0.5 --0.0677104 0.172869 -0.0572602 0.695141 0.5 -0.0142001 0.118043 -0.013917 0.45799 0.403894 --0.0698171 0.0699687 0.0326375 0.529959 0.5 -0.0607097 0.0648802 0.0151632 0.434757 0.451533 -0.0609346 0.0630505 0.0131585 0.526971 0.5 -0.0602205 0.0643718 0.00864139 0.443146 0.456896 -0.0574055 0.0638877 0.00271573 0.413274 0.5 --0.0797793 0.103858 -0.00660016 0.553637 0.5 --0.0563867 0.137359 -0.00421998 0.659682 0.5 -0.0344512 0.0638263 -0.0152012 0.581486 0.5 -0.0307139 0.0605317 -0.0184589 0.617611 0.449874 -0.0185684 0.121789 -0.00725624 0.61441 0.349043 --0.0456617 0.112414 -0.0169658 0.70381 0.5 -0.0456177 0.0644845 -0.00162168 0.572144 0.5 --0.0584268 0.0349015 0.0441202 0.767369 0.5 --0.0747982 0.0723674 0.0308514 0.656357 0.5 --0.0699373 0.0621854 0.0151778 0.587415 0.5 --0.052889 0.136519 -0.00170821 0.593683 0.5 -0.0410205 0.0644886 -0.00476733 0.363401 0.5 -0.0388712 0.0646166 -0.00976797 0.384344 0.5 -0.0514871 0.0637279 -0.00174794 0.518067 0.5 --0.0787297 0.0744551 0.0267421 0.809934 0.5 --0.0850281 0.144269 0.00618082 0.578063 0.5 -0.0313094 0.064487 -0.0188936 0.672704 0.5 -0.0267274 0.0646171 -0.0220842 0.752591 0.5 -0.0318737 0.0877439 -0.0192705 0.740422 0.5 --0.0772455 0.143995 -0.00470939 0.452269 0.5 -0.0132576 0.110443 -0.0183541 0.539267 0.5 --0.00289343 0.124723 -0.00863032 0.516883 0.5 --0.0342868 0.038582 0.0485461 0.546061 0.5 -0.0200397 0.0876233 -0.0261205 0.735721 0.5 -0.0585453 0.0705354 0.0146976 0.608535 0.5 -0.0581405 0.0699819 0.00856199 0.483528 0.5 -0.056099 0.069436 0.00424359 0.385578 0.5 -0.0370479 0.0665186 -0.0132637 0.645736 0.5 --0.062561 0.172971 -0.0616721 0.43069 0.5 --0.0702718 0.15494 -0.0455472 0.29179 0.457421 --0.0916259 0.130499 0.00930481 0.432982 0.472725 --0.070021 0.148229 -0.0328231 0.322588 0.195946 --0.0721274 0.0680183 0.0267753 0.656727 0.5 --0.0745337 0.15067 -0.0264303 0.331486 0.5 -0.0431087 0.0713461 -0.002764 0.390428 0.45538 -0.0421659 0.0692525 -0.00466106 0.55545 0.5 -0.0345404 0.0699378 -0.0160391 0.727409 0.5 --0.0342368 0.122912 -0.00708584 0.432969 0.5 -0.0401518 0.070932 -0.00951127 0.706551 0.5 -0.0370706 0.0707408 -0.013301 0.722628 0.5 -0.0310856 0.0702175 -0.0192905 0.761897 0.5 -0.0283004 0.0705453 -0.0222447 0.701199 0.5 --0.00859023 0.101699 -0.0237897 0.731824 0.5 --0.0328234 0.0400139 -0.029875 0.413461 0.5 --0.0830588 0.11047 0.0397334 0.931001 0.5 -0.0142724 0.123237 -0.00806485 0.479991 0.484444 --0.0760443 0.108637 0.0389078 0.769887 0.5 --0.0732762 0.154939 -0.0321392 0.640327 0.5 -0.0160324 0.0889232 -0.0282477 0.595959 0.5 --0.0901677 0.131361 0.0394374 0.633972 0.457764 -0.0455828 0.0768365 0.00270178 0.323813 0.5 --0.0516717 0.0553965 0.014906 0.168077 0.5 --0.0376545 0.121002 -0.0109724 0.599451 0.451266 -0.0466318 0.0762885 0.00910629 0.334003 0.5 -0.0437303 0.0769241 -0.00295564 0.541016 0.5 -0.0405043 0.0766784 -0.0084913 0.540094 0.5 -0.0369463 0.0762836 -0.0128837 0.716695 0.5 -0.0349351 0.0766648 -0.0155944 0.687304 0.5 -0.0319237 0.0763904 -0.0194186 0.722365 0.5 -0.0285208 0.0758075 -0.0225233 0.729644 0.5 --0.0646857 0.068809 0.0348219 0.518098 0.396839 --0.00335573 0.0986136 -0.0269283 0.762285 0.5 --0.0383606 0.100112 -0.0217661 0.633523 0.5 --0.0705433 0.149897 -0.0387319 0.143598 0.5 --0.0247871 0.179215 -0.0188356 0.466421 0.5 -0.00339058 0.0937023 -0.0318365 0.697748 0.5 --0.09099 0.142689 0.0226645 0.743514 0.5 --0.0851088 0.102115 0.000391121 0.420019 0.403283 -0.00299202 0.124707 -0.00864775 0.631346 0.5 --0.0649459 0.167336 -0.0329944 0.692397 0.5 -0.045975 0.0827243 0.0146716 0.494123 0.463874 -0.0461931 0.0827376 0.00867911 0.540283 0.443947 -0.0453461 0.0826602 0.00269811 0.520808 0.5 -0.032594 0.082231 -0.0190597 0.700575 0.5 --0.0707752 0.142011 -0.00901143 0.440829 0.5 --0.0396694 0.045239 -0.0210351 0.371561 0.5 --0.0736488 0.145787 -0.0131048 0.298566 0.5 --0.0661855 0.1779 -0.0529018 0.456268 0.5 --0.0698006 0.179227 -0.0517285 0.330383 0.5 --0.0719677 0.177848 -0.0474604 0.498199 0.393806 --0.0131817 0.0974247 0.0509808 0.29677 0.5 --0.0760529 0.177651 -0.0471457 0.200482 0.341482 --0.0875274 0.149451 0.00937476 0.260452 0.5 --0.0847504 0.149536 0.00652369 0.220089 0.5 --0.0853843 0.0980412 -0.000554198 0.453316 0.5 --0.070162 0.172945 -0.0393132 0.377002 0.42015 --0.0669053 0.17136 -0.0404187 0.587367 0.5 --0.0915765 0.114644 0.0108349 0.335405 0.476851 -0.0311175 0.116345 -0.00142056 0.524001 0.485056 --0.09039 0.144074 0.0142555 0.571623 0.5 -0.0533752 0.0724173 0.00805773 0.504643 0.5 -0.0348115 0.113636 0.00289967 0.517745 0.5 -0.0321047 0.117128 0.00373672 0.512637 0.481334 --0.0558554 0.16013 0.00226313 0.176407 0.35978 -0.0284127 0.12005 0.00266093 0.800124 0.5 --0.0693417 0.151526 -0.0443255 0.162625 0.220555 -0.0509143 0.0733396 0.0112131 0.81315 0.5 -0.0485286 0.0726358 0.00856732 0.779683 0.5 -0.0251471 0.122517 0.00254898 0.804299 0.5 --0.0684168 0.170157 -0.0319531 0.535557 0.5 --0.071028 0.171274 -0.0325886 0.712016 0.5 --0.0765634 0.155757 -0.00874762 0.256295 0.5 -0.0525206 0.0734678 0.0148876 0.468908 0.45355 -0.035521 0.113454 0.00908801 0.654915 0.5 -0.0208324 0.125627 0.00327965 0.76886 0.5 --0.0476722 0.134348 0.0194434 0.579216 0.488505 --0.0746083 0.171229 -0.0326516 0.439107 0.422901 -0.0322027 0.117616 0.0093642 0.646061 0.5 -0.0162523 0.127588 0.00132734 0.679655 0.445027 --0.0914669 0.142805 0.0167223 0.344959 0.5 -0.0290775 0.120474 0.00686894 0.798143 0.5 -0.0135909 0.12914 0.00336546 0.632038 0.474565 --0.0861635 0.100458 0.025719 0.514874 0.431291 --0.0653051 0.165945 -0.0269849 0.665887 0.5 --0.0698492 0.16889 -0.0268648 0.536219 0.5 --0.07827 0.167473 -0.032496 0.259817 0.452429 -0.0215557 0.0945234 -0.0226594 0.630702 0.48336 -0.0260612 0.123082 0.00873766 0.803075 0.5 -0.00920342 0.130081 0.00248247 0.641161 0.5 --0.0709934 0.170517 -0.0295248 0.566905 0.409383 --0.0760202 0.167938 -0.0272636 0.242234 0.5 -0.0525229 0.0716654 0.0211203 0.349876 0.431389 -0.0207167 0.126566 0.00922145 0.763786 0.5 --0.0746025 0.0998033 -0.0126456 0.503102 0.5 --0.0864333 0.0890874 0.0257055 0.752441 0.5 -0.0354941 0.113435 0.0150848 0.708057 0.5 -0.0320737 0.117698 0.0146262 0.694886 0.5 -0.00294754 0.130714 0.00292443 0.849802 0.5 --0.0256391 0.0823957 0.0519489 0.764034 0.5 --0.0666258 0.165416 -0.0221631 0.534987 0.5 --0.0804177 0.153092 0.00488677 0.321879 0.39417 --0.0645623 0.0350017 0.0151892 0.352362 0.5 --0.0627936 0.0352479 0.02012 0.616295 0.5 --0.0642932 0.0349381 0.0264604 0.161121 0.384305 --0.0642421 0.0397497 0.0267659 0.206373 0.5 --0.0652419 0.0352202 0.0324357 0.167045 0.5 --0.06432 0.0352261 0.0387914 0.349097 0.5 --0.0869014 0.0944088 0.0260869 0.722262 0.5 --0.026376 0.100403 -0.0237519 0.527518 0.47737 --0.0704394 0.0348288 0.00888692 0.228898 0.5 --0.0696375 0.039673 0.0091864 0.30841 0.5 --0.0678064 0.035728 0.013362 0.509091 0.5 --0.0778433 0.0819732 0.0354617 0.774608 0.5 --0.0809318 0.0827942 0.0325 0.767831 0.5 --0.0712316 0.038974 0.00275642 0.155719 0.237906 --0.0616101 0.0379618 0.0219344 0 0 --0.0653778 0.0407054 0.0323415 0.379158 0.5 --0.0612949 0.040108 0.0438783 0.388361 0.5 --0.0748891 0.0826916 0.0381154 0.772848 0.5 --0.0841641 0.133769 0.0486564 0.546232 0.467433 --0.0849106 0.0945271 0.0290479 0.754258 0.5 --0.082994 0.144712 0.0404065 0.382972 0.420138 --0.0265479 0.117619 -0.0132781 0.755106 0.5 --0.0679678 0.0383221 0.0123903 0.271535 0.306541 --0.0639259 0.0401146 0.0151101 0.258252 0.450399 --0.0588527 0.0407802 0.0202136 0.51937 0.5 --0.0869621 0.135589 0.0440584 0.520567 0.5 --0.038827 0.0398484 0.042564 0.570175 0.5 --0.0253238 0.0773437 0.0501603 0.646885 0.5 -0.00864855 0.111878 -0.0192252 0.821439 0.5 --0.0625014 0.04424 0.0388616 0.455153 0.47063 --0.088493 0.125258 0.0461673 0.674925 0.5 -0.0150785 0.10107 -0.0220372 0.749486 0.5 --0.0810533 0.0876325 0.0334622 0.750019 0.5 --0.0636602 0.0439221 0.0322355 0.437404 0.5 --0.0823757 0.12585 -0.00459555 0.376136 0.464207 --0.0374554 0.042873 0.0429512 0.492581 0.5 --0.031328 0.0432863 0.0501185 0.483275 0.5 --0.0841802 0.0875016 0.0285815 0.671149 0.464325 --0.0690099 0.0427216 0.00298087 0.372436 0.5 --0.0690323 0.0427133 0.00739115 0.277083 0.5 --0.0642007 0.0449178 0.00895163 0.562755 0.5 --0.0630005 0.0427497 0.0133004 0.520064 0.348086 --0.0580777 0.0444032 0.0143596 0.493924 0.5 --0.087476 0.130712 0.0458544 0.531379 0.477045 --0.0837712 0.0999337 0.029339 0.668895 0.5 --0.083719 0.0822846 0.0270932 0.660348 0.5 --0.0209183 0.0934772 0.0512134 0.479975 0.5 --0.0868983 0.142651 0.0383505 0.486766 0.469754 --0.0588984 0.0467651 0.00989959 0.460736 0.319245 --0.0529144 0.0464475 0.0158024 0.381525 0.5 --0.0881654 0.0882094 0.0209192 0.624947 0.5 --0.0494075 0.165901 0.000731671 0.369742 0.391777 --0.0586114 0.0473978 0.0337061 0.152377 0.410418 --0.05614 0.0517476 0.00835186 0.396733 0.5 --0.0865231 0.148073 0.0321271 0.367072 0.452379 --0.0308497 0.0493297 0.0429654 0.330168 0.454747 --0.0769102 0.114994 0.0501188 0.653806 0.5 --0.0209065 0.0959579 0.0474195 0.622864 0.5 --0.0509947 0.0509637 0.0150799 0.759028 0.5 -0.00842415 0.0889657 -0.0320537 0.627702 0.5 --0.0240561 0.0544386 0.0416973 0.433194 0.5 --0.0510392 0.0524223 0.0203213 0.262945 0.5 --0.0526208 0.0518271 0.027021 0.695325 0.5 --0.0504022 0.0591186 0.0326891 0.768296 0.5 --0.0478821 0.0590694 0.0363134 0.800191 0.5 --0.0239128 0.0586553 0.0421308 0.768223 0.5 --0.0759314 0.119228 -0.00697007 0.568703 0.5 --0.0183181 0.0604564 0.0506182 0.70539 0.5 --0.0298441 0.0972531 -0.0235715 0.830462 0.5 --0.0241926 0.0628773 0.0422936 0.709715 0.5 --0.0223998 0.06467 0.045979 0.606456 0.5 --0.0192899 0.0641483 0.0503928 0.754401 0.5 --0.0260109 0.172925 -0.0191453 0.51739 0.5 --0.0265331 0.161574 -0.0144318 0.84044 0.5 --0.0558556 0.15572 -0.00121016 0.41523 0.5 --0.0599028 0.136466 -0.0064456 0.660892 0.5 --0.063538 0.071665 0.0379463 0.556494 0.5 --0.0200417 0.0869862 -0.0378876 0.500126 0.449734 --0.0557176 0.105745 -0.0186241 0.707273 0.5 --0.0530691 0.143914 -0.00100898 0.728895 0.5 --0.0256688 0.0704637 0.0438935 0.717372 0.393932 --0.0235577 0.0693774 0.0470203 0.657726 0.5 --0.0525759 0.127247 -0.00521525 0.567734 0.5 --0.0787859 0.131858 -0.00545913 0.44224 0.460808 --0.0580212 0.120088 -0.0102747 0.564344 0.455328 --0.0396294 0.110441 -0.0186258 0.62346 0.5 --0.0210282 0.173113 -0.0214922 0.42389 0.352327 --0.0547593 0.0563289 0.0107147 0.179388 0.5 --0.0435534 0.0345758 -0.024752 0.176398 0.205782 --0.0449833 0.0346921 -0.0207483 0.159962 0.261208 --0.0443576 0.0390403 -0.0217491 0.178142 0.5 --0.0462855 0.0345037 -0.0153112 0.189574 0.5 --0.046619 0.0396457 -0.0141457 0.194812 0.5 --0.00904923 0.0343826 -0.0246429 0.15305 0.5 -0.00311748 0.100303 -0.0227929 0.684313 0.5 --0.0690809 0.0392217 -0.00181724 0.169982 0.409113 --0.0920289 0.131041 0.0262349 0.856795 0.5 --0.043414 0.0372487 -0.0253064 0.219927 0.5 -0.0280974 0.0818294 -0.0220931 0.752623 0.5 --0.067702 0.169446 -0.0560134 0.487347 0.455218 --0.0915377 0.129674 0.0312365 0.601516 0.48259 --0.0663086 0.0411162 -0.00443149 0.346306 0.5 --0.0731255 0.151935 -0.0368879 0.40925 0.5 --0.0390145 0.0394889 -0.027598 0.3765 0.5 --0.0637372 0.0437827 -0.00264533 0.37233 0.5 --0.0605427 0.0425565 0.0246975 0.23689 0.5 --0.0857603 0.130763 -0.000714461 0.66754 0.5 --0.0520472 0.0403573 -0.0107411 0.62257 0.5 --0.0568522 0.0434504 0.0224413 0.404188 0.5 --0.043239 0.0429342 -0.0193166 0.339314 0.38382 --0.0438787 0.0441322 -0.0144222 0.427488 0.468839 --0.0457505 0.046486 -0.0105694 0.340556 0.5 --0.0645938 0.0456897 0.00313082 0.3549 0.5 --0.0525978 0.0464843 0.0207116 0.3335 0.5 --0.0572578 0.0459489 0.026887 0.439332 0.5 --0.0618962 0.0443648 0.0286813 0.302557 0.45843 --0.0331467 0.0453179 -0.0267282 0.481653 0.5 --0.0377669 0.0443547 -0.0252099 0.392631 0.5 --0.0320922 0.114425 -0.0162304 0.853943 0.5 --0.0578027 0.0470669 -0.0032674 0.530144 0.5 --0.0914954 0.147994 0.0205137 0.478387 0.480384 --0.0400067 0.0471536 -0.0151042 0.224844 0.33752 -0.00454895 0.121869 -0.0124797 0.622385 0.5 -0.0151282 0.112708 -0.0165496 0.634759 0.463552 --0.0525787 0.0463291 -0.00775444 0.598118 0.5 --0.0599276 0.0475112 0.00267117 0.286734 0.429608 --0.0726458 0.147126 -0.0218625 0.235551 0.5 --0.0740924 0.168686 -0.0440312 0.451963 0.347747 --0.057494 0.0515426 0.00319413 0.311918 0.5 --0.0536918 0.0483048 0.0264945 0.447469 0.5 --0.0147156 0.114453 -0.0172255 0.634887 0.5 --0.0335191 0.0480424 -0.021246 0.299501 0.5 -0.019461 0.0924333 -0.0244344 0.636237 0.5 -0.0169402 0.0952065 -0.0238278 0.793707 0.5 -0.0201047 0.104156 -0.0188197 0.859301 0.5 --0.0319642 0.0516657 -0.0152509 0.265727 0.5 --0.0368448 0.0488256 -0.0131071 0.109826 0.5 --0.0391265 0.0518909 -0.0109467 0.555432 0.5 --0.00892221 0.111576 -0.0202733 0.785262 0.5 --0.0515659 0.0515158 -0.00751393 0.527245 0.5 --0.0557028 0.05294 -0.00268598 0.514955 0.5 --0.0293421 0.0526398 -0.0213991 0.356317 0.5 --0.0314453 0.0496351 -0.0193539 0.306544 0.5 -0.0322381 0.10409 -0.0128482 0.653044 0.5 --0.0261025 0.0525801 -0.0264669 0.366688 0.5 --0.0583031 0.116733 -0.0130038 0.568329 0.5 --0.014851 0.111599 -0.0191484 0.630253 0.463696 --0.0521348 0.118189 -0.0137451 0.464136 0.474515 --0.0517493 0.0582798 -0.00896954 0.683087 0.5 --0.0561982 0.0582462 -0.00310645 0.618759 0.5 --0.0587989 0.0586119 0.00276734 0.328771 0.427166 --0.0585564 0.0578416 0.00857596 0.293131 0.5 -0.019026 0.11614 -0.0131686 0.497701 0.5 --0.0211893 0.111662 -0.0190883 0.650648 0.5 --0.0239176 0.0561149 -0.030057 0.484351 0.5 --0.0272603 0.058548 -0.027478 0.457773 0.5 --0.0295766 0.0582799 -0.0217551 0.550969 0.5 --0.0320928 0.0589382 -0.0147618 0.534177 0.453646 -0.0073938 0.121789 -0.0126555 0.654152 0.5 --0.0251946 0.0595227 -0.0308632 0.509396 0.5 --0.0307167 0.06013 -0.0194181 0.549851 0.422118 --0.0650113 0.0632174 -0.00293095 0.168435 0.5 --0.0696479 0.065751 -0.00198101 0.165663 0.5 --0.0699926 0.0635013 0.00374106 0.275779 0.5 --0.0799435 0.0724812 0.0191514 0.599916 0.5 --0.0676844 0.160922 -0.0559942 0.35716 0.5 --0.0215435 0.0636559 -0.0350431 0.45692 0.5 --0.0258325 0.0648252 -0.0322087 0.452259 0.5 --0.028982 0.0636438 -0.0274997 0.410415 0.5 --0.0304226 0.0629368 -0.0224261 0.908229 0.5 --0.0319042 0.0651819 -0.0201942 0.518875 0.434998 --0.0332741 0.0636337 -0.0160032 0.40837 0.447765 --0.0205547 0.034111 -0.026401 0.174612 0.215481 --0.0743367 0.0658286 0.00833126 0.649876 0.5 -0.016103 0.120745 -0.0103843 0.509865 0.5 --0.0770212 0.0700544 0.00316631 0.305775 0.384345 --0.0748219 0.06693 0.00451345 0.433069 0.463791 --0.0306317 0.0657524 -0.025453 0.517895 0.5 --0.0711433 0.0687078 -0.00390291 0.256016 0.135401 --0.0762625 0.0716316 -0.00295918 0.293636 0.296358 --0.0802204 0.0713935 0.00991267 0.507181 0.5 --0.0913413 0.148143 0.0161458 0.474933 0.5 --0.0273736 0.0700052 -0.0335323 0.445714 0.5 --0.0300274 0.0692073 -0.0289677 0.511122 0.5 --0.0316277 0.0711218 -0.0266514 0.502235 0.5 --0.0330629 0.0699765 -0.0212743 0.929225 0.5 --0.0353642 0.0705896 -0.0177097 0.263666 0.5 --0.0587004 0.0391044 -0.0090027 0.295521 0.5 --0.0697696 0.0703857 -0.00808666 0.238472 0.5 --0.0804832 0.0726462 0.00472466 0.630221 0.5 -0.0151616 0.126104 -0.00266395 0.542796 0.5 --0.0745721 0.072883 -0.00757069 0.303203 0.5 --0.0823908 0.076277 0.00270117 0.615888 0.5 --0.0912831 0.133698 0.0142161 0.68945 0.5 -0.00371049 0.0968817 -0.0280931 0.670854 0.5 --0.0761392 0.0766258 -0.00859487 0.260107 0.5 --0.0784749 0.0748827 -0.00523624 0.238143 0.440892 --0.0806781 0.0771902 -0.00290803 0.36458 0.43512 --0.0834622 0.0765209 0.00927112 0.562933 0.5 -0.00983826 0.11402 -0.0178612 0.519736 0.475688 -0.00210649 0.0981565 -0.0261244 0.689185 0.5 --0.0285085 0.0757575 -0.0348118 0.64535 0.304239 --0.0330874 0.0761249 -0.0270661 0.564742 0.5 --0.0346568 0.0757906 -0.0215029 0.930953 0.5 -0.0231104 0.0892807 -0.0240236 0.697809 0.45449 --0.0312132 0.0771357 -0.0320416 0.687582 0.5 --0.0700425 0.0763633 -0.0141464 0.485274 0.5 --0.0861137 0.0814707 0.00908143 0.590509 0.5 --0.086319 0.08152 0.0149936 0.698173 0.5 --0.0208042 0.0963182 -0.0270563 0.75553 0.5 --0.0211078 0.114391 -0.0171285 0.793027 0.5 --0.0746162 0.0828529 -0.0139325 0.683447 0.5 --0.077295 0.081216 -0.0100568 0.47673 0.5 --0.0800127 0.0821605 -0.00722237 0.637376 0.5 --0.0826334 0.0820868 -0.00324616 0.569954 0.5 --0.0844667 0.0817669 0.00249573 0.601403 0.5 --0.0860445 0.0832591 0.0203255 0.630527 0.5 --0.084816 0.0816746 0.0219849 0.638209 0.5 -0.0545549 0.0661692 0.000765649 0.628404 0.43579 --0.0331604 0.0828369 -0.0270493 0.417784 0.5 --0.0358028 0.0829047 -0.0227723 0.112354 0 --0.0861942 0.0842505 0.00298565 0.418742 0.5 --0.0287072 0.0827267 -0.0349537 0.48086 0.471486 --0.0311601 0.0822387 -0.0315627 0.627475 0.5 --0.085403 0.141865 0.00516647 0.463398 0.5 --0.0785169 0.0885628 -0.0107607 0.69884 0.5 --0.0807046 0.0887676 -0.00826584 0.689404 0.5 --0.0843972 0.0878743 -0.00349923 0.402052 0.5 --0.0855708 0.0882073 -0.00109946 0.425364 0.422235 --0.0876157 0.0881286 0.00369184 0.414972 0.435161 --0.0885339 0.0876942 0.00897158 0.630733 0.5 --0.0885791 0.0877213 0.0149616 0.665472 0.5 --0.0643854 0.0348576 -0.00775085 0.279509 0.5 --0.0512932 0.034227 -0.0129013 0.159841 0.5 --0.0266839 0.0458556 -0.027274 0.610127 0.5 --0.0146368 0.0981541 -0.0264318 0.44201 0.5 --0.0213468 0.10077 -0.0239588 0.58675 0.5 -0.020932 0.0825954 -0.0267347 0.750174 0.5 -0.00759225 0.0928541 -0.0309237 0.580726 0.5 --0.0144478 0.0879274 -0.0380297 0.689122 0.5 --0.00859724 0.11451 -0.0173132 0.77831 0.5 -0.0264818 0.109935 -0.0126182 0.652634 0.5 --0.0145855 0.0385179 -0.0267991 0.230538 0.5 --0.0330054 0.0337044 -0.0272991 0.262513 0.5 --0.0267872 0.0340475 -0.0271901 0.244173 0 --0.00849157 0.0985859 -0.0270535 0.53889 0.411612 --0.0110954 0.120824 -0.0120135 0.770076 0.5 -0.0367379 0.0925992 -0.0129888 0.684003 0.5 --0.0571635 0.0435755 -0.00717607 0.581004 0.404197 --0.0193328 0.0979251 -0.024792 0.661276 0.5 --0.0203798 0.0385467 -0.0283088 0.392689 0.5 --0.0587681 0.0337133 -0.00871891 0.1361 0.5 --0.0517919 0.100655 -0.0213258 0.798237 0.5 -0.00702627 0.0978418 -0.0246055 0.732067 0.326346 --0.0148892 0.126068 -0.00252126 0.467449 0.5 -0.0307578 0.092446 -0.0188519 0.704525 0.5 -0.0211049 0.0578126 -0.0266116 0.685576 0.5 --0.0169237 0.0970481 -0.0278718 0.775366 0.5 -0.0460004 0.0581866 -0.00508589 0.612698 0.5 --0.00944331 0.0822271 -0.0381067 0.670336 0.467319 --0.0635881 0.0392124 -0.00717766 0.572252 0.5 -0.00864227 0.0386371 -0.0233053 0.540697 0.5 -0.0252935 0.0769557 -0.0248407 0.75695 0.5 --0.0229653 0.0895159 -0.036199 0.454072 0.467569 --0.0523791 0.0341193 -0.00994653 0.132813 0.5 -0.0211693 0.0643935 -0.0268578 0.690366 0.5 --0.0515867 0.13164 -0.0028092 0.545448 0.5 --0.0149669 0.0345529 -0.0254273 0.17846 0.5 --0.0161167 0.127288 0.00169291 0.694465 0.5 --0.0469232 0.128515 -0.00163965 0.389857 0.5 --0.00961381 0.127158 -0.00378809 0.714685 0.5 --0.0074566 0.128562 -0.00130751 0.72817 0.5 --0.00304493 0.128909 -0.00174857 0.778769 0.5 -0.0028379 0.129022 -0.00194723 0.574275 0.5 -0.00903363 0.128674 -0.00165013 0.617309 0.5 --0.0561607 0.131588 -0.00571429 0.687735 0.5 --0.0457551 0.127167 -0.00484962 0.645893 0.5 --0.00304746 0.127678 -0.00456004 0.562309 0.5 -0.00303811 0.12768 -0.00442 0.624596 0.5 -0.0101526 0.126812 -0.00466464 0.64326 0.5 --0.0553259 0.126836 -0.00601308 0.517644 0.5 -0.00799473 0.034846 -0.0206913 0.278473 0.5 -0.0027179 0.0342191 -0.0204737 0.322372 0.5 --0.00295804 0.0342418 -0.0216222 0.194059 0.5 -0.0134674 0.0353221 -0.0196961 0.466171 0.5 -0.00440963 0.0383063 -0.0240776 0.3469 0.5 -0.00140752 0.0383474 -0.0246147 0.361099 0.5 --0.00309177 0.0383877 -0.0251866 0.314174 0.5 --0.0575023 0.100661 -0.0195211 0.459895 0.452391 --0.0485739 0.15316 -0.00547278 0.691758 0.5 --0.0646573 0.0334831 -0.00296009 0.187639 0.5 --0.0640796 0.100426 -0.0173936 0.44544 0.466101 --0.0704415 0.100139 -0.0146037 0.499781 0.478548 --0.0326376 0.155806 -0.00949884 0.828995 0.5 -0.0336094 0.0373624 0.00273412 0.290019 0.5 -0.0320943 0.0397885 -0.00195136 0.323719 0.5 -0.0158502 0.0449602 -0.0237212 0.910511 0.5 -0.00889467 0.0426449 -0.0242659 0.891863 0.5 -0.00312499 0.0452721 -0.026588 0.665265 0.460024 --0.00298345 0.044686 -0.0272222 0.905955 0.5 --0.00912346 0.0448524 -0.0280671 0.895801 0.5 --0.0145351 0.0443266 -0.0277771 0.887903 0.5 --0.0209223 0.0460913 -0.0281918 0.705844 0.5 -0.034052 0.0448434 -0.00540113 0.626363 0.5 --0.0312646 0.158257 -0.01223 0.732334 0.5 -0.0401509 0.0448981 -0.00354586 0.446696 0.5 -0.0143253 0.0473484 -0.0251513 0.546545 0.456757 -0.00937888 0.0466526 -0.0261685 0.907397 0.5 --0.0766531 0.0695423 0.0207982 0.774152 0.5 -0.0087246 0.0517916 -0.0291615 0.840924 0.5 -0.00299372 0.0506927 -0.0298557 0.901259 0.5 --0.00164566 0.0489436 -0.0304144 0.872257 0.5 --0.00321397 0.0522596 -0.0314075 0.634884 0.475184 --0.00915341 0.0509217 -0.0318681 0.650022 0.5 --0.0146018 0.0513752 -0.0319045 0.891033 0.5 --0.0161558 0.0488543 -0.0303763 0.808351 0.5 --0.0205843 0.0508011 -0.0296435 0.813106 0.5 -0.0405252 0.0518855 -0.00654453 0.65569 0.5 -0.0149309 0.0520772 -0.0273859 0.655547 0.5 -0.041884 0.0490868 -0.00604367 0.898378 0.5 -0.019962 0.0529908 -0.0261219 0.592286 0.5 --0.0198501 0.0534234 -0.0312267 0.768335 0.5 --0.0336273 0.0527187 -0.0106243 0.102172 0.5 --0.0461112 0.0529158 -0.0101664 0.636429 0.372142 --0.0204 0.161875 -0.014658 0.822907 0.5 -0.0449924 0.0530898 -0.00614891 0.575737 0.5 -0.00733679 0.0546532 -0.0305038 0.688621 0.5 -0.00283568 0.0546532 -0.0307468 0.611749 0.5 --0.00302245 0.0577 -0.0331477 0.67582 0.5 --0.00914668 0.0576676 -0.0341165 0.698389 0.5 --0.01517 0.058199 -0.0349877 0.856637 0.5 --0.0202707 0.0581031 -0.0333681 0.552506 0.5 -0.0140844 0.057965 -0.028983 0.564173 0.483714 -0.0103301 0.0588553 -0.0299472 0.602031 0.489059 -0.00732823 0.0588898 -0.0306117 0.710141 0.5 -0.0027369 0.0590151 -0.0321928 0.690932 0.5 --0.0337187 0.0579742 -0.0115824 0.143826 0.5 --0.0390711 0.0582467 -0.0115033 0.780735 0.5 --0.0460474 0.0579124 -0.0115174 0.472305 0.5 --0.00961439 0.0642168 -0.0358564 0.670518 0.457134 --0.044157 0.0599825 -0.0123877 0.830365 0.5 -0.015251 0.0645803 -0.029567 0.626368 0.396114 -0.00839294 0.0649214 -0.0316957 0.79033 0.385997 -0.00325858 0.0643529 -0.0332439 0.728322 0.418376 --0.00361257 0.0645861 -0.034907 0.670644 0.5 --0.0144709 0.065006 -0.0371603 0.712311 0.5 --0.0366623 0.060679 -0.0122791 0.525705 0.5 --0.0526404 0.0636402 -0.0101297 0.452904 0.5 --0.0381866 0.0648919 -0.0142073 0.543504 0.5 --0.0452495 0.0647856 -0.0139819 0.883769 0.5 --0.0599262 0.0622966 -0.00429285 0.195385 0.344922 --0.0778641 0.117463 -0.00576778 0.523105 0.5 --0.0187447 0.0664151 -0.0374779 0.820087 0.5 --0.0577616 0.0644884 -0.00779097 0.472929 0.5 --0.0625778 0.0655353 -0.00741131 0.379588 0.453283 -0.0251088 0.0710945 -0.0248604 0.704567 0.5 -0.021457 0.0702729 -0.0273415 0.740248 0.5 -0.0166747 0.0701586 -0.0297203 0.658948 0.5 -0.0132745 0.0702643 -0.0312074 0.651019 0.5 -0.00867525 0.0703509 -0.0324278 0.818076 0.5 -0.00229643 0.0708694 -0.0343123 0.73028 0.5 --0.0030646 0.070381 -0.0353565 0.764349 0.5 --0.00773679 0.0691749 -0.0362051 0.757441 0.5 --0.0101988 0.0715122 -0.0373778 0.76291 0.5 --0.0147454 0.0704429 -0.0382943 0.581028 0.470136 --0.0203984 0.0706516 -0.038158 0.645161 0.5 --0.0240967 0.0693418 -0.0362521 0.4533 0.5 --0.0605175 0.0673597 -0.0108259 0.635082 0.5 --0.0387293 0.0706355 -0.0168457 0.666323 0.5 --0.0451347 0.0705064 -0.0164504 0.875899 0.5 --0.0523435 0.0697862 -0.0145984 0.401473 0.5 --0.0591515 0.0702891 -0.0147203 0.639534 0.5 --0.0652515 0.0688492 -0.00993982 0.422384 0.422462 --0.0247614 0.0719777 -0.0368317 0.497524 0.5 --0.0637884 0.0712697 -0.0138535 0.437166 0.5 -0.0211454 0.0769268 -0.0268772 0.737516 0.5 -0.0162128 0.0765268 -0.0293784 0.712202 0.5 -0.0133247 0.0760196 -0.0306715 0.679361 0.5 -0.00907695 0.076038 -0.0330382 0.719764 0.5 -0.00245085 0.0760857 -0.0351615 0.721395 0.5 --0.00176321 0.0762288 -0.0360688 0.799862 0.5 --0.00476487 0.076286 -0.0369742 0.814155 0.377247 --0.00962992 0.0765936 -0.0378651 0.627364 0.487104 --0.0144481 0.0764118 -0.0385775 0.832444 0.5 --0.021453 0.0763574 -0.038668 0.751656 0.5 --0.024977 0.0762484 -0.0374518 0.39297 0.457854 --0.0377453 0.0766164 -0.0189124 0.273711 0.5 --0.0397395 0.0746623 -0.0180255 0.973337 0.5 --0.0437423 0.0765905 -0.0187922 0.595439 0.440211 --0.0466377 0.0744845 -0.0173668 0.538698 0.468502 --0.0518623 0.0745812 -0.0175084 0.855826 0.5 --0.0589866 0.0745368 -0.01766 0.879682 0.5 --0.0644081 0.0756279 -0.0167529 0.562234 0.481782 --0.0721295 0.0740256 -0.0105719 0.341576 0.432723 --0.0615233 0.0354132 0.043881 0.499903 0.5 --0.0524971 0.0769872 -0.0189536 0.873913 0.5 --0.0587482 0.0767445 -0.0187462 0.882838 0.5 -0.013102 0.0809953 -0.0307917 0.69611 0.5 -0.00892296 0.0820652 -0.0325478 0.700162 0.5 -0.0022917 0.0820297 -0.0349279 0.829579 0.5 --0.00177837 0.0804805 -0.0364471 0.647084 0.379833 --0.00379684 0.0824193 -0.037328 0.824332 0.5 --0.0142988 0.0820384 -0.0390211 0.832022 0.373406 --0.0207708 0.0823862 -0.0387335 0.805306 0.5 --0.0248089 0.0818968 -0.0377031 0.470046 0.439483 --0.0735819 0.0777026 -0.0122023 0.445372 0.5 -0.015425 0.0831288 -0.0295207 0.735694 0.5 --0.0383994 0.0817919 -0.0209596 0.290803 0.5 --0.0451184 0.0815526 -0.020434 0.548777 0.45056 --0.051814 0.0818472 -0.0211348 0.886135 0.5 --0.0583689 0.0812724 -0.0202975 0.847354 0.5 --0.063949 0.082768 -0.0188935 0.606874 0.5 --0.0662709 0.080065 -0.0177832 0.593549 0.449354 --0.0695594 0.0830593 -0.0170582 0.4495 0.5 --0.00481814 0.086841 -0.0367951 0.827149 0.5 --0.0248206 0.0867524 -0.0367639 0.487957 0.5 -0.0132046 0.0871602 -0.0305473 0.663835 0.5 --0.0360837 0.0867076 -0.023791 0.366486 0.5 --0.00877843 0.0340556 -0.0204927 0 0 --0.0207128 0.0342382 -0.0208728 0.319674 0.5 --0.0147915 0.0341096 -0.0207616 0.312592 0.5 --0.0265767 0.0342963 -0.0210989 0.482378 0.5 -0.00282685 0.0351053 -0.0158136 0.508357 0.5 -0.00885967 0.034471 -0.0147487 0.490133 0.5 --0.0390848 0.0337228 -0.0202617 0.628543 0.5 --0.0326656 0.0345334 -0.0201874 0.788348 0.5 --0.00224535 0.0351539 -0.0166234 0.756398 0.5 --0.0149096 0.0357313 -0.0180956 0.933106 0.5 --0.0114808 0.0353662 -0.0177045 0.933613 0.5 --0.00921575 0.0380183 -0.0149732 0.909294 0.5 --0.00282494 0.0382292 -0.0140636 0.920543 0.5 -0.00285919 0.0377324 -0.0134715 0.965028 0.5 -0.0159109 0.0347098 -0.00882204 0.420938 0.5 --0.0306839 0.036693 -0.0184598 0.875112 0.5 --0.0265216 0.0367471 -0.0188177 0.84266 0.5 --0.0218341 0.0369718 -0.0184303 0.873319 0.5 --0.0203027 0.0382765 -0.0152577 0.887215 0.5 --0.0152596 0.0382328 -0.0156428 0.873575 0.5 -0.00738356 0.0366172 -0.0125003 0.962688 0.5 -0.00992361 0.0351979 -0.00924624 0.9642 0.5 -0.00702596 0.0378387 -0.00879015 0.927286 0.5 --0.0396958 0.0342843 -0.014578 0.76643 0.5 --0.0329517 0.0382154 -0.014678 0.654319 0.5 --0.0263862 0.0385778 -0.0153644 0.924592 0.5 -0.00320835 0.0389424 -0.00953857 0.945732 0.5 --0.0364387 0.0357946 -0.0155844 0.543249 0.5 --0.00301526 0.0391061 -0.00886496 0.816802 0.5 -0.00831664 0.0348156 -0.00321961 0.671683 0.5 -0.0145039 0.0343685 -0.0028433 0.748562 0.5 --0.0365752 0.0370276 -0.0136534 0.498247 0.5 --0.0146234 0.0388055 -0.00887465 0.759701 0.5 --0.00886749 0.0389394 -0.00890173 0.761944 0.5 --0.0451032 0.0336721 -0.00848668 0.772585 0.5 --0.040313 0.0350801 -0.00861758 0.462745 0.5 --0.0206235 0.0386 -0.00878063 0.747754 0.5 -0.00267879 0.038424 -0.00319748 0.448355 0.5 -0.015044 0.0350517 0.00289039 0.579133 0.5 -0.0201479 0.0347806 0.00348327 0.403273 0.5 -0.027119 0.0353514 0.00366834 0.0909279 0.5 -0.0280785 0.0365531 0.000826759 0 0 --0.0376066 0.0375692 -0.00942418 0.22755 0.5 --0.0332748 0.0384549 -0.00855692 0.752109 0.5 --0.0264541 0.0384497 -0.00886193 0.729343 0.5 --0.00299262 0.0389582 -0.00292437 0.746846 0.5 -0.00451408 0.0356078 -0.00103635 0.413486 0.5 -0.00881079 0.0350428 0.00356828 0.588251 0.5 -0.0314184 0.0360255 0.00457907 0.187967 0.5 --0.00888202 0.0387884 -0.00299409 0.73859 0.5 -0.00271787 0.0349091 0.00339755 0.645421 0.5 --0.041199 0.0341471 -0.00327644 0 0 --0.0205479 0.0384259 -0.00283766 0.741413 0.5 --0.0146618 0.0385908 -0.00288739 0.718901 0.5 -0.00103528 0.0375917 0.000952222 0.441385 0.5 -0.0215747 0.0354906 0.0086194 0.395945 0.5 -0.0264794 0.0346514 0.00870654 0.414057 0.5 -0.0322391 0.0355412 0.00882378 0.515667 0.5 --0.0521057 0.0334794 -0.00318207 0.614129 0.5 --0.0455078 0.0336572 -0.00225818 0.757211 0.5 --0.0334104 0.0383259 -0.00292317 0.611245 0.5 --0.0265122 0.0383343 -0.00296504 0.763748 0.5 --0.00224847 0.0383354 0.00320971 0.728422 0.5 --0.0589386 0.0334143 -0.00291301 0.444064 0.5 --0.00874044 0.0385976 0.00291227 0.735039 0.5 -0.00273457 0.0342734 0.0088248 0.796819 0.5 -0.00621941 0.0351341 0.00654928 0 0 --0.080018 0.109279 0.0373655 0.503151 0.426569 --0.0393178 0.0336443 0.00354096 0.266658 0.5 --0.0213111 0.0382973 0.00334866 0.753895 0.5 --0.0146196 0.0384265 0.00290922 0.762157 0.5 --0.00353554 0.0379644 0.00874752 0.658939 0.5 -0.0276681 0.0349662 0.0149532 0.360666 0.5 -0.03282 0.0359255 0.0147037 0.719837 0.5 -0.0389763 0.0383079 0.0145025 0.635106 0.5 --0.0523961 0.0335249 0.00326874 0.742717 0.5 --0.0462346 0.0335696 0.00267776 0.743661 0.5 --0.0277984 0.0382296 0.00286126 0.456211 0.5 --0.000947006 0.0357374 0.0103469 0.779853 0.5 -0.0222276 0.0358262 0.0160256 0.180494 0.5 -0.0448051 0.0411192 0.0150961 0.294679 0.5 --0.0581064 0.033504 0.00272997 0.775526 0.5 --0.0352323 0.0337248 0.00491425 0.152905 0 --0.0312985 0.0381858 0.00167702 0 0 --0.0088641 0.03847 0.00876261 0.73345 0.5 -0.0028919 0.0342894 0.0147059 0.676527 0.5 --0.0703332 0.0340583 0.00286723 0.639535 0.5 --0.0648245 0.0334924 0.00301734 0.793089 0.5 --0.0387963 0.034763 0.00935652 0.458758 0.5 --0.0332327 0.0337932 0.00943608 0.151116 0.5 --0.0203456 0.0382265 0.00836296 0.759992 0.5 --0.0152156 0.0383161 0.00935801 0.755179 0.5 --0.000385714 0.0351459 0.0134171 0.848157 0.5 -0.00663645 0.0342324 0.0159688 0 0 -0.0268074 0.0356469 0.0204126 0.619176 0.5 -0.0309391 0.0362152 0.0189937 0.762661 0.5 -0.0334119 0.0376179 0.0210082 0.70177 0.5 --0.0515734 0.0338904 0.00817232 0.493124 0.5 --0.0454999 0.0352808 0.00804865 0.53914 0.5 --0.0263229 0.0380313 0.00871732 0.143858 0.5 --0.0031858 0.0377098 0.014513 0.797449 0.5 -0.0211051 0.0351552 0.0207004 0.432057 0.5 -0.0391983 0.0395969 0.0205879 0.670001 0.5 -0.0441778 0.0418755 0.0204802 0.609797 0.5 --0.0580282 0.0335624 0.00918162 0.776077 0.5 --0.00922404 0.0383488 0.0150261 0.754001 0.5 -0.00313746 0.0352426 0.0204176 0.692001 0.5 -0.00877508 0.0346179 0.020856 0.290121 0.5 -0.0468489 0.0434226 0.0210936 0.239557 0.5 --0.0648031 0.0337402 0.00884817 0.802283 0.5 --0.0338156 0.0345063 0.0150293 0.572312 0.5 --0.0149173 0.0382498 0.0147214 0.753708 0.5 -0.0146344 0.0345628 0.0222588 0.157065 0.5 --0.0365655 0.0357926 0.0130139 0.391807 0.5 --0.0262153 0.0376693 0.0148666 0.146481 0.5 --0.0205165 0.0381248 0.0146779 0.715632 0.5 --0.00229335 0.0382456 0.020565 0.923102 0.5 -0.014723 0.0347707 0.0263935 0.310145 0.5 -0.0210245 0.0353476 0.0265418 0.313898 0.5 -0.0250756 0.0364517 0.0246847 0.678097 0.5 -0.0273584 0.0381522 0.0267127 0.778478 0.5 -0.0321164 0.0401984 0.026762 0.778536 0.5 --0.053829 0.0335431 0.0139547 0.458851 0.5 -0.00114114 0.037661 0.0223414 0.978558 0.5 -0.00915473 0.0353589 0.0262457 0.701449 0.5 -0.0380552 0.0412819 0.02589 0.374179 0.417844 --0.0588034 0.0336951 0.0146283 0.798139 0.5 --0.0339319 0.0346253 0.0202274 0.513983 0.5 --0.0152545 0.0382629 0.0204704 0.75125 0.5 --0.00888844 0.0384087 0.0207206 0.746481 0.5 -0.00307272 0.0384964 0.0264151 0.996029 0.5 --0.0261643 0.0378491 0.0205422 0.603577 0.5 --0.0205429 0.0381473 0.0213758 0.772551 0.5 --0.0538188 0.0335608 0.0210581 0 0 --0.00301594 0.03875 0.0263901 0.805634 0.5 -0.00756209 0.0380712 0.0285007 0.978659 0.5 -0.0143741 0.0348327 0.0331833 0.915728 0.5 -0.0198279 0.03555 0.0321213 0.749506 0.5 -0.0236875 0.0373106 0.0299772 0.517201 0.5 --0.0588476 0.033906 0.020465 0.657735 0.5 --0.00882687 0.0386047 0.0265705 0.756827 0.5 -0.00847025 0.0383344 0.0315598 0.739987 0.5 -0.0108958 0.035647 0.0330663 0.649316 0.5 --0.0366651 0.0353042 0.023032 0.153172 0.5 --0.0340084 0.0344659 0.0266224 0.263742 0.5 --0.0270447 0.0379104 0.0270529 0.074682 0.5 --0.0210471 0.0383013 0.026282 0.782021 0.5 --0.0147317 0.0384888 0.0265233 0.791552 0.5 --0.0712786 0.0733348 0.0355839 0.683322 0.427231 --0.0388887 0.0346255 0.0265538 0.109729 0 -0.00290004 0.0393205 0.032168 0.626516 0.5 -0.0155389 0.0350901 0.0393977 0.759188 0.5 -0.0195159 0.0358111 0.0367948 0.405286 0.5 --0.0589139 0.0341314 0.0264586 0.808252 0.5 --0.052234 0.0340737 0.0268887 0.497915 0.5 --0.0447866 0.0339274 0.0274346 0.154159 0.5 --0.0310127 0.0369382 0.02848 0.240675 0.5 --0.00908756 0.0390146 0.0330901 0.79352 0.5 --0.00293287 0.039209 0.03365 0.804769 0.5 -0.00861952 0.0346654 0.0391536 0.125418 0.5 --0.0149144 0.0388312 0.0324344 0.795183 0.5 -0.00392423 0.0347398 0.0399064 0.146347 0.5 --0.0657827 0.0618455 0.00187562 0.442355 0.5 --0.0640051 0.0606097 0.00361345 0.333039 0.5 --0.0455164 0.0345095 0.0326748 0.510388 0.5 --0.0385699 0.0344168 0.033204 0.485482 0.5 --0.0342024 0.0351611 0.0325685 0.248514 0.5 --0.0270303 0.0384799 0.0326469 0.783767 0.5 --0.0209433 0.0387397 0.0332273 0.806699 0.5 --0.0520994 0.0344582 0.0326775 0.466807 0.5 --0.0313489 0.0377268 0.0321213 0.178238 0.5 --0.00219023 0.0348305 0.0410082 0.139343 0 -0.00818206 0.0355366 0.0443043 0.642932 0.5 -0.014947 0.0361331 0.0431407 0.796588 0.5 --0.0642564 0.0597236 0.0092932 0.716255 0.5 --0.0584732 0.0343588 0.0331559 0.775713 0.5 --0.0145859 0.0393004 0.0380317 0.483641 0.5 --0.00937548 0.0394517 0.037871 0.328321 0.5 --0.0588297 0.0579582 0.0145443 0 0 --0.038732 0.0346956 0.0400227 0.628019 0.5 --0.0331487 0.034492 0.0390527 0.154826 0.5 --0.0201914 0.0391628 0.0381696 0.483919 0.5 --0.00878985 0.0348233 0.0452949 0.139305 0.5 --0.0031441 0.0351515 0.045825 0.295611 0.5 --0.0701619 0.0622789 0.00863964 0.42197 0.408074 --0.0451191 0.034688 0.0396457 0.766116 0.5 --0.0256628 0.0389081 0.0373249 0 0 --0.0146115 0.0348173 0.0458198 0.143796 0.5 --0.0636462 0.0593677 0.014889 0.807508 0.5 --0.0531671 0.0345191 0.0391729 0.74918 0.5 --0.0595372 0.034497 0.0397515 0.783724 0.5 --0.0329555 0.0349777 0.045552 0.474674 0.5 --0.0262436 0.034809 0.0452831 0.162616 0.5 --0.0215554 0.0348112 0.0459347 0.152356 0 --0.0633407 0.0601272 0.0190813 0.939061 0.5 --0.0471 0.0351015 0.0434178 0.627709 0.5 --0.0120723 0.0353434 0.0494553 0.877126 0.5 --0.016313 0.0351836 0.0504037 0.67915 0.5 --0.0483699 0.146034 -0.00115148 0.583019 0.5 --0.0264335 0.156562 -0.00835956 0.469485 0.437523 --0.065003 0.144791 -0.0142909 0.400803 0.470167 --0.066228 0.151547 -0.0394609 0.538048 0.5 --0.0663323 0.145309 -0.018858 0.764025 0.5 --0.0412403 0.152108 -0.00674014 0.633348 0.5 -3 4 132 80 -3 80 132 544 -3 373 80 544 -3 387 299 241 -3 859 1475 1474 -3 371 299 401 -3 401 326 333 -3 347 673 402 -3 1187 1354 386 -3 1221 457 69 -3 186 224 114 -3 1250 1256 116 -3 164 333 376 -3 19 488 1245 -3 749 19 1245 -3 667 19 749 -3 1040 412 543 -3 1359 1358 1500 -3 216 4 80 -3 152 544 146 -3 4 387 505 -3 543 1235 1205 -3 610 604 297 -3 250 801 1274 -3 504 148 111 -3 387 348 299 -3 401 333 164 -3 1484 1483 1110 -3 91 196 310 -3 90 91 310 -3 952 406 609 -3 1244 1247 1240 -3 93 327 65 -3 373 544 152 -3 373 152 644 -3 1321 158 22 -3 401 416 326 -3 644 152 1263 -3 276 59 181 -3 294 853 150 -3 308 249 529 -3 406 1124 604 -3 609 406 463 -3 146 3 145 -3 90 310 3 -3 58 186 10 -3 575 261 384 -3 25 40 43 -3 379 535 713 -3 348 704 157 -3 388 443 22 -3 396 146 145 -3 152 133 1263 -3 1830 1829 1812 -3 214 114 224 -3 157 147 324 -3 1335 430 1274 -3 282 230 214 -3 92 346 652 -3 1151 1012 1491 -3 571 1151 1491 -3 571 1491 183 -3 310 196 111 -3 91 4 505 -3 1250 116 108 -3 110 183 47 -3 1209 854 953 -3 132 4 91 -3 111 148 327 -3 93 111 327 -3 110 571 183 -3 713 171 402 -3 294 920 200 -3 81 180 52 -3 525 731 784 -3 347 256 673 -3 175 57 220 -3 338 175 220 -3 27 14 220 -3 57 27 220 -3 359 446 27 -3 359 36 446 -3 145 28 262 -3 133 16 419 -3 1447 576 1465 -3 1885 287 444 -3 133 396 16 -3 598 543 1205 -3 447 93 65 -3 73 213 36 -3 1236 1255 1250 -3 1235 1236 1250 -3 115 782 731 -3 28 93 447 -3 525 548 115 -3 299 416 401 -3 667 603 463 -3 292 667 463 -3 492 70 637 -3 133 146 396 -3 1166 1125 619 -3 1151 1219 959 -3 821 304 409 -3 1486 1487 1684 -3 15 175 167 -3 120 15 167 -3 15 131 57 -3 175 15 57 -3 57 131 27 -3 257 209 359 -3 27 257 359 -3 209 55 36 -3 359 209 36 -3 55 87 73 -3 36 55 73 -3 101 108 735 -3 108 101 64 -3 310 365 3 -3 576 859 1465 -3 262 28 447 -3 102 64 101 -3 544 91 90 -3 262 447 485 -3 485 447 211 -3 1443 1440 1442 -3 697 457 1221 -3 1008 383 1011 -3 451 435 1330 -3 129 405 426 -3 70 75 161 -3 648 693 692 -3 204 129 426 -3 812 481 123 -3 406 292 463 -3 878 1591 1009 -3 478 128 50 -3 900 979 977 -3 490 900 977 -3 241 299 371 -3 1164 701 734 -3 683 703 682 -3 719 718 682 -3 703 719 682 -3 760 759 718 -3 719 760 718 -3 137 729 728 -3 54 130 2 -3 302 358 301 -3 566 567 614 -3 1069 1103 1068 -3 1186 1190 1208 -3 4 348 387 -3 277 311 228 -3 707 226 706 -3 355 394 393 -3 773 129 755 -3 646 647 679 -3 356 355 269 -3 270 356 269 -3 424 394 356 -3 623 654 602 -3 654 683 602 -3 193 217 192 -3 1677 1676 1662 -3 1018 1019 1025 -3 597 1231 1165 -3 490 26 605 -3 299 157 416 -3 504 241 148 -3 84 528 714 -3 1247 669 1240 -3 683 719 703 -3 1886 1231 1066 -3 79 168 218 -3 211 318 426 -3 165 377 148 -3 91 505 387 -3 577 623 622 -3 692 693 707 -3 255 254 218 -3 194 270 255 -3 695 137 728 -3 1475 1498 1474 -3 67 808 1010 -3 1190 240 1208 -3 242 259 300 -3 476 509 567 -3 743 755 558 -3 1025 1024 1018 -3 194 255 218 -3 270 269 254 -3 203 271 12 -3 603 667 749 -3 1379 1395 1392 -3 783 546 1340 -3 578 600 577 -3 624 623 577 -3 600 624 577 -3 655 654 623 -3 684 683 654 -3 655 684 654 -3 720 719 683 -3 684 720 683 -3 720 739 719 -3 761 760 719 -3 739 761 719 -3 218 254 253 -3 694 695 437 -3 255 270 254 -3 1202 488 19 -3 412 1222 543 -3 60 528 84 -3 1352 494 702 -3 624 655 623 -3 1361 221 143 -3 755 129 204 -3 132 91 544 -3 543 1221 1235 -3 216 5 4 -3 1221 1236 1235 -3 754 755 204 -3 1169 732 715 -3 756 755 743 -3 1036 1035 1024 -3 728 756 743 -3 476 567 508 -3 4 5 348 -3 244 1339 546 -3 405 445 211 -3 254 269 268 -3 253 254 268 -3 381 358 302 -3 346 92 59 -3 517 450 1560 -3 1618 1333 141 -3 1498 1497 1474 -3 1231 597 1165 -3 228 264 215 -3 100 151 99 -3 151 215 99 -3 151 228 215 -3 1864 827 1870 -3 561 578 480 -3 207 561 480 -3 579 600 578 -3 561 579 578 -3 600 625 624 -3 656 655 624 -3 625 656 624 -3 685 684 655 -3 656 685 655 -3 685 721 720 -3 684 685 720 -3 721 740 739 -3 720 721 739 -3 739 740 761 -3 762 789 788 -3 761 762 788 -3 789 239 770 -3 788 789 770 -3 328 770 239 -3 423 424 476 -3 121 195 522 -3 423 476 422 -3 381 431 358 -3 148 371 401 -3 579 625 600 -3 465 464 431 -3 381 465 431 -3 464 465 227 -3 248 11 71 -3 548 142 1005 -3 740 762 761 -3 767 900 490 -3 728 743 437 -3 776 195 121 -3 1177 1176 1153 -3 1043 1034 1035 -3 137 708 729 -3 91 387 196 -3 1721 1729 1703 -3 728 729 756 -3 727 728 437 -3 196 387 241 -3 404 458 522 -3 355 354 268 -3 647 648 692 -3 979 846 901 -3 241 371 148 -3 142 1155 574 -3 269 355 268 -3 358 301 300 -3 301 358 300 -3 753 754 793 -3 184 229 228 -3 229 277 228 -3 312 311 277 -3 1845 1853 1831 -3 1523 1532 1153 -3 580 579 561 -3 1276 1280 1771 -3 580 626 625 -3 579 580 625 -3 626 657 656 -3 625 626 656 -3 656 657 685 -3 722 721 685 -3 741 740 721 -3 722 741 721 -3 740 763 762 -3 790 789 762 -3 763 790 762 -3 790 339 239 -3 789 790 239 -3 377 165 327 -3 476 508 422 -3 259 301 300 -3 162 170 169 -3 81 162 169 -3 580 561 562 -3 657 686 685 -3 229 312 277 -3 28 365 93 -3 1263 419 1254 -3 396 145 144 -3 685 686 722 -3 741 763 740 -3 133 152 146 -3 1263 133 419 -3 207 520 562 -3 520 562 580 -3 562 520 580 -3 562 626 580 -3 239 339 487 -3 597 1063 1066 -3 3 365 28 -3 649 648 615 -3 108 64 116 -3 571 1225 1218 -3 184 185 229 -3 313 312 229 -3 185 313 229 -3 439 501 520 -3 501 581 562 -3 520 501 562 -3 627 626 562 -3 581 627 562 -3 627 628 626 -3 658 657 626 -3 628 658 626 -3 658 675 657 -3 687 686 657 -3 675 687 657 -3 723 722 686 -3 687 723 686 -3 722 723 741 -3 741 723 763 -3 764 791 790 -3 763 764 790 -3 791 407 339 -3 790 791 339 -3 407 303 339 -3 303 487 339 -3 303 460 487 -3 303 325 460 -3 170 106 105 -3 105 106 68 -3 439 440 501 -3 723 764 763 -3 1 1027 453 -3 1067 511 942 -3 775 121 774 -3 1281 1270 1291 -3 368 440 439 -3 367 368 439 -3 582 581 501 -3 628 627 581 -3 658 688 687 -3 675 658 687 -3 1733 1562 1561 -3 757 775 756 -3 74 68 46 -3 398 1223 317 -3 631 607 231 -3 1465 859 1474 -3 1775 1784 1754 -3 204 138 793 -3 74 122 97 -3 584 533 570 -3 278 313 185 -3 265 278 185 -3 369 368 313 -3 278 369 313 -3 369 440 368 -3 502 501 440 -3 583 582 501 -3 502 583 501 -3 583 581 582 -3 629 628 581 -3 583 629 581 -3 629 659 658 -3 628 629 658 -3 658 659 688 -3 724 723 687 -3 688 724 687 -3 724 742 723 -3 742 765 764 -3 723 742 764 -3 764 238 791 -3 791 238 407 -3 407 238 303 -3 238 333 303 -3 333 325 303 -3 614 615 647 -3 46 122 74 -3 606 199 112 -3 441 440 369 -3 83 173 573 -3 775 776 121 -3 846 979 901 -3 441 502 440 -3 659 689 688 -3 84 714 1367 -3 535 52 171 -3 551 798 1883 -3 630 629 583 -3 629 630 659 -3 689 724 688 -3 792 238 764 -3 765 792 764 -3 1207 1208 177 -3 195 96 522 -3 122 13 97 -3 344 492 637 -3 1025 1036 1024 -3 775 774 756 -3 1012 1151 959 -3 1270 1372 1291 -3 145 3 28 -3 649 670 695 -3 517 1888 243 -3 444 399 1885 -3 370 369 278 -3 724 765 742 -3 376 333 238 -3 1372 1375 1291 -3 1060 1161 1162 -3 16 396 144 -3 369 442 441 -3 583 601 630 -3 690 689 659 -3 318 295 427 -3 138 204 427 -3 693 694 707 -3 310 111 365 -3 365 111 93 -3 636 660 659 -3 567 566 508 -3 426 405 211 -3 121 126 774 -3 471 601 583 -3 251 237 188 -3 1303 188 237 -3 278 314 370 -3 370 442 369 -3 442 503 502 -3 441 442 502 -3 503 471 583 -3 502 503 583 -3 858 302 259 -3 16 144 319 -3 660 690 659 -3 690 725 724 -3 689 690 724 -3 750 765 724 -3 725 750 724 -3 8 792 765 -3 750 8 765 -3 376 238 792 -3 8 376 792 -3 164 376 238 -3 376 164 238 -3 1381 1380 1375 -3 1135 1134 1103 -3 1104 1135 1103 -3 794 204 793 -3 447 65 211 -3 442 1347 503 -3 249 262 485 -3 1036 1043 1035 -3 522 96 438 -3 204 426 427 -3 188 283 251 -3 1235 1250 1205 -3 485 262 23 -3 597 1066 1165 -3 144 308 319 -3 1027 767 589 -3 648 649 694 -3 567 615 614 -3 821 409 304 -3 63 711 903 -3 8 164 376 -3 12 478 50 -3 171 347 402 -3 284 1327 314 -3 1447 1465 1459 -3 1456 1447 1459 -3 1329 1328 1380 -3 755 756 773 -3 756 774 773 -3 193 218 253 -3 648 694 693 -3 168 194 218 -3 190 188 189 -3 284 283 188 -3 190 284 188 -3 283 284 314 -3 262 485 23 -3 108 116 64 -3 751 750 725 -3 726 751 725 -3 751 771 750 -3 37 8 750 -3 771 37 750 -3 632 164 8 -3 569 53 411 -3 511 1560 1884 -3 386 1354 1320 -3 165 632 8 -3 37 165 8 -3 165 164 632 -3 662 661 638 -3 354 393 422 -3 401 165 148 -3 979 1883 798 -3 144 145 262 -3 413 408 349 -3 16 319 669 -3 318 211 295 -3 156 1213 198 -3 1153 1152 1119 -3 1225 1448 247 -3 190 266 284 -3 419 669 1247 -3 479 233 232 -3 166 165 37 -3 709 492 344 -3 567 568 615 -3 107 827 1864 -3 695 727 437 -3 485 211 23 -3 1254 419 1247 -3 419 16 669 -3 1884 1591 1009 -3 249 485 24 -3 41 249 24 -3 1103 1134 1133 -3 272 398 492 -3 754 204 794 -3 1498 159 113 -3 24 485 23 -3 1102 1103 1133 -3 308 144 249 -3 164 165 401 -3 692 707 706 -3 509 568 567 -3 191 252 190 -3 190 252 266 -3 252 285 284 -3 266 252 284 -3 285 286 284 -3 284 286 337 -3 144 262 249 -3 536 564 563 -3 563 564 593 -3 564 612 611 -3 593 564 611 -3 645 361 611 -3 612 645 611 -3 645 691 1313 -3 309 752 751 -3 726 309 751 -3 752 772 771 -3 751 752 771 -3 119 37 771 -3 772 119 771 -3 425 166 37 -3 119 425 37 -3 380 165 166 -3 425 380 166 -3 128 83 17 -3 50 128 17 -3 729 757 756 -3 394 423 422 -3 589 767 490 -3 424 509 476 -3 1374 1359 1531 -3 408 372 349 -3 679 692 706 -3 855 242 300 -3 766 757 730 -3 354 355 393 -3 79 218 193 -3 129 126 405 -3 126 458 405 -3 647 692 679 -3 757 766 775 -3 766 776 775 -3 1699 1014 1013 -3 393 394 422 -3 252 286 285 -3 752 119 772 -3 425 327 380 -3 696 730 729 -3 708 696 729 -3 649 695 694 -3 78 79 193 -3 1497 1498 113 -3 901 979 798 -3 404 24 445 -3 24 23 445 -3 776 795 195 -3 1340 1591 1884 -3 1035 1034 1024 -3 177 203 12 -3 380 327 425 -3 510 509 424 -3 477 510 424 -3 458 404 405 -3 192 217 252 -3 191 192 252 -3 217 267 286 -3 252 217 286 -3 286 267 352 -3 353 421 420 -3 352 353 420 -3 421 507 506 -3 506 507 536 -3 507 565 564 -3 536 507 564 -3 565 613 612 -3 564 565 612 -3 646 645 612 -3 613 646 612 -3 646 679 691 -3 645 646 691 -3 706 705 691 -3 679 706 691 -3 753 309 280 -3 138 119 752 -3 753 138 752 -3 427 425 119 -3 138 427 119 -3 295 380 425 -3 427 295 425 -3 65 327 380 -3 295 65 380 -3 769 104 315 -3 426 318 427 -3 568 616 615 -3 695 728 727 -3 404 445 405 -3 1635 1653 1453 -3 271 478 12 -3 839 136 830 -3 615 648 647 -3 311 277 228 -3 749 1245 1225 -3 353 392 421 -3 793 138 753 -3 315 104 33 -3 432 466 465 -3 381 432 465 -3 465 466 527 -3 1170 1190 1099 -3 754 794 793 -3 558 754 280 -3 193 253 217 -3 253 268 267 -3 217 253 267 -3 268 354 353 -3 267 268 353 -3 354 392 353 -3 422 421 392 -3 354 422 392 -3 422 508 507 -3 421 422 507 -3 508 566 565 -3 507 508 565 -3 614 613 565 -3 566 614 565 -3 614 647 646 -3 613 614 646 -3 168 810 194 -3 886 940 923 -3 946 945 930 -3 929 939 944 -3 940 569 887 -3 661 649 616 -3 320 919 878 -3 227 526 464 -3 882 873 866 -3 552 384 820 -3 464 927 358 -3 917 432 905 -3 879 829 820 -3 194 836 880 -3 935 466 432 -3 917 935 432 -3 1038 1725 1013 -3 1378 1391 1406 -3 173 448 293 -3 477 943 510 -3 616 568 617 -3 1405 550 980 -3 665 86 847 -3 891 906 912 -3 845 130 54 -3 999 925 822 -3 1885 928 555 -3 904 910 270 -3 315 33 478 -3 1033 1034 1042 -3 490 921 26 -3 850 257 131 -3 1070 1077 1034 -3 843 860 15 -3 120 843 15 -3 850 209 257 -3 914 913 300 -3 880 911 910 -3 641 661 616 -3 843 120 797 -3 860 870 15 -3 870 131 15 -3 870 850 131 -3 894 873 882 -3 811 248 875 -3 974 981 992 -3 850 201 131 -3 131 201 850 -3 850 201 209 -3 907 917 905 -3 694 437 226 -3 895 843 797 -3 870 860 843 -3 816 870 843 -3 870 201 850 -3 913 933 932 -3 968 969 986 -3 840 118 712 -3 816 843 895 -3 201 856 209 -3 856 845 55 -3 209 856 55 -3 931 930 911 -3 228 151 184 -3 1340 884 1884 -3 553 506 536 -3 539 867 842 -3 870 924 201 -3 977 823 490 -3 868 829 780 -3 999 1000 925 -3 198 701 156 -3 787 816 895 -3 924 877 856 -3 201 924 856 -3 877 845 856 -3 66 305 941 -3 769 203 1208 -3 848 847 919 -3 880 889 911 -3 1027 589 605 -3 957 816 787 -3 849 870 816 -3 957 849 816 -3 414 821 409 -3 1887 1004 928 -3 569 888 887 -3 459 384 552 -3 891 889 890 -3 839 892 891 -3 1080 1057 1051 -3 957 328 816 -3 328 957 816 -3 849 881 870 -3 881 849 870 -3 870 849 924 -3 481 531 123 -3 777 835 698 -3 891 892 906 -3 912 911 889 -3 891 912 889 -3 546 1339 746 -3 328 849 957 -3 849 88 924 -3 1043 1070 1034 -3 777 122 46 -3 477 929 943 -3 617 641 616 -3 822 915 72 -3 915 331 72 -3 834 806 956 -3 788 957 787 -3 770 788 787 -3 788 328 957 -3 864 877 924 -3 833 938 130 -3 845 833 130 -3 938 256 130 -3 1005 142 574 -3 661 676 137 -3 730 305 776 -3 1186 1208 1207 -3 1189 1186 1207 -3 798 1888 1067 -3 864 924 88 -3 864 922 877 -3 982 845 877 -3 922 982 877 -3 982 833 845 -3 894 905 873 -3 879 665 86 -3 879 665 847 -3 817 922 864 -3 833 982 922 -3 817 833 922 -3 894 907 905 -3 1562 1561 1038 -3 305 893 776 -3 899 864 88 -3 1071 1049 1072 -3 788 770 328 -3 776 768 795 -3 835 919 847 -3 817 864 899 -3 833 256 938 -3 1177 1195 1176 -3 1276 1771 1275 -3 155 100 813 -3 832 96 449 -3 879 384 665 -3 879 86 665 -3 834 956 320 -3 863 898 328 -3 826 849 328 -3 898 826 328 -3 849 826 88 -3 826 899 88 -3 1346 1883 900 -3 930 945 944 -3 939 930 944 -3 810 818 836 -3 838 836 837 -3 1077 1069 1034 -3 891 890 838 -3 1473 1680 1679 -3 44 24 438 -3 899 200 817 -3 1374 1391 1378 -3 466 935 527 -3 66 941 730 -3 913 906 912 -3 956 919 320 -3 662 676 661 -3 239 395 863 -3 395 898 863 -3 819 826 898 -3 826 200 899 -3 35 86 82 -3 880 270 194 -3 935 950 527 -3 670 661 695 -3 134 256 94 -3 818 837 836 -3 848 879 847 -3 395 819 898 -3 826 819 200 -3 200 920 817 -3 920 876 833 -3 817 920 833 -3 833 876 256 -3 1034 1069 1068 -3 932 933 947 -3 997 676 662 -3 836 889 880 -3 757 729 730 -3 956 806 919 -3 603 749 1460 -3 876 48 256 -3 827 107 155 -3 107 184 155 -3 830 855 841 -3 1042 1034 1068 -3 832 449 795 -3 997 662 638 -3 384 261 665 -3 997 696 676 -3 294 48 876 -3 920 294 876 -3 925 915 822 -3 1199 1231 1886 -3 941 305 730 -3 200 418 294 -3 569 940 886 -3 100 155 184 -3 840 712 331 -3 921 379 26 -3 1016 1014 1699 -3 776 766 730 -3 983 997 638 -3 676 696 137 -3 487 395 239 -3 487 819 395 -3 569 886 511 -3 940 887 923 -3 986 1000 985 -3 1125 110 47 -3 947 968 958 -3 842 874 834 -3 822 918 66 -3 985 999 998 -3 984 985 998 -3 999 822 998 -3 983 984 997 -3 984 998 997 -3 819 418 200 -3 177 85 1206 -3 12 275 397 -3 1231 1165 1066 -3 240 769 1208 -3 1000 999 985 -3 943 965 568 -3 906 913 932 -3 300 913 892 -3 997 998 66 -3 998 822 66 -3 478 33 128 -3 570 701 1076 -3 305 72 768 -3 72 811 768 -3 878 884 411 -3 878 835 884 -3 930 939 929 -3 968 978 967 -3 958 968 967 -3 946 958 967 -3 819 853 418 -3 510 943 509 -3 509 943 568 -3 151 100 184 -3 978 984 983 -3 967 978 983 -3 474 1122 799 -3 932 931 912 -3 487 460 819 -3 460 29 819 -3 819 29 853 -3 340 867 383 -3 1134 1135 1161 -3 947 946 931 -3 1411 1501 1408 -3 300 892 855 -3 356 910 929 -3 136 838 837 -3 1259 351 523 -3 887 896 923 -3 260 86 665 -3 774 129 773 -3 872 873 871 -3 906 932 912 -3 661 137 695 -3 511 886 942 -3 985 984 978 -3 968 985 978 -3 818 136 837 -3 1559 851 857 -3 872 871 865 -3 1222 1221 543 -3 548 1005 115 -3 430 1198 1065 -3 768 811 832 -3 945 967 944 -3 1132 1134 1160 -3 1019 1036 1025 -3 1134 1161 1160 -3 615 616 649 -3 1560 884 1884 -3 884 835 888 -3 214 230 114 -3 811 332 832 -3 878 411 53 -3 848 842 879 -3 842 829 879 -3 48 673 256 -3 869 811 768 -3 912 931 911 -3 935 936 950 -3 871 302 381 -3 972 991 971 -3 708 137 696 -3 1225 571 110 -3 847 955 13 -3 803 190 189 -3 865 871 858 -3 986 985 968 -3 929 944 943 -3 227 972 526 -3 888 835 896 -3 1001 1002 840 -3 1830 1841 1829 -3 50 140 275 -3 394 424 423 -3 411 884 888 -3 936 935 917 -3 907 936 917 -3 835 847 698 -3 811 6 332 -3 842 867 829 -3 1161 1060 1226 -3 1885 399 1887 -3 808 834 995 -3 1659 1658 1638 -3 65 295 211 -3 918 822 305 -3 302 871 381 -3 847 86 955 -3 1001 840 925 -3 1010 937 834 -3 1208 203 177 -3 1135 1162 1161 -3 921 81 379 -3 271 315 478 -3 948 969 947 -3 464 526 927 -3 834 848 806 -3 409 296 414 -3 302 873 432 -3 885 896 777 -3 841 892 839 -3 811 875 6 -3 1077 1104 1069 -3 1104 1103 1069 -3 68 106 46 -3 823 921 490 -3 162 81 921 -3 823 162 921 -3 989 1001 1000 -3 986 989 1000 -3 1000 1001 925 -3 888 896 887 -3 929 477 356 -3 974 972 534 -3 87 2 213 -3 915 840 331 -3 970 969 948 -3 965 641 568 -3 1207 177 1206 -3 1726 1725 1038 -3 1002 51 840 -3 814 191 803 -3 191 190 803 -3 855 892 841 -3 302 432 381 -3 173 293 573 -3 880 904 270 -3 871 873 302 -3 358 914 300 -3 239 863 328 -3 910 911 929 -3 331 712 811 -3 438 24 404 -3 892 913 906 -3 991 1002 990 -3 128 33 83 -3 810 836 194 -3 788 770 787 -3 814 803 804 -3 774 126 129 -3 242 855 830 -3 981 1189 1206 -3 927 934 914 -3 847 13 777 -3 301 358 300 -3 822 72 305 -3 641 617 568 -3 839 838 136 -3 904 880 910 -3 1850 1864 1870 -3 118 248 811 -3 949 970 948 -3 970 989 986 -3 1328 1325 1316 -3 358 927 914 -3 867 340 829 -3 943 944 966 -3 1100 221 1361 -3 530 805 525 -3 327 148 377 -3 1259 179 351 -3 1029 1028 1014 -3 969 968 947 -3 970 986 969 -3 832 795 768 -3 888 569 411 -3 342 344 113 -3 458 126 121 -3 943 966 965 -3 979 901 823 -3 823 861 162 -3 701 198 1076 -3 966 638 641 -3 769 315 271 -3 760 761 787 -3 965 966 641 -3 927 949 934 -3 949 948 934 -3 558 755 754 -3 919 835 878 -3 270 910 356 -3 852 162 861 -3 106 170 162 -3 852 106 162 -3 947 958 946 -3 815 192 191 -3 814 815 191 -3 820 384 879 -3 305 768 893 -3 698 847 777 -3 829 340 780 -3 534 972 227 -3 121 522 458 -3 1071 1077 1070 -3 846 823 901 -3 846 861 823 -3 918 305 66 -3 893 768 776 -3 1190 1186 1099 -3 67 1010 937 -3 925 840 915 -3 862 861 846 -3 862 852 861 -3 835 777 896 -3 946 945 944 -3 862 106 852 -3 1885 1887 928 -3 464 358 431 -3 526 949 927 -3 946 944 945 -3 890 889 838 -3 66 696 997 -3 1019 1561 1026 -3 1375 1380 1291 -3 1071 1061 1077 -3 712 118 811 -3 806 848 919 -3 971 990 970 -3 661 670 649 -3 971 970 949 -3 749 1225 110 -3 122 777 13 -3 35 13 955 -3 734 701 1164 -3 795 449 195 -3 874 842 848 -3 990 1002 989 -3 977 979 823 -3 526 971 949 -3 78 193 192 -3 815 78 192 -3 990 989 970 -3 834 539 842 -3 839 891 838 -3 1146 767 1064 -3 1002 1001 989 -3 840 51 118 -3 886 862 846 -3 280 754 753 -3 811 869 768 -3 906 913 912 -3 967 966 944 -3 931 946 930 -3 829 552 820 -3 886 106 862 -3 885 46 106 -3 1061 1104 1077 -3 320 67 834 -3 905 432 873 -3 874 848 834 -3 911 930 929 -3 1026 1572 1019 -3 972 974 992 -3 934 933 913 -3 914 934 913 -3 923 106 886 -3 777 46 885 -3 355 356 394 -3 449 96 195 -3 66 730 696 -3 807 96 832 -3 72 331 811 -3 896 106 923 -3 896 885 106 -3 1071 1070 1043 -3 932 947 931 -3 1049 1071 1043 -3 450 39 785 -3 946 967 945 -3 836 838 889 -3 787 761 788 -3 967 983 638 -3 966 967 638 -3 991 990 971 -3 597 1165 1231 -3 937 539 834 -3 934 948 947 -3 933 934 947 -3 886 846 942 -3 972 971 526 -3 1737 1762 1746 -3 1841 1851 1829 -3 417 1219 1218 -3 1166 110 1125 -3 159 342 113 -3 1065 1032 1274 -3 430 1065 1274 -3 1307 1320 1395 -3 767 1027 1 -3 846 798 1067 -3 735 1256 469 -3 1829 1850 1834 -3 398 317 1039 -3 288 32 34 -3 1051 1057 1058 -3 515 1684 1674 -3 1080 1079 1057 -3 1051 1058 1029 -3 1039 288 34 -3 1561 1726 1038 -3 1379 1307 1395 -3 304 642 409 -3 1396 1380 1381 -3 1030 1051 1029 -3 1219 1218 959 -3 598 1205 642 -3 1604 1615 1613 -3 1209 953 1193 -3 389 1521 1121 -3 398 75 70 -3 1314 273 524 -3 1022 1030 1021 -3 1022 1021 1016 -3 1030 1029 1021 -3 598 642 304 -3 528 1185 714 -3 1194 1209 1193 -3 177 12 397 -3 878 67 320 -3 1057 1045 1028 -3 1096 1095 1079 -3 1296 264 1319 -3 101 491 1237 -3 834 808 67 -3 1312 1484 1110 -3 963 1312 1110 -3 113 344 637 -3 1497 113 1496 -3 1119 1127 1113 -3 1312 1483 1484 -3 1799 1816 1812 -3 1079 1095 1057 -3 854 357 1191 -3 399 444 1210 -3 539 1011 383 -3 246 250 664 -3 1028 1038 1020 -3 1058 1057 1029 -3 311 1329 1396 -3 1260 1483 1312 -3 1187 1328 428 -3 1851 1864 1850 -3 317 609 619 -3 609 463 619 -3 1223 952 317 -3 603 1166 619 -3 1003 976 1094 -3 1248 556 297 -3 287 1885 555 -3 1138 1172 1163 -3 297 556 610 -3 1591 878 1009 -3 463 603 619 -3 749 110 1166 -3 1157 680 1081 -3 1886 304 409 -3 436 1027 605 -3 1015 1029 1014 -3 556 20 610 -3 20 604 610 -3 1099 1186 1189 -3 20 599 604 -3 1209 854 953 -3 1360 1550 1685 -3 492 398 70 -3 1172 1193 1192 -3 1175 1172 1192 -3 733 292 406 -3 202 733 406 -3 1010 834 67 -3 468 113 637 -3 154 1157 1081 -3 1172 1175 1163 -3 1193 854 1192 -3 953 854 1193 -3 1055 174 493 -3 1502 650 1046 -3 236 60 84 -3 1195 1194 1176 -3 85 177 397 -3 1163 1175 1148 -3 585 433 357 -3 1050 1045 1028 -3 1138 1148 1112 -3 1603 1402 1589 -3 1174 1192 1191 -3 1170 1174 1190 -3 1416 1417 1617 -3 398 1039 34 -3 75 398 1007 -3 1095 1107 1078 -3 1133 1134 1132 -3 1528 1022 1551 -3 1066 598 304 -3 292 733 667 -3 63 903 18 -3 619 1125 288 -3 1357 1355 1356 -3 733 1363 667 -3 470 1 212 -3 1017 830 136 -3 1119 1113 1095 -3 1387 231 247 -3 1107 1112 1078 -3 113 468 1496 -3 1028 1045 1050 -3 1014 1028 1013 -3 808 1011 539 -3 830 841 839 -3 12 50 275 -3 1344 1530 1115 -3 1363 153 19 -3 667 1363 19 -3 1103 1102 1068 -3 952 609 317 -3 1175 1174 1148 -3 1031 236 681 -3 595 10 555 -3 1119 1114 1587 -3 1114 1119 1096 -3 709 272 492 -3 451 736 434 -3 1174 1175 1192 -3 1380 1328 1316 -3 928 595 555 -3 153 489 1202 -3 572 598 1066 -3 19 153 1202 -3 1737 1746 1721 -3 1418 1417 1395 -3 1148 1147 1126 -3 488 1387 1448 -3 1245 488 1448 -3 1040 543 598 -3 572 1040 598 -3 1021 1029 1015 -3 1654 1653 1635 -3 329 58 595 -3 489 125 488 -3 1163 1148 1138 -3 1534 1687 1439 -3 342 709 344 -3 1112 1148 1126 -3 1202 489 488 -3 125 231 1387 -3 488 125 1387 -3 398 272 1223 -3 383 867 539 -3 414 296 928 -3 1176 1194 1172 -3 1028 1020 1013 -3 173 176 448 -3 1591 878 1009 -3 444 287 263 -3 1083 444 263 -3 272 952 1223 -3 1192 854 1191 -3 854 585 357 -3 1119 1152 1139 -3 1547 461 513 -3 296 329 595 -3 296 595 928 -3 603 749 1166 -3 1319 1329 1381 -3 1138 1152 1172 -3 63 18 33 -3 433 63 104 -3 769 433 104 -3 1174 1171 1147 -3 1372 1381 1375 -3 1613 1424 1603 -3 1113 1138 1107 -3 571 1218 1219 -3 1528 1551 1548 -3 1007 398 34 -3 1738 1737 1717 -3 1396 1329 1380 -3 1063 572 1066 -3 1153 1176 1152 -3 1139 1113 1127 -3 1119 1139 1127 -3 1191 357 1190 -3 357 240 1190 -3 1148 1174 1147 -3 29 460 325 -3 317 619 1039 -3 1754 1762 1737 -3 1329 311 1396 -3 1309 1380 1316 -3 1225 247 1218 -3 1448 1387 247 -3 1028 1045 1038 -3 1635 1453 1452 -3 116 1256 735 -3 514 1032 962 -3 1095 1078 1086 -3 1079 1095 1086 -3 357 433 240 -3 1174 1170 1171 -3 1218 1219 959 -3 1067 942 846 -3 1057 1095 1079 -3 10 114 287 -3 150 853 620 -3 555 10 287 -3 1152 1138 1139 -3 1052 1085 1370 -3 1704 1721 1703 -3 89 51 1002 -3 512 89 1002 -3 1152 1176 1172 -3 981 1206 992 -3 991 512 1002 -3 402 673 48 -3 1016 1551 1022 -3 1151 571 1219 -3 433 769 240 -3 1291 1380 1309 -3 1571 785 884 -3 589 490 605 -3 584 572 1063 -3 1057 1079 1045 -3 1138 1112 1107 -3 1045 1086 1078 -3 1095 1113 1107 -3 76 512 991 -3 1549 1552 1548 -3 203 769 271 -3 992 76 991 -3 274 89 512 -3 76 274 512 -3 274 51 89 -3 139 118 51 -3 274 139 51 -3 11 248 118 -3 139 11 118 -3 1056 1042 1068 -3 737 103 17 -3 871 302 858 -3 273 489 153 -3 1826 1835 1820 -3 197 48 294 -3 975 197 294 -3 197 713 402 -3 48 197 402 -3 584 1076 1040 -3 1079 1086 1045 -3 1029 1057 1028 -3 1139 1138 1113 -3 572 584 1040 -3 198 412 1040 -3 1076 198 1040 -3 298 273 153 -3 1500 1531 1359 -3 1096 1119 1095 -3 1194 1193 1172 -3 1560 785 1571 -3 882 866 894 -3 49 139 274 -3 1189 1207 1206 -3 1102 1133 1132 -3 1717 1721 1704 -3 1674 1487 1653 -3 584 570 1076 -3 894 1102 907 -3 821 1167 1199 -3 17 103 140 -3 50 17 140 -3 1042 1056 866 -3 1056 1068 894 -3 866 1056 894 -3 894 1068 1102 -3 1102 1132 936 -3 907 1102 936 -3 1160 950 936 -3 1132 1160 936 -3 1174 1191 1190 -3 1206 85 76 -3 992 1206 76 -3 397 274 76 -3 85 397 76 -3 275 49 274 -3 397 275 274 -3 140 139 49 -3 275 140 49 -3 103 11 139 -3 140 103 139 -3 409 642 329 -3 296 409 329 -3 436 975 1241 -3 436 605 975 -3 605 26 975 -3 26 197 975 -3 26 379 713 -3 197 26 713 -3 1010 539 937 -3 59 454 346 -3 652 408 413 -3 21 61 149 -3 171 345 347 -3 94 2 130 -3 130 256 134 -3 1004 1393 715 -3 313 368 367 -3 544 90 146 -3 81 535 379 -3 1257 527 950 -3 1257 950 1160 -3 302 301 259 -3 1004 414 928 -3 1160 1238 1257 -3 102 214 186 -3 1238 1160 1161 -3 1226 1238 1161 -3 1257 227 527 -3 95 233 364 -3 620 853 29 -3 1257 534 227 -3 282 454 230 -3 1453 1653 1452 -3 232 233 95 -3 821 1199 1886 -3 1232 1238 1226 -3 1238 981 1257 -3 1257 981 534 -3 417 408 652 -3 1233 1238 1232 -3 1027 436 42 -3 196 504 111 -3 169 180 81 -3 61 21 479 -3 631 231 388 -3 372 631 388 -3 1300 1382 1270 -3 1558 1559 857 -3 714 298 800 -3 298 153 800 -3 981 974 534 -3 704 348 5 -3 706 226 234 -3 388 231 443 -3 311 1330 1329 -3 1282 1300 1270 -3 1189 981 1238 -3 1233 1189 1238 -3 334 94 256 -3 1462 1672 1473 -3 895 786 787 -3 595 58 10 -3 1242 1251 1256 -3 489 231 125 -3 1236 1256 1250 -3 0 717 40 -3 470 212 0 -3 717 279 40 -3 276 230 59 -3 454 282 1237 -3 521 219 213 -3 417 652 346 -3 1266 417 346 -3 364 521 213 -3 171 363 345 -3 279 704 40 -3 470 0 160 -3 94 95 2 -3 42 281 717 -3 97 375 540 -3 61 479 363 -3 1216 705 706 -3 349 372 233 -3 453 42 717 -3 1241 975 150 -3 150 975 294 -3 214 362 282 -3 959 417 1266 -3 959 1219 417 -3 281 42 279 -3 408 607 372 -3 372 607 631 -3 0 40 25 -3 1221 69 1242 -3 287 114 263 -3 279 147 157 -3 704 279 157 -3 134 94 130 -3 81 52 535 -3 1265 58 329 -3 1249 1265 329 -3 82 97 13 -3 364 643 158 -3 82 375 97 -3 156 542 1214 -3 479 232 345 -3 35 82 13 -3 147 620 29 -3 102 186 58 -3 64 102 58 -3 363 479 345 -3 21 413 479 -3 652 413 21 -3 372 388 233 -3 216 43 5 -3 61 171 52 -3 413 349 479 -3 186 114 10 -3 619 288 1039 -3 697 1221 412 -3 171 61 363 -3 212 717 0 -3 1236 1242 1256 -3 607 408 417 -3 92 21 149 -3 279 42 147 -3 1221 1222 412 -3 697 1217 457 -3 156 1214 1213 -3 453 717 1 -3 552 829 868 -3 114 276 263 -3 570 734 701 -3 324 29 325 -3 1 717 212 -3 214 102 101 -3 2 364 213 -3 95 364 2 -3 74 97 68 -3 108 58 1265 -3 196 241 504 -3 416 325 326 -3 1346 900 767 -3 642 1205 1249 -3 71 135 6 -3 665 261 260 -3 389 43 216 -3 108 64 58 -3 1255 1236 1250 -3 7 1261 71 -3 1261 135 71 -3 83 737 17 -3 165 380 327 -3 147 29 324 -3 279 717 281 -3 417 1218 607 -3 1218 247 607 -3 83 573 737 -3 737 1239 7 -3 1239 1261 7 -3 42 620 147 -3 1215 697 1214 -3 1221 1242 1236 -3 1261 172 135 -3 651 62 6 -3 117 332 6 -3 62 117 6 -3 416 324 325 -3 157 324 416 -3 40 5 43 -3 1227 1239 737 -3 573 1227 737 -3 1261 1262 172 -3 172 651 6 -3 135 172 6 -3 62 807 117 -3 0 25 160 -3 364 388 643 -3 345 95 94 -3 1214 909 1215 -3 336 149 180 -3 233 388 364 -3 807 832 117 -3 1243 1262 1261 -3 1239 1243 1261 -3 42 150 620 -3 1215 1217 697 -3 1214 412 198 -3 1213 1214 198 -3 293 1227 573 -3 172 62 651 -3 878 1591 67 -3 1214 697 412 -3 1228 1243 1239 -3 1227 1228 1239 -3 96 45 438 -3 40 704 5 -3 59 92 181 -3 172 9 62 -3 643 22 158 -3 388 22 643 -3 92 149 181 -3 345 94 334 -3 652 21 92 -3 345 232 95 -3 214 101 362 -3 535 171 713 -3 1262 678 172 -3 678 9 172 -3 9 592 62 -3 479 349 233 -3 326 325 333 -3 117 832 332 -3 347 345 334 -3 234 1216 706 -3 486 62 592 -3 486 807 62 -3 884 1340 1884 -3 1270 1381 1372 -3 348 157 299 -3 1320 1418 1395 -3 1243 452 1262 -3 1262 452 678 -3 343 592 9 -3 149 61 52 -3 1224 1230 1228 -3 1246 1253 1243 -3 1243 1253 452 -3 163 486 592 -3 163 96 486 -3 2 87 54 -3 1474 1497 1496 -3 1488 1474 1496 -3 525 115 731 -3 1230 1246 1243 -3 1228 1230 1243 -3 452 343 9 -3 678 452 9 -3 31 592 343 -3 31 163 592 -3 743 226 437 -3 334 256 347 -3 149 52 180 -3 6 875 248 -3 1482 1474 1488 -3 1246 1230 1253 -3 452 31 343 -3 45 96 163 -3 364 158 521 -3 737 7 103 -3 213 73 87 -3 1063 533 584 -3 45 44 438 -3 42 436 150 -3 1244 1240 1092 -3 211 445 23 -3 1459 1465 1482 -3 1440 988 1442 -3 163 44 45 -3 1418 1354 1863 -3 436 1241 150 -3 453 1027 42 -3 108 1265 1249 -3 230 454 59 -3 1465 1474 1482 -3 311 1329 1319 -3 677 1234 1230 -3 1230 1234 1253 -3 452 374 31 -3 163 323 44 -3 282 214 230 -3 214 282 230 -3 1258 374 452 -3 1253 1258 452 -3 1215 909 1217 -3 1354 1418 1320 -3 1234 1240 1253 -3 294 418 853 -3 558 234 226 -3 11 103 71 -3 1240 1258 1253 -3 31 77 163 -3 77 323 163 -3 558 280 234 -3 214 224 186 -3 1205 1250 1249 -3 586 1296 1282 -3 1240 1234 677 -3 114 230 276 -3 1125 47 32 -3 308 77 31 -3 868 780 340 -3 1250 108 1249 -3 694 226 707 -3 288 1125 32 -3 319 31 374 -3 31 319 308 -3 529 323 77 -3 323 24 44 -3 280 309 234 -3 234 309 1216 -3 1491 1012 183 -3 77 308 529 -3 323 41 24 -3 225 361 1313 -3 6 248 71 -3 1258 669 374 -3 669 319 374 -3 249 41 323 -3 529 249 323 -3 115 444 782 -3 146 90 3 -3 309 705 1216 -3 669 1258 1240 -3 1264 109 636 -3 1302 185 1293 -3 1217 909 960 -3 237 265 1302 -3 337 1337 1336 -3 547 541 205 -3 1313 691 705 -3 286 352 337 -3 1327 1332 370 -3 798 846 901 -3 337 1338 1337 -3 361 225 611 -3 451 439 484 -3 677 1092 1240 -3 225 1313 109 -3 264 228 277 -3 352 1334 337 -3 785 783 1340 -3 309 1313 705 -3 674 683 682 -3 663 623 602 -3 622 663 710 -3 995 1591 806 -3 450 206 1047 -3 1283 99 215 -3 611 563 593 -3 475 246 664 -3 1294 1264 636 -3 442 1337 1347 -3 465 527 227 -3 659 630 636 -3 1454 1499 1527 -3 602 674 663 -3 107 1293 185 -3 1829 1851 1850 -3 109 690 660 -3 1313 690 109 -3 563 611 1264 -3 362 101 1237 -3 337 1334 1338 -3 206 450 517 -3 1347 471 503 -3 167 554 1323 -3 1468 1472 1489 -3 1091 1141 702 -3 471 563 1294 -3 715 1167 821 -3 1264 611 225 -3 1332 337 1336 -3 1004 1887 399 -3 586 1283 215 -3 1023 1252 1400 -3 1179 1370 1383 -3 1313 726 1324 -3 471 636 630 -3 352 420 1334 -3 1047 39 450 -3 99 1283 586 -3 237 1302 107 -3 14 446 330 -3 1313 361 645 -3 530 525 784 -3 1338 553 1348 -3 1337 1338 1348 -3 370 1332 442 -3 1332 1336 442 -3 715 821 414 -3 237 283 1322 -3 362 1237 282 -3 187 1303 237 -3 257 27 131 -3 801 430 1335 -3 1287 36 213 -3 554 167 338 -3 335 1331 1330 -3 311 335 1330 -3 1331 439 451 -3 506 420 421 -3 1330 1331 451 -3 663 674 1284 -3 674 385 1284 -3 184 107 185 -3 1322 283 314 -3 14 27 446 -3 439 520 484 -3 265 185 1302 -3 420 553 1338 -3 554 338 916 -3 1400 1298 1023 -3 553 563 471 -3 1324 726 1313 -3 1285 14 446 -3 434 435 451 -3 338 167 175 -3 277 311 1319 -3 546 783 244 -3 801 1335 1274 -3 338 1297 916 -3 1294 563 1264 -3 420 1338 1334 -3 783 606 244 -3 1337 1348 1347 -3 1313 1324 690 -3 311 312 335 -3 220 1285 1310 -3 1284 385 1278 -3 1128 1023 1252 -3 1285 220 14 -3 622 623 663 -3 109 660 636 -3 524 446 330 -3 1589 1402 1403 -3 338 220 1310 -3 674 682 385 -3 284 337 1332 -3 107 1302 1293 -3 663 1284 710 -3 1888 517 1067 -3 350 1251 69 -3 435 434 415 -3 435 415 428 -3 1297 338 1310 -3 682 307 385 -3 1306 1305 1280 -3 1276 1306 1280 -3 313 367 312 -3 1327 284 1332 -3 1336 1337 442 -3 1264 225 109 -3 180 169 1229 -3 475 801 246 -3 352 267 353 -3 1403 1404 1589 -3 1285 1292 1310 -3 307 682 748 -3 682 718 748 -3 1277 1276 1275 -3 1158 237 107 -3 1067 517 511 -3 1271 1282 1270 -3 489 125 443 -3 446 14 330 -3 586 1282 1271 -3 1292 1285 446 -3 446 330 1287 -3 443 125 489 -3 108 116 735 -3 813 100 99 -3 1276 1307 1306 -3 1483 1260 1317 -3 1272 586 1271 -3 1348 553 471 -3 1287 213 219 -3 330 446 1287 -3 443 231 489 -3 330 36 1287 -3 86 35 955 -3 450 785 1560 -3 1312 1304 1260 -3 1329 435 428 -3 1289 1276 1277 -3 1289 1290 1276 -3 1158 187 237 -3 1311 556 1248 -3 558 226 743 -3 1323 554 993 -3 1292 446 524 -3 273 443 489 -3 1290 1289 1277 -3 1290 1307 1276 -3 215 264 1296 -3 1304 1286 1273 -3 1260 1304 1273 -3 1311 1248 1273 -3 1286 1311 1273 -3 246 801 250 -3 1322 314 278 -3 1019 1572 1036 -3 307 748 608 -3 182 307 608 -3 1321 443 273 -3 471 1294 636 -3 215 1296 586 -3 1322 278 265 -3 542 701 1129 -3 1101 1284 1278 -3 39 783 785 -3 1304 400 1286 -3 400 1311 1286 -3 1339 244 1200 -3 1324 309 726 -3 674 602 683 -3 265 237 1322 -3 1653 1487 1470 -3 446 36 330 -3 1321 22 443 -3 1277 1267 1290 -3 1290 1308 1307 -3 1313 309 1324 -3 467 68 97 -3 1312 1279 1304 -3 367 1331 335 -3 524 330 1287 -3 1347 1348 471 -3 1308 1315 1307 -3 1365 1529 1108 -3 531 530 784 -3 123 531 784 -3 1041 556 1311 -3 666 1041 1311 -3 312 367 335 -3 1705 1707 1711 -3 690 1324 725 -3 1331 367 439 -3 710 1284 1101 -3 608 748 758 -3 170 699 169 -3 1308 1309 1315 -3 1368 1362 1371 -3 306 1200 244 -3 1279 1299 1304 -3 1304 1299 400 -3 666 1311 400 -3 251 283 237 -3 1853 1866 1871 -3 1312 963 1279 -3 1101 1279 963 -3 1314 1321 273 -3 699 1229 169 -3 1268 1290 1267 -3 1290 1309 1308 -3 386 1320 1315 -3 1320 386 1315 -3 314 1327 370 -3 542 156 701 -3 475 1486 1684 -3 1297 1185 528 -3 1031 916 60 -3 1297 1310 1185 -3 158 1321 1314 -3 1379 1305 1306 -3 553 420 506 -3 291 1342 782 -3 608 758 1041 -3 666 608 1041 -3 1635 1452 1453 -3 60 916 528 -3 916 1297 528 -3 1314 1287 158 -3 601 471 630 -3 1291 1290 1268 -3 1316 1315 1309 -3 1316 1320 1315 -3 400 608 666 -3 1292 524 1185 -3 187 189 188 -3 68 467 1318 -3 187 188 1303 -3 1281 1291 1268 -3 1290 1291 1309 -3 1320 1316 386 -3 1278 385 1299 -3 1279 1278 1299 -3 385 307 400 -3 1299 385 400 -3 307 182 400 -3 400 182 608 -3 801 208 430 -3 243 547 205 -3 1292 1185 1310 -3 1324 726 725 -3 699 170 105 -3 105 68 1318 -3 699 105 1318 -3 1316 1325 386 -3 1325 1187 386 -3 1096 1587 1114 -3 515 208 801 -3 1287 1314 524 -3 1287 219 158 -3 1541 1546 1545 -3 1540 1541 1545 -3 1361 519 1520 -3 570 1129 701 -3 785 1340 884 -3 176 903 127 -3 1232 1226 1233 -3 570 1366 1129 -3 1571 884 1560 -3 378 533 1432 -3 210 570 533 -3 378 210 533 -3 570 210 1366 -3 210 290 1129 -3 1366 210 1129 -3 1129 290 542 -3 290 909 542 -3 290 960 909 -3 124 697 290 -3 210 124 290 -3 697 457 290 -3 290 457 960 -3 960 457 1217 -3 378 124 210 -3 1477 1420 1006 -3 591 378 597 -3 1165 591 597 -3 378 591 124 -3 124 457 697 -3 124 1394 457 -3 1653 1470 1452 -3 1377 1378 1388 -3 1199 1048 1231 -3 124 350 1394 -3 1394 350 457 -3 1048 1165 1231 -3 1048 671 591 -3 1165 1048 591 -3 671 350 124 -3 591 671 124 -3 350 69 457 -3 98 467 97 -3 827 155 1880 -3 1544 1545 1157 -3 176 173 18 -3 1273 700 1260 -3 1369 1048 1199 -3 671 588 350 -3 1545 1546 1204 -3 1546 640 1204 -3 607 247 231 -3 1278 1279 1101 -3 154 1081 1513 -3 1777 1770 1785 -3 1295 499 143 -3 1850 1849 1834 -3 1199 732 1369 -3 732 1183 1369 -3 926 1048 1369 -3 1183 926 1369 -3 926 635 671 -3 1048 926 671 -3 671 635 588 -3 635 1251 350 -3 588 635 350 -3 1449 1472 1468 -3 1490 1489 1472 -3 1425 1074 1389 -3 1198 494 1065 -3 758 718 759 -3 1449 1468 1472 -3 1260 700 1317 -3 732 926 1183 -3 1449 1451 1468 -3 1468 1451 1472 -3 1490 538 1489 -3 272 406 952 -3 1183 926 732 -3 926 1183 635 -3 1426 1435 1434 -3 1449 1450 1451 -3 1421 1422 1426 -3 1426 1422 1435 -3 1469 1486 1490 -3 1472 1469 1490 -3 1183 455 635 -3 1435 1450 1449 -3 1434 1435 1449 -3 1451 1469 1472 -3 475 538 1490 -3 1486 475 1490 -3 475 664 538 -3 250 289 538 -3 664 250 538 -3 306 260 575 -3 455 1183 732 -3 1169 455 732 -3 455 469 635 -3 469 1256 1251 -3 635 469 1251 -3 1204 1389 1074 -3 1319 1381 1382 -3 1364 1370 1085 -3 1329 1396 1381 -3 1330 435 1329 -3 1444 1451 1450 -3 1435 1444 1450 -3 1520 519 1120 -3 1505 1120 1326 -3 640 883 1425 -3 1357 1364 1355 -3 1357 1370 1364 -3 1357 1211 1370 -3 1225 1245 1448 -3 1408 1423 1422 -3 1411 1408 1422 -3 1423 1436 1435 -3 1422 1423 1435 -3 1436 1437 1444 -3 1435 1436 1444 -3 1437 1452 1451 -3 1444 1437 1451 -3 1452 1470 1469 -3 1451 1452 1469 -3 1469 1470 1486 -3 1486 1674 1487 -3 1413 980 1420 -3 1470 1487 1486 -3 1537 154 1105 -3 1393 1054 1169 -3 668 455 1169 -3 1054 668 1169 -3 668 735 469 -3 455 668 469 -3 1455 1445 1446 -3 1185 524 298 -3 459 552 38 -3 1731 1739 1722 -3 1376 1211 1357 -3 1409 1408 1398 -3 1427 1437 1436 -3 1423 1427 1436 -3 1403 1388 1404 -3 84 1367 1363 -3 596 556 1041 -3 714 1185 298 -3 1004 1054 1393 -3 1210 574 399 -3 1320 1307 1315 -3 1635 1453 1438 -3 1359 1357 1356 -3 1358 1359 1356 -3 1377 1376 1357 -3 1359 1377 1357 -3 1388 1211 1376 -3 1377 1388 1376 -3 1402 1409 1398 -3 1388 1398 1211 -3 1402 1408 1409 -3 1402 1424 1423 -3 1408 1402 1423 -3 1423 1424 1427 -3 1424 1438 1437 -3 1427 1424 1437 -3 1438 1453 1452 -3 1437 1438 1452 -3 1197 828 650 -3 1111 1511 1510 -3 1300 1319 1382 -3 1010 808 539 -3 208 1198 430 -3 1200 459 38 -3 1539 1540 1544 -3 1507 1094 1405 -3 1094 976 1405 -3 475 515 801 -3 533 378 1432 -3 744 491 668 -3 1054 744 668 -3 491 101 735 -3 668 491 735 -3 384 459 1200 -3 306 384 1200 -3 1512 1197 650 -3 7 71 103 -3 1466 1295 1074 -3 1325 1328 1187 -3 1329 428 1328 -3 1507 1405 1397 -3 1120 897 1184 -3 1388 1403 1402 -3 1110 859 576 -3 1431 1110 576 -3 399 1212 744 -3 1363 800 153 -3 575 384 306 -3 1178 1100 1512 -3 1425 883 1074 -3 733 84 1363 -3 55 54 87 -3 1296 1300 1282 -3 1378 1377 1359 -3 1004 715 414 -3 1462 1479 1478 -3 1479 1492 222 -3 1478 1479 222 -3 1492 30 179 -3 222 1492 179 -3 30 351 179 -3 1544 1157 154 -3 429 297 709 -3 1110 1483 1475 -3 86 306 391 -3 700 159 1498 -3 1317 700 1498 -3 205 467 540 -3 828 518 650 -3 1672 1462 1473 -3 399 574 1212 -3 574 634 744 -3 1212 574 744 -3 634 1237 491 -3 744 634 491 -3 1367 714 1363 -3 375 606 112 -3 375 82 606 -3 82 86 391 -3 1457 1181 640 -3 1546 1457 640 -3 1479 1493 1492 -3 1493 258 30 -3 1492 1493 30 -3 429 1248 297 -3 39 375 199 -3 336 181 149 -3 1439 1511 1111 -3 1684 515 475 -3 1483 1317 1475 -3 1317 1498 1475 -3 429 342 159 -3 700 429 159 -3 1510 1052 1179 -3 1181 1130 883 -3 640 1181 883 -3 1405 980 1413 -3 1140 964 1181 -3 1509 1439 1517 -3 1479 1480 1493 -3 403 351 30 -3 258 403 30 -3 390 389 1121 -3 1400 897 1298 -3 604 272 709 -3 1460 749 603 -3 403 523 351 -3 1249 329 642 -3 1390 1466 883 -3 1382 1381 1270 -3 1363 714 800 -3 342 429 709 -3 540 375 1047 -3 297 604 709 -3 1467 1461 1201 -3 1130 1390 883 -3 1374 1454 1515 -3 1462 1480 1479 -3 1136 523 403 -3 964 1441 1181 -3 1059 1522 1128 -3 1003 221 500 -3 976 1003 500 -3 1100 1197 1512 -3 390 25 43 -3 1407 1416 1415 -3 1406 1407 1415 -3 1455 1446 1458 -3 1446 1463 1462 -3 1458 1446 1462 -3 1463 1464 1462 -3 1464 1481 1480 -3 1462 1464 1480 -3 1481 1494 1493 -3 1480 1481 1493 -3 1494 994 258 -3 1493 1494 258 -3 456 403 258 -3 994 456 258 -3 621 1136 403 -3 456 621 403 -3 621 523 1136 -3 621 745 523 -3 141 473 523 -3 745 141 523 -3 1516 1524 1476 -3 1128 245 1471 -3 1155 321 634 -3 574 1155 634 -3 599 681 202 -3 298 524 273 -3 681 236 202 -3 1368 1371 1527 -3 1263 1254 1540 -3 1502 1524 1476 -3 1476 1046 1115 -3 321 454 1237 -3 634 321 1237 -3 541 467 205 -3 467 97 540 -3 98 97 467 -3 236 84 733 -3 1446 1464 1463 -3 621 141 745 -3 1516 1476 1503 -3 1467 1201 828 -3 174 639 142 -3 202 236 733 -3 1686 1703 1702 -3 1494 1495 994 -3 1495 1123 994 -3 516 141 621 -3 1037 1059 1128 -3 590 467 541 -3 701 156 1164 -3 1398 1408 1383 -3 493 1301 322 -3 639 321 1155 -3 1429 1446 1445 -3 1481 1495 1494 -3 1220 456 994 -3 1123 1220 994 -3 954 322 495 -3 1373 493 322 -3 987 321 639 -3 260 306 86 -3 1370 1384 1383 -3 1280 1305 1362 -3 1305 1371 1362 -3 1305 1379 1371 -3 1392 1386 1371 -3 1392 1395 1386 -3 1395 1407 1386 -3 1395 1417 1416 -3 1407 1395 1416 -3 1703 1694 1704 -3 1428 1430 1429 -3 1430 1442 1446 -3 1429 1430 1446 -3 1442 1459 1464 -3 1446 1442 1464 -3 1459 1482 1481 -3 1464 1459 1481 -3 1482 1488 1481 -3 1488 1496 1495 -3 1481 1488 1495 -3 1496 468 1123 -3 1495 1496 1123 -3 637 1220 1123 -3 468 637 1123 -3 637 456 1220 -3 637 1203 456 -3 161 621 456 -3 1203 161 456 -3 75 516 621 -3 161 75 621 -3 1687 1694 1703 -3 75 34 495 -3 954 495 34 -3 34 32 322 -3 954 34 322 -3 32 47 322 -3 47 1373 322 -3 47 493 1373 -3 47 183 493 -3 183 1055 493 -3 1055 1012 174 -3 1012 639 174 -3 959 987 639 -3 1012 959 639 -3 959 321 987 -3 959 346 321 -3 346 454 321 -3 1341 1229 541 -3 1229 699 541 -3 699 1318 590 -3 541 699 590 -3 637 161 1203 -3 1615 1635 1438 -3 1300 1296 1319 -3 1379 1395 1392 -3 1615 1438 1424 -3 1613 1615 1424 -3 75 1007 34 -3 1229 1341 336 -3 700 1273 1248 -3 1392 1395 1379 -3 70 161 637 -3 183 1012 1055 -3 1673 1184 1504 -3 1159 1504 1184 -3 1266 346 959 -3 1604 1613 1603 -3 1459 1442 1456 -3 1075 1502 1503 -3 221 1100 500 -3 677 1084 1092 -3 1230 1224 677 -3 1537 1544 154 -3 1105 1097 1088 -3 1121 1105 1088 -3 1146 1346 767 -3 1087 293 176 -3 1100 1467 1197 -3 1154 585 1209 -3 962 1032 1065 -3 1765 1759 1024 -3 1408 1501 1383 -3 1516 1502 1524 -3 143 499 519 -3 1147 1142 1126 -3 1074 1094 680 -3 1399 897 1400 -3 1087 176 366 -3 235 1087 653 -3 897 1399 1184 -3 1149 1135 1061 -3 1685 1687 1360 -3 1379 1392 1371 -3 1810 259 242 -3 293 448 176 -3 1521 1537 1105 -3 235 653 677 -3 1100 1361 1467 -3 373 1538 1537 -3 1514 585 1059 -3 1059 585 341 -3 462 796 1023 -3 964 1106 1419 -3 1505 1326 1201 -3 711 63 1514 -3 964 1140 1092 -3 340 780 868 -3 796 1037 1128 -3 1037 127 796 -3 127 1037 796 -3 18 903 127 -3 1059 341 1522 -3 1508 366 1098 -3 1410 176 127 -3 293 1087 235 -3 1117 187 1876 -3 366 1508 1106 -3 1399 1159 1184 -3 1399 1400 1252 -3 1170 1099 1142 -3 1410 1037 1098 -3 903 18 127 -3 1383 1384 1211 -3 1522 341 1154 -3 1120 1505 1201 -3 1087 366 653 -3 1060 1135 1485 -3 964 1419 1130 -3 293 235 1224 -3 1244 1092 1457 -3 1545 1204 1157 -3 1252 1471 1399 -3 366 964 653 -3 1525 1126 1142 -3 160 360 1173 -3 366 176 1098 -3 499 1401 1298 -3 1539 1544 1537 -3 677 653 1084 -3 176 18 903 -3 199 375 112 -3 1520 1120 1461 -3 644 1539 1538 -3 80 1535 216 -3 176 1410 1098 -3 1140 1181 1457 -3 462 1098 796 -3 1541 1457 1546 -3 1361 1520 1467 -3 1467 1520 1461 -3 373 644 1538 -3 1106 462 781 -3 1591 834 67 -3 390 594 360 -3 160 390 360 -3 1254 1247 1541 -3 1075 1503 980 -3 903 711 127 -3 181 263 276 -3 444 1083 291 -3 1538 1539 1537 -3 1419 1106 1390 -3 519 1361 143 -3 216 1535 1521 -3 1094 976 680 -3 1441 1130 1181 -3 1006 672 1385 -3 1060 1485 1149 -3 43 389 390 -3 181 809 263 -3 1120 1201 1461 -3 1130 1419 1390 -3 1081 680 1507 -3 1231 1165 597 -3 809 1083 263 -3 964 366 1106 -3 809 181 336 -3 809 291 1083 -3 496 1506 1046 -3 650 496 1046 -3 390 1121 594 -3 1295 1003 1074 -3 1832 1845 1831 -3 1204 640 1389 -3 341 585 1154 -3 1081 1507 1082 -3 511 1884 569 -3 1197 1467 828 -3 1341 809 336 -3 1094 680 976 -3 1540 1545 1544 -3 1398 1388 1402 -3 594 1121 1088 -3 1233 1099 1189 -3 1502 1516 1503 -3 1506 1344 1115 -3 291 1137 1342 -3 1097 1513 1082 -3 1412 812 123 -3 498 831 812 -3 1412 498 812 -3 883 1466 1074 -3 1006 1420 962 -3 1399 1471 1159 -3 962 672 1006 -3 1118 1091 702 -3 1686 1687 1703 -3 653 964 1084 -3 1735 1756 1747 -3 1 470 1536 -3 127 1059 1037 -3 1046 1506 1115 -3 1288 1006 1385 -3 1044 1288 1385 -3 1147 1171 1170 -3 1170 1142 1147 -3 1137 291 1346 -3 808 1008 1011 -3 1159 245 1504 -3 672 962 1065 -3 1390 1106 781 -3 1390 1156 1466 -3 1466 1156 1295 -3 1015 1016 1021 -3 644 1540 1539 -3 1137 1533 1542 -3 1088 1089 1288 -3 594 1088 1288 -3 1721 1746 1729 -3 360 594 1044 -3 594 1288 1044 -3 245 1108 1504 -3 216 1521 389 -3 1370 1211 1384 -3 1089 1006 1288 -3 461 587 513 -3 513 587 1351 -3 1351 1414 1412 -3 1091 498 1412 -3 1414 1091 1412 -3 1115 1530 538 -3 1092 1140 1457 -3 1509 1090 1534 -3 1137 1146 1533 -3 1349 461 1547 -3 767 1 1064 -3 1529 1365 1195 -3 964 1130 1441 -3 1351 587 1414 -3 1115 538 289 -3 1405 1413 1397 -3 1513 1081 1082 -3 980 514 1420 -3 680 1094 1507 -3 461 1414 587 -3 1106 1508 462 -3 1052 1370 1179 -3 1457 1541 1247 -3 587 1414 461 -3 1420 514 962 -3 545 1201 1326 -3 63 585 1514 -3 1105 154 1097 -3 1064 1533 1146 -3 1414 587 461 -3 973 1414 587 -3 1414 973 587 -3 250 1476 289 -3 1157 1204 680 -3 1398 1383 1211 -3 1507 1397 1082 -3 1543 1349 1533 -3 1536 1543 1533 -3 1543 410 461 -3 1349 1543 461 -3 973 1141 1414 -3 1141 1091 1414 -3 1476 1115 289 -3 1084 964 1092 -3 373 1537 1521 -3 1521 1105 1121 -3 1476 250 1274 -3 1149 1525 1142 -3 1254 1541 1540 -3 1064 1 1533 -3 1082 1397 1089 -3 1088 1082 1089 -3 80 373 1521 -3 1535 80 1521 -3 1341 541 547 -3 39 199 783 -3 1536 1533 1 -3 973 1414 461 -3 410 973 461 -3 1397 1413 1420 -3 1089 1397 1420 -3 1111 1383 1501 -3 1503 1476 1274 -3 606 82 391 -3 780 38 868 -3 1135 1104 1061 -3 711 1514 1059 -3 1365 1194 1195 -3 1111 1510 1179 -3 1485 1135 1149 -3 796 1128 1252 -3 1228 293 1224 -3 644 1263 1540 -3 390 160 25 -3 63 33 104 -3 391 306 606 -3 306 244 606 -3 1097 154 1513 -3 494 672 1065 -3 1543 618 410 -3 537 973 410 -3 618 537 410 -3 1141 1352 702 -3 972 992 991 -3 1509 1534 1439 -3 1088 1097 1082 -3 1401 1023 1298 -3 53 569 1884 -3 1536 470 1543 -3 1410 127 1037 -3 1227 293 1228 -3 1128 1522 245 -3 1522 1154 245 -3 1850 1870 1849 -3 796 1252 1023 -3 173 83 33 -3 1543 470 618 -3 1242 69 1251 -3 1515 1527 1371 -3 1162 1135 1060 -3 1188 537 618 -3 1109 973 537 -3 1109 1141 973 -3 1109 1352 1141 -3 545 518 828 -3 1201 545 828 -3 1244 1457 1247 -3 1386 1515 1371 -3 1454 1518 1499 -3 1089 1477 1006 -3 462 1401 781 -3 1401 499 781 -3 63 433 585 -3 1886 1066 304 -3 1204 1074 680 -3 127 711 1059 -3 640 1425 1389 -3 1188 618 537 -3 499 1298 519 -3 1226 1060 1099 -3 1233 1226 1099 -3 1515 1454 1386 -3 1298 897 1120 -3 519 1298 1120 -3 1188 537 618 -3 1524 1502 1046 -3 1178 980 550 -3 1178 1512 1075 -3 1515 1386 1391 -3 1386 1454 1515 -3 1149 1142 1099 -3 1060 1149 1099 -3 1508 1098 462 -3 1401 462 1023 -3 1178 1075 980 -3 552 868 459 -3 1061 1525 1149 -3 1098 1037 796 -3 1524 1502 1476 -3 1476 1524 1046 -3 1828 1829 1834 -3 1089 1420 1477 -3 1352 672 494 -3 1502 1512 650 -3 1252 1128 1471 -3 1531 1518 1454 -3 1374 1531 1454 -3 1512 1502 1075 -3 1173 618 470 -3 160 1173 470 -3 1173 1188 618 -3 1173 360 1188 -3 1188 360 537 -3 360 1044 537 -3 537 1044 1109 -3 1044 1385 1109 -3 672 1352 1109 -3 1385 672 1109 -3 511 517 1560 -3 1390 781 1156 -3 223 222 178 -3 831 123 812 -3 141 1333 1618 -3 1812 1829 1828 -3 115 1005 1210 -3 1636 1637 1656 -3 1515 1454 1527 -3 1682 538 1530 -3 1637 1657 1656 -3 1072 1525 1061 -3 1071 1072 1061 -3 548 1350 142 -3 1072 1592 1525 -3 1487 1674 1684 -3 67 937 1010 -3 1754 1784 1762 -3 1462 1478 1473 -3 1137 1542 778 -3 1614 1637 1616 -3 1036 1572 1049 -3 1049 1584 1072 -3 1072 1584 1592 -3 1126 1525 1592 -3 1584 1126 1592 -3 199 606 783 -3 1499 1362 1368 -3 1680 1678 1679 -3 1049 1586 1584 -3 799 178 1558 -3 702 494 1198 -3 1499 1368 1527 -3 868 552 459 -3 1486 1487 1674 -3 1572 1584 1586 -3 1049 1572 1586 -3 779 702 1198 -3 1799 1812 1795 -3 1618 1333 141 -3 1662 1676 1675 -3 805 1350 548 -3 1026 1570 1572 -3 1572 1073 1584 -3 1073 1078 1584 -3 1112 1126 1584 -3 1078 1112 1584 -3 1617 1620 1416 -3 1676 560 483 -3 1675 1676 483 -3 1659 1678 1663 -3 1572 1570 1073 -3 1054 1004 399 -3 827 1880 1870 -3 1404 1590 1604 -3 1374 1515 1391 -3 1345 472 498 -3 802 1555 1519 -3 1655 1675 1674 -3 1416 1614 1415 -3 1407 1406 1386 -3 482 560 1676 -3 1678 1677 1663 -3 1146 1137 1346 -3 1026 1562 1570 -3 1562 1570 1572 -3 1570 1562 1572 -3 1677 482 1676 -3 547 1556 798 -3 701 734 570 -3 1589 1404 1603 -3 1641 1638 1634 -3 1639 1641 1634 -3 1657 1658 1662 -3 260 261 575 -3 156 701 1164 -3 1639 1634 1621 -3 1638 1658 1657 -3 1637 1638 1657 -3 1519 1118 702 -3 1415 1605 1590 -3 779 1519 702 -3 1406 1415 1590 -3 1663 1677 1662 -3 1641 1659 1638 -3 1658 1663 1662 -3 1635 1636 1654 -3 1562 1073 1570 -3 1687 1686 1439 -3 1047 375 39 -3 1621 1620 1617 -3 738 1519 779 -3 483 515 1674 -3 473 1333 531 -3 481 473 531 -3 1155 142 639 -3 1662 1675 1655 -3 1656 1662 1655 -3 1038 1045 1073 -3 1562 1038 1073 -3 222 179 178 -3 1428 1621 1617 -3 1675 483 1674 -3 1159 1471 245 -3 1365 245 1154 -3 1209 1365 1154 -3 245 1365 1108 -3 1637 1636 1616 -3 1416 1620 1614 -3 1638 1637 1614 -3 884 1340 1884 -3 1049 1043 1036 -3 1605 1616 1607 -3 1620 1638 1614 -3 1455 1428 1445 -3 1622 1529 1195 -3 1177 1622 1195 -3 550 976 500 -3 1587 1523 1119 -3 1428 1455 1639 -3 1096 1079 1080 -3 553 536 563 -3 1404 1604 1603 -3 1153 1622 1177 -3 641 638 661 -3 1013 1020 1038 -3 1051 1114 1096 -3 1080 1051 1096 -3 1114 1587 1096 -3 1556 243 798 -3 1532 1623 1622 -3 1153 1532 1622 -3 1642 1529 1622 -3 1623 1642 1622 -3 1642 1504 1108 -3 1529 1642 1108 -3 1378 1404 1388 -3 178 179 1559 -3 1455 1473 1641 -3 1653 1655 1674 -3 805 530 531 -3 33 18 173 -3 1605 1604 1590 -3 179 1259 1559 -3 1051 1587 1114 -3 1118 1345 1091 -3 851 523 532 -3 715 732 1167 -3 1636 1655 1654 -3 1621 1634 1620 -3 1093 1280 1362 -3 1051 1114 1587 -3 1604 1605 1607 -3 1022 1563 1051 -3 1030 1022 1051 -3 1563 1573 1114 -3 1051 1563 1114 -3 1573 1585 1587 -3 1114 1573 1587 -3 1585 1599 1523 -3 1587 1585 1523 -3 1599 1608 1532 -3 1523 1599 1532 -3 1608 1624 1623 -3 1532 1608 1623 -3 1643 1642 1623 -3 1624 1643 1623 -3 1643 1673 1504 -3 1642 1643 1504 -3 551 547 798 -3 1014 1016 1015 -3 1306 1307 1379 -3 805 548 525 -3 1656 1655 1636 -3 1333 805 531 -3 1683 1184 1673 -3 1608 1625 1624 -3 1644 1643 1624 -3 1625 1644 1624 -3 1664 1673 1643 -3 1644 1664 1643 -3 1023 1128 1252 -3 585 854 1209 -3 1351 1412 123 -3 322 1301 495 -3 799 844 474 -3 516 495 141 -3 1555 1345 1118 -3 495 1618 141 -3 1047 205 540 -3 141 1333 473 -3 1433 1426 1434 -3 597 378 1063 -3 1528 1564 1563 -3 1022 1528 1563 -3 1564 1574 1573 -3 1563 1564 1573 -3 1573 1574 1585 -3 1574 1576 1585 -3 1585 1576 1599 -3 1576 1600 1599 -3 1600 1609 1608 -3 1599 1600 1608 -3 1609 1626 1625 -3 1608 1609 1625 -3 1645 1644 1625 -3 1626 1645 1625 -3 1645 1665 1664 -3 1644 1645 1664 -3 1665 1673 1664 -3 1665 1326 1683 -3 1673 1665 1683 -3 1326 1184 1683 -3 1590 1404 1378 -3 1614 1616 1605 -3 1415 1614 1605 -3 495 1333 1618 -3 738 802 1519 -3 1473 1659 1641 -3 1301 805 1333 -3 205 206 517 -3 1405 976 550 -3 495 1301 1333 -3 1593 1601 1600 -3 1576 1593 1600 -3 1600 1601 1609 -3 716 208 515 -3 500 1178 550 -3 1259 523 851 -3 1559 1259 851 -3 831 481 812 -3 513 1349 1547 -3 1616 1636 1635 -3 222 223 1680 -3 1301 493 1350 -3 805 1301 1350 -3 1548 1552 1528 -3 1552 1565 1564 -3 1528 1552 1564 -3 1564 1565 1574 -3 1574 1565 1576 -3 1565 1577 1576 -3 1594 1593 1576 -3 1577 1594 1576 -3 1602 1601 1593 -3 1594 1602 1593 -3 1602 1610 1609 -3 1601 1602 1609 -3 1610 1627 1626 -3 1609 1610 1626 -3 1627 1646 1645 -3 1626 1627 1645 -3 1666 1665 1645 -3 1646 1666 1645 -3 1666 545 1326 -3 1665 1666 1326 -3 483 716 515 -3 547 243 1556 -3 221 1003 1295 -3 143 221 1295 -3 809 1341 547 -3 551 809 547 -3 782 1342 778 -3 731 782 778 -3 1458 1660 1455 -3 752 309 753 -3 1424 1402 1603 -3 1519 1555 1118 -3 1549 1553 1552 -3 1552 1553 1565 -3 1775 1799 1784 -3 1406 1590 1378 -3 493 174 142 -3 1350 493 142 -3 1656 1657 1662 -3 291 809 551 -3 731 778 513 -3 523 473 481 -3 1365 1209 1194 -3 1346 291 551 -3 784 731 513 -3 1550 1554 1553 -3 1549 1550 1553 -3 1566 1565 1553 -3 1554 1566 1553 -3 1566 1578 1577 -3 1565 1566 1577 -3 1578 1579 1577 -3 1577 1579 1594 -3 1579 1595 1602 -3 1594 1579 1602 -3 1595 1611 1610 -3 1602 1595 1610 -3 1628 1627 1610 -3 1611 1628 1610 -3 1628 1647 1646 -3 1627 1628 1646 -3 1647 1667 1666 -3 1646 1647 1666 -3 1667 1668 1666 -3 518 545 1666 -3 1668 518 1666 -3 1074 1003 1094 -3 1607 1616 1615 -3 123 784 513 -3 1499 1527 1454 -3 1604 1607 1615 -3 1566 1579 1578 -3 1628 1648 1647 -3 1648 1668 1667 -3 1647 1648 1667 -3 1681 518 1668 -3 778 1533 1349 -3 513 778 1349 -3 496 650 497 -3 1615 1616 1635 -3 1429 1445 1428 -3 718 758 748 -3 1678 1680 474 -3 1680 223 474 -3 778 1542 1533 -3 206 205 1047 -3 1478 222 1680 -3 1679 1678 1659 -3 857 831 498 -3 1386 1406 1391 -3 1360 1090 1554 -3 1550 1360 1554 -3 1567 1566 1554 -3 1090 1567 1554 -3 1567 1580 1579 -3 1566 1567 1579 -3 1580 1596 1595 -3 1579 1580 1595 -3 1596 1606 1611 -3 1595 1596 1611 -3 1606 1629 1628 -3 1611 1606 1628 -3 1629 1630 1628 -3 1630 1649 1648 -3 1628 1630 1648 -3 1649 1526 1668 -3 1648 1649 1668 -3 496 1681 1668 -3 1526 496 1668 -3 497 518 1681 -3 496 497 1681 -3 518 497 650 -3 1005 574 1210 -3 123 513 1351 -3 1877 1876 1865 -3 1558 1555 802 -3 799 1558 802 -3 472 857 498 -3 1455 1641 1639 -3 1634 1638 1620 -3 482 802 738 -3 1248 429 700 -3 1654 1655 1653 -3 1606 1630 1629 -3 1473 1478 1680 -3 1362 1499 1557 -3 1558 857 472 -3 1120 1184 1326 -3 857 851 831 -3 844 802 482 -3 474 844 482 -3 1555 1558 472 -3 844 799 802 -3 1342 1137 778 -3 1649 1669 1526 -3 1669 1506 496 -3 1526 1669 496 -3 1421 1411 1422 -3 851 532 481 -3 780 340 383 -3 1008 780 383 -3 1568 1567 1090 -3 1509 1568 1090 -3 1568 1581 1580 -3 1567 1568 1580 -3 1597 1596 1580 -3 1581 1597 1580 -3 1596 1597 1606 -3 1597 1612 1606 -3 1612 1631 1630 -3 1606 1612 1630 -3 1631 1650 1649 -3 1630 1631 1649 -3 1649 1650 1669 -3 1678 482 1677 -3 560 738 716 -3 1345 498 1091 -3 500 1100 1178 -3 1678 474 482 -3 1009 878 53 -3 1841 1855 1851 -3 1454 1527 1499 -3 827 107 1864 -3 495 516 75 -3 208 716 1198 -3 1428 1639 1621 -3 1771 1280 1093 -3 842 1008 808 -3 378 533 1063 -3 1582 1581 1568 -3 1659 1663 1658 -3 1865 1864 1851 -3 1503 514 980 -3 1583 1582 1568 -3 1588 1581 1582 -3 1583 1588 1582 -3 1598 1597 1581 -3 1588 1598 1581 -3 1433 1612 1597 -3 1433 1619 1612 -3 1632 1631 1612 -3 1619 1632 1612 -3 1651 1650 1631 -3 1632 1651 1631 -3 1651 1670 1669 -3 1650 1651 1669 -3 1670 1344 1506 -3 1669 1670 1506 -3 1660 1473 1455 -3 1353 842 808 -3 995 1353 808 -3 1353 1008 842 -3 1353 842 1008 -3 38 780 1008 -3 842 38 1008 -3 1517 1569 1568 -3 1509 1517 1568 -3 1569 1583 1568 -3 716 779 1198 -3 716 738 779 -3 560 482 738 -3 1360 1687 1534 -3 1353 38 842 -3 1111 1179 1383 -3 1598 1433 1597 -3 868 38 552 -3 1045 1078 1073 -3 1124 406 272 -3 1433 1632 1619 -3 474 223 1122 -3 1033 1765 1024 -3 1378 1359 1374 -3 1269 1270 1281 -3 291 782 444 -3 483 560 716 -3 1462 1473 1660 -3 499 1156 781 -3 1214 542 909 -3 1555 472 1345 -3 178 1559 1558 -3 851 481 831 -3 1269 1281 1268 -3 824 1856 1846 -3 53 1884 1009 -3 1439 1111 1517 -3 1111 1501 1569 -3 1517 1111 1569 -3 1411 1583 1569 -3 1411 1588 1583 -3 1411 1421 1588 -3 1421 1598 1588 -3 1421 1426 1598 -3 1426 1433 1598 -3 1434 1433 1598 -3 1433 1434 1598 -3 1633 1632 1433 -3 1434 1633 1433 -3 1633 1640 1632 -3 1652 1651 1632 -3 1640 1652 1632 -3 1671 1670 1651 -3 1652 1671 1651 -3 1671 1682 1344 -3 1670 1671 1344 -3 1274 1032 514 -3 1503 1274 514 -3 532 523 481 -3 1319 264 277 -3 546 806 1591 -3 546 995 806 -3 546 746 995 -3 1339 1353 995 -3 746 1339 995 -3 1339 1200 38 -3 1353 1339 38 -3 223 178 799 -3 1530 1344 1682 -3 1449 1633 1434 -3 399 744 1054 -3 831 812 123 -3 1122 223 799 -3 243 205 517 -3 1473 1679 1659 -3 1024 1034 1033 -3 1591 1340 546 -3 1501 1411 1569 -3 1156 499 1295 -3 1449 1640 1633 -3 1209 953 854 -3 1458 1462 1660 -3 1224 235 677 -3 1523 1153 1119 -3 1085 1355 1364 -3 1468 1652 1640 -3 1449 1468 1640 -3 1489 1671 1652 -3 1468 1489 1652 -3 1671 1489 1682 -3 1489 538 1682 -3 1836 1857 1844 -3 803 189 1117 -3 1685 1696 1695 -3 1785 1791 1801 -3 1808 1801 1791 -3 1791 1792 1815 -3 1751 1750 1735 -3 1843 1862 1842 -3 1210 444 115 -3 1800 1816 1799 -3 1803 1821 1802 -3 995 834 1591 -3 758 759 1182 -3 1836 1858 1857 -3 810 168 1857 -3 1858 810 1857 -3 1740 1757 1764 -3 873 872 865 -3 1808 1815 1801 -3 1815 1819 1801 -3 804 803 1117 -3 1741 1757 1740 -3 1793 865 1788 -3 1812 1816 1830 -3 804 1117 1878 -3 1561 1725 1726 -3 1857 168 824 -3 1757 1779 1764 -3 1764 1779 1786 -3 78 815 1868 -3 1822 1821 1803 -3 1717 1737 1721 -3 1844 1857 1846 -3 1725 1724 1013 -3 824 168 79 -3 1713 1718 1696 -3 1715 1714 1699 -3 1722 1730 1711 -3 1843 1842 1825 -3 1819 1843 1825 -3 1857 824 1846 -3 1821 1827 1826 -3 1809 1821 1826 -3 1815 1843 1819 -3 1821 1809 1802 -3 1548 1689 1549 -3 1733 1561 1562 -3 1733 1725 1561 -3 604 599 406 -3 406 599 202 -3 1822 1836 1821 -3 815 1881 1867 -3 1852 1855 1830 -3 1699 1706 1016 -3 54 55 845 -3 158 219 521 -3 1742 1741 1725 -3 1733 1742 1725 -3 1763 1777 1785 -3 1033 1788 1765 -3 1769 1776 1749 -3 1749 1755 1734 -3 1756 1769 1747 -3 1732 1751 1735 -3 1707 1714 1722 -3 1738 1754 1737 -3 1876 1864 1865 -3 1722 1714 1731 -3 865 1810 1787 -3 1788 865 1787 -3 1715 1732 1714 -3 1742 1757 1741 -3 1804 1803 1786 -3 1779 1804 1786 -3 1770 1791 1785 -3 1806 1810 242 -3 1722 1747 1730 -3 1705 1706 1707 -3 1804 1805 1803 -3 1835 1843 1815 -3 1346 551 1883 -3 1802 1809 1792 -3 1837 1836 1822 -3 1017 1837 1822 -3 1878 1117 1877 -3 1711 1730 1713 -3 1690 1706 1705 -3 1837 136 1836 -3 1830 1855 1841 -3 1868 1867 1856 -3 599 20 681 -3 136 1858 1836 -3 1791 1815 1808 -3 1024 1759 1018 -3 1730 1734 1713 -3 1785 1790 1756 -3 20 596 681 -3 1831 1830 1817 -3 1797 1802 1792 -3 1864 1876 827 -3 1881 815 814 -3 1787 1806 1781 -3 1116 916 1031 -3 814 1882 1872 -3 1711 1713 1697 -3 1110 1475 859 -3 1690 1705 1698 -3 1785 1801 1790 -3 1765 1787 1759 -3 596 20 556 -3 596 1180 681 -3 681 1180 1031 -3 1882 804 1872 -3 1698 1711 1697 -3 1759 1781 1758 -3 900 1883 979 -3 1696 1717 1704 -3 1026 1561 1562 -3 1769 1796 1776 -3 1013 1723 1715 -3 1734 1717 1718 -3 1832 1831 1813 -3 1180 316 1116 -3 1031 1180 1116 -3 1561 1742 1733 -3 1882 814 804 -3 1820 1835 1815 -3 1442 988 1447 -3 710 577 622 -3 1810 1806 1787 -3 596 1752 1180 -3 1180 316 1116 -3 316 1180 1116 -3 316 993 916 -3 1116 316 916 -3 1759 1787 1781 -3 1776 1800 1775 -3 1732 1735 1714 -3 1886 409 821 -3 1703 1729 1710 -3 1693 1685 1550 -3 1016 1706 1690 -3 1693 1689 1697 -3 1842 1862 1861 -3 1694 1695 1704 -3 1687 1685 1694 -3 988 382 1447 -3 1447 382 576 -3 747 797 120 -3 1776 1775 1755 -3 1199 1167 732 -3 1041 758 596 -3 596 758 1752 -3 1876 1158 107 -3 1685 1695 1694 -3 1858 818 810 -3 382 1431 576 -3 1693 1697 1696 -3 243 1888 798 -3 1117 189 187 -3 1823 1822 1803 -3 1805 1823 1803 -3 1442 1430 1443 -3 818 1858 136 -3 356 477 424 -3 382 1575 1431 -3 916 993 554 -3 467 590 1318 -3 1685 1693 1696 -3 1845 1866 1853 -3 1431 1575 1110 -3 1182 1752 758 -3 1182 1180 1752 -3 1182 825 1180 -3 1180 825 316 -3 1017 136 1837 -3 1430 1440 1443 -3 1440 908 988 -3 988 908 382 -3 1575 549 1110 -3 549 1150 963 -3 1110 549 963 -3 1825 1813 1814 -3 1796 1817 1800 -3 825 633 316 -3 1699 1714 1706 -3 633 993 316 -3 633 1323 993 -3 1430 1869 1440 -3 908 1575 382 -3 1101 963 1150 -3 1734 1738 1717 -3 1819 1825 1814 -3 1801 1819 1814 -3 633 825 1182 -3 1440 1869 908 -3 908 996 1575 -3 759 787 786 -3 1809 1826 1820 -3 1869 1145 908 -3 549 1101 1150 -3 1723 1732 1715 -3 1428 1847 1430 -3 1145 56 908 -3 908 56 996 -3 1144 1101 549 -3 1809 1820 1815 -3 1793 1788 1033 -3 797 633 1182 -3 759 797 1182 -3 1735 1750 1756 -3 996 56 1575 -3 56 549 1575 -3 1750 1763 1756 -3 1847 1848 1430 -3 1848 1859 1430 -3 1430 1859 1869 -3 56 1168 549 -3 1690 1689 1548 -3 1758 1779 1757 -3 786 797 759 -3 747 633 797 -3 633 747 1323 -3 1323 747 167 -3 865 866 873 -3 1778 1791 1770 -3 78 1868 824 -3 1805 1804 1779 -3 1428 1848 1847 -3 56 1053 1168 -3 1168 1131 1144 -3 549 1168 1144 -3 1877 1117 1876 -3 1707 1722 1711 -3 1731 1735 1739 -3 830 1823 1805 -3 830 1822 1823 -3 1859 1873 1145 -3 1869 1859 1145 -3 1131 1101 1144 -3 1814 1813 1790 -3 830 1017 1822 -3 207 562 561 -3 1772 1771 1093 -3 1557 1772 1093 -3 866 1033 1042 -3 1617 1417 1428 -3 1428 1417 1848 -3 1734 1755 1738 -3 1821 1836 1844 -3 1801 1814 1790 -3 895 797 786 -3 787 759 760 -3 1873 961 1145 -3 1145 961 56 -3 1053 1131 1168 -3 1833 1101 1131 -3 1833 710 1101 -3 1853 1871 1852 -3 1689 1690 1698 -3 1772 1275 1771 -3 1848 1417 1859 -3 242 830 1806 -3 1713 1734 1718 -3 1800 1799 1775 -3 1695 1696 1704 -3 1518 1557 1499 -3 1794 1275 1772 -3 1809 1815 1792 -3 1417 1418 1859 -3 961 951 56 -3 56 951 1053 -3 1833 1131 710 -3 1019 1742 1561 -3 1758 1757 1742 -3 1780 1779 1758 -3 1748 1557 1518 -3 1794 1277 1275 -3 1873 1879 961 -3 951 559 1053 -3 1053 559 1131 -3 1876 107 827 -3 1747 1769 1749 -3 1267 1277 1794 -3 1418 1863 1859 -3 1859 1863 1873 -3 1868 815 1867 -3 1766 1772 1557 -3 1748 1766 1557 -3 866 1793 1033 -3 559 1196 1131 -3 1196 1343 1131 -3 1131 1343 710 -3 1766 1794 1772 -3 180 1229 336 -3 415 1879 1873 -3 415 961 1879 -3 1343 577 710 -3 866 865 1793 -3 1362 1557 1093 -3 1789 1794 1766 -3 1873 1863 415 -3 1456 1442 1447 -3 1018 1742 1019 -3 1743 1748 1518 -3 1531 1743 1518 -3 1789 1267 1794 -3 434 961 415 -3 434 951 961 -3 1781 1779 1780 -3 1811 1267 1789 -3 1781 1805 1779 -3 404 522 438 -3 434 736 951 -3 736 559 951 -3 1743 1766 1748 -3 559 736 1196 -3 1722 1739 1747 -3 715 1393 1169 -3 1534 1090 1360 -3 1269 1271 1270 -3 604 1124 272 -3 1358 1531 1500 -3 1824 1268 1267 -3 1811 1824 1267 -3 155 813 1880 -3 736 480 1196 -3 1196 480 1343 -3 1343 480 577 -3 1790 1813 1796 -3 1782 1789 1766 -3 1760 1782 1766 -3 1803 1802 1797 -3 1777 1770 1785 -3 1719 1743 1531 -3 1760 1766 1743 -3 1838 1269 1268 -3 1824 1838 1268 -3 1750 1770 1777 -3 480 578 577 -3 1689 1693 1550 -3 1763 1750 1777 -3 1770 1777 1785 -3 1691 1358 1356 -3 1719 1531 1358 -3 736 1062 480 -3 1813 1831 1817 -3 1549 1689 1550 -3 1756 1763 1785 -3 1691 1356 1355 -3 1085 1691 1355 -3 1761 1760 1743 -3 1744 1761 1743 -3 1807 1811 1789 -3 1838 1271 1269 -3 78 824 79 -3 1876 187 1158 -3 1821 1844 1827 -3 1708 1719 1358 -3 1744 1743 1719 -3 1782 1807 1789 -3 1807 1824 1811 -3 1860 1271 1838 -3 736 451 1062 -3 1756 1790 1769 -3 1725 1740 1724 -3 1698 1705 1711 -3 1510 1691 1085 -3 1708 1358 1691 -3 1761 1782 1760 -3 1818 1824 1807 -3 1860 1272 1271 -3 1718 1717 1696 -3 451 207 480 -3 1062 451 480 -3 1817 1830 1816 -3 1796 1800 1776 -3 1510 1085 1052 -3 1818 1838 1824 -3 1875 1272 1860 -3 1813 1817 1796 -3 1720 1719 1708 -3 1736 1744 1719 -3 1839 1838 1818 -3 96 807 486 -3 1018 1758 1742 -3 1842 1861 1845 -3 1881 814 1872 -3 1781 1780 1758 -3 1867 1881 1872 -3 1692 1691 1510 -3 1720 1736 1719 -3 1783 1782 1761 -3 1839 1860 1838 -3 1875 1661 586 -3 1272 1875 586 -3 1806 1805 1781 -3 1712 1716 1708 -3 1727 1720 1708 -3 1716 1727 1708 -3 1854 1860 1839 -3 1143 1661 1875 -3 1661 99 586 -3 1143 99 1661 -3 1031 60 236 -3 1709 1708 1691 -3 1692 1709 1691 -3 1709 1712 1708 -3 1709 1716 1712 -3 1709 1727 1716 -3 1727 1728 1720 -3 1786 1803 1797 -3 747 120 167 -3 484 207 451 -3 1736 1753 1744 -3 1753 1761 1744 -3 1753 1783 1761 -3 1874 1860 1854 -3 1874 1875 1860 -3 1792 1791 1778 -3 824 1868 1856 -3 1817 1816 1800 -3 520 207 484 -3 1692 1700 1709 -3 1728 1727 1709 -3 1728 1745 1727 -3 1511 1688 1510 -3 1688 1692 1510 -3 1874 1143 1875 -3 1013 1715 1699 -3 1749 1776 1755 -3 1759 1758 1018 -3 1688 1701 1700 -3 1692 1688 1700 -3 1773 1783 1753 -3 1849 1854 1839 -3 813 1143 1874 -3 813 99 1143 -3 1842 1845 1832 -3 1710 1709 1700 -3 1701 1710 1700 -3 1872 804 1878 -3 1825 1842 1832 -3 1853 1852 1830 -3 1730 1749 1734 -3 1689 1698 1697 -3 1805 1806 830 -3 1710 1728 1709 -3 1840 1849 1839 -3 1831 1853 1830 -3 1724 1723 1013 -3 1729 1728 1710 -3 1849 1874 1854 -3 1849 1870 1874 -3 1741 1740 1725 -3 1755 1775 1754 -3 1731 1714 1735 -3 1747 1749 1730 -3 1706 1714 1707 -3 1729 1745 1728 -3 1767 1773 1753 -3 1880 813 1874 -3 1870 1880 1874 -3 865 858 1810 -3 1810 858 259 -3 1861 1866 1845 -3 1790 1796 1769 -3 1755 1754 1738 -3 1739 1735 1747 -3 1686 1688 1511 -3 1439 1686 1511 -3 1746 1745 1729 -3 1774 1773 1767 -3 1834 1849 1840 -3 1016 1690 1548 -3 1788 1787 1765 -3 1551 1016 1548 -3 1686 1702 1701 -3 1688 1686 1701 -3 1703 1710 1701 -3 1702 1703 1701 -3 1795 1798 1773 -3 1825 1832 1813 -3 1697 1713 1696 -3 1762 1745 1746 -3 1762 1768 1745 -3 1795 1773 1774 +-0.0369122 0.127512 0.00276757 0.850855 0.5 +-0.0457707 0.130327 0.00306785 0.900159 0.5 +-0.0708847 0.149834 0.0388672 0.398443 0.5 +-0.00331557 0.130403 0.0212208 0.85268 0.5 +-0.0211979 0.1272 0.00915278 0.675938 0.5 +-0.0265255 0.12592 0.00874866 0.711533 0.5 +0.0339261 0.112038 0.0269672 0.652757 0.5 +0.0376485 0.110455 0.0145481 0.708171 0.5 +-0.0259368 0.111118 0.0379115 0.454541 0.437538 +0.027952 0.120939 0.0215377 0.533079 0.5 +-0.0628308 0.155987 -0.0150105 0.404517 0.5 +0.0390029 0.106711 0.0215202 0.535542 0.5 +0.0447976 0.0950477 0.00866471 0.579563 0.425995 +-0.0330636 0.173619 -0.0031267 0.365607 0.5 +-0.0808069 0.136243 0.0495014 0.499575 0.5 +-0.0705086 0.12445 0.0526685 0.564827 0.5 +0.00874873 0.131225 0.0145345 0.748371 0.5 +0.0401015 0.106711 0.00874166 0.680399 0.5 +0.0379483 0.100145 -0.00827134 0.600054 0.5 +-0.0906538 0.137201 0.0207305 0.824561 0.5 +-0.0841655 0.110667 0.0275273 0.690889 0.5 +-0.0705214 0.156214 0.0144536 0.807492 0.5 +-0.083872 0.15212 0.0282652 0.248168 0.41865 +0.00305028 0.12432 0.0332425 0.555044 0.354559 +0.00870828 0.124165 0.0330348 0.653433 0.5 +-0.0328896 0.12613 0.00300653 0.898771 0.5 +-0.0506302 0.143065 0.0150611 0.691477 0.5 +-0.0757863 0.13637 0.050172 0.566256 0.5 +-0.0027191 0.128962 0.0264678 0.271491 0.462815 +-0.0460961 0.125118 0.0263142 0.539149 0.5 +-0.0785104 0.0942728 -0.0109192 0.710999 0.5 +0.0216915 0.125373 0.0211452 0.530957 0.5 +-0.0888469 0.124305 0.00237041 0.635593 0.5 +0.040386 0.100825 -0.00303043 0.574857 0.5 +-0.0884145 0.117791 0.00268555 0.487167 0.430737 +-0.0319074 0.177421 -0.00491879 0.269231 0.447035 +-0.0765825 0.143224 0.0455148 0.414139 0.5 +-0.0209748 0.112544 0.0388613 0.482541 0.5 +-0.020836 0.179425 -0.0221622 0.341071 0.440034 +-0.0377039 0.167987 -0.0130391 0.396317 0.473039 +-0.0331765 0.12681 0.00839958 0.896274 0.5 +0.00893926 0.127114 0.0292916 0.350014 0.41288 +-0.044944 0.131083 0.0147963 0.599596 0.5 +-0.0266041 0.12515 0.00282384 0.73687 0.5 +0.0144285 0.12328 0.0319185 0.625269 0.5 +0.019244 0.122284 0.0308314 0.611204 0.34486 +-0.0390225 0.167317 0.00215527 0.413994 0.469929 +-0.08808 0.129976 0.00206377 0.625486 0.5 +-0.0537203 0.142608 0.0266058 0.696873 0.5 +0.043095 0.0980072 0.0191617 0.665192 0.5 +0.0432138 0.100117 0.00866473 0.691828 0.5 +0.0415448 0.0944954 0.0275695 0.671611 0.5 +-0.0578726 0.155337 0.0149245 0.394763 0.437313 +-0.0231577 0.157375 -0.0046304 0.136389 0.380194 +-0.0683123 0.145735 0.0420568 0.751812 0.5 +-0.0708351 0.142847 0.0451248 0.627973 0.5 +-0.070664 0.0642894 0.0209789 0.413051 0.5 +-0.0761519 0.130581 0.0525324 0.629117 0.5 +-0.0640036 0.161784 -0.0208118 0.449093 0.5 +-0.0706461 0.155711 0.00252406 0.855717 0.5 +-0.0924366 0.118434 0.0399838 0.673877 0.5 +-0.0635349 0.156052 0.0148814 0.798496 0.5 +0.0282675 0.118192 0.0274382 0.635485 0.5 +0.0392736 0.0938857 -0.00915453 0.585857 0.459742 +-0.0695973 0.164844 -0.0174846 0.548789 0.5 +-0.00892354 0.123904 0.0330319 0.602316 0.374044 +0.0269099 0.0942476 0.0444911 0.649753 0.5 +-0.0146258 0.162377 -0.0144398 0.338176 0.5 +-0.0450983 0.167072 0.00289327 0.449091 0.5 +-0.0761536 0.172742 -0.0384391 0.256591 0.4298 +-0.0858274 0.105458 0.00472318 0.523819 0.297125 +0.0370431 0.110443 0.0207229 0.52623 0.448558 +0.0321593 0.0994027 0.0380657 0.733041 0.5 +-0.075287 0.146433 0.0428582 0.424358 0.5 +-0.0395145 0.171107 0.000531747 0.452893 0.5 +-0.0839586 0.11215 0.00148754 0.436727 0.419097 +0.0446848 0.0883378 0.0216285 0.487783 0.481728 +0.0161783 0.127819 0.0220535 0.481793 0.5 +-0.00251635 0.0397232 0.0474087 0.280725 0.5 +0.00303163 0.0406968 0.0460422 0.331809 0.5 +-0.0143059 0.128197 0.00333856 0.693854 0.5 +-0.0526117 0.155596 0.0109972 0.561042 0.5 +-0.0332043 0.17776 -0.00906223 0.212789 0.5 +0.0394391 0.106654 0.00306577 0.522321 0.489889 +-0.0923799 0.1249 0.0327641 0.848517 0.5 +0.0454681 0.0882959 0.0146642 0.575503 0.5 +-0.0274495 0.179802 -0.00925837 0.258799 0.457369 +-0.072504 0.146297 0.0429682 0.549207 0.5 +-0.0579959 0.129793 0.0383118 0.658867 0.444043 +0.043117 0.0923689 0.0251649 0.622686 0.5 +-0.00865718 0.130323 0.0149721 0.633691 0.5 +-0.0141304 0.129188 0.0147431 0.547632 0.5 +-0.0707877 0.15583 0.00921954 0.739059 0.5 +-0.00952731 0.127041 0.0281475 0.375412 0.377874 +-0.0646289 0.153404 0.0329146 0.855321 0.5 +-0.0706939 0.15347 0.0328596 0.444959 0.455263 +0.0208126 0.118434 0.0336393 0.519282 0.5 +-0.0396566 0.173008 -0.00299705 0.274377 0.177706 +-0.0442176 0.170815 -0.00391429 0.245926 0.5 +-0.0582565 0.0395149 0.0457796 0.417977 0.459314 +-0.0523033 0.0401501 0.04623 0.454776 0.456044 +-0.0760211 0.161274 -0.0145891 0.267801 0.372187 +-0.0693983 0.163016 -0.0140293 0.403228 0.45768 +0.0399663 0.106491 0.014952 0.713602 0.5 +0.041536 0.0950084 -0.00475737 0.490139 0.464008 +-0.0470079 0.163779 0.00528295 0.432857 0.486946 +-0.0402546 0.161678 0.00298655 0.447592 0.5 +-0.0386569 0.0389805 0.0441153 0.509262 0.5 +-0.0704175 0.166991 -0.0216976 0.332592 0.447054 +-0.0254201 0.0886622 0.0503827 0.608282 0.5 +-0.0886334 0.137429 0.00876953 0.549009 0.5 +-0.014179 0.12627 0.0266417 0.420759 0.5 +-0.0360017 0.17408 -0.0118959 0.409753 0.289042 +-0.0886251 0.0937834 0.00823534 0.753697 0.5 +-0.0648672 0.155874 -0.00891497 0.595216 0.5 +-0.0704508 0.137752 -0.00774011 0.446131 0.5 +-0.0750154 0.166247 -0.0219558 0.263106 0.5 +0.0299465 0.114869 0.0300239 0.642356 0.5 +0.0398138 0.0998788 0.0273101 0.51725 0.5 +-0.015242 0.111698 0.0407424 0.605597 0.5 +-0.0700387 0.118219 0.0524379 0.585543 0.5 +0.0149973 0.112399 0.0386082 0.669811 0.5 +-0.036487 0.171225 0.000545037 0.438578 0.5 +-0.0641664 0.118551 -0.00968333 0.569796 0.5 +-0.071817 0.166979 -0.0463822 0.381568 0.451091 +-0.0913559 0.14534 0.0246937 0.648478 0.5 +0.00903703 0.112569 0.0396571 0.549283 0.408623 +0.0324674 0.0997396 -0.0141603 0.732658 0.5 +0.0417911 0.101845 0.00188609 0.547756 0.5 +0.00302992 0.112517 0.0415434 0.592572 0.5 +-0.0650368 0.148485 0.0382561 0.62562 0.5 +-0.0706519 0.13063 0.0502497 0.563116 0.5 +-0.0144471 0.128935 0.00903509 0.682121 0.5 +0.00292575 0.131541 0.00912318 0.795238 0.5 +-0.0625682 0.151125 0.035875 0.463512 0.5 +0.0349829 0.113328 0.0214487 0.620597 0.5 +0.021327 0.0385664 0.0392992 0.259499 0.426724 +0.0145125 0.093771 0.0501571 0.654705 0.5 +-0.00923752 0.112849 0.0413907 0.615633 0.5 +0.0415329 0.100906 0.0210277 0.662312 0.5 +0.0422859 0.101486 0.0146614 0.569693 0.490777 +-0.0773783 0.112839 -0.00448759 0.505277 0.5 +-0.078035 0.137641 -0.00517379 0.466714 0.5 +0.00873437 0.106347 -0.0202193 0.792948 0.5 +0.0090324 0.13035 0.0211569 0.465873 0.5 +0.00301322 0.130902 0.0206741 0.592486 0.5 +-0.00286342 0.13115 0.0147367 0.587804 0.5 +-0.0391578 0.12569 0.0207996 0.438744 0.464814 +-0.0205725 0.123523 0.0265579 0.445477 0.415699 +-0.0644194 0.155634 0.00928477 0.611624 0.331941 +-0.0463385 0.131411 0.0207671 0.674928 0.5 +-0.0532034 0.0439067 0.044658 0.417403 0.440199 +-0.00297651 0.131046 0.00884967 0.738924 0.5 +-0.089664 0.137755 0.0263925 0.80362 0.5 +-0.00888731 0.124273 -0.00880284 0.767738 0.284429 +-0.0460971 0.0385107 0.0446891 0.654962 0.5 +-0.0649255 0.178874 -0.0579325 0.245129 0.411885 +-0.0329347 0.124601 0.0211235 0.32811 0.5 +-0.0831301 0.149901 0.0334123 0.331963 0.314683 +-0.0895652 0.093948 0.0149303 0.603378 0.5 +-0.0328901 0.124518 -0.00282055 0.63839 0.5 +-0.0845271 0.106161 0.00204328 0.338681 0.43162 +-0.0469341 0.155816 0.00872921 0.470367 0.484595 +0.0206202 0.123943 0.0267275 0.477255 0.5 +-0.026256 0.117499 0.0321672 0.543293 0.5 +-0.021392 0.118632 0.0336445 0.468887 0.429556 +-0.0195069 0.116132 0.0368525 0.534732 0.411301 +-0.0761618 0.118382 0.0520923 0.490413 0.5 +0.00889281 0.0395765 0.0451727 0.476347 0.38769 +-0.0534736 0.159548 0.00753828 0.476667 0.5 +-0.0469464 0.161226 0.00680216 0.495992 0.483766 +-0.0574886 0.154862 0.0204748 0.677314 0.5 +0.0317199 0.117635 0.0202007 0.579556 0.5 +0.0378683 0.105514 -0.00259159 0.588286 0.5 +-0.0811847 0.137693 -0.00253994 0.641736 0.5 +-0.0764348 0.124515 0.0528345 0.65366 0.5 +0.0343816 0.106104 -0.00900254 0.534403 0.5 +0.0457922 0.088316 0.00867097 0.586292 0.439394 +-0.0703288 0.0944195 -0.0159143 0.511499 0.5 +-0.0756048 0.0937947 -0.0135536 0.429902 0.5 +-0.058657 0.156369 0.0093256 0.31374 0.5 +-0.0637335 0.153848 0.00222718 0.478676 0.5 +-0.0777278 0.0960024 0.0363437 0.678588 0.5 +-0.0868519 0.136556 0.00309926 0.517441 0.5 +-0.0455299 0.0432404 0.0432162 0.712662 0.5 +-0.0402011 0.045749 0.0408051 0.669165 0.320516 +-0.0654123 0.160403 -0.0149066 0.335302 0.5 +-0.0318898 0.0387174 0.0510004 0.553401 0.5 +-0.0267997 0.0453977 0.0509311 0.501112 0.5 +-0.0271043 0.0396972 0.0535379 0.487956 0.5 +-0.0215575 0.0460868 0.0517209 0.709553 0.5 +-0.0143078 0.0445295 0.0504368 0.575852 0.5 +-0.00981594 0.043264 0.0493162 0.448927 0.393067 +-0.00348436 0.044054 0.0472086 0.598081 0.5 +0.009577 0.0458139 0.0465877 0.519814 0.433928 +0.02048 0.111086 0.0379569 0.681163 0.5 +-0.0141831 0.128547 0.0200007 0.293349 0.5 +-0.0526702 0.144108 0.0210347 0.639643 0.5 +-0.0634838 0.17384 -0.0527131 0.549906 0.5 +-0.0366553 0.171999 -0.0125745 0.436075 0.5 +-0.0525548 0.131228 0.0328277 0.727547 0.5 +-0.0659567 0.132023 0.0442925 0.724494 0.5 +-0.0921726 0.11832 0.0267606 0.794672 0.5 +0.0452792 0.0882737 0.00268175 0.507794 0.5 +-0.00305651 0.112889 0.0417789 0.635396 0.5 +-0.0451955 0.161396 -0.00871567 0.424682 0.5 +-0.0402914 0.160933 -0.0115368 0.411895 0.405943 +-0.0521414 0.0701165 0.0389584 0.682177 0.456916 +-0.0383315 0.093604 -0.0232581 0.72469 0.5 +-0.0690556 0.137374 0.046352 0.61723 0.5 +-0.0695996 0.167401 -0.0516299 0.518552 0.5 +-0.00246047 0.124102 0.0337609 0.444043 0.5 +-0.0398624 0.128204 0.00299348 0.864483 0.5 +-0.0753331 0.149032 0.0395625 0.432149 0.5 +-0.0701432 0.160618 -0.00917801 0.464361 0.5 +-0.0589378 0.0440425 0.0434222 0.437887 0.447715 +-0.0207164 0.126445 0.00312493 0.710427 0.5 +-0.00850666 0.0467286 0.0481052 0.613173 0.5 +0.00300323 0.0450308 0.0469911 0.464978 0.5 +-0.0802174 0.148665 0.0379438 0.47939 0.5 +-0.0819961 0.130698 0.0513437 0.54405 0.5 +0.00273088 0.106333 -0.0209927 0.733954 0.5 +-0.0757273 0.0885687 -0.0138399 0.397424 0.5 +-0.0698477 0.0882875 -0.0167823 0.420617 0.5 +-0.0668508 0.159243 -0.0102161 0.42216 0.440727 +-0.0226988 0.0885773 0.0536309 0.546444 0.5 +-0.00281419 0.0990077 0.0505614 0.455087 0.5 +0.0452902 0.0696213 0.0253974 0.33948 0.5 +-0.0525629 0.0472823 0.040482 0.279548 0.5 +-0.046959 0.0466581 0.0408127 0.43714 0.5 +-0.0691348 0.156682 -0.00276369 0.629099 0.5 +-0.0897599 0.150073 0.0220744 0.276354 0.5 +-0.0702883 0.155637 0.0263654 0.47565 0.441038 +-0.0765031 0.154893 0.0266005 0.799832 0.5 +-0.00804843 0.0987379 0.0505998 0.327523 0.438474 +0.0300791 0.11567 -0.00430465 0.66246 0.5 +-0.0923054 0.117757 0.0334441 0.476916 0.5 +-0.0331192 0.0449511 0.0462474 0.432059 0.466683 +-0.0337794 0.113308 0.034612 0.683562 0.5 +-0.0521291 0.113769 0.0349566 0.515399 0.5 +0.0437636 0.0825382 -0.0027974 0.568535 0.5 +-0.0202819 0.126016 0.0210507 0.374818 0.437592 +0.0327872 0.043925 0.0295904 0.650152 0.5 +-0.0453372 0.155266 -0.0075525 0.386286 0.5 +-0.0284609 0.173987 -0.0175958 0.379432 0.418735 +0.0268448 0.0881755 -0.0223077 0.715629 0.5 +-0.0308231 0.0923023 -0.0246377 0.474586 0.431409 +-0.0899732 0.149975 0.0141115 0.257143 0.5 +0.0381804 0.105121 0.0266947 0.534482 0.490368 +0.00842001 0.12907 0.0258154 0.374593 0.448613 +-0.0266549 0.0942999 -0.0265555 0.294426 0.332222 +-0.0279896 0.0475815 0.0485532 0.381268 0.5 +-0.0150037 0.048073 0.0483203 0.576068 0.5 +-0.00298993 0.0473817 0.0491102 0.446744 0.431743 +0.00376754 0.0477551 0.0502037 0.495901 0.44823 +0.00748504 0.0473851 0.0493363 0.494952 0.5 +-0.0581651 0.149751 0.032858 0.470966 0.5 +-0.0720688 0.136456 0.0490662 0.625357 0.5 +-0.0810638 0.0939541 -0.0082617 0.685573 0.5 +0.0380863 0.0458646 0.0307423 0.807573 0.5 +-0.0253234 0.182998 -0.0108168 0.245054 0.5 +-0.0230508 0.183235 -0.0110157 0.246322 0.458572 +0.00323317 0.129146 0.0263855 0.347796 0.441746 +-0.0626125 0.149788 -0.00343342 0.691705 0.5 +-0.0591471 0.0466998 0.0395843 0.0883466 0.213805 +-0.0353862 0.0471292 0.0414241 0.656538 0.5 +-0.0194948 0.0486404 0.0485565 0.373069 0.5 +-0.00849455 0.0521633 0.0517688 0.61481 0.5 +-0.00296485 0.051429 0.0527827 0.53012 0.5 +0.00279019 0.0517664 0.0528352 0.560812 0.423049 +0.00904034 0.0517165 0.051222 0.558244 0.5 +0.0443839 0.0943042 0.00268377 0.582116 0.455816 +-0.0886145 0.111113 0.0148415 0.604102 0.5 +-0.0885219 0.144027 0.0329221 0.623335 0.5 +0.0440719 0.0937787 0.0206165 0.493368 0.454688 +0.0436531 0.0980341 0.0146596 0.668233 0.5 +-0.0650976 0.153799 -0.00285808 0.715743 0.5 +-0.0517297 0.0490759 0.0371355 0 0 +-0.0331222 0.0518259 0.0385377 0.676102 0.5 +-0.0377352 0.127448 0.0152358 0.612182 0.5 +-0.00906608 0.100701 0.0460122 0.338462 0.5 +-0.0410683 0.128416 0.0134054 0.417331 0.5 +-0.0712056 0.158724 -0.00521868 0.246338 0.5 +-0.0266313 0.0501544 0.044695 0.182016 0.5 +-0.0211065 0.0519946 0.0455753 0.195646 0.404388 +-0.0168667 0.0505241 0.0476889 0.520032 0.5 +-0.0147601 0.0527687 0.050103 0.451613 0.5 +-0.0626395 0.149972 -0.00897733 0.363787 0.461156 +-0.090861 0.124732 0.00627835 0.587249 0.5 +-0.0255786 0.0923499 -0.0315595 0.294527 0.5 +-0.0709738 0.172947 -0.052768 0.460427 0.5 +-0.0588974 0.143232 -0.00327646 0.48145 0.5 +-0.0943643 0.12436 0.0216467 0.570519 0.5 +0.0337044 0.112449 -0.00269877 0.532211 0.5 +-0.0515051 0.136557 0.0263185 0.72719 0.5 +-0.00886593 0.121199 0.0360577 0.614897 0.5 +-0.061729 0.155665 -0.0259512 0.690546 0.5 +-0.0862637 0.10567 0.0206042 0.519516 0.5 +-0.0895584 0.138606 0.032689 0.685876 0.5 +-0.0268168 0.123904 0.0208113 0.428255 0.5 +0.0341937 0.0515433 0.033081 0.609925 0.5 +0.0401268 0.0512743 0.0322702 0.669803 0.5 +0.0449306 0.0526595 0.0319582 0.655209 0.5 +-0.0405348 0.117168 0.0319438 0.657986 0.5 +-0.0636902 0.155546 -0.0390642 0.523327 0.5 +0.0278663 0.100401 0.0410064 0.689793 0.5 +-0.0275828 0.179275 -0.0157605 0.314049 0.5 +-0.0758871 0.0942302 0.0383961 0.647987 0.457049 +0.0138371 0.129201 0.0203961 0.412341 0.5 +-0.0152723 0.0998429 0.0451638 0.271215 0.427554 +-0.00916763 0.129718 0.0206646 0.438679 0.430152 +-0.0512444 0.0516901 0.0334801 0.192432 0.5 +-0.0461563 0.0523184 0.0379981 0.311543 0.5 +-0.0410001 0.05272 0.0393793 0.629588 0.477809 +-0.0270993 0.0526642 0.0393104 0.155274 0.5 +0.0434924 0.0931097 -0.00154028 0.576953 0.480183 +-0.0823819 0.112683 0.045427 0.438131 0.5 +-0.092066 0.118055 0.00909937 0.325678 0.5 +-0.00448884 0.121713 0.0362976 0.591545 0.5 +0.0147346 0.129423 0.0143146 0.840212 0.5 +-0.0158113 0.161888 -0.00973584 0.202865 0.5 +-0.0778838 0.149704 -0.00337488 0.403345 0.5 +-0.0865357 0.12477 -0.00166991 0.677311 0.5 +0.0153656 0.126058 0.0275381 0.479299 0.429147 +-0.0388913 0.123761 0.0249778 0.514489 0.5 +-0.0390351 0.121238 0.0283673 0.510424 0.470651 +-0.0324963 0.120237 0.0283344 0.568849 0.348087 +-0.0149052 0.12311 0.0316417 0.446842 0.5 +-0.0582873 0.117688 0.0386719 0.634635 0.5 +-0.0626536 0.161861 -0.0264031 0.685413 0.5 +-0.0818147 0.141639 0.0444825 0.392929 0.5 +0.0350734 0.100071 0.0345975 0.716199 0.5 +0.0311856 0.11215 0.0310216 0.689434 0.5 +-0.0335778 0.11743 0.031458 0.525408 0.5 +-0.059637 0.153475 0.031348 0.93076 0.5 +-0.0481256 0.0536625 0.0362191 0.58186 0.5 +-0.059026 0.156388 0.00269852 0.133166 0.5 +-0.0211187 0.0578754 0.0461125 0.660553 0.5 +-0.082738 0.124721 0.050554 0.665202 0.5 +-0.0466997 0.11363 0.0348133 0.568902 0.5 +-0.0107262 0.179662 -0.0277472 0.400699 0.458536 +0.0347725 0.0894441 -0.0170339 0.702331 0.5 +-0.0891825 0.100351 0.0148945 0.574286 0.477791 +0.0257275 0.122894 0.0207337 0.498278 0.5 +-0.0883949 0.100277 0.00841226 0.477822 0.5 +-0.0649858 0.155518 0.0263367 0.864791 0.5 +-0.0768402 0.154073 0.00257877 0.57436 0.5 +-0.0576877 0.154146 0.0262123 0.402162 0.5 +-0.0266966 0.125729 0.0145923 0.393422 0.5 +-0.076376 0.155782 0.0208875 0.505065 0.5 +-0.0763295 0.167188 -0.039594 0.405226 0.426366 +-0.0771877 0.100229 -0.0103313 0.528684 0.5 +-0.0153681 0.0590839 0.0519909 0.652683 0.5 +-0.010206 0.0576345 0.0535443 0.781548 0.413019 +-0.00350044 0.0578672 0.0543757 0.774384 0.5 +0.00300818 0.0568916 0.0538692 0.704357 0.5 +0.0088308 0.0580497 0.0529859 0.692645 0.5 +0.0410915 0.0820775 -0.00893411 0.500391 0.430286 +0.0395449 0.0576373 0.0318985 0.612032 0.4505 +-0.0762443 0.139336 0.0484763 0.588653 0.42756 +-0.0324306 0.120379 -0.00955344 0.656019 0.5 +-0.0194451 0.0881559 0.0557639 0.449983 0.473992 +-0.074787 0.159471 -0.00898201 0.281303 0.5 +-0.0639935 0.15611 0.0210031 0.687157 0.5 +-0.0762438 0.153101 0.0322442 0.323875 0.45561 +-0.00876679 0.128727 0.025102 0.735708 0.5 +0.0282216 0.112237 -0.00983067 0.567922 0.385391 +-0.0451341 0.0593225 0.0387559 0.511245 0.5 +-0.0405005 0.0579499 0.040202 0.540369 0.5 +-0.033993 0.0584028 0.038704 0.646744 0.5 +-0.0272756 0.0585468 0.0382285 0.571263 0.5 +-0.0248608 0.122913 0.0245429 0.379391 0.5 +-0.0825276 0.154355 0.0206132 0.385494 0.444119 +-0.00884271 0.129403 0.00305159 0.702319 0.5 +0.0207587 0.126654 0.0147646 0.624434 0.5 +-0.0394868 0.173351 -0.00839443 0.199648 0.251821 +-0.028421 0.114019 0.0347746 0.603313 0.5 +-0.0193575 0.122009 0.0306737 0.55532 0.5 +-0.0691626 0.161675 -0.0514614 0.38665 0.5 +-0.0516736 0.15006 0.0148119 0.716684 0.5 +-0.0156325 0.120151 0.0349054 0.470635 0.336572 +0.0467454 0.0582319 0.0314404 0.576429 0.5 +-0.0770165 0.0685425 0.0147863 0.703257 0.5 +-0.00967101 0.173225 -0.0264945 0.379771 0.5 +-0.0213141 0.184813 -0.0151112 0.186313 0.403961 +-0.0766524 0.0882188 0.0382876 0.650646 0.5 +-0.0540219 0.0521463 0.0110698 0.270787 0.5 +-0.0219451 0.126821 0.0155536 0.534695 0.5 +-0.0820391 0.153392 0.0264506 0.292051 0.4047 +-0.0213183 0.124468 -0.00290836 0.782181 0.5 +-0.0268364 0.123465 -0.00321538 0.727949 0.5 +-0.0312035 0.177796 -0.0133521 0.371348 0.5 +-0.00749945 0.0598042 0.0553302 0.778631 0.5 +-0.00108951 0.0601245 0.0554892 0.776353 0.5 +0.00280202 0.0599746 0.0555283 0.768603 0.5 +-0.051797 0.118119 0.033678 0.677092 0.438456 +0.00302464 0.131618 0.0149353 0.692956 0.5 +0.0446005 0.0942619 0.0151198 0.554026 0.5 +-0.0880636 0.111855 0.00852285 0.304511 0.3924 +-0.0704321 0.144096 -0.0148369 0.130446 0.5 +-0.0820967 0.0943634 0.0322765 0.629357 0.5 +-0.0269642 0.120812 0.0275676 0.345323 0.386314 +-0.0540164 0.149968 0.0253393 0.49489 0.5 +-0.0800337 0.0995053 -0.00770139 0.499264 0.5 +0.00922138 0.12038 0.0360924 0.562107 0.5 +0.00286056 0.117968 0.0387331 0.649494 0.5 +-0.0936229 0.118494 0.0206524 0.664933 0.5 +-0.0409923 0.113229 0.035109 0.667726 0.5 +-0.0822185 0.154488 0.0146661 0.500539 0.5 +-0.0625956 0.155202 -0.0329876 0.814083 0.5 +-0.0462511 0.124621 -0.00898124 0.590842 0.5 +-0.0220336 0.160676 -0.00426008 0.309766 0.47069 +-0.065621 0.172767 -0.0466049 0.613718 0.5 +-0.0762614 0.155884 0.0148687 0.717415 0.5 +-0.0644988 0.149044 -0.0265159 0.690046 0.5 +-0.0581979 0.0593456 0.0210895 0.079935 0 +-0.0335439 0.122618 0.0254024 0.514037 0.5 +-0.0826578 0.153434 0.00921403 0.601617 0.5 +-0.049999 0.132417 0.0286961 0.650903 0.5 +0.0088217 0.131096 0.00864908 0.834131 0.5 +-0.0154842 0.0644282 0.0533754 0.608033 0.445048 +-0.00871951 0.065015 0.0556827 0.650491 0.470895 +-0.00324815 0.0640003 0.0562816 0.762387 0.5 +0.00292601 0.0643094 0.0563956 0.748671 0.5 +0.00738462 0.0651614 0.0553402 0.488299 0.46872 +-0.0143174 0.116971 0.037836 0.441459 0.5 +-0.00299223 0.118083 0.0390751 0.65526 0.5 +-0.00864301 0.117816 0.0385662 0.681198 0.5 +-0.0532884 0.0571719 0.0206631 0.106703 0 +-0.0882588 0.100387 0.0210097 0.535268 0.5 +-0.0324377 0.099703 -0.0227313 0.620611 0.5 +0.0425072 0.0603725 0.0302275 0.744481 0.5 +0.0523383 0.0580401 0.0290457 0.405493 0.41666 +0.0413612 0.0877503 -0.00929235 0.635782 0.5 +-0.0581547 0.0620148 0.0270981 0.448705 0.5 +-0.0530328 0.0590503 0.0266933 0.136202 0.5 +-0.0477227 0.135526 0.0148654 0.740469 0.5 +0.00323512 0.0983053 0.0504424 0.395048 0.366076 +0.0150627 0.119642 0.034806 0.696033 0.374342 +-0.0453373 0.0643061 0.0391142 0.587502 0.5 +-0.0394097 0.0644278 0.0414133 0.715885 0.5 +-0.033068 0.0642666 0.0396407 0.650585 0.5 +-0.0270237 0.0644489 0.0395335 0.617817 0.5 +-0.0881604 0.149479 0.0268507 0.265855 0.5 +-0.0640727 0.143434 -0.00894036 0.668887 0.5 +0.00286033 0.121151 0.036139 0.623932 0.5 +-0.0827306 0.138152 0.0466993 0.412428 0.5 +-0.00261511 0.127006 0.030132 0.335862 0.5 +0.0355841 0.108498 -0.00452523 0.461807 0.466834 +0.0219203 0.114136 0.0356941 0.554683 0.5 +-0.0379555 0.161954 -0.0128021 0.499753 0.5 +-0.0526362 0.0643632 0.0340621 0.277414 0.5 +0.025874 0.123374 0.0143811 0.506732 0.5 +-0.0451406 0.131184 0.00901599 0.493237 0.5 +-0.075778 0.155361 -0.00310678 0.708579 0.5 +-0.0739145 0.156437 -0.0274945 0.645327 0.5 +-0.0833056 0.100778 -0.00354288 0.490806 0.397415 +-0.0767099 0.173942 -0.0452732 0.259897 0.5 +0.00846106 0.116985 0.038033 0.66824 0.5 +-0.0200899 0.184788 -0.020546 0.237973 0.106197 +-0.046571 0.120413 0.0285524 0.752764 0.5 +-0.0515313 0.123718 -0.0088569 0.538005 0.5 +0.0212116 0.105804 -0.0171101 0.576137 0.468722 +-0.0938613 0.124487 0.0151416 0.737559 0.5 +0.0414591 0.064577 0.0290352 0.617794 0.5 +0.0466725 0.0643471 0.0285539 0.486488 0.5 +0.0526423 0.0634018 0.0283831 0.501229 0.5 +-0.0468141 0.168322 -0.00285433 0.371444 0.5 +-0.0869152 0.0944156 0.00293118 0.494536 0.346642 +-0.0773713 0.161559 -0.0267238 0.476378 0.5 +-0.0396095 0.126677 -0.00334699 0.853498 0.5 +-0.0271315 0.0764239 0.0455715 0.693464 0.5 +-0.0587953 0.107012 -0.0177177 0.484023 0.5 +-0.0748314 0.11156 -0.00720996 0.44421 0.5 +-0.0642623 0.0888181 -0.018733 0.676741 0.5 +-0.0325172 0.0881157 -0.0255424 0.370176 0.330832 +0.00325654 0.0700086 0.0561047 0.731659 0.5 +0.0103151 0.0636713 0.0537558 0.477793 0.458716 +0.0432701 0.0979967 0.00267804 0.544182 0.465461 +-0.0708223 0.156244 0.021207 0.768676 0.5 +-0.0584176 0.0702277 0.0384322 0.673529 0.5 +-0.0703207 0.112305 -0.00963846 0.530989 0.5 +-0.0581653 0.0881983 -0.0208369 0.619673 0.5 +-0.0443038 0.0877156 -0.0218942 0.693083 0.5 +-0.0488091 0.0660127 0.0373959 0.829801 0.5 +0.00269411 0.126911 0.030114 0.419275 0.5 +0.0239692 0.12105 0.0288706 0.523768 0.5 +-0.0469203 0.117468 0.0314407 0.649888 0.5 +-0.091552 0.143361 0.0201623 0.515231 0.5 +-0.0907563 0.143859 0.0263089 0.504684 0.469425 +-0.0495713 0.144022 0.00976642 0.636632 0.45621 +-0.0770934 0.15583 -0.0147903 0.519503 0.5 +-0.0868322 0.105634 0.00887573 0.731519 0.5 +-0.082848 0.131648 -0.00299747 0.386393 0.5 +-0.0384249 0.106407 -0.0201393 0.79815 0.5 +-0.0823953 0.118841 -0.00336022 0.540306 0.5 +-0.0102333 0.0876697 -0.0375101 0.564234 0.5 +-0.00789361 0.089842 -0.0363492 0.755212 0.5 +-0.0579097 0.111769 -0.0161856 0.463258 0.5 +0.0140074 0.105793 -0.0193841 0.554632 0.5 +-0.00328561 0.105435 -0.0225198 0.740261 0.5 +-0.0409613 0.070972 0.0419904 0.795206 0.5 +-0.033501 0.0710512 0.0409793 0.706864 0.5 +-0.0272732 0.0701361 0.0410332 0.726443 0.5 +-0.0161963 0.127121 0.0228897 0.305628 0.5 +-0.0190644 0.127936 0.0133818 0.519435 0.5 +-0.0149926 0.0694778 0.0545159 0.595577 0.5 +-0.00932719 0.0707313 0.0562936 0.785998 0.5 +-0.002994 0.0710941 0.0575426 0.779773 0.5 +0.00838831 0.0714267 0.0556585 0.671976 0.5 +0.0102531 0.0693533 0.0547665 0.525573 0.5 +-0.0323939 0.153399 -0.00240332 0.209483 0.5 +0.0435981 0.0881514 0.0254203 0.603121 0.478265 +-0.0586529 0.124882 -0.00781093 0.700525 0.5 +-0.0204287 0.107045 -0.022046 0.723165 0.5 +-0.0382961 0.0879422 -0.0229335 0.629507 0.5 +-0.081573 0.113394 -0.00173083 0.508624 0.426711 +-0.0380811 0.154778 -0.00889149 0.748063 0.5 +-0.00212588 0.0889926 -0.0354677 0.782073 0.5 +0.00904065 0.100193 -0.0222794 0.54652 0.5 +-0.0467068 0.0700493 0.0405769 0.710023 0.5 +-0.0779974 0.151244 0.0352264 0.347296 0.5 +0.0149019 0.116126 0.0367849 0.635361 0.5 +-0.07603 0.106301 -0.0087688 0.520423 0.5 +-0.0885261 0.137839 0.0393964 0.651389 0.5 +-0.0703112 0.131278 -0.00857724 0.737784 0.5 +0.0419377 0.0703605 0.0288832 0.54196 0.5 +0.0514194 0.0684326 0.0256968 0.512602 0.5 +-0.0922548 0.124813 0.0393757 0.806636 0.5 +0.0135035 0.128105 0.0250558 0.487288 0.424656 +-0.0704618 0.125421 -0.00881334 0.801453 0.5 +-0.0703931 0.118731 -0.00840961 0.381625 0.5 +-0.0719685 0.106305 -0.0114493 0.499561 0.5 +-0.0646972 0.161498 -0.0573125 0.41682 0.5 +0.0463693 0.0715128 0.0216754 0.461473 0.448797 +-0.0538246 0.153497 0.0152346 0.602795 0.402362 +-0.0142869 0.0724666 0.0554243 0.617853 0.5 +-0.0394057 0.118512 -0.01336 0.602235 0.5 +-0.0280509 0.0880065 -0.0330858 0.33771 0.5 +-0.00957701 0.168254 -0.0212321 0.359593 0.5 +-0.0445856 0.167324 -0.00782662 0.413138 0.327414 +-0.0513101 0.161594 -0.00355965 0.292939 0.5 +-0.0702356 0.179304 -0.0569867 0.253404 0.5 +-0.0644695 0.168402 -0.0398946 0.676128 0.5 +-0.0089459 0.130139 0.00911776 0.703889 0.5 +0.00219503 0.0880369 -0.0342201 0.75972 0.5 +-0.0268891 0.16726 -0.0174204 0.847505 0.5 +-0.0525985 0.155054 -0.00368706 0.37123 0.419006 +-0.0761618 0.131736 -0.00696723 0.42394 0.44361 +-0.0759576 0.07099 0.0265672 0.757943 0.5 +-0.00875341 0.10588 -0.02285 0.71177 0.5 +-0.0519242 0.1493 -0.00277595 0.483301 0.5 +-0.016371 0.18465 -0.0214272 0.271878 0.5 +-0.020548 0.0705632 0.0520411 0.601639 0.5 +-0.0813371 0.120073 0.049533 0.662828 0.5 +-0.0625087 0.149934 -0.0150319 0.415531 0.480025 +-0.0831098 0.10651 0.0273461 0.515033 0.5 +-0.011119 0.163582 -0.018751 0.17813 0.5 +-0.00291057 0.101147 0.0456419 0.307462 0.5 +-0.0635467 0.0660523 0.0318653 0.49936 0.45677 +-0.0511979 0.0873878 -0.0217212 0.75515 0.5 +-0.0530335 0.0740367 0.0417219 0.727079 0.5 +-0.0465007 0.0756701 0.0421325 0.696934 0.5 +-0.022314 0.0760359 0.0530306 0.607912 0.5 +-0.0151351 0.0764056 0.0563566 0.616605 0.5 +-0.00900601 0.0766621 0.0575852 0.791265 0.5 +-0.00299732 0.0767339 0.0584651 0.678647 0.450838 +0.00347424 0.0769755 0.0565905 0.523043 0.5 +0.00860763 0.0767538 0.0557293 0.612782 0.5 +-0.0271239 0.156216 -0.00302734 0.139755 0.329034 +-0.0633091 0.16738 -0.0580906 0.358909 0.45373 +-0.0873943 0.144225 0.00902371 0.583528 0.5 +-0.0626891 0.162297 -0.0470925 0.70746 0.5 +0.0370111 0.110397 0.00265294 0.516602 0.481774 +-0.0744006 0.144062 -0.00864565 0.417075 0.5 +-0.0244124 0.183841 -0.0135068 0.166659 0.5 +-0.0803381 0.0715473 0.0150483 0.5669 0.5 +-0.0644528 0.0761561 0.040638 0.610448 0.476331 +-0.0588413 0.0753794 0.0421022 0.634349 0.5 +-0.0524294 0.077372 0.0433357 0.774603 0.5 +-0.0484981 0.0769334 0.043281 0.674446 0.5 +-0.0414954 0.0773856 0.0429005 0.752035 0.5 +-0.0395008 0.0754808 0.0425134 0.72256 0.5 +-0.033488 0.0764759 0.0414605 0.748994 0.5 +-0.0627838 0.162163 -0.0530538 0.691143 0.5 +0.0381456 0.0881056 -0.0138675 0.676152 0.5 +-0.0642837 0.0396418 0.039624 0.532543 0.5 +-0.0526672 0.121335 -0.010917 0.523608 0.5 +-0.0738104 0.162942 -0.037093 0.458525 0.324439 +-0.0490869 0.13938 0.00889895 0.657159 0.5 +-0.0495771 0.166027 -0.00171113 0.322064 0.5 +-0.0709736 0.161609 -0.0450808 0.365011 0.420984 +0.0251847 0.12195 0.0254854 0.524179 0.5 +-0.0193615 0.0781018 0.0558163 0.595703 0.4544 +-0.0265458 0.120645 -0.00911332 0.52669 0.5 +-0.061796 0.155741 -0.0207923 0.443336 0.5 +-0.082476 0.110295 0.0324103 0.745977 0.5 +-0.0691674 0.156314 -0.050857 0.360984 0.5 +-0.0622848 0.16236 -0.0396288 0.427869 0.464762 +-0.088248 0.113803 0.0264606 0.595923 0.5 +-0.0575392 0.0787026 0.0436363 0.801201 0.5 +-0.0298439 0.0782596 0.0421168 0.771067 0.5 +-0.0677617 0.0876701 0.0434928 0.59211 0.5 +-0.0921939 0.131884 0.015227 0.781723 0.5 +-0.0878987 0.111742 0.0209206 0.698028 0.5 +-0.049353 0.139298 0.0147955 0.761861 0.5 +-0.0327071 0.173321 -0.0149209 0.384317 0.5 +-0.0866298 0.152851 0.0149144 0.267781 0.5 +-0.0779646 0.100025 0.035185 0.697079 0.5 +-0.0935537 0.118404 0.0151524 0.667612 0.5 +-0.084908 0.10801 0.0228537 0.694681 0.5 +-0.0210677 0.0821213 0.0562096 0.557699 0.5 +-0.0149957 0.082187 0.0572635 0.665194 0.5 +-0.00899671 0.0822178 0.0576875 0.71377 0.5 +-0.00299966 0.0822055 0.0574653 0.668024 0.472979 +0.0034748 0.0817533 0.0567544 0.69456 0.5 +0.00824833 0.082992 0.0556315 0.615627 0.5 +0.0102414 0.0812949 0.0546523 0.424956 0.485927 +-0.0398496 0.123966 -0.00878898 0.60318 0.5 +-0.092257 0.124769 0.00902091 0.309094 0.468872 +-0.0436728 0.126191 0.0209533 0.472028 0.413108 +-0.0820425 0.105873 -0.00271871 0.341089 0.347157 +-0.0663016 0.0807623 0.0424437 0.632223 0.5 +-0.0639939 0.0836688 0.0439754 0.778832 0.5 +-0.058539 0.0825906 0.0439671 0.770991 0.5 +-0.0521209 0.0822523 0.0446262 0.782751 0.5 +-0.0467559 0.0828569 0.0439458 0.699516 0.399968 +-0.0424962 0.0810729 0.0423266 0.617938 0.5 +-0.0404903 0.0830123 0.0430984 0.712874 0.5 +-0.0365108 0.0825773 0.0434355 0.675696 0.5 +-0.032204 0.0824171 0.0421121 0.529763 0.5 +-0.0864005 0.152981 0.0204492 0.250247 0.416029 +-0.0235661 0.115415 0.0353667 0.518805 0.471584 +-0.0764871 0.111685 0.0461598 0.498936 0.5 +-0.0763895 0.14977 -0.00829972 0.604451 0.5 +-0.0754801 0.161855 -0.0327796 0.39691 0.5 +-0.0285733 0.0828247 0.0462702 0.636794 0.5 +-0.0862819 0.100797 0.0028483 0.65379 0.5 +0.021088 0.08242 0.0504086 0.491924 0.475524 +-0.0801892 0.143128 -0.00230055 0.641961 0.5 +0.00844098 0.124407 -0.00878569 0.555015 0.5 +0.0147552 0.0825883 0.0529115 0.480476 0.5 +-0.061995 0.161169 -0.032654 0.499509 0.5 +-0.0807571 0.1525 0.0307996 0.295115 0.454522 +-0.00295953 0.130272 0.00279699 0.742188 0.5 +-0.0153619 0.0884791 0.0565599 0.818561 0.5 +-0.00899729 0.0878977 0.0570287 0.818958 0.5 +-0.00299611 0.0880658 0.0568489 0.695384 0.5 +0.00301457 0.0885291 0.0562756 0.81087 0.5 +0.00834267 0.0873808 0.0555541 0.577038 0.479545 +-0.00897481 0.0941651 -0.0338408 0.678465 0.5 +0.0314278 0.11673 0.0250113 0.597807 0.5 +-0.0760602 0.155337 0.0093949 0.68566 0.5 +0.0257808 0.116776 -0.00728909 0.54747 0.36626 +-0.0646577 0.0882843 0.0447113 0.69894 0.5 +-0.058996 0.0882997 0.0449149 0.778337 0.5 +-0.0529958 0.0883132 0.0451395 0.696869 0.45083 +-0.0465421 0.0881579 0.0443187 0.605881 0.5 +-0.0404961 0.0876863 0.0430941 0.556958 0.5 +-0.0331792 0.0885648 0.04366 0.668172 0.5 +-0.0280482 0.0879652 0.046363 0.699915 0.5 +0.0150626 0.0881784 0.0517745 0.702815 0.5 +0.0205955 0.087113 0.0492325 0.678548 0.5 +-0.0702712 0.0823874 0.0409431 0.628092 0.5 +-0.0296926 0.0896882 -0.0286839 0.317989 0.390463 +-0.0236137 0.179242 -0.0115629 0.264741 0.5 +-0.0809391 0.100029 0.0323433 0.683272 0.5 +-0.0928336 0.130683 0.0207107 0.62518 0.472282 +-0.0761771 0.156201 -0.0204165 0.612769 0.5 +0.0146577 0.129396 0.00843576 0.595962 0.5 +0.0104845 0.089766 0.0542005 0.46622 0.5 +-0.072579 0.161253 -0.0389447 0.482103 0.5 +-0.0322741 0.110391 -0.0184574 0.809584 0.5 +-0.0550172 0.150108 0.027792 0.412797 0.5 +-0.071635 0.0883254 0.0414652 0.604622 0.463567 +-0.0424904 0.0895336 0.0426086 0.959715 0.5 +0.0207945 0.0897491 0.0484315 0.669841 0.5 +0.0273189 0.118845 -0.00265658 0.615055 0.5 +0.0285218 0.121112 0.0162366 0.593248 0.434231 +-0.00899735 0.0930598 0.0559298 0.639163 0.5 +-0.00291176 0.118727 -0.0144021 0.826286 0.5 +-0.0885191 0.113233 0.0327948 0.447552 0.461926 +-0.0713744 0.0938304 0.0415269 0.544171 0.444972 +-0.0641029 0.0935514 0.0439488 0.597795 0.395518 +-0.0584965 0.0944146 0.0446213 0.678752 0.5 +-0.0515853 0.0939836 0.0442383 0.634435 0.477778 +-0.0465591 0.0937901 0.0436103 0.714507 0.5 +-0.0414914 0.0942416 0.0425268 0.490492 0.46307 +-0.0377723 0.0933327 0.0434889 0.620752 0.5 +-0.0332864 0.0945766 0.0443868 0.723538 0.5 +-0.0263807 0.094318 0.0450568 0.620324 0.5 +-0.0141606 0.0929618 0.0553898 0.503825 0.5 +-0.00319641 0.0930898 0.0557853 0.624082 0.5 +0.00150357 0.0931879 0.0551544 0.492015 0.5 +0.00367616 0.0950752 0.0535295 0.508462 0.5 +0.00915739 0.0941794 0.0519212 0.597357 0.452723 +0.0216553 0.0937794 0.0473202 0.671835 0.5 +-0.0702968 0.174481 -0.045888 0.43732 0.455145 +-0.0305889 0.168899 -0.00702359 0.59106 0.5 +-0.0528191 0.162649 0.00296711 0.343566 0.5 +-0.0890968 0.0940104 0.0208024 0.539357 0.478012 +-0.0626249 0.173112 -0.0586131 0.353011 0.447085 +-0.0443835 0.105923 -0.0201903 0.683228 0.5 +-0.0664958 0.0951776 0.0424531 0.672396 0.5 +-0.0324384 0.126415 0.0146752 0.445893 0.463327 +-0.0152469 0.0961657 0.0518098 0.323594 0.5 +-0.0097537 0.0960506 0.0535818 0.446732 0.426556 +-0.00304601 0.0963367 0.0537791 0.579525 0.5 +0.01642 0.0957081 0.0480381 0.687032 0.5 +-0.0876548 0.105191 0.0148253 0.774556 0.5 +-0.0699417 0.0763232 0.0381496 0.596573 0.5 +0.0358078 0.0958594 -0.0120328 0.738943 0.5 +0.0374966 0.100154 0.031249 0.720944 0.5 +-0.0530195 0.150059 0.0207323 0.696139 0.5 +-0.0905911 0.131765 0.0328667 0.816274 0.5 +-0.0709717 0.147309 -0.0268389 0.224341 0.389051 +-0.0443321 0.0935075 -0.0222668 0.709831 0.5 +-0.0400911 0.128618 0.00909496 0.81345 0.5 +-0.0710054 0.100275 0.0398128 0.481571 0.5 +-0.0653063 0.100124 0.0417262 0.670525 0.470095 +-0.0589969 0.0980495 0.0430328 0.779482 0.5 +-0.0529938 0.0980631 0.0432952 0.836255 0.5 +-0.0469951 0.0980659 0.043235 0.637806 0.5 +-0.0408476 0.100401 0.0414668 0.648927 0.395789 +-0.0323344 0.0988071 0.0435216 0.652032 0.5 +-0.0259464 0.0998425 0.0438947 0.737424 0.5 +-0.0212066 0.0999849 0.0444194 0.576924 0.5 +0.00749586 0.09835 0.0488255 0.46146 0.5 +0.0090271 0.101109 0.0469975 0.470012 0.5 +0.0153076 0.100008 0.0472449 0.600016 0.5 +0.0208175 0.100067 0.0453866 0.595024 0.46889 +-0.0648326 0.131509 -0.00838673 0.790869 0.5 +-0.0740297 0.150832 -0.0323367 0.406089 0.5 +-0.0932444 0.124885 0.026841 0.802537 0.5 +-0.0633239 0.169093 -0.0610358 0.362406 0.5 +-0.0771158 0.162488 -0.0202679 0.465605 0.5 +-0.0585669 0.0647555 0.0323611 0.494963 0.328305 +0.0377689 0.110383 0.00969065 0.710008 0.5 +-0.0503559 0.0935892 -0.0218956 0.807094 0.5 +-0.0589961 0.101543 0.042437 0.529374 0.5 +-0.0516647 0.101981 0.0417488 0.647378 0.5 +-0.0469248 0.101325 0.0421166 0.608323 0.5 +-0.0352173 0.101965 0.0413638 0.751982 0.5 +0.00285015 0.100935 0.0464433 0.395489 0.5 +-0.075479 0.150312 -0.0143808 0.730394 0.5 +-0.078936 0.108126 -0.00525459 0.540251 0.381971 +-0.0251472 0.168981 -0.0187156 0.757996 0.5 +-0.071457 0.113692 0.0499983 0.429195 0.5 +-0.0747771 0.0997536 0.0377868 0.551123 0.5 +-0.0902919 0.137212 0.0146286 0.495279 0.5 +-0.0264568 0.105883 0.0411765 0.58994 0.471484 +-0.0209966 0.1044 0.0429589 0.797197 0.5 +-0.0145208 0.105597 0.0430511 0.780555 0.5 +-0.00899316 0.10622 0.0435541 0.510194 0.5 +-0.00289533 0.105882 0.0438861 0.384284 0.5 +0.00245231 0.105621 0.0429868 0.332307 0.5 +0.00945613 0.104903 0.0439002 0.435482 0.5 +0.0149913 0.104769 0.0443348 0.548532 0.5 +-0.0772186 0.106139 0.0350601 0.430274 0.367589 +-0.0708601 0.106945 0.0381598 0.402417 0.5 +-0.0652985 0.106577 0.0390805 0.558067 0.398761 +-0.0583896 0.105623 0.0405326 0.594554 0.5 +-0.0529341 0.106445 0.0398435 0.644542 0.398207 +-0.0461638 0.105797 0.0404843 0.759883 0.5 +-0.0400204 0.106789 0.0388993 0.653599 0.5 +-0.03311 0.106322 0.0394461 0.532024 0.5 +0.0193026 0.10477 0.0431964 0.486674 0.480281 +-0.0501412 0.13774 0.00286739 0.569746 0.5 +0.0266104 0.105911 0.0384052 0.650339 0.5 +0.0438719 0.088439 -0.0031027 0.506353 0.478726 +-0.0590381 0.113203 0.0362299 0.87726 0.5 +-0.021499 0.107851 0.0414162 0.584043 0.5 +-0.0164951 0.107881 0.0420289 0.633836 0.5 +0.00450524 0.107918 0.0419336 0.79888 0.5 +0.00856234 0.108229 0.0410531 0.820786 0.5 +0.0149994 0.10779 0.0412845 0.598409 0.5 +0.0213049 0.106041 0.0409433 0.561561 0.479574 +-0.0336665 0.167843 -0.00338268 0.478764 0.5 +-0.0587789 0.131705 -0.00671001 0.673026 0.5 +-0.0443517 0.100306 -0.0215281 0.825942 0.5 +-0.0147306 0.179604 -0.0266222 0.40888 0.5 +0.0159582 0.108177 -0.0177822 0.564672 0.468958 +-0.0638447 0.138119 -0.00733006 0.633194 0.5 +-0.0330953 0.167861 -0.0155539 0.527374 0.428366 +-0.0643684 0.125359 -0.00876153 0.813046 0.5 +-0.032583 0.161992 -0.0142418 0.852313 0.5 +-0.068568 0.110392 0.0392194 0.353622 0.364353 +-0.0643494 0.112195 0.0388907 0.34696 0.5 +-0.0593722 0.112082 0.0373875 0.588374 0.5 +-0.0529986 0.110472 0.0373551 0.513233 0.408461 +-0.0468613 0.11028 0.0378862 0.569336 0.5 +-0.040984 0.110496 0.0370883 0.553647 0.5 +-0.0320055 0.110468 0.0370438 0.565129 0.5 +-0.0074871 0.110717 0.042649 0.617568 0.5 +-0.00449218 0.110714 0.0426582 0.621679 0.5 +0.0250033 0.110611 0.0368459 0.631257 0.5 +0.025919 0.0995286 -0.0189206 0.684181 0.5 +-0.06973 0.112153 0.0457184 0.746569 0.5 +-0.045604 0.148834 -0.00329924 0.521986 0.5 +-0.0653006 0.0947889 -0.0177657 0.582853 0.5 +-0.0906677 0.13318 0.0277848 0.773217 0.5 +-0.0331508 0.094474 -0.0237799 0.742 0.5 +-0.0575764 0.0941613 -0.0208023 0.703326 0.5 +-0.0200586 0.0397198 0.0532237 0.447203 0.5 +-0.0203685 0.0352888 0.051184 0.291685 0.457265 +-0.0764163 0.125947 -0.00745144 0.524375 0.5 +-0.0205906 0.167551 -0.0139677 0.809186 0.5 +0.025858 0.116851 0.0315289 0.660225 0.5 +-0.0139279 0.167191 -0.021044 0.669958 0.5 +-0.0587481 0.149802 -0.00133886 0.562881 0.5 +0.0144191 0.0395247 0.0443396 0.266796 0.5 +0.0332953 0.105473 0.0329627 0.721815 0.5 +-0.0647461 0.114313 -0.0115219 0.592211 0.5 +-0.0520818 0.0353771 0.0449331 0.341981 0.5 +-0.015004 0.0392095 0.0513548 0.312679 0.5 +-0.0094925 0.0384962 0.049554 0.302651 0.5 +-0.0638496 0.117631 0.0454477 0.559641 0.5 +-0.0573025 0.136864 0.033162 0.554568 0.5 +0.0189101 0.0400942 0.0428502 0.270107 0.5 +-0.0508192 0.124393 0.0332635 0.581555 0.5 +-0.0182623 0.180885 -0.017743 0.594618 0.5 +-0.0651271 0.150343 -0.0325707 0.505808 0.5 +0.0332966 0.0936886 0.0400216 0.637373 0.5 +-0.0463011 0.149493 0.00833001 0.611316 0.5 +0.00260773 0.0354887 0.0450013 0.261253 0.345588 +-0.0780807 0.10971 0.0423535 0.916894 0.5 +-0.0542262 0.124756 0.0369858 0.64506 0.5 +-0.0402584 0.0361447 0.0436625 0.193197 0.5 +-0.00317483 0.0942874 -0.0331049 0.71511 0.325502 +-0.0151032 0.179716 -0.0207621 0.731902 0.5 +0.026141 0.0403246 0.0327265 0.294647 0.339561 +-0.0640247 0.111376 -0.0136272 0.608847 0.5 +0.027817 0.112309 0.0339118 0.692282 0.5 +-0.0586332 0.142774 0.0334953 0.761767 0.5 +-0.0146622 0.167501 -0.0154455 0.61604 0.5 +-0.0270893 0.167298 -0.00866399 0.642638 0.5 +0.0152056 0.045813 0.0442638 0.487785 0.5 +0.0190988 0.0442996 0.0429 0.362689 0.463942 +0.0215694 0.0456112 0.041209 0.479281 0.5 +0.0257452 0.0459137 0.0381185 0.444171 0.5 +0.0387365 0.0944447 0.0327088 0.718127 0.5 +0.0287308 0.0456722 0.0347466 0.335561 0.431941 +-0.0151805 0.173809 -0.0213305 0.730436 0.5 +-0.0658903 0.118253 0.0498126 0.307185 0.5 +-0.0628345 0.093206 -0.0188544 0.659442 0.5 +-0.0643065 0.142451 0.0394123 0.621016 0.5 +-0.040079 0.150283 0.00280951 0.491474 0.5 +-0.026851 0.173268 -0.00983852 0.620534 0.5 +-0.0207913 0.173767 -0.0147826 0.653794 0.5 +-0.0582334 0.124238 0.0403406 0.70004 0.5 +-0.0683337 0.131545 0.0479709 0.732904 0.5 +-0.0693547 0.10637 -0.012803 0.472443 0.5 +-0.0428668 0.157627 0.0050419 0.670804 0.5 +-0.0476449 0.130368 0.0258834 0.623828 0.5 +0.0379451 0.0817167 -0.0141547 0.644934 0.5 +0.0312298 0.0470286 0.0324465 0.426433 0.5 +-0.0662284 0.138149 0.042896 0.72515 0.5 +-0.0644094 0.105575 -0.0158634 0.566501 0.5 +0.0411271 0.0443713 0.0285474 0.466284 0.5 +-0.0830031 0.0762361 0.0150296 0.67606 0.5 +-0.0660167 0.123488 0.0501643 0.718404 0.5 +-0.0416352 0.155329 0.00636435 0.466436 0.5 +-0.0388456 0.155994 0.00477206 0.438555 0.402124 +-0.0551732 0.116538 0.0359195 0.457649 0.5 +-0.0600069 0.134082 0.0369434 0.682472 0.5 +0.0452816 0.0453284 0.0263124 0.471094 0.5 +0.0513161 0.0463154 0.0204963 0.342211 0.398387 +-0.0106687 0.172847 -0.0215627 0.69267 0.5 +-0.0147735 0.18419 -0.0259341 0.309641 0.5 +0.0301064 0.106776 0.0358091 0.72383 0.5 +-0.063709 0.125122 0.0457451 0.712215 0.420475 +0.0473431 0.0499217 0.0295077 0.554948 0.5 +0.0497106 0.0482066 0.0259506 0.48379 0.5 +0.0518484 0.0518415 0.0267161 0.416499 0.5 +-0.0162732 0.172938 -0.0174582 0.719256 0.5 +0.0355097 0.107304 0.0291151 0.718782 0.5 +-0.0552656 0.143077 0.0300537 0.622521 0.5 +-0.0637191 0.136482 0.0388176 0.603354 0.5 +-0.0199086 0.161072 -0.00863325 0.350317 0.5 +-0.0209172 0.179282 -0.0148523 0.455842 0.5 +0.014511 0.0513519 0.0474271 0.589102 0.5 +-0.0610259 0.126912 0.0416133 0.698375 0.5 +0.0539905 0.0494141 0.0219114 0.418448 0.5 +0.00925922 0.118865 -0.0148674 0.54369 0.457314 +-0.0268384 0.162091 -0.00836699 0.546076 0.486591 +-0.0367024 0.163198 -0.00107067 0.680811 0.5 +-0.0336432 0.155948 0.00188963 0.445666 0.44081 +-0.0280966 0.159587 0.000483069 0.431301 0.5 +-0.026491 0.16163 -0.00321758 0.537982 0.323001 +0.0206613 0.0528733 0.0451655 0.647628 0.324331 +0.0231576 0.0513069 0.0414753 0.507052 0.5 +0.0266044 0.0526516 0.039853 0.635463 0.446542 +0.0309772 0.0527823 0.0371348 0.671735 0.5 +0.0239371 0.103424 0.0418106 0.654526 0.5 +0.0568895 0.0527484 0.0209204 0.474964 0.5 +-0.0664209 0.11329 0.0441331 0.212624 0.5 +-0.0326789 0.162384 -0.00243762 0.543585 0.5 +0.0145199 0.0932586 -0.026363 0.546403 0.5 +-0.0543983 0.119186 0.0365781 0.502204 0.44785 +-0.0564272 0.132376 0.0357966 0.720059 0.5 +-0.0501636 0.142911 0.00230897 0.376445 0.5 +-0.043714 0.147707 0.0038501 0.245798 0.5 +-0.0291346 0.177171 -0.00534178 0.371295 0.5 +0.0357304 0.100363 -0.0111604 0.61591 0.5 +0.0133943 0.0541536 0.0499521 0.532724 0.5 +0.0551089 0.0545007 0.0253961 0.545646 0.5 +0.0291033 0.0572886 0.0407089 0.633826 0.5 +0.0585723 0.0583402 0.0214893 0.549998 0.477428 +-0.0740322 0.0656952 0.0144875 0.594594 0.5 +-0.0749844 0.179305 -0.0518221 0.216638 0.5 +0.0145778 0.0585769 0.0501691 0.387785 0.5 +0.0214876 0.058332 0.0470549 0.596242 0.5 +0.0259507 0.0590004 0.0437762 0.663038 0.5 +0.032833 0.0585633 0.0387158 0.630786 0.5 +0.0358218 0.0578374 0.0350365 0.591179 0.5 +0.0360585 0.0951301 0.0364902 0.726421 0.5 +-0.0886806 0.118283 0.0459142 0.444358 0.5 +0.0562736 0.0586365 0.0253398 0.57284 0.5 +0.0303311 0.0951295 0.0419589 0.717458 0.5 +-0.0222315 0.167389 -0.0110472 0.688671 0.5 +-0.0543257 0.136577 0.0307959 0.688078 0.5 +-0.0500074 0.150447 0.0117579 0.563476 0.5 +-0.0616289 0.137406 0.0354744 0.592141 0.5 +-0.0319367 0.159507 0.00191749 0.44862 0.5 +-0.0634458 0.132148 0.0406867 0.731705 0.5 +0.0368678 0.0921989 0.0367449 0.708135 0.5 +-0.0728433 0.156137 -0.0339112 0.713518 0.5 +0.0389872 0.0640689 0.0330299 0.521361 0.5 +-0.0636611 0.1488 -0.0205996 0.618447 0.5 +0.0153938 0.0648444 0.0513036 0.554385 0.463079 +0.0213958 0.0645506 0.0473078 0.414803 0.412252 +0.0265105 0.0649235 0.0439721 0.611901 0.5 +0.0302364 0.0650657 0.0415975 0.600683 0.487653 +0.0331295 0.0642221 0.0397381 0.500385 0.490901 +0.0367885 0.065027 0.0366867 0.593561 0.5 +0.0563131 0.0650782 0.0252208 0.639437 0.5 +0.0591364 0.0644742 0.0211357 0.550839 0.448044 +-0.0110683 0.167098 -0.0167807 0.360187 0.5 +-0.0605202 0.146205 0.0366666 0.591479 0.5 +0.0194528 0.0665736 0.0491642 0.603282 0.5 +-0.0286777 0.158132 0.000508817 0.402765 0.431383 +0.0253025 0.0989569 0.0434277 0.623394 0.5 +-0.0349979 0.152158 8.20736e-05 0.217633 0.5 +0.014665 0.070627 0.0528306 0.52613 0.5 +0.0202908 0.071041 0.0498828 0.634288 0.435356 +0.0230702 0.0702991 0.0473835 0.571849 0.5 +0.0263693 0.0706238 0.0441789 0.622852 0.474797 +0.0328306 0.0707606 0.0401362 0.612279 0.409693 +0.0368832 0.070672 0.0365953 0.662199 0.5 +0.0398878 0.0705632 0.0325808 0.656566 0.5 +0.0579544 0.0694794 0.0198345 0.6125 0.5 +-0.0641704 0.063724 0.0268682 0.425507 0.418571 +-0.0919499 0.114216 0.0149265 0.530043 0.5 +0.0351624 0.0819076 -0.0172502 0.760295 0.5 +-0.0862408 0.119271 -0.00117534 0.455279 0.5 +-0.0294401 0.174958 -0.00579982 0.562984 0.5 +-0.0175288 0.165418 -0.0114925 0.675539 0.5 +-0.0617869 0.117789 0.0409144 0.40334 0.5 +0.0301891 0.0723658 0.0418804 0.606777 0.5 +-0.0822099 0.149486 0.00288044 0.385889 0.468811 +-0.0760271 0.175704 -0.0506937 0.340571 0.5 +-0.0652343 0.0614738 0.0211346 0.414933 0.425841 +-0.0266574 0.110394 -0.019007 0.783101 0.5 +-0.0813538 0.0779161 0.0268055 0.756683 0.5 +0.021417 0.118723 -0.00893569 0.549 0.5 +0.0149346 0.0759297 0.0536191 0.48671 0.476705 +0.0209886 0.0761609 0.0506055 0.575091 0.5 +0.0268396 0.0762089 0.0459193 0.572664 0.5 +0.0336785 0.0760737 0.0405166 0.630563 0.5 +0.0373422 0.0760306 0.0366776 0.505468 0.5 +0.0400324 0.0763062 0.0328345 0.645662 0.5 +0.0419048 0.076876 0.0296092 0.673034 0.5 +0.0438094 0.0763805 0.0258638 0.624347 0.5 +-0.0452412 0.118472 -0.0142046 0.833781 0.5 +0.0456773 0.0768089 0.0208187 0.458504 0.467907 +-0.050165 0.137714 0.0207618 0.606401 0.481088 +-0.00327054 0.111563 -0.0203549 0.551699 0.482404 +-0.0483236 0.145111 0.00757835 0.59165 0.5 +0.0310833 0.0775315 0.0432282 0.624343 0.5 +-0.046855 0.145222 0.00288431 0.195425 0.432502 +-0.0141716 0.10541 -0.0225802 0.672132 0.5 +0.0470348 0.0753979 0.0148736 0.455861 0.5 +-0.0611433 0.140542 0.0356184 0.646306 0.5 +0.0272779 0.0823714 0.0459243 0.61663 0.478488 +0.0309212 0.08255 0.0430252 0.611382 0.5 +0.0343037 0.0825412 0.0402907 0.613309 0.465282 +0.0370354 0.0824663 0.0369099 0.642585 0.5 +-0.0799946 0.147989 -0.000835337 0.484293 0.5 +-0.0774435 0.0690153 0.00961977 0.704234 0.277826 +0.0404363 0.0826995 0.0326021 0.686672 0.5 +0.0417479 0.0827335 0.0302524 0.63553 0.5 +0.0436887 0.0825508 0.0263844 0.61829 0.5 +0.0454407 0.0825465 0.0207137 0.601475 0.480065 +-0.0822812 0.116295 0.0482855 0.66926 0.5 +-0.0844726 0.0947391 -0.00345192 0.592061 0.5 +-0.020271 0.168003 -0.0193935 0.821267 0.5 +-0.0742716 0.0668501 0.0190414 0.706894 0.5 +0.026747 0.0882417 0.0458314 0.539865 0.389736 +0.0308722 0.0882572 0.0430146 0.948814 0.5 +0.0344922 0.0883047 0.0403697 0.638338 0.5 +0.0372481 0.0881263 0.0366393 0.643327 0.5 +0.039927 0.088094 0.0326668 0.711283 0.5 +0.0419027 0.0877782 0.0290815 0.667656 0.5 +0.00264738 0.112302 -0.019871 0.766242 0.5 +-0.0703315 0.1455 -0.0205576 0.136819 0.239158 +-0.0749446 0.137879 -0.00653312 0.459033 0.397283 +-0.0266967 0.114299 -0.0159903 0.856895 0.5 +-0.0869924 0.113518 0.00410409 0.344807 0.5 +-0.0142186 0.174013 -0.0259807 0.439072 0.5 +-0.0221564 0.157852 -0.00861651 0.254248 0.5 +-0.011587 0.164129 -0.0163045 0.228563 0.367524 +-0.00997381 0.169338 -0.0247765 0.42189 0.5 +-0.082875 0.143405 0.00186692 0.494272 0.5 +0.0203757 0.0354405 -0.00287175 0 0 +0.0191274 0.0363337 -0.00917714 0.174536 0.5 +0.0184456 0.036388 -0.013479 0.173751 0.5 +0.0149535 0.0347732 -0.0154937 0.144529 0.253209 +0.0221204 0.0372026 0.0342324 0.156956 0.287305 +0.039271 0.0382866 0.00854708 0.245023 0.5 +0.0397549 0.0398545 0.002614 0.276002 0.5 +0.0221892 0.0380614 -0.00446361 0.173629 0.5 +0.0179901 0.0369066 -0.0161835 0.336518 0.5 +0.0154148 0.0392444 -0.0212861 0.367832 0.5 +0.0208023 0.100118 -0.0213392 0.648293 0.46589 +0.0446004 0.0409064 0.00927401 0.208963 0.5 +0.0435625 0.0411355 0.00427044 0.357471 0.452104 +0.0381381 0.0411139 -0.00147908 0.514406 0.5 +-0.0478807 0.135207 0.00885778 0.482359 0.5 +0.0217274 0.0404287 -0.00964433 0.311593 0.5 +0.0206744 0.0405956 -0.0144437 0.473825 0.5 +0.0192578 0.0411681 -0.0195074 0.414351 0.5 +-0.0885736 0.112913 0.0395856 0.488806 0.5 +-0.026793 0.106457 -0.0218501 0.617481 0.5 +0.0481487 0.0428585 0.0145594 0.265572 0.5 +0.0521212 0.0461655 0.0089655 0.199267 0.5 +0.0480438 0.0430647 0.00724585 0.412258 0.5 +0.0460936 0.0434131 0.00284357 0.566688 0.5 +0.0285003 0.100485 -0.0168103 0.728425 0.5 +0.0269462 0.0395833 -0.00334578 0.464947 0.5 +-0.0907856 0.117838 0.00647331 0.421552 0.5 +-0.062721 0.167567 -0.0470628 0.645866 0.5 +-0.0799532 0.106813 0.0316838 0.420249 0.5 +0.0527437 0.0462125 0.0139554 0.286197 0.5 +0.0504533 0.0466263 0.00264513 0.57721 0.5 +-0.0322581 0.117324 -0.0133273 0.811815 0.5 +0.0272475 0.0455966 -0.00927071 0.533119 0.5 +-0.0146455 0.0942084 -0.0337341 0.520871 0.5 +-0.0411545 0.16722 -0.010818 0.48116 0.5 +-0.0721385 0.156112 -0.0384102 0.511983 0.468875 +0.0456803 0.0474217 -0.00311192 0.412576 0.5 +0.0239407 0.0433254 -0.00969837 0.651864 0.5 +0.021084 0.0462585 -0.0205303 0.476548 0.5 +-0.0348527 0.0351549 -0.0307351 0.16856 0.5 +-0.0699867 0.0663066 0.0259153 0.590849 0.43032 +-0.0747071 0.149891 -0.0201453 0.5851 0.5 +-0.0845448 0.13725 0.000743181 0.580039 0.5 +0.0549514 0.0484178 0.0163982 0.295573 0.5 +0.0264565 0.0466261 -0.0141039 0.515417 0.5 +0.0225276 0.0444655 -0.0157683 0.505631 0.5 +0.0330538 0.0938135 -0.0160538 0.699679 0.5 +0.0526476 0.0694992 0.00297306 0.629664 0.372945 +0.0528544 0.0581339 -0.00277966 0.592036 0.5 +-0.0571464 0.0671799 0.0361705 0.503626 0.472266 +-0.0651544 0.157167 -0.0515491 0.708429 0.5 +-0.0493189 0.133682 0.00119868 0.355836 0.438333 +-0.032962 0.10595 -0.0206729 0.810434 0.5 +-0.0649538 0.155656 -0.045631 0.820472 0.5 +-0.0390456 0.150445 -0.00354536 0.204281 0.5 +0.0574365 0.051618 0.0145183 0.351624 0.5 +0.0574129 0.0522531 0.00903377 0.511629 0.5 +0.0536112 0.0500965 0.00204174 0.768402 0.5 +0.0512204 0.0520121 -0.00218354 0.534755 0.5 +0.0471226 0.0515811 -0.00481298 0.434179 0.5 +0.033443 0.047576 -0.0063817 0.557462 0.465257 +0.00280933 0.118297 -0.0158208 0.570337 0.473222 +-0.0147841 0.10125 -0.0238408 0.771507 0.5 +-0.0620037 0.167422 -0.0527165 0.538383 0.466596 +0.0559147 0.0528382 0.00339683 0.824166 0.5 +0.0334801 0.0518506 -0.00825293 0.591066 0.5 +0.0287814 0.0501171 -0.0157926 0.574224 0.5 +0.0256197 0.0485542 -0.0190548 0.421586 0.5 +-0.00863537 0.118406 -0.0146114 0.827086 0.5 +-0.0148322 0.117675 -0.014701 0.559736 0.5 +-0.0615138 0.145712 -0.00481276 0.466074 0.5 +0.0232531 0.12083 -0.00456186 0.617393 0.5 +-0.0401535 0.0342718 -0.0275149 0.0979878 0.5 +0.0302657 0.0496868 -0.0107289 0.647285 0.5 +0.0320066 0.111334 -0.00737407 0.536101 0.5 +-0.0211003 0.120417 -0.0102482 0.732965 0.5 +-0.0204991 0.117125 -0.0140803 0.767014 0.5 +-0.00910263 0.0383602 -0.025776 0.274297 0.5 +-0.0525144 0.11229 -0.0171034 0.442719 0.484227 +0.0202353 0.123713 -0.00247094 0.59012 0.5 +-0.0701749 0.0347541 -0.0017891 0.135623 0.5 +-0.00340266 0.114844 -0.0176928 0.826111 0.5 +0.0310248 0.053713 -0.0140522 0.572913 0.5 +0.0268191 0.0528482 -0.020339 0.412387 0.455219 +-0.0147458 0.120673 -0.0105853 0.653192 0.5 +0.0270905 0.106214 -0.0146756 0.603346 0.5 +0.0465541 0.0697991 0.00228503 0.590477 0.5 +-0.00300122 0.100676 -0.0235814 0.77298 0.5 +-0.0755874 0.076212 0.033468 0.651011 0.5 +0.059738 0.0572998 0.0151736 0.624329 0.5 +0.0595394 0.0578717 0.00861672 0.650231 0.5 +0.0572091 0.0580526 0.00253507 0.577167 0.5 +-0.0142907 0.123147 -0.00746744 0.689207 0.5 +0.0211831 0.112303 -0.0140834 0.636933 0.5 +0.0347455 0.0565046 -0.010714 0.517615 0.5 +0.0249138 0.0825163 -0.0245877 0.759593 0.5 +-0.0382227 0.114521 -0.016178 0.845616 0.5 +-0.0819485 0.0761672 0.0208322 0.76776 0.5 +-0.0269557 0.0392251 -0.0293943 0.537642 0.5 +0.0377037 0.0593401 -0.00852013 0.537798 0.5 +0.0330295 0.0586306 -0.014729 0.60439 0.5 +0.0218121 0.0515865 -0.0236492 0.56032 0.5 +-0.0204953 0.0935908 -0.0331675 0.485557 0.5 +-0.0872217 0.113521 0.0440666 0.448078 0.427651 +-0.0271537 0.0351608 0.0509267 0.96808 0.5 +-0.0503825 0.106302 -0.0194598 0.649024 0.5 +0.0266611 0.0585067 -0.0219134 0.622435 0.5 +0.00975018 0.0945932 -0.0280451 0.504262 0.457756 +-0.0205524 0.122391 -0.00754739 0.498583 0.5 +-0.0668021 0.0909191 -0.0174744 0.566525 0.5 +-0.0856155 0.0942099 -0.00109094 0.420789 0.436678 +-0.0915274 0.11444 0.0204492 0.759207 0.5 +-0.0909048 0.131701 0.00809159 0.558083 0.5 +0.0404851 0.0578886 -0.0051698 0.425865 0.437223 +0.0295964 0.0580473 -0.0178274 0.608291 0.460655 +0.0266986 0.0941359 -0.0205949 0.662934 0.5 +-0.0677104 0.172869 -0.0572602 0.695141 0.5 +0.0142001 0.118043 -0.013917 0.45799 0.403894 +-0.0698171 0.0699687 0.0326375 0.529959 0.5 +0.0607097 0.0648802 0.0151632 0.434757 0.451533 +0.0609346 0.0630505 0.0131585 0.526971 0.5 +0.0602205 0.0643718 0.00864139 0.443146 0.456896 +0.0574055 0.0638877 0.00271573 0.413274 0.5 +-0.0797793 0.103858 -0.00660016 0.553637 0.5 +-0.0563867 0.137359 -0.00421998 0.659682 0.5 +0.0344512 0.0638263 -0.0152012 0.581486 0.5 +0.0307139 0.0605317 -0.0184589 0.617611 0.449874 +0.0185684 0.121789 -0.00725624 0.61441 0.349043 +-0.0456617 0.112414 -0.0169658 0.70381 0.5 +0.0456177 0.0644845 -0.00162168 0.572144 0.5 +-0.0584268 0.0349015 0.0441202 0.767369 0.5 +-0.0747982 0.0723674 0.0308514 0.656357 0.5 +-0.0699373 0.0621854 0.0151778 0.587415 0.5 +-0.052889 0.136519 -0.00170821 0.593683 0.5 +0.0410205 0.0644886 -0.00476733 0.363401 0.5 +0.0388712 0.0646166 -0.00976797 0.384344 0.5 +0.0514871 0.0637279 -0.00174794 0.518067 0.5 +-0.0787297 0.0744551 0.0267421 0.809934 0.5 +-0.0850281 0.144269 0.00618082 0.578063 0.5 +0.0313094 0.064487 -0.0188936 0.672704 0.5 +0.0267274 0.0646171 -0.0220842 0.752591 0.5 +0.0318737 0.0877439 -0.0192705 0.740422 0.5 +-0.0772455 0.143995 -0.00470939 0.452269 0.5 +0.0132576 0.110443 -0.0183541 0.539267 0.5 +-0.00289343 0.124723 -0.00863032 0.516883 0.5 +-0.0342868 0.038582 0.0485461 0.546061 0.5 +0.0200397 0.0876233 -0.0261205 0.735721 0.5 +0.0585453 0.0705354 0.0146976 0.608535 0.5 +0.0581405 0.0699819 0.00856199 0.483528 0.5 +0.056099 0.069436 0.00424359 0.385578 0.5 +0.0370479 0.0665186 -0.0132637 0.645736 0.5 +-0.062561 0.172971 -0.0616721 0.43069 0.5 +-0.0702718 0.15494 -0.0455472 0.29179 0.457421 +-0.0916259 0.130499 0.00930481 0.432982 0.472725 +-0.070021 0.148229 -0.0328231 0.322588 0.195946 +-0.0721274 0.0680183 0.0267753 0.656727 0.5 +-0.0745337 0.15067 -0.0264303 0.331486 0.5 +0.0431087 0.0713461 -0.002764 0.390428 0.45538 +0.0421659 0.0692525 -0.00466106 0.55545 0.5 +0.0345404 0.0699378 -0.0160391 0.727409 0.5 +-0.0342368 0.122912 -0.00708584 0.432969 0.5 +0.0401518 0.070932 -0.00951127 0.706551 0.5 +0.0370706 0.0707408 -0.013301 0.722628 0.5 +0.0310856 0.0702175 -0.0192905 0.761897 0.5 +0.0283004 0.0705453 -0.0222447 0.701199 0.5 +-0.00859023 0.101699 -0.0237897 0.731824 0.5 +-0.0328234 0.0400139 -0.029875 0.413461 0.5 +-0.0830588 0.11047 0.0397334 0.931001 0.5 +0.0142724 0.123237 -0.00806485 0.479991 0.484444 +-0.0760443 0.108637 0.0389078 0.769887 0.5 +-0.0732762 0.154939 -0.0321392 0.640327 0.5 +0.0160324 0.0889232 -0.0282477 0.595959 0.5 +-0.0901677 0.131361 0.0394374 0.633972 0.457764 +0.0455828 0.0768365 0.00270178 0.323813 0.5 +-0.0516717 0.0553965 0.014906 0.168077 0.5 +-0.0376545 0.121002 -0.0109724 0.599451 0.451266 +0.0466318 0.0762885 0.00910629 0.334003 0.5 +0.0437303 0.0769241 -0.00295564 0.541016 0.5 +0.0405043 0.0766784 -0.0084913 0.540094 0.5 +0.0369463 0.0762836 -0.0128837 0.716695 0.5 +0.0349351 0.0766648 -0.0155944 0.687304 0.5 +0.0319237 0.0763904 -0.0194186 0.722365 0.5 +0.0285208 0.0758075 -0.0225233 0.729644 0.5 +-0.0646857 0.068809 0.0348219 0.518098 0.396839 +-0.00335573 0.0986136 -0.0269283 0.762285 0.5 +-0.0383606 0.100112 -0.0217661 0.633523 0.5 +-0.0705433 0.149897 -0.0387319 0.143598 0.5 +-0.0247871 0.179215 -0.0188356 0.466421 0.5 +0.00339058 0.0937023 -0.0318365 0.697748 0.5 +-0.09099 0.142689 0.0226645 0.743514 0.5 +-0.0851088 0.102115 0.000391121 0.420019 0.403283 +0.00299202 0.124707 -0.00864775 0.631346 0.5 +-0.0649459 0.167336 -0.0329944 0.692397 0.5 +0.045975 0.0827243 0.0146716 0.494123 0.463874 +0.0461931 0.0827376 0.00867911 0.540283 0.443947 +0.0453461 0.0826602 0.00269811 0.520808 0.5 +0.032594 0.082231 -0.0190597 0.700575 0.5 +-0.0707752 0.142011 -0.00901143 0.440829 0.5 +-0.0396694 0.045239 -0.0210351 0.371561 0.5 +-0.0736488 0.145787 -0.0131048 0.298566 0.5 +-0.0661855 0.1779 -0.0529018 0.456268 0.5 +-0.0698006 0.179227 -0.0517285 0.330383 0.5 +-0.0719677 0.177848 -0.0474604 0.498199 0.393806 +-0.0131817 0.0974247 0.0509808 0.29677 0.5 +-0.0760529 0.177651 -0.0471457 0.200482 0.341482 +-0.0875274 0.149451 0.00937476 0.260452 0.5 +-0.0847504 0.149536 0.00652369 0.220089 0.5 +-0.0853843 0.0980412 -0.000554198 0.453316 0.5 +-0.070162 0.172945 -0.0393132 0.377002 0.42015 +-0.0669053 0.17136 -0.0404187 0.587367 0.5 +-0.0915765 0.114644 0.0108349 0.335405 0.476851 +0.0311175 0.116345 -0.00142056 0.524001 0.485056 +-0.09039 0.144074 0.0142555 0.571623 0.5 +0.0533752 0.0724173 0.00805773 0.504643 0.5 +0.0348115 0.113636 0.00289967 0.517745 0.5 +0.0321047 0.117128 0.00373672 0.512637 0.481334 +-0.0558554 0.16013 0.00226313 0.176407 0.35978 +0.0284127 0.12005 0.00266093 0.800124 0.5 +-0.0693417 0.151526 -0.0443255 0.162625 0.220555 +0.0509143 0.0733396 0.0112131 0.81315 0.5 +0.0485286 0.0726358 0.00856732 0.779683 0.5 +0.0251471 0.122517 0.00254898 0.804299 0.5 +-0.0684168 0.170157 -0.0319531 0.535557 0.5 +-0.071028 0.171274 -0.0325886 0.712016 0.5 +-0.0765634 0.155757 -0.00874762 0.256295 0.5 +0.0525206 0.0734678 0.0148876 0.468908 0.45355 +0.035521 0.113454 0.00908801 0.654915 0.5 +0.0208324 0.125627 0.00327965 0.76886 0.5 +-0.0476722 0.134348 0.0194434 0.579216 0.488505 +-0.0746083 0.171229 -0.0326516 0.439107 0.422901 +0.0322027 0.117616 0.0093642 0.646061 0.5 +0.0162523 0.127588 0.00132734 0.679655 0.445027 +-0.0914669 0.142805 0.0167223 0.344959 0.5 +0.0290775 0.120474 0.00686894 0.798143 0.5 +0.0135909 0.12914 0.00336546 0.632038 0.474565 +-0.0861635 0.100458 0.025719 0.514874 0.431291 +-0.0653051 0.165945 -0.0269849 0.665887 0.5 +-0.0698492 0.16889 -0.0268648 0.536219 0.5 +-0.07827 0.167473 -0.032496 0.259817 0.452429 +0.0215557 0.0945234 -0.0226594 0.630702 0.48336 +0.0260612 0.123082 0.00873766 0.803075 0.5 +0.00920342 0.130081 0.00248247 0.641161 0.5 +-0.0709934 0.170517 -0.0295248 0.566905 0.409383 +-0.0760202 0.167938 -0.0272636 0.242234 0.5 +0.0525229 0.0716654 0.0211203 0.349876 0.431389 +0.0207167 0.126566 0.00922145 0.763786 0.5 +-0.0746025 0.0998033 -0.0126456 0.503102 0.5 +-0.0864333 0.0890874 0.0257055 0.752441 0.5 +0.0354941 0.113435 0.0150848 0.708057 0.5 +0.0320737 0.117698 0.0146262 0.694886 0.5 +0.00294754 0.130714 0.00292443 0.849802 0.5 +-0.0256391 0.0823957 0.0519489 0.764034 0.5 +-0.0666258 0.165416 -0.0221631 0.534987 0.5 +-0.0804177 0.153092 0.00488677 0.321879 0.39417 +-0.0645623 0.0350017 0.0151892 0.352362 0.5 +-0.0627936 0.0352479 0.02012 0.616295 0.5 +-0.0642932 0.0349381 0.0264604 0.161121 0.384305 +-0.0642421 0.0397497 0.0267659 0.206373 0.5 +-0.0652419 0.0352202 0.0324357 0.167045 0.5 +-0.06432 0.0352261 0.0387914 0.349097 0.5 +-0.0869014 0.0944088 0.0260869 0.722262 0.5 +-0.026376 0.100403 -0.0237519 0.527518 0.47737 +-0.0704394 0.0348288 0.00888692 0.228898 0.5 +-0.0696375 0.039673 0.0091864 0.30841 0.5 +-0.0678064 0.035728 0.013362 0.509091 0.5 +-0.0778433 0.0819732 0.0354617 0.774608 0.5 +-0.0809318 0.0827942 0.0325 0.767831 0.5 +-0.0712316 0.038974 0.00275642 0.155719 0.237906 +-0.0616101 0.0379618 0.0219344 0 0 +-0.0653778 0.0407054 0.0323415 0.379158 0.5 +-0.0612949 0.040108 0.0438783 0.388361 0.5 +-0.0748891 0.0826916 0.0381154 0.772848 0.5 +-0.0841641 0.133769 0.0486564 0.546232 0.467433 +-0.0849106 0.0945271 0.0290479 0.754258 0.5 +-0.082994 0.144712 0.0404065 0.382972 0.420138 +-0.0265479 0.117619 -0.0132781 0.755106 0.5 +-0.0679678 0.0383221 0.0123903 0.271535 0.306541 +-0.0639259 0.0401146 0.0151101 0.258252 0.450399 +-0.0588527 0.0407802 0.0202136 0.51937 0.5 +-0.0869621 0.135589 0.0440584 0.520567 0.5 +-0.038827 0.0398484 0.042564 0.570175 0.5 +-0.0253238 0.0773437 0.0501603 0.646885 0.5 +0.00864855 0.111878 -0.0192252 0.821439 0.5 +-0.0625014 0.04424 0.0388616 0.455153 0.47063 +-0.088493 0.125258 0.0461673 0.674925 0.5 +0.0150785 0.10107 -0.0220372 0.749486 0.5 +-0.0810533 0.0876325 0.0334622 0.750019 0.5 +-0.0636602 0.0439221 0.0322355 0.437404 0.5 +-0.0823757 0.12585 -0.00459555 0.376136 0.464207 +-0.0374554 0.042873 0.0429512 0.492581 0.5 +-0.031328 0.0432863 0.0501185 0.483275 0.5 +-0.0841802 0.0875016 0.0285815 0.671149 0.464325 +-0.0690099 0.0427216 0.00298087 0.372436 0.5 +-0.0690323 0.0427133 0.00739115 0.277083 0.5 +-0.0642007 0.0449178 0.00895163 0.562755 0.5 +-0.0630005 0.0427497 0.0133004 0.520064 0.348086 +-0.0580777 0.0444032 0.0143596 0.493924 0.5 +-0.087476 0.130712 0.0458544 0.531379 0.477045 +-0.0837712 0.0999337 0.029339 0.668895 0.5 +-0.083719 0.0822846 0.0270932 0.660348 0.5 +-0.0209183 0.0934772 0.0512134 0.479975 0.5 +-0.0868983 0.142651 0.0383505 0.486766 0.469754 +-0.0588984 0.0467651 0.00989959 0.460736 0.319245 +-0.0529144 0.0464475 0.0158024 0.381525 0.5 +-0.0881654 0.0882094 0.0209192 0.624947 0.5 +-0.0494075 0.165901 0.000731671 0.369742 0.391777 +-0.0586114 0.0473978 0.0337061 0.152377 0.410418 +-0.05614 0.0517476 0.00835186 0.396733 0.5 +-0.0865231 0.148073 0.0321271 0.367072 0.452379 +-0.0308497 0.0493297 0.0429654 0.330168 0.454747 +-0.0769102 0.114994 0.0501188 0.653806 0.5 +-0.0209065 0.0959579 0.0474195 0.622864 0.5 +-0.0509947 0.0509637 0.0150799 0.759028 0.5 +0.00842415 0.0889657 -0.0320537 0.627702 0.5 +-0.0240561 0.0544386 0.0416973 0.433194 0.5 +-0.0510392 0.0524223 0.0203213 0.262945 0.5 +-0.0526208 0.0518271 0.027021 0.695325 0.5 +-0.0504022 0.0591186 0.0326891 0.768296 0.5 +-0.0478821 0.0590694 0.0363134 0.800191 0.5 +-0.0239128 0.0586553 0.0421308 0.768223 0.5 +-0.0759314 0.119228 -0.00697007 0.568703 0.5 +-0.0183181 0.0604564 0.0506182 0.70539 0.5 +-0.0298441 0.0972531 -0.0235715 0.830462 0.5 +-0.0241926 0.0628773 0.0422936 0.709715 0.5 +-0.0223998 0.06467 0.045979 0.606456 0.5 +-0.0192899 0.0641483 0.0503928 0.754401 0.5 +-0.0260109 0.172925 -0.0191453 0.51739 0.5 +-0.0265331 0.161574 -0.0144318 0.84044 0.5 +-0.0558556 0.15572 -0.00121016 0.41523 0.5 +-0.0599028 0.136466 -0.0064456 0.660892 0.5 +-0.063538 0.071665 0.0379463 0.556494 0.5 +-0.0200417 0.0869862 -0.0378876 0.500126 0.449734 +-0.0557176 0.105745 -0.0186241 0.707273 0.5 +-0.0530691 0.143914 -0.00100898 0.728895 0.5 +-0.0256688 0.0704637 0.0438935 0.717372 0.393932 +-0.0235577 0.0693774 0.0470203 0.657726 0.5 +-0.0525759 0.127247 -0.00521525 0.567734 0.5 +-0.0787859 0.131858 -0.00545913 0.44224 0.460808 +-0.0580212 0.120088 -0.0102747 0.564344 0.455328 +-0.0396294 0.110441 -0.0186258 0.62346 0.5 +-0.0210282 0.173113 -0.0214922 0.42389 0.352327 +-0.0547593 0.0563289 0.0107147 0.179388 0.5 +-0.0435534 0.0345758 -0.024752 0.176398 0.205782 +-0.0449833 0.0346921 -0.0207483 0.159962 0.261208 +-0.0443576 0.0390403 -0.0217491 0.178142 0.5 +-0.0462855 0.0345037 -0.0153112 0.189574 0.5 +-0.046619 0.0396457 -0.0141457 0.194812 0.5 +-0.00904923 0.0343826 -0.0246429 0.15305 0.5 +0.00311748 0.100303 -0.0227929 0.684313 0.5 +-0.0690809 0.0392217 -0.00181724 0.169982 0.409113 +-0.0920289 0.131041 0.0262349 0.856795 0.5 +-0.043414 0.0372487 -0.0253064 0.219927 0.5 +0.0280974 0.0818294 -0.0220931 0.752623 0.5 +-0.067702 0.169446 -0.0560134 0.487347 0.455218 +-0.0915377 0.129674 0.0312365 0.601516 0.48259 +-0.0663086 0.0411162 -0.00443149 0.346306 0.5 +-0.0731255 0.151935 -0.0368879 0.40925 0.5 +-0.0390145 0.0394889 -0.027598 0.3765 0.5 +-0.0637372 0.0437827 -0.00264533 0.37233 0.5 +-0.0605427 0.0425565 0.0246975 0.23689 0.5 +-0.0857603 0.130763 -0.000714461 0.66754 0.5 +-0.0520472 0.0403573 -0.0107411 0.62257 0.5 +-0.0568522 0.0434504 0.0224413 0.404188 0.5 +-0.043239 0.0429342 -0.0193166 0.339314 0.38382 +-0.0438787 0.0441322 -0.0144222 0.427488 0.468839 +-0.0457505 0.046486 -0.0105694 0.340556 0.5 +-0.0645938 0.0456897 0.00313082 0.3549 0.5 +-0.0525978 0.0464843 0.0207116 0.3335 0.5 +-0.0572578 0.0459489 0.026887 0.439332 0.5 +-0.0618962 0.0443648 0.0286813 0.302557 0.45843 +-0.0331467 0.0453179 -0.0267282 0.481653 0.5 +-0.0377669 0.0443547 -0.0252099 0.392631 0.5 +-0.0320922 0.114425 -0.0162304 0.853943 0.5 +-0.0578027 0.0470669 -0.0032674 0.530144 0.5 +-0.0914954 0.147994 0.0205137 0.478387 0.480384 +-0.0400067 0.0471536 -0.0151042 0.224844 0.33752 +0.00454895 0.121869 -0.0124797 0.622385 0.5 +0.0151282 0.112708 -0.0165496 0.634759 0.463552 +-0.0525787 0.0463291 -0.00775444 0.598118 0.5 +-0.0599276 0.0475112 0.00267117 0.286734 0.429608 +-0.0726458 0.147126 -0.0218625 0.235551 0.5 +-0.0740924 0.168686 -0.0440312 0.451963 0.347747 +-0.057494 0.0515426 0.00319413 0.311918 0.5 +-0.0536918 0.0483048 0.0264945 0.447469 0.5 +-0.0147156 0.114453 -0.0172255 0.634887 0.5 +-0.0335191 0.0480424 -0.021246 0.299501 0.5 +0.019461 0.0924333 -0.0244344 0.636237 0.5 +0.0169402 0.0952065 -0.0238278 0.793707 0.5 +0.0201047 0.104156 -0.0188197 0.859301 0.5 +-0.0319642 0.0516657 -0.0152509 0.265727 0.5 +-0.0368448 0.0488256 -0.0131071 0.109826 0.5 +-0.0391265 0.0518909 -0.0109467 0.555432 0.5 +-0.00892221 0.111576 -0.0202733 0.785262 0.5 +-0.0515659 0.0515158 -0.00751393 0.527245 0.5 +-0.0557028 0.05294 -0.00268598 0.514955 0.5 +-0.0293421 0.0526398 -0.0213991 0.356317 0.5 +-0.0314453 0.0496351 -0.0193539 0.306544 0.5 +0.0322381 0.10409 -0.0128482 0.653044 0.5 +-0.0261025 0.0525801 -0.0264669 0.366688 0.5 +-0.0583031 0.116733 -0.0130038 0.568329 0.5 +-0.014851 0.111599 -0.0191484 0.630253 0.463696 +-0.0521348 0.118189 -0.0137451 0.464136 0.474515 +-0.0517493 0.0582798 -0.00896954 0.683087 0.5 +-0.0561982 0.0582462 -0.00310645 0.618759 0.5 +-0.0587989 0.0586119 0.00276734 0.328771 0.427166 +-0.0585564 0.0578416 0.00857596 0.293131 0.5 +0.019026 0.11614 -0.0131686 0.497701 0.5 +-0.0211893 0.111662 -0.0190883 0.650648 0.5 +-0.0239176 0.0561149 -0.030057 0.484351 0.5 +-0.0272603 0.058548 -0.027478 0.457773 0.5 +-0.0295766 0.0582799 -0.0217551 0.550969 0.5 +-0.0320928 0.0589382 -0.0147618 0.534177 0.453646 +0.0073938 0.121789 -0.0126555 0.654152 0.5 +-0.0251946 0.0595227 -0.0308632 0.509396 0.5 +-0.0307167 0.06013 -0.0194181 0.549851 0.422118 +-0.0650113 0.0632174 -0.00293095 0.168435 0.5 +-0.0696479 0.065751 -0.00198101 0.165663 0.5 +-0.0699926 0.0635013 0.00374106 0.275779 0.5 +-0.0799435 0.0724812 0.0191514 0.599916 0.5 +-0.0676844 0.160922 -0.0559942 0.35716 0.5 +-0.0215435 0.0636559 -0.0350431 0.45692 0.5 +-0.0258325 0.0648252 -0.0322087 0.452259 0.5 +-0.028982 0.0636438 -0.0274997 0.410415 0.5 +-0.0304226 0.0629368 -0.0224261 0.908229 0.5 +-0.0319042 0.0651819 -0.0201942 0.518875 0.434998 +-0.0332741 0.0636337 -0.0160032 0.40837 0.447765 +-0.0205547 0.034111 -0.026401 0.174612 0.215481 +-0.0743367 0.0658286 0.00833126 0.649876 0.5 +0.016103 0.120745 -0.0103843 0.509865 0.5 +-0.0770212 0.0700544 0.00316631 0.305775 0.384345 +-0.0748219 0.06693 0.00451345 0.433069 0.463791 +-0.0306317 0.0657524 -0.025453 0.517895 0.5 +-0.0711433 0.0687078 -0.00390291 0.256016 0.135401 +-0.0762625 0.0716316 -0.00295918 0.293636 0.296358 +-0.0802204 0.0713935 0.00991267 0.507181 0.5 +-0.0913413 0.148143 0.0161458 0.474933 0.5 +-0.0273736 0.0700052 -0.0335323 0.445714 0.5 +-0.0300274 0.0692073 -0.0289677 0.511122 0.5 +-0.0316277 0.0711218 -0.0266514 0.502235 0.5 +-0.0330629 0.0699765 -0.0212743 0.929225 0.5 +-0.0353642 0.0705896 -0.0177097 0.263666 0.5 +-0.0587004 0.0391044 -0.0090027 0.295521 0.5 +-0.0697696 0.0703857 -0.00808666 0.238472 0.5 +-0.0804832 0.0726462 0.00472466 0.630221 0.5 +0.0151616 0.126104 -0.00266395 0.542796 0.5 +-0.0745721 0.072883 -0.00757069 0.303203 0.5 +-0.0823908 0.076277 0.00270117 0.615888 0.5 +-0.0912831 0.133698 0.0142161 0.68945 0.5 +0.00371049 0.0968817 -0.0280931 0.670854 0.5 +-0.0761392 0.0766258 -0.00859487 0.260107 0.5 +-0.0784749 0.0748827 -0.00523624 0.238143 0.440892 +-0.0806781 0.0771902 -0.00290803 0.36458 0.43512 +-0.0834622 0.0765209 0.00927112 0.562933 0.5 +0.00983826 0.11402 -0.0178612 0.519736 0.475688 +0.00210649 0.0981565 -0.0261244 0.689185 0.5 +-0.0285085 0.0757575 -0.0348118 0.64535 0.304239 +-0.0330874 0.0761249 -0.0270661 0.564742 0.5 +-0.0346568 0.0757906 -0.0215029 0.930953 0.5 +0.0231104 0.0892807 -0.0240236 0.697809 0.45449 +-0.0312132 0.0771357 -0.0320416 0.687582 0.5 +-0.0700425 0.0763633 -0.0141464 0.485274 0.5 +-0.0861137 0.0814707 0.00908143 0.590509 0.5 +-0.086319 0.08152 0.0149936 0.698173 0.5 +-0.0208042 0.0963182 -0.0270563 0.75553 0.5 +-0.0211078 0.114391 -0.0171285 0.793027 0.5 +-0.0746162 0.0828529 -0.0139325 0.683447 0.5 +-0.077295 0.081216 -0.0100568 0.47673 0.5 +-0.0800127 0.0821605 -0.00722237 0.637376 0.5 +-0.0826334 0.0820868 -0.00324616 0.569954 0.5 +-0.0844667 0.0817669 0.00249573 0.601403 0.5 +-0.0860445 0.0832591 0.0203255 0.630527 0.5 +-0.084816 0.0816746 0.0219849 0.638209 0.5 +0.0545549 0.0661692 0.000765649 0.628404 0.43579 +-0.0331604 0.0828369 -0.0270493 0.417784 0.5 +-0.0358028 0.0829047 -0.0227723 0.112354 0 +-0.0861942 0.0842505 0.00298565 0.418742 0.5 +-0.0287072 0.0827267 -0.0349537 0.48086 0.471486 +-0.0311601 0.0822387 -0.0315627 0.627475 0.5 +-0.085403 0.141865 0.00516647 0.463398 0.5 +-0.0785169 0.0885628 -0.0107607 0.69884 0.5 +-0.0807046 0.0887676 -0.00826584 0.689404 0.5 +-0.0843972 0.0878743 -0.00349923 0.402052 0.5 +-0.0855708 0.0882073 -0.00109946 0.425364 0.422235 +-0.0876157 0.0881286 0.00369184 0.414972 0.435161 +-0.0885339 0.0876942 0.00897158 0.630733 0.5 +-0.0885791 0.0877213 0.0149616 0.665472 0.5 +-0.0643854 0.0348576 -0.00775085 0.279509 0.5 +-0.0512932 0.034227 -0.0129013 0.159841 0.5 +-0.0266839 0.0458556 -0.027274 0.610127 0.5 +-0.0146368 0.0981541 -0.0264318 0.44201 0.5 +-0.0213468 0.10077 -0.0239588 0.58675 0.5 +0.020932 0.0825954 -0.0267347 0.750174 0.5 +0.00759225 0.0928541 -0.0309237 0.580726 0.5 +-0.0144478 0.0879274 -0.0380297 0.689122 0.5 +-0.00859724 0.11451 -0.0173132 0.77831 0.5 +0.0264818 0.109935 -0.0126182 0.652634 0.5 +-0.0145855 0.0385179 -0.0267991 0.230538 0.5 +-0.0330054 0.0337044 -0.0272991 0.262513 0.5 +-0.0267872 0.0340475 -0.0271901 0.244173 0 +-0.00849157 0.0985859 -0.0270535 0.53889 0.411612 +-0.0110954 0.120824 -0.0120135 0.770076 0.5 +0.0367379 0.0925992 -0.0129888 0.684003 0.5 +-0.0571635 0.0435755 -0.00717607 0.581004 0.404197 +-0.0193328 0.0979251 -0.024792 0.661276 0.5 +-0.0203798 0.0385467 -0.0283088 0.392689 0.5 +-0.0587681 0.0337133 -0.00871891 0.1361 0.5 +-0.0517919 0.100655 -0.0213258 0.798237 0.5 +0.00702627 0.0978418 -0.0246055 0.732067 0.326346 +-0.0148892 0.126068 -0.00252126 0.467449 0.5 +0.0307578 0.092446 -0.0188519 0.704525 0.5 +0.0211049 0.0578126 -0.0266116 0.685576 0.5 +-0.0169237 0.0970481 -0.0278718 0.775366 0.5 +0.0460004 0.0581866 -0.00508589 0.612698 0.5 +-0.00944331 0.0822271 -0.0381067 0.670336 0.467319 +-0.0635881 0.0392124 -0.00717766 0.572252 0.5 +0.00864227 0.0386371 -0.0233053 0.540697 0.5 +0.0252935 0.0769557 -0.0248407 0.75695 0.5 +-0.0229653 0.0895159 -0.036199 0.454072 0.467569 +-0.0523791 0.0341193 -0.00994653 0.132813 0.5 +0.0211693 0.0643935 -0.0268578 0.690366 0.5 +-0.0515867 0.13164 -0.0028092 0.545448 0.5 +-0.0149669 0.0345529 -0.0254273 0.17846 0.5 +-0.0161167 0.127288 0.00169291 0.694465 0.5 +-0.0469232 0.128515 -0.00163965 0.389857 0.5 +-0.00961381 0.127158 -0.00378809 0.714685 0.5 +-0.0074566 0.128562 -0.00130751 0.72817 0.5 +-0.00304493 0.128909 -0.00174857 0.778769 0.5 +0.0028379 0.129022 -0.00194723 0.574275 0.5 +0.00903363 0.128674 -0.00165013 0.617309 0.5 +-0.0561607 0.131588 -0.00571429 0.687735 0.5 +-0.0457551 0.127167 -0.00484962 0.645893 0.5 +-0.00304746 0.127678 -0.00456004 0.562309 0.5 +0.00303811 0.12768 -0.00442 0.624596 0.5 +0.0101526 0.126812 -0.00466464 0.64326 0.5 +-0.0553259 0.126836 -0.00601308 0.517644 0.5 +0.00799473 0.034846 -0.0206913 0.278473 0.5 +0.0027179 0.0342191 -0.0204737 0.322372 0.5 +-0.00295804 0.0342418 -0.0216222 0.194059 0.5 +0.0134674 0.0353221 -0.0196961 0.466171 0.5 +0.00440963 0.0383063 -0.0240776 0.3469 0.5 +0.00140752 0.0383474 -0.0246147 0.361099 0.5 +-0.00309177 0.0383877 -0.0251866 0.314174 0.5 +-0.0575023 0.100661 -0.0195211 0.459895 0.452391 +-0.0485739 0.15316 -0.00547278 0.691758 0.5 +-0.0646573 0.0334831 -0.00296009 0.187639 0.5 +-0.0640796 0.100426 -0.0173936 0.44544 0.466101 +-0.0704415 0.100139 -0.0146037 0.499781 0.478548 +-0.0326376 0.155806 -0.00949884 0.828995 0.5 +0.0336094 0.0373624 0.00273412 0.290019 0.5 +0.0320943 0.0397885 -0.00195136 0.323719 0.5 +0.0158502 0.0449602 -0.0237212 0.910511 0.5 +0.00889467 0.0426449 -0.0242659 0.891863 0.5 +0.00312499 0.0452721 -0.026588 0.665265 0.460024 +-0.00298345 0.044686 -0.0272222 0.905955 0.5 +-0.00912346 0.0448524 -0.0280671 0.895801 0.5 +-0.0145351 0.0443266 -0.0277771 0.887903 0.5 +-0.0209223 0.0460913 -0.0281918 0.705844 0.5 +0.034052 0.0448434 -0.00540113 0.626363 0.5 +-0.0312646 0.158257 -0.01223 0.732334 0.5 +0.0401509 0.0448981 -0.00354586 0.446696 0.5 +0.0143253 0.0473484 -0.0251513 0.546545 0.456757 +0.00937888 0.0466526 -0.0261685 0.907397 0.5 +-0.0766531 0.0695423 0.0207982 0.774152 0.5 +0.0087246 0.0517916 -0.0291615 0.840924 0.5 +0.00299372 0.0506927 -0.0298557 0.901259 0.5 +-0.00164566 0.0489436 -0.0304144 0.872257 0.5 +-0.00321397 0.0522596 -0.0314075 0.634884 0.475184 +-0.00915341 0.0509217 -0.0318681 0.650022 0.5 +-0.0146018 0.0513752 -0.0319045 0.891033 0.5 +-0.0161558 0.0488543 -0.0303763 0.808351 0.5 +-0.0205843 0.0508011 -0.0296435 0.813106 0.5 +0.0405252 0.0518855 -0.00654453 0.65569 0.5 +0.0149309 0.0520772 -0.0273859 0.655547 0.5 +0.041884 0.0490868 -0.00604367 0.898378 0.5 +0.019962 0.0529908 -0.0261219 0.592286 0.5 +-0.0198501 0.0534234 -0.0312267 0.768335 0.5 +-0.0336273 0.0527187 -0.0106243 0.102172 0.5 +-0.0461112 0.0529158 -0.0101664 0.636429 0.372142 +-0.0204 0.161875 -0.014658 0.822907 0.5 +0.0449924 0.0530898 -0.00614891 0.575737 0.5 +0.00733679 0.0546532 -0.0305038 0.688621 0.5 +0.00283568 0.0546532 -0.0307468 0.611749 0.5 +-0.00302245 0.0577 -0.0331477 0.67582 0.5 +-0.00914668 0.0576676 -0.0341165 0.698389 0.5 +-0.01517 0.058199 -0.0349877 0.856637 0.5 +-0.0202707 0.0581031 -0.0333681 0.552506 0.5 +0.0140844 0.057965 -0.028983 0.564173 0.483714 +0.0103301 0.0588553 -0.0299472 0.602031 0.489059 +0.00732823 0.0588898 -0.0306117 0.710141 0.5 +0.0027369 0.0590151 -0.0321928 0.690932 0.5 +-0.0337187 0.0579742 -0.0115824 0.143826 0.5 +-0.0390711 0.0582467 -0.0115033 0.780735 0.5 +-0.0460474 0.0579124 -0.0115174 0.472305 0.5 +-0.00961439 0.0642168 -0.0358564 0.670518 0.457134 +-0.044157 0.0599825 -0.0123877 0.830365 0.5 +0.015251 0.0645803 -0.029567 0.626368 0.396114 +0.00839294 0.0649214 -0.0316957 0.79033 0.385997 +0.00325858 0.0643529 -0.0332439 0.728322 0.418376 +-0.00361257 0.0645861 -0.034907 0.670644 0.5 +-0.0144709 0.065006 -0.0371603 0.712311 0.5 +-0.0366623 0.060679 -0.0122791 0.525705 0.5 +-0.0526404 0.0636402 -0.0101297 0.452904 0.5 +-0.0381866 0.0648919 -0.0142073 0.543504 0.5 +-0.0452495 0.0647856 -0.0139819 0.883769 0.5 +-0.0599262 0.0622966 -0.00429285 0.195385 0.344922 +-0.0778641 0.117463 -0.00576778 0.523105 0.5 +-0.0187447 0.0664151 -0.0374779 0.820087 0.5 +-0.0577616 0.0644884 -0.00779097 0.472929 0.5 +-0.0625778 0.0655353 -0.00741131 0.379588 0.453283 +0.0251088 0.0710945 -0.0248604 0.704567 0.5 +0.021457 0.0702729 -0.0273415 0.740248 0.5 +0.0166747 0.0701586 -0.0297203 0.658948 0.5 +0.0132745 0.0702643 -0.0312074 0.651019 0.5 +0.00867525 0.0703509 -0.0324278 0.818076 0.5 +0.00229643 0.0708694 -0.0343123 0.73028 0.5 +-0.0030646 0.070381 -0.0353565 0.764349 0.5 +-0.00773679 0.0691749 -0.0362051 0.757441 0.5 +-0.0101988 0.0715122 -0.0373778 0.76291 0.5 +-0.0147454 0.0704429 -0.0382943 0.581028 0.470136 +-0.0203984 0.0706516 -0.038158 0.645161 0.5 +-0.0240967 0.0693418 -0.0362521 0.4533 0.5 +-0.0605175 0.0673597 -0.0108259 0.635082 0.5 +-0.0387293 0.0706355 -0.0168457 0.666323 0.5 +-0.0451347 0.0705064 -0.0164504 0.875899 0.5 +-0.0523435 0.0697862 -0.0145984 0.401473 0.5 +-0.0591515 0.0702891 -0.0147203 0.639534 0.5 +-0.0652515 0.0688492 -0.00993982 0.422384 0.422462 +-0.0247614 0.0719777 -0.0368317 0.497524 0.5 +-0.0637884 0.0712697 -0.0138535 0.437166 0.5 +0.0211454 0.0769268 -0.0268772 0.737516 0.5 +0.0162128 0.0765268 -0.0293784 0.712202 0.5 +0.0133247 0.0760196 -0.0306715 0.679361 0.5 +0.00907695 0.076038 -0.0330382 0.719764 0.5 +0.00245085 0.0760857 -0.0351615 0.721395 0.5 +-0.00176321 0.0762288 -0.0360688 0.799862 0.5 +-0.00476487 0.076286 -0.0369742 0.814155 0.377247 +-0.00962992 0.0765936 -0.0378651 0.627364 0.487104 +-0.0144481 0.0764118 -0.0385775 0.832444 0.5 +-0.021453 0.0763574 -0.038668 0.751656 0.5 +-0.024977 0.0762484 -0.0374518 0.39297 0.457854 +-0.0377453 0.0766164 -0.0189124 0.273711 0.5 +-0.0397395 0.0746623 -0.0180255 0.973337 0.5 +-0.0437423 0.0765905 -0.0187922 0.595439 0.440211 +-0.0466377 0.0744845 -0.0173668 0.538698 0.468502 +-0.0518623 0.0745812 -0.0175084 0.855826 0.5 +-0.0589866 0.0745368 -0.01766 0.879682 0.5 +-0.0644081 0.0756279 -0.0167529 0.562234 0.481782 +-0.0721295 0.0740256 -0.0105719 0.341576 0.432723 +-0.0615233 0.0354132 0.043881 0.499903 0.5 +-0.0524971 0.0769872 -0.0189536 0.873913 0.5 +-0.0587482 0.0767445 -0.0187462 0.882838 0.5 +0.013102 0.0809953 -0.0307917 0.69611 0.5 +0.00892296 0.0820652 -0.0325478 0.700162 0.5 +0.0022917 0.0820297 -0.0349279 0.829579 0.5 +-0.00177837 0.0804805 -0.0364471 0.647084 0.379833 +-0.00379684 0.0824193 -0.037328 0.824332 0.5 +-0.0142988 0.0820384 -0.0390211 0.832022 0.373406 +-0.0207708 0.0823862 -0.0387335 0.805306 0.5 +-0.0248089 0.0818968 -0.0377031 0.470046 0.439483 +-0.0735819 0.0777026 -0.0122023 0.445372 0.5 +0.015425 0.0831288 -0.0295207 0.735694 0.5 +-0.0383994 0.0817919 -0.0209596 0.290803 0.5 +-0.0451184 0.0815526 -0.020434 0.548777 0.45056 +-0.051814 0.0818472 -0.0211348 0.886135 0.5 +-0.0583689 0.0812724 -0.0202975 0.847354 0.5 +-0.063949 0.082768 -0.0188935 0.606874 0.5 +-0.0662709 0.080065 -0.0177832 0.593549 0.449354 +-0.0695594 0.0830593 -0.0170582 0.4495 0.5 +-0.00481814 0.086841 -0.0367951 0.827149 0.5 +-0.0248206 0.0867524 -0.0367639 0.487957 0.5 +0.0132046 0.0871602 -0.0305473 0.663835 0.5 +-0.0360837 0.0867076 -0.023791 0.366486 0.5 +-0.00877843 0.0340556 -0.0204927 0 0 +-0.0207128 0.0342382 -0.0208728 0.319674 0.5 +-0.0147915 0.0341096 -0.0207616 0.312592 0.5 +-0.0265767 0.0342963 -0.0210989 0.482378 0.5 +0.00282685 0.0351053 -0.0158136 0.508357 0.5 +0.00885967 0.034471 -0.0147487 0.490133 0.5 +-0.0390848 0.0337228 -0.0202617 0.628543 0.5 +-0.0326656 0.0345334 -0.0201874 0.788348 0.5 +-0.00224535 0.0351539 -0.0166234 0.756398 0.5 +-0.0149096 0.0357313 -0.0180956 0.933106 0.5 +-0.0114808 0.0353662 -0.0177045 0.933613 0.5 +-0.00921575 0.0380183 -0.0149732 0.909294 0.5 +-0.00282494 0.0382292 -0.0140636 0.920543 0.5 +0.00285919 0.0377324 -0.0134715 0.965028 0.5 +0.0159109 0.0347098 -0.00882204 0.420938 0.5 +-0.0306839 0.036693 -0.0184598 0.875112 0.5 +-0.0265216 0.0367471 -0.0188177 0.84266 0.5 +-0.0218341 0.0369718 -0.0184303 0.873319 0.5 +-0.0203027 0.0382765 -0.0152577 0.887215 0.5 +-0.0152596 0.0382328 -0.0156428 0.873575 0.5 +0.00738356 0.0366172 -0.0125003 0.962688 0.5 +0.00992361 0.0351979 -0.00924624 0.9642 0.5 +0.00702596 0.0378387 -0.00879015 0.927286 0.5 +-0.0396958 0.0342843 -0.014578 0.76643 0.5 +-0.0329517 0.0382154 -0.014678 0.654319 0.5 +-0.0263862 0.0385778 -0.0153644 0.924592 0.5 +0.00320835 0.0389424 -0.00953857 0.945732 0.5 +-0.0364387 0.0357946 -0.0155844 0.543249 0.5 +-0.00301526 0.0391061 -0.00886496 0.816802 0.5 +0.00831664 0.0348156 -0.00321961 0.671683 0.5 +0.0145039 0.0343685 -0.0028433 0.748562 0.5 +-0.0365752 0.0370276 -0.0136534 0.498247 0.5 +-0.0146234 0.0388055 -0.00887465 0.759701 0.5 +-0.00886749 0.0389394 -0.00890173 0.761944 0.5 +-0.0451032 0.0336721 -0.00848668 0.772585 0.5 +-0.040313 0.0350801 -0.00861758 0.462745 0.5 +-0.0206235 0.0386 -0.00878063 0.747754 0.5 +0.00267879 0.038424 -0.00319748 0.448355 0.5 +0.015044 0.0350517 0.00289039 0.579133 0.5 +0.0201479 0.0347806 0.00348327 0.403273 0.5 +0.027119 0.0353514 0.00366834 0.0909279 0.5 +0.0280785 0.0365531 0.000826759 0 0 +-0.0376066 0.0375692 -0.00942418 0.22755 0.5 +-0.0332748 0.0384549 -0.00855692 0.752109 0.5 +-0.0264541 0.0384497 -0.00886193 0.729343 0.5 +-0.00299262 0.0389582 -0.00292437 0.746846 0.5 +0.00451408 0.0356078 -0.00103635 0.413486 0.5 +0.00881079 0.0350428 0.00356828 0.588251 0.5 +0.0314184 0.0360255 0.00457907 0.187967 0.5 +-0.00888202 0.0387884 -0.00299409 0.73859 0.5 +0.00271787 0.0349091 0.00339755 0.645421 0.5 +-0.041199 0.0341471 -0.00327644 0 0 +-0.0205479 0.0384259 -0.00283766 0.741413 0.5 +-0.0146618 0.0385908 -0.00288739 0.718901 0.5 +0.00103528 0.0375917 0.000952222 0.441385 0.5 +0.0215747 0.0354906 0.0086194 0.395945 0.5 +0.0264794 0.0346514 0.00870654 0.414057 0.5 +0.0322391 0.0355412 0.00882378 0.515667 0.5 +-0.0521057 0.0334794 -0.00318207 0.614129 0.5 +-0.0455078 0.0336572 -0.00225818 0.757211 0.5 +-0.0334104 0.0383259 -0.00292317 0.611245 0.5 +-0.0265122 0.0383343 -0.00296504 0.763748 0.5 +-0.00224847 0.0383354 0.00320971 0.728422 0.5 +-0.0589386 0.0334143 -0.00291301 0.444064 0.5 +-0.00874044 0.0385976 0.00291227 0.735039 0.5 +0.00273457 0.0342734 0.0088248 0.796819 0.5 +0.00621941 0.0351341 0.00654928 0 0 +-0.080018 0.109279 0.0373655 0.503151 0.426569 +-0.0393178 0.0336443 0.00354096 0.266658 0.5 +-0.0213111 0.0382973 0.00334866 0.753895 0.5 +-0.0146196 0.0384265 0.00290922 0.762157 0.5 +-0.00353554 0.0379644 0.00874752 0.658939 0.5 +0.0276681 0.0349662 0.0149532 0.360666 0.5 +0.03282 0.0359255 0.0147037 0.719837 0.5 +0.0389763 0.0383079 0.0145025 0.635106 0.5 +-0.0523961 0.0335249 0.00326874 0.742717 0.5 +-0.0462346 0.0335696 0.00267776 0.743661 0.5 +-0.0277984 0.0382296 0.00286126 0.456211 0.5 +-0.000947006 0.0357374 0.0103469 0.779853 0.5 +0.0222276 0.0358262 0.0160256 0.180494 0.5 +0.0448051 0.0411192 0.0150961 0.294679 0.5 +-0.0581064 0.033504 0.00272997 0.775526 0.5 +-0.0352323 0.0337248 0.00491425 0.152905 0 +-0.0312985 0.0381858 0.00167702 0 0 +-0.0088641 0.03847 0.00876261 0.73345 0.5 +0.0028919 0.0342894 0.0147059 0.676527 0.5 +-0.0703332 0.0340583 0.00286723 0.639535 0.5 +-0.0648245 0.0334924 0.00301734 0.793089 0.5 +-0.0387963 0.034763 0.00935652 0.458758 0.5 +-0.0332327 0.0337932 0.00943608 0.151116 0.5 +-0.0203456 0.0382265 0.00836296 0.759992 0.5 +-0.0152156 0.0383161 0.00935801 0.755179 0.5 +-0.000385714 0.0351459 0.0134171 0.848157 0.5 +0.00663645 0.0342324 0.0159688 0 0 +0.0268074 0.0356469 0.0204126 0.619176 0.5 +0.0309391 0.0362152 0.0189937 0.762661 0.5 +0.0334119 0.0376179 0.0210082 0.70177 0.5 +-0.0515734 0.0338904 0.00817232 0.493124 0.5 +-0.0454999 0.0352808 0.00804865 0.53914 0.5 +-0.0263229 0.0380313 0.00871732 0.143858 0.5 +-0.0031858 0.0377098 0.014513 0.797449 0.5 +0.0211051 0.0351552 0.0207004 0.432057 0.5 +0.0391983 0.0395969 0.0205879 0.670001 0.5 +0.0441778 0.0418755 0.0204802 0.609797 0.5 +-0.0580282 0.0335624 0.00918162 0.776077 0.5 +-0.00922404 0.0383488 0.0150261 0.754001 0.5 +0.00313746 0.0352426 0.0204176 0.692001 0.5 +0.00877508 0.0346179 0.020856 0.290121 0.5 +0.0468489 0.0434226 0.0210936 0.239557 0.5 +-0.0648031 0.0337402 0.00884817 0.802283 0.5 +-0.0338156 0.0345063 0.0150293 0.572312 0.5 +-0.0149173 0.0382498 0.0147214 0.753708 0.5 +0.0146344 0.0345628 0.0222588 0.157065 0.5 +-0.0365655 0.0357926 0.0130139 0.391807 0.5 +-0.0262153 0.0376693 0.0148666 0.146481 0.5 +-0.0205165 0.0381248 0.0146779 0.715632 0.5 +-0.00229335 0.0382456 0.020565 0.923102 0.5 +0.014723 0.0347707 0.0263935 0.310145 0.5 +0.0210245 0.0353476 0.0265418 0.313898 0.5 +0.0250756 0.0364517 0.0246847 0.678097 0.5 +0.0273584 0.0381522 0.0267127 0.778478 0.5 +0.0321164 0.0401984 0.026762 0.778536 0.5 +-0.053829 0.0335431 0.0139547 0.458851 0.5 +0.00114114 0.037661 0.0223414 0.978558 0.5 +0.00915473 0.0353589 0.0262457 0.701449 0.5 +0.0380552 0.0412819 0.02589 0.374179 0.417844 +-0.0588034 0.0336951 0.0146283 0.798139 0.5 +-0.0339319 0.0346253 0.0202274 0.513983 0.5 +-0.0152545 0.0382629 0.0204704 0.75125 0.5 +-0.00888844 0.0384087 0.0207206 0.746481 0.5 +0.00307272 0.0384964 0.0264151 0.996029 0.5 +-0.0261643 0.0378491 0.0205422 0.603577 0.5 +-0.0205429 0.0381473 0.0213758 0.772551 0.5 +-0.0538188 0.0335608 0.0210581 0 0 +-0.00301594 0.03875 0.0263901 0.805634 0.5 +0.00756209 0.0380712 0.0285007 0.978659 0.5 +0.0143741 0.0348327 0.0331833 0.915728 0.5 +0.0198279 0.03555 0.0321213 0.749506 0.5 +0.0236875 0.0373106 0.0299772 0.517201 0.5 +-0.0588476 0.033906 0.020465 0.657735 0.5 +-0.00882687 0.0386047 0.0265705 0.756827 0.5 +0.00847025 0.0383344 0.0315598 0.739987 0.5 +0.0108958 0.035647 0.0330663 0.649316 0.5 +-0.0366651 0.0353042 0.023032 0.153172 0.5 +-0.0340084 0.0344659 0.0266224 0.263742 0.5 +-0.0270447 0.0379104 0.0270529 0.074682 0.5 +-0.0210471 0.0383013 0.026282 0.782021 0.5 +-0.0147317 0.0384888 0.0265233 0.791552 0.5 +-0.0712786 0.0733348 0.0355839 0.683322 0.427231 +-0.0388887 0.0346255 0.0265538 0.109729 0 +0.00290004 0.0393205 0.032168 0.626516 0.5 +0.0155389 0.0350901 0.0393977 0.759188 0.5 +0.0195159 0.0358111 0.0367948 0.405286 0.5 +-0.0589139 0.0341314 0.0264586 0.808252 0.5 +-0.052234 0.0340737 0.0268887 0.497915 0.5 +-0.0447866 0.0339274 0.0274346 0.154159 0.5 +-0.0310127 0.0369382 0.02848 0.240675 0.5 +-0.00908756 0.0390146 0.0330901 0.79352 0.5 +-0.00293287 0.039209 0.03365 0.804769 0.5 +0.00861952 0.0346654 0.0391536 0.125418 0.5 +-0.0149144 0.0388312 0.0324344 0.795183 0.5 +0.00392423 0.0347398 0.0399064 0.146347 0.5 +-0.0657827 0.0618455 0.00187562 0.442355 0.5 +-0.0640051 0.0606097 0.00361345 0.333039 0.5 +-0.0455164 0.0345095 0.0326748 0.510388 0.5 +-0.0385699 0.0344168 0.033204 0.485482 0.5 +-0.0342024 0.0351611 0.0325685 0.248514 0.5 +-0.0270303 0.0384799 0.0326469 0.783767 0.5 +-0.0209433 0.0387397 0.0332273 0.806699 0.5 +-0.0520994 0.0344582 0.0326775 0.466807 0.5 +-0.0313489 0.0377268 0.0321213 0.178238 0.5 +-0.00219023 0.0348305 0.0410082 0.139343 0 +0.00818206 0.0355366 0.0443043 0.642932 0.5 +0.014947 0.0361331 0.0431407 0.796588 0.5 +-0.0642564 0.0597236 0.0092932 0.716255 0.5 +-0.0584732 0.0343588 0.0331559 0.775713 0.5 +-0.0145859 0.0393004 0.0380317 0.483641 0.5 +-0.00937548 0.0394517 0.037871 0.328321 0.5 +-0.0588297 0.0579582 0.0145443 0 0 +-0.038732 0.0346956 0.0400227 0.628019 0.5 +-0.0331487 0.034492 0.0390527 0.154826 0.5 +-0.0201914 0.0391628 0.0381696 0.483919 0.5 +-0.00878985 0.0348233 0.0452949 0.139305 0.5 +-0.0031441 0.0351515 0.045825 0.295611 0.5 +-0.0701619 0.0622789 0.00863964 0.42197 0.408074 +-0.0451191 0.034688 0.0396457 0.766116 0.5 +-0.0256628 0.0389081 0.0373249 0 0 +-0.0146115 0.0348173 0.0458198 0.143796 0.5 +-0.0636462 0.0593677 0.014889 0.807508 0.5 +-0.0531671 0.0345191 0.0391729 0.74918 0.5 +-0.0595372 0.034497 0.0397515 0.783724 0.5 +-0.0329555 0.0349777 0.045552 0.474674 0.5 +-0.0262436 0.034809 0.0452831 0.162616 0.5 +-0.0215554 0.0348112 0.0459347 0.152356 0 +-0.0633407 0.0601272 0.0190813 0.939061 0.5 +-0.0471 0.0351015 0.0434178 0.627709 0.5 +-0.0120723 0.0353434 0.0494553 0.877126 0.5 +-0.016313 0.0351836 0.0504037 0.67915 0.5 +-0.0483699 0.146034 -0.00115148 0.583019 0.5 +-0.0264335 0.156562 -0.00835956 0.469485 0.437523 +-0.065003 0.144791 -0.0142909 0.400803 0.470167 +-0.066228 0.151547 -0.0394609 0.538048 0.5 +-0.0663323 0.145309 -0.018858 0.764025 0.5 +-0.0412403 0.152108 -0.00674014 0.633348 0.5 +3 4 132 80 +3 80 132 544 +3 373 80 544 +3 387 299 241 +3 859 1475 1474 +3 371 299 401 +3 401 326 333 +3 347 673 402 +3 1187 1354 386 +3 1221 457 69 +3 186 224 114 +3 1250 1256 116 +3 164 333 376 +3 19 488 1245 +3 749 19 1245 +3 667 19 749 +3 1040 412 543 +3 1359 1358 1500 +3 216 4 80 +3 152 544 146 +3 4 387 505 +3 543 1235 1205 +3 610 604 297 +3 250 801 1274 +3 504 148 111 +3 387 348 299 +3 401 333 164 +3 1484 1483 1110 +3 91 196 310 +3 90 91 310 +3 952 406 609 +3 1244 1247 1240 +3 93 327 65 +3 373 544 152 +3 373 152 644 +3 1321 158 22 +3 401 416 326 +3 644 152 1263 +3 276 59 181 +3 294 853 150 +3 308 249 529 +3 406 1124 604 +3 609 406 463 +3 146 3 145 +3 90 310 3 +3 58 186 10 +3 575 261 384 +3 25 40 43 +3 379 535 713 +3 348 704 157 +3 388 443 22 +3 396 146 145 +3 152 133 1263 +3 1830 1829 1812 +3 214 114 224 +3 157 147 324 +3 1335 430 1274 +3 282 230 214 +3 92 346 652 +3 1151 1012 1491 +3 571 1151 1491 +3 571 1491 183 +3 310 196 111 +3 91 4 505 +3 1250 116 108 +3 110 183 47 +3 1209 854 953 +3 132 4 91 +3 111 148 327 +3 93 111 327 +3 110 571 183 +3 713 171 402 +3 294 920 200 +3 81 180 52 +3 525 731 784 +3 347 256 673 +3 175 57 220 +3 338 175 220 +3 27 14 220 +3 57 27 220 +3 359 446 27 +3 359 36 446 +3 145 28 262 +3 133 16 419 +3 1447 576 1465 +3 1885 287 444 +3 133 396 16 +3 598 543 1205 +3 447 93 65 +3 73 213 36 +3 1236 1255 1250 +3 1235 1236 1250 +3 115 782 731 +3 28 93 447 +3 525 548 115 +3 299 416 401 +3 667 603 463 +3 292 667 463 +3 492 70 637 +3 133 146 396 +3 1166 1125 619 +3 1151 1219 959 +3 821 304 409 +3 1486 1487 1684 +3 15 175 167 +3 120 15 167 +3 15 131 57 +3 175 15 57 +3 57 131 27 +3 257 209 359 +3 27 257 359 +3 209 55 36 +3 359 209 36 +3 55 87 73 +3 36 55 73 +3 101 108 735 +3 108 101 64 +3 310 365 3 +3 576 859 1465 +3 262 28 447 +3 102 64 101 +3 544 91 90 +3 262 447 485 +3 485 447 211 +3 1443 1440 1442 +3 697 457 1221 +3 1008 383 1011 +3 451 435 1330 +3 129 405 426 +3 70 75 161 +3 648 693 692 +3 204 129 426 +3 812 481 123 +3 406 292 463 +3 878 1591 1009 +3 478 128 50 +3 900 979 977 +3 490 900 977 +3 241 299 371 +3 1164 701 734 +3 683 703 682 +3 719 718 682 +3 703 719 682 +3 760 759 718 +3 719 760 718 +3 137 729 728 +3 54 130 2 +3 302 358 301 +3 566 567 614 +3 1069 1103 1068 +3 1186 1190 1208 +3 4 348 387 +3 277 311 228 +3 707 226 706 +3 355 394 393 +3 773 129 755 +3 646 647 679 +3 356 355 269 +3 270 356 269 +3 424 394 356 +3 623 654 602 +3 654 683 602 +3 193 217 192 +3 1677 1676 1662 +3 1018 1019 1025 +3 597 1231 1165 +3 490 26 605 +3 299 157 416 +3 504 241 148 +3 84 528 714 +3 1247 669 1240 +3 683 719 703 +3 1886 1231 1066 +3 79 168 218 +3 211 318 426 +3 165 377 148 +3 91 505 387 +3 577 623 622 +3 692 693 707 +3 255 254 218 +3 194 270 255 +3 695 137 728 +3 1475 1498 1474 +3 67 808 1010 +3 1190 240 1208 +3 242 259 300 +3 476 509 567 +3 743 755 558 +3 1025 1024 1018 +3 194 255 218 +3 270 269 254 +3 203 271 12 +3 603 667 749 +3 1379 1395 1392 +3 783 546 1340 +3 578 600 577 +3 624 623 577 +3 600 624 577 +3 655 654 623 +3 684 683 654 +3 655 684 654 +3 720 719 683 +3 684 720 683 +3 720 739 719 +3 761 760 719 +3 739 761 719 +3 218 254 253 +3 694 695 437 +3 255 270 254 +3 1202 488 19 +3 412 1222 543 +3 60 528 84 +3 1352 494 702 +3 624 655 623 +3 1361 221 143 +3 755 129 204 +3 132 91 544 +3 543 1221 1235 +3 216 5 4 +3 1221 1236 1235 +3 754 755 204 +3 1169 732 715 +3 756 755 743 +3 1036 1035 1024 +3 728 756 743 +3 476 567 508 +3 4 5 348 +3 244 1339 546 +3 405 445 211 +3 254 269 268 +3 253 254 268 +3 381 358 302 +3 346 92 59 +3 517 450 1560 +3 1618 1333 141 +3 1498 1497 1474 +3 1231 597 1165 +3 228 264 215 +3 100 151 99 +3 151 215 99 +3 151 228 215 +3 1864 827 1870 +3 561 578 480 +3 207 561 480 +3 579 600 578 +3 561 579 578 +3 600 625 624 +3 656 655 624 +3 625 656 624 +3 685 684 655 +3 656 685 655 +3 685 721 720 +3 684 685 720 +3 721 740 739 +3 720 721 739 +3 739 740 761 +3 762 789 788 +3 761 762 788 +3 789 239 770 +3 788 789 770 +3 328 770 239 +3 423 424 476 +3 121 195 522 +3 423 476 422 +3 381 431 358 +3 148 371 401 +3 579 625 600 +3 465 464 431 +3 381 465 431 +3 464 465 227 +3 248 11 71 +3 548 142 1005 +3 740 762 761 +3 767 900 490 +3 728 743 437 +3 776 195 121 +3 1177 1176 1153 +3 1043 1034 1035 +3 137 708 729 +3 91 387 196 +3 1721 1729 1703 +3 728 729 756 +3 727 728 437 +3 196 387 241 +3 404 458 522 +3 355 354 268 +3 647 648 692 +3 979 846 901 +3 241 371 148 +3 142 1155 574 +3 269 355 268 +3 358 301 300 +3 301 358 300 +3 753 754 793 +3 184 229 228 +3 229 277 228 +3 312 311 277 +3 1845 1853 1831 +3 1523 1532 1153 +3 580 579 561 +3 1276 1280 1771 +3 580 626 625 +3 579 580 625 +3 626 657 656 +3 625 626 656 +3 656 657 685 +3 722 721 685 +3 741 740 721 +3 722 741 721 +3 740 763 762 +3 790 789 762 +3 763 790 762 +3 790 339 239 +3 789 790 239 +3 377 165 327 +3 476 508 422 +3 259 301 300 +3 162 170 169 +3 81 162 169 +3 580 561 562 +3 657 686 685 +3 229 312 277 +3 28 365 93 +3 1263 419 1254 +3 396 145 144 +3 685 686 722 +3 741 763 740 +3 133 152 146 +3 1263 133 419 +3 207 520 562 +3 520 562 580 +3 562 520 580 +3 562 626 580 +3 239 339 487 +3 597 1063 1066 +3 3 365 28 +3 649 648 615 +3 108 64 116 +3 571 1225 1218 +3 184 185 229 +3 313 312 229 +3 185 313 229 +3 439 501 520 +3 501 581 562 +3 520 501 562 +3 627 626 562 +3 581 627 562 +3 627 628 626 +3 658 657 626 +3 628 658 626 +3 658 675 657 +3 687 686 657 +3 675 687 657 +3 723 722 686 +3 687 723 686 +3 722 723 741 +3 741 723 763 +3 764 791 790 +3 763 764 790 +3 791 407 339 +3 790 791 339 +3 407 303 339 +3 303 487 339 +3 303 460 487 +3 303 325 460 +3 170 106 105 +3 105 106 68 +3 439 440 501 +3 723 764 763 +3 1 1027 453 +3 1067 511 942 +3 775 121 774 +3 1281 1270 1291 +3 368 440 439 +3 367 368 439 +3 582 581 501 +3 628 627 581 +3 658 688 687 +3 675 658 687 +3 1733 1562 1561 +3 757 775 756 +3 74 68 46 +3 398 1223 317 +3 631 607 231 +3 1465 859 1474 +3 1775 1784 1754 +3 204 138 793 +3 74 122 97 +3 584 533 570 +3 278 313 185 +3 265 278 185 +3 369 368 313 +3 278 369 313 +3 369 440 368 +3 502 501 440 +3 583 582 501 +3 502 583 501 +3 583 581 582 +3 629 628 581 +3 583 629 581 +3 629 659 658 +3 628 629 658 +3 658 659 688 +3 724 723 687 +3 688 724 687 +3 724 742 723 +3 742 765 764 +3 723 742 764 +3 764 238 791 +3 791 238 407 +3 407 238 303 +3 238 333 303 +3 333 325 303 +3 614 615 647 +3 46 122 74 +3 606 199 112 +3 441 440 369 +3 83 173 573 +3 775 776 121 +3 846 979 901 +3 441 502 440 +3 659 689 688 +3 84 714 1367 +3 535 52 171 +3 551 798 1883 +3 630 629 583 +3 629 630 659 +3 689 724 688 +3 792 238 764 +3 765 792 764 +3 1207 1208 177 +3 195 96 522 +3 122 13 97 +3 344 492 637 +3 1025 1036 1024 +3 775 774 756 +3 1012 1151 959 +3 1270 1372 1291 +3 145 3 28 +3 649 670 695 +3 517 1888 243 +3 444 399 1885 +3 370 369 278 +3 724 765 742 +3 376 333 238 +3 1372 1375 1291 +3 1060 1161 1162 +3 16 396 144 +3 369 442 441 +3 583 601 630 +3 690 689 659 +3 318 295 427 +3 138 204 427 +3 693 694 707 +3 310 111 365 +3 365 111 93 +3 636 660 659 +3 567 566 508 +3 426 405 211 +3 121 126 774 +3 471 601 583 +3 251 237 188 +3 1303 188 237 +3 278 314 370 +3 370 442 369 +3 442 503 502 +3 441 442 502 +3 503 471 583 +3 502 503 583 +3 858 302 259 +3 16 144 319 +3 660 690 659 +3 690 725 724 +3 689 690 724 +3 750 765 724 +3 725 750 724 +3 8 792 765 +3 750 8 765 +3 376 238 792 +3 8 376 792 +3 164 376 238 +3 376 164 238 +3 1381 1380 1375 +3 1135 1134 1103 +3 1104 1135 1103 +3 794 204 793 +3 447 65 211 +3 442 1347 503 +3 249 262 485 +3 1036 1043 1035 +3 522 96 438 +3 204 426 427 +3 188 283 251 +3 1235 1250 1205 +3 485 262 23 +3 597 1066 1165 +3 144 308 319 +3 1027 767 589 +3 648 649 694 +3 567 615 614 +3 821 409 304 +3 63 711 903 +3 8 164 376 +3 12 478 50 +3 171 347 402 +3 284 1327 314 +3 1447 1465 1459 +3 1456 1447 1459 +3 1329 1328 1380 +3 755 756 773 +3 756 774 773 +3 193 218 253 +3 648 694 693 +3 168 194 218 +3 190 188 189 +3 284 283 188 +3 190 284 188 +3 283 284 314 +3 262 485 23 +3 108 116 64 +3 751 750 725 +3 726 751 725 +3 751 771 750 +3 37 8 750 +3 771 37 750 +3 632 164 8 +3 569 53 411 +3 511 1560 1884 +3 386 1354 1320 +3 165 632 8 +3 37 165 8 +3 165 164 632 +3 662 661 638 +3 354 393 422 +3 401 165 148 +3 979 1883 798 +3 144 145 262 +3 413 408 349 +3 16 319 669 +3 318 211 295 +3 156 1213 198 +3 1153 1152 1119 +3 1225 1448 247 +3 190 266 284 +3 419 669 1247 +3 479 233 232 +3 166 165 37 +3 709 492 344 +3 567 568 615 +3 107 827 1864 +3 695 727 437 +3 485 211 23 +3 1254 419 1247 +3 419 16 669 +3 1884 1591 1009 +3 249 485 24 +3 41 249 24 +3 1103 1134 1133 +3 272 398 492 +3 754 204 794 +3 1498 159 113 +3 24 485 23 +3 1102 1103 1133 +3 308 144 249 +3 164 165 401 +3 692 707 706 +3 509 568 567 +3 191 252 190 +3 190 252 266 +3 252 285 284 +3 266 252 284 +3 285 286 284 +3 284 286 337 +3 144 262 249 +3 536 564 563 +3 563 564 593 +3 564 612 611 +3 593 564 611 +3 645 361 611 +3 612 645 611 +3 645 691 1313 +3 309 752 751 +3 726 309 751 +3 752 772 771 +3 751 752 771 +3 119 37 771 +3 772 119 771 +3 425 166 37 +3 119 425 37 +3 380 165 166 +3 425 380 166 +3 128 83 17 +3 50 128 17 +3 729 757 756 +3 394 423 422 +3 589 767 490 +3 424 509 476 +3 1374 1359 1531 +3 408 372 349 +3 679 692 706 +3 855 242 300 +3 766 757 730 +3 354 355 393 +3 79 218 193 +3 129 126 405 +3 126 458 405 +3 647 692 679 +3 757 766 775 +3 766 776 775 +3 1699 1014 1013 +3 393 394 422 +3 252 286 285 +3 752 119 772 +3 425 327 380 +3 696 730 729 +3 708 696 729 +3 649 695 694 +3 78 79 193 +3 1497 1498 113 +3 901 979 798 +3 404 24 445 +3 24 23 445 +3 776 795 195 +3 1340 1591 1884 +3 1035 1034 1024 +3 177 203 12 +3 380 327 425 +3 510 509 424 +3 477 510 424 +3 458 404 405 +3 192 217 252 +3 191 192 252 +3 217 267 286 +3 252 217 286 +3 286 267 352 +3 353 421 420 +3 352 353 420 +3 421 507 506 +3 506 507 536 +3 507 565 564 +3 536 507 564 +3 565 613 612 +3 564 565 612 +3 646 645 612 +3 613 646 612 +3 646 679 691 +3 645 646 691 +3 706 705 691 +3 679 706 691 +3 753 309 280 +3 138 119 752 +3 753 138 752 +3 427 425 119 +3 138 427 119 +3 295 380 425 +3 427 295 425 +3 65 327 380 +3 295 65 380 +3 769 104 315 +3 426 318 427 +3 568 616 615 +3 695 728 727 +3 404 445 405 +3 1635 1653 1453 +3 271 478 12 +3 839 136 830 +3 615 648 647 +3 311 277 228 +3 749 1245 1225 +3 353 392 421 +3 793 138 753 +3 315 104 33 +3 432 466 465 +3 381 432 465 +3 465 466 527 +3 1170 1190 1099 +3 754 794 793 +3 558 754 280 +3 193 253 217 +3 253 268 267 +3 217 253 267 +3 268 354 353 +3 267 268 353 +3 354 392 353 +3 422 421 392 +3 354 422 392 +3 422 508 507 +3 421 422 507 +3 508 566 565 +3 507 508 565 +3 614 613 565 +3 566 614 565 +3 614 647 646 +3 613 614 646 +3 168 810 194 +3 886 940 923 +3 946 945 930 +3 929 939 944 +3 940 569 887 +3 661 649 616 +3 320 919 878 +3 227 526 464 +3 882 873 866 +3 552 384 820 +3 464 927 358 +3 917 432 905 +3 879 829 820 +3 194 836 880 +3 935 466 432 +3 917 935 432 +3 1038 1725 1013 +3 1378 1391 1406 +3 173 448 293 +3 477 943 510 +3 616 568 617 +3 1405 550 980 +3 665 86 847 +3 891 906 912 +3 845 130 54 +3 999 925 822 +3 1885 928 555 +3 904 910 270 +3 315 33 478 +3 1033 1034 1042 +3 490 921 26 +3 850 257 131 +3 1070 1077 1034 +3 843 860 15 +3 120 843 15 +3 850 209 257 +3 914 913 300 +3 880 911 910 +3 641 661 616 +3 843 120 797 +3 860 870 15 +3 870 131 15 +3 870 850 131 +3 894 873 882 +3 811 248 875 +3 974 981 992 +3 850 201 131 +3 131 201 850 +3 850 201 209 +3 907 917 905 +3 694 437 226 +3 895 843 797 +3 870 860 843 +3 816 870 843 +3 870 201 850 +3 913 933 932 +3 968 969 986 +3 840 118 712 +3 816 843 895 +3 201 856 209 +3 856 845 55 +3 209 856 55 +3 931 930 911 +3 228 151 184 +3 1340 884 1884 +3 553 506 536 +3 539 867 842 +3 870 924 201 +3 977 823 490 +3 868 829 780 +3 999 1000 925 +3 198 701 156 +3 787 816 895 +3 924 877 856 +3 201 924 856 +3 877 845 856 +3 66 305 941 +3 769 203 1208 +3 848 847 919 +3 880 889 911 +3 1027 589 605 +3 957 816 787 +3 849 870 816 +3 957 849 816 +3 414 821 409 +3 1887 1004 928 +3 569 888 887 +3 459 384 552 +3 891 889 890 +3 839 892 891 +3 1080 1057 1051 +3 957 328 816 +3 328 957 816 +3 849 881 870 +3 881 849 870 +3 870 849 924 +3 481 531 123 +3 777 835 698 +3 891 892 906 +3 912 911 889 +3 891 912 889 +3 546 1339 746 +3 328 849 957 +3 849 88 924 +3 1043 1070 1034 +3 777 122 46 +3 477 929 943 +3 617 641 616 +3 822 915 72 +3 915 331 72 +3 834 806 956 +3 788 957 787 +3 770 788 787 +3 788 328 957 +3 864 877 924 +3 833 938 130 +3 845 833 130 +3 938 256 130 +3 1005 142 574 +3 661 676 137 +3 730 305 776 +3 1186 1208 1207 +3 1189 1186 1207 +3 798 1888 1067 +3 864 924 88 +3 864 922 877 +3 982 845 877 +3 922 982 877 +3 982 833 845 +3 894 905 873 +3 879 665 86 +3 879 665 847 +3 817 922 864 +3 833 982 922 +3 817 833 922 +3 894 907 905 +3 1562 1561 1038 +3 305 893 776 +3 899 864 88 +3 1071 1049 1072 +3 788 770 328 +3 776 768 795 +3 835 919 847 +3 817 864 899 +3 833 256 938 +3 1177 1195 1176 +3 1276 1771 1275 +3 155 100 813 +3 832 96 449 +3 879 384 665 +3 879 86 665 +3 834 956 320 +3 863 898 328 +3 826 849 328 +3 898 826 328 +3 849 826 88 +3 826 899 88 +3 1346 1883 900 +3 930 945 944 +3 939 930 944 +3 810 818 836 +3 838 836 837 +3 1077 1069 1034 +3 891 890 838 +3 1473 1680 1679 +3 44 24 438 +3 899 200 817 +3 1374 1391 1378 +3 466 935 527 +3 66 941 730 +3 913 906 912 +3 956 919 320 +3 662 676 661 +3 239 395 863 +3 395 898 863 +3 819 826 898 +3 826 200 899 +3 35 86 82 +3 880 270 194 +3 935 950 527 +3 670 661 695 +3 134 256 94 +3 818 837 836 +3 848 879 847 +3 395 819 898 +3 826 819 200 +3 200 920 817 +3 920 876 833 +3 817 920 833 +3 833 876 256 +3 1034 1069 1068 +3 932 933 947 +3 997 676 662 +3 836 889 880 +3 757 729 730 +3 956 806 919 +3 603 749 1460 +3 876 48 256 +3 827 107 155 +3 107 184 155 +3 830 855 841 +3 1042 1034 1068 +3 832 449 795 +3 997 662 638 +3 384 261 665 +3 997 696 676 +3 294 48 876 +3 920 294 876 +3 925 915 822 +3 1199 1231 1886 +3 941 305 730 +3 200 418 294 +3 569 940 886 +3 100 155 184 +3 840 712 331 +3 921 379 26 +3 1016 1014 1699 +3 776 766 730 +3 983 997 638 +3 676 696 137 +3 487 395 239 +3 487 819 395 +3 569 886 511 +3 940 887 923 +3 986 1000 985 +3 1125 110 47 +3 947 968 958 +3 842 874 834 +3 822 918 66 +3 985 999 998 +3 984 985 998 +3 999 822 998 +3 983 984 997 +3 984 998 997 +3 819 418 200 +3 177 85 1206 +3 12 275 397 +3 1231 1165 1066 +3 240 769 1208 +3 1000 999 985 +3 943 965 568 +3 906 913 932 +3 300 913 892 +3 997 998 66 +3 998 822 66 +3 478 33 128 +3 570 701 1076 +3 305 72 768 +3 72 811 768 +3 878 884 411 +3 878 835 884 +3 930 939 929 +3 968 978 967 +3 958 968 967 +3 946 958 967 +3 819 853 418 +3 510 943 509 +3 509 943 568 +3 151 100 184 +3 978 984 983 +3 967 978 983 +3 474 1122 799 +3 932 931 912 +3 487 460 819 +3 460 29 819 +3 819 29 853 +3 340 867 383 +3 1134 1135 1161 +3 947 946 931 +3 1411 1501 1408 +3 300 892 855 +3 356 910 929 +3 136 838 837 +3 1259 351 523 +3 887 896 923 +3 260 86 665 +3 774 129 773 +3 872 873 871 +3 906 932 912 +3 661 137 695 +3 511 886 942 +3 985 984 978 +3 968 985 978 +3 818 136 837 +3 1559 851 857 +3 872 871 865 +3 1222 1221 543 +3 548 1005 115 +3 430 1198 1065 +3 768 811 832 +3 945 967 944 +3 1132 1134 1160 +3 1019 1036 1025 +3 1134 1161 1160 +3 615 616 649 +3 1560 884 1884 +3 884 835 888 +3 214 230 114 +3 811 332 832 +3 878 411 53 +3 848 842 879 +3 842 829 879 +3 48 673 256 +3 869 811 768 +3 912 931 911 +3 935 936 950 +3 871 302 381 +3 972 991 971 +3 708 137 696 +3 1225 571 110 +3 847 955 13 +3 803 190 189 +3 865 871 858 +3 986 985 968 +3 929 944 943 +3 227 972 526 +3 888 835 896 +3 1001 1002 840 +3 1830 1841 1829 +3 50 140 275 +3 394 424 423 +3 411 884 888 +3 936 935 917 +3 907 936 917 +3 835 847 698 +3 811 6 332 +3 842 867 829 +3 1161 1060 1226 +3 1885 399 1887 +3 808 834 995 +3 1659 1658 1638 +3 65 295 211 +3 918 822 305 +3 302 871 381 +3 847 86 955 +3 1001 840 925 +3 1010 937 834 +3 1208 203 177 +3 1135 1162 1161 +3 921 81 379 +3 271 315 478 +3 948 969 947 +3 464 526 927 +3 834 848 806 +3 409 296 414 +3 302 873 432 +3 885 896 777 +3 841 892 839 +3 811 875 6 +3 1077 1104 1069 +3 1104 1103 1069 +3 68 106 46 +3 823 921 490 +3 162 81 921 +3 823 162 921 +3 989 1001 1000 +3 986 989 1000 +3 1000 1001 925 +3 888 896 887 +3 929 477 356 +3 974 972 534 +3 87 2 213 +3 915 840 331 +3 970 969 948 +3 965 641 568 +3 1207 177 1206 +3 1726 1725 1038 +3 1002 51 840 +3 814 191 803 +3 191 190 803 +3 855 892 841 +3 302 432 381 +3 173 293 573 +3 880 904 270 +3 871 873 302 +3 358 914 300 +3 239 863 328 +3 910 911 929 +3 331 712 811 +3 438 24 404 +3 892 913 906 +3 991 1002 990 +3 128 33 83 +3 810 836 194 +3 788 770 787 +3 814 803 804 +3 774 126 129 +3 242 855 830 +3 981 1189 1206 +3 927 934 914 +3 847 13 777 +3 301 358 300 +3 822 72 305 +3 641 617 568 +3 839 838 136 +3 904 880 910 +3 1850 1864 1870 +3 118 248 811 +3 949 970 948 +3 970 989 986 +3 1328 1325 1316 +3 358 927 914 +3 867 340 829 +3 943 944 966 +3 1100 221 1361 +3 530 805 525 +3 327 148 377 +3 1259 179 351 +3 1029 1028 1014 +3 969 968 947 +3 970 986 969 +3 832 795 768 +3 888 569 411 +3 342 344 113 +3 458 126 121 +3 943 966 965 +3 979 901 823 +3 823 861 162 +3 701 198 1076 +3 966 638 641 +3 769 315 271 +3 760 761 787 +3 965 966 641 +3 927 949 934 +3 949 948 934 +3 558 755 754 +3 919 835 878 +3 270 910 356 +3 852 162 861 +3 106 170 162 +3 852 106 162 +3 947 958 946 +3 815 192 191 +3 814 815 191 +3 820 384 879 +3 305 768 893 +3 698 847 777 +3 829 340 780 +3 534 972 227 +3 121 522 458 +3 1071 1077 1070 +3 846 823 901 +3 846 861 823 +3 918 305 66 +3 893 768 776 +3 1190 1186 1099 +3 67 1010 937 +3 925 840 915 +3 862 861 846 +3 862 852 861 +3 835 777 896 +3 946 945 944 +3 862 106 852 +3 1885 1887 928 +3 464 358 431 +3 526 949 927 +3 946 944 945 +3 890 889 838 +3 66 696 997 +3 1019 1561 1026 +3 1375 1380 1291 +3 1071 1061 1077 +3 712 118 811 +3 806 848 919 +3 971 990 970 +3 661 670 649 +3 971 970 949 +3 749 1225 110 +3 122 777 13 +3 35 13 955 +3 734 701 1164 +3 795 449 195 +3 874 842 848 +3 990 1002 989 +3 977 979 823 +3 526 971 949 +3 78 193 192 +3 815 78 192 +3 990 989 970 +3 834 539 842 +3 839 891 838 +3 1146 767 1064 +3 1002 1001 989 +3 840 51 118 +3 886 862 846 +3 280 754 753 +3 811 869 768 +3 906 913 912 +3 967 966 944 +3 931 946 930 +3 829 552 820 +3 886 106 862 +3 885 46 106 +3 1061 1104 1077 +3 320 67 834 +3 905 432 873 +3 874 848 834 +3 911 930 929 +3 1026 1572 1019 +3 972 974 992 +3 934 933 913 +3 914 934 913 +3 923 106 886 +3 777 46 885 +3 355 356 394 +3 449 96 195 +3 66 730 696 +3 807 96 832 +3 72 331 811 +3 896 106 923 +3 896 885 106 +3 1071 1070 1043 +3 932 947 931 +3 1049 1071 1043 +3 450 39 785 +3 946 967 945 +3 836 838 889 +3 787 761 788 +3 967 983 638 +3 966 967 638 +3 991 990 971 +3 597 1165 1231 +3 937 539 834 +3 934 948 947 +3 933 934 947 +3 886 846 942 +3 972 971 526 +3 1737 1762 1746 +3 1841 1851 1829 +3 417 1219 1218 +3 1166 110 1125 +3 159 342 113 +3 1065 1032 1274 +3 430 1065 1274 +3 1307 1320 1395 +3 767 1027 1 +3 846 798 1067 +3 735 1256 469 +3 1829 1850 1834 +3 398 317 1039 +3 288 32 34 +3 1051 1057 1058 +3 515 1684 1674 +3 1080 1079 1057 +3 1051 1058 1029 +3 1039 288 34 +3 1561 1726 1038 +3 1379 1307 1395 +3 304 642 409 +3 1396 1380 1381 +3 1030 1051 1029 +3 1219 1218 959 +3 598 1205 642 +3 1604 1615 1613 +3 1209 953 1193 +3 389 1521 1121 +3 398 75 70 +3 1314 273 524 +3 1022 1030 1021 +3 1022 1021 1016 +3 1030 1029 1021 +3 598 642 304 +3 528 1185 714 +3 1194 1209 1193 +3 177 12 397 +3 878 67 320 +3 1057 1045 1028 +3 1096 1095 1079 +3 1296 264 1319 +3 101 491 1237 +3 834 808 67 +3 1312 1484 1110 +3 963 1312 1110 +3 113 344 637 +3 1497 113 1496 +3 1119 1127 1113 +3 1312 1483 1484 +3 1799 1816 1812 +3 1079 1095 1057 +3 854 357 1191 +3 399 444 1210 +3 539 1011 383 +3 246 250 664 +3 1028 1038 1020 +3 1058 1057 1029 +3 311 1329 1396 +3 1260 1483 1312 +3 1187 1328 428 +3 1851 1864 1850 +3 317 609 619 +3 609 463 619 +3 1223 952 317 +3 603 1166 619 +3 1003 976 1094 +3 1248 556 297 +3 287 1885 555 +3 1138 1172 1163 +3 297 556 610 +3 1591 878 1009 +3 463 603 619 +3 749 110 1166 +3 1157 680 1081 +3 1886 304 409 +3 436 1027 605 +3 1015 1029 1014 +3 556 20 610 +3 20 604 610 +3 1099 1186 1189 +3 20 599 604 +3 1209 854 953 +3 1360 1550 1685 +3 492 398 70 +3 1172 1193 1192 +3 1175 1172 1192 +3 733 292 406 +3 202 733 406 +3 1010 834 67 +3 468 113 637 +3 154 1157 1081 +3 1172 1175 1163 +3 1193 854 1192 +3 953 854 1193 +3 1055 174 493 +3 1502 650 1046 +3 236 60 84 +3 1195 1194 1176 +3 85 177 397 +3 1163 1175 1148 +3 585 433 357 +3 1050 1045 1028 +3 1138 1148 1112 +3 1603 1402 1589 +3 1174 1192 1191 +3 1170 1174 1190 +3 1416 1417 1617 +3 398 1039 34 +3 75 398 1007 +3 1095 1107 1078 +3 1133 1134 1132 +3 1528 1022 1551 +3 1066 598 304 +3 292 733 667 +3 63 903 18 +3 619 1125 288 +3 1357 1355 1356 +3 733 1363 667 +3 470 1 212 +3 1017 830 136 +3 1119 1113 1095 +3 1387 231 247 +3 1107 1112 1078 +3 113 468 1496 +3 1028 1045 1050 +3 1014 1028 1013 +3 808 1011 539 +3 830 841 839 +3 12 50 275 +3 1344 1530 1115 +3 1363 153 19 +3 667 1363 19 +3 1103 1102 1068 +3 952 609 317 +3 1175 1174 1148 +3 1031 236 681 +3 595 10 555 +3 1119 1114 1587 +3 1114 1119 1096 +3 709 272 492 +3 451 736 434 +3 1174 1175 1192 +3 1380 1328 1316 +3 928 595 555 +3 153 489 1202 +3 572 598 1066 +3 19 153 1202 +3 1737 1746 1721 +3 1418 1417 1395 +3 1148 1147 1126 +3 488 1387 1448 +3 1245 488 1448 +3 1040 543 598 +3 572 1040 598 +3 1021 1029 1015 +3 1654 1653 1635 +3 329 58 595 +3 489 125 488 +3 1163 1148 1138 +3 1534 1687 1439 +3 342 709 344 +3 1112 1148 1126 +3 1202 489 488 +3 125 231 1387 +3 488 125 1387 +3 398 272 1223 +3 383 867 539 +3 414 296 928 +3 1176 1194 1172 +3 1028 1020 1013 +3 173 176 448 +3 1591 878 1009 +3 444 287 263 +3 1083 444 263 +3 272 952 1223 +3 1192 854 1191 +3 854 585 357 +3 1119 1152 1139 +3 1547 461 513 +3 296 329 595 +3 296 595 928 +3 603 749 1166 +3 1319 1329 1381 +3 1138 1152 1172 +3 63 18 33 +3 433 63 104 +3 769 433 104 +3 1174 1171 1147 +3 1372 1381 1375 +3 1613 1424 1603 +3 1113 1138 1107 +3 571 1218 1219 +3 1528 1551 1548 +3 1007 398 34 +3 1738 1737 1717 +3 1396 1329 1380 +3 1063 572 1066 +3 1153 1176 1152 +3 1139 1113 1127 +3 1119 1139 1127 +3 1191 357 1190 +3 357 240 1190 +3 1148 1174 1147 +3 29 460 325 +3 317 619 1039 +3 1754 1762 1737 +3 1329 311 1396 +3 1309 1380 1316 +3 1225 247 1218 +3 1448 1387 247 +3 1028 1045 1038 +3 1635 1453 1452 +3 116 1256 735 +3 514 1032 962 +3 1095 1078 1086 +3 1079 1095 1086 +3 357 433 240 +3 1174 1170 1171 +3 1218 1219 959 +3 1067 942 846 +3 1057 1095 1079 +3 10 114 287 +3 150 853 620 +3 555 10 287 +3 1152 1138 1139 +3 1052 1085 1370 +3 1704 1721 1703 +3 89 51 1002 +3 512 89 1002 +3 1152 1176 1172 +3 981 1206 992 +3 991 512 1002 +3 402 673 48 +3 1016 1551 1022 +3 1151 571 1219 +3 433 769 240 +3 1291 1380 1309 +3 1571 785 884 +3 589 490 605 +3 584 572 1063 +3 1057 1079 1045 +3 1138 1112 1107 +3 1045 1086 1078 +3 1095 1113 1107 +3 76 512 991 +3 1549 1552 1548 +3 203 769 271 +3 992 76 991 +3 274 89 512 +3 76 274 512 +3 274 51 89 +3 139 118 51 +3 274 139 51 +3 11 248 118 +3 139 11 118 +3 1056 1042 1068 +3 737 103 17 +3 871 302 858 +3 273 489 153 +3 1826 1835 1820 +3 197 48 294 +3 975 197 294 +3 197 713 402 +3 48 197 402 +3 584 1076 1040 +3 1079 1086 1045 +3 1029 1057 1028 +3 1139 1138 1113 +3 572 584 1040 +3 198 412 1040 +3 1076 198 1040 +3 298 273 153 +3 1500 1531 1359 +3 1096 1119 1095 +3 1194 1193 1172 +3 1560 785 1571 +3 882 866 894 +3 49 139 274 +3 1189 1207 1206 +3 1102 1133 1132 +3 1717 1721 1704 +3 1674 1487 1653 +3 584 570 1076 +3 894 1102 907 +3 821 1167 1199 +3 17 103 140 +3 50 17 140 +3 1042 1056 866 +3 1056 1068 894 +3 866 1056 894 +3 894 1068 1102 +3 1102 1132 936 +3 907 1102 936 +3 1160 950 936 +3 1132 1160 936 +3 1174 1191 1190 +3 1206 85 76 +3 992 1206 76 +3 397 274 76 +3 85 397 76 +3 275 49 274 +3 397 275 274 +3 140 139 49 +3 275 140 49 +3 103 11 139 +3 140 103 139 +3 409 642 329 +3 296 409 329 +3 436 975 1241 +3 436 605 975 +3 605 26 975 +3 26 197 975 +3 26 379 713 +3 197 26 713 +3 1010 539 937 +3 59 454 346 +3 652 408 413 +3 21 61 149 +3 171 345 347 +3 94 2 130 +3 130 256 134 +3 1004 1393 715 +3 313 368 367 +3 544 90 146 +3 81 535 379 +3 1257 527 950 +3 1257 950 1160 +3 302 301 259 +3 1004 414 928 +3 1160 1238 1257 +3 102 214 186 +3 1238 1160 1161 +3 1226 1238 1161 +3 1257 227 527 +3 95 233 364 +3 620 853 29 +3 1257 534 227 +3 282 454 230 +3 1453 1653 1452 +3 232 233 95 +3 821 1199 1886 +3 1232 1238 1226 +3 1238 981 1257 +3 1257 981 534 +3 417 408 652 +3 1233 1238 1232 +3 1027 436 42 +3 196 504 111 +3 169 180 81 +3 61 21 479 +3 631 231 388 +3 372 631 388 +3 1300 1382 1270 +3 1558 1559 857 +3 714 298 800 +3 298 153 800 +3 981 974 534 +3 704 348 5 +3 706 226 234 +3 388 231 443 +3 311 1330 1329 +3 1282 1300 1270 +3 1189 981 1238 +3 1233 1189 1238 +3 334 94 256 +3 1462 1672 1473 +3 895 786 787 +3 595 58 10 +3 1242 1251 1256 +3 489 231 125 +3 1236 1256 1250 +3 0 717 40 +3 470 212 0 +3 717 279 40 +3 276 230 59 +3 454 282 1237 +3 521 219 213 +3 417 652 346 +3 1266 417 346 +3 364 521 213 +3 171 363 345 +3 279 704 40 +3 470 0 160 +3 94 95 2 +3 42 281 717 +3 97 375 540 +3 61 479 363 +3 1216 705 706 +3 349 372 233 +3 453 42 717 +3 1241 975 150 +3 150 975 294 +3 214 362 282 +3 959 417 1266 +3 959 1219 417 +3 281 42 279 +3 408 607 372 +3 372 607 631 +3 0 40 25 +3 1221 69 1242 +3 287 114 263 +3 279 147 157 +3 704 279 157 +3 134 94 130 +3 81 52 535 +3 1265 58 329 +3 1249 1265 329 +3 82 97 13 +3 364 643 158 +3 82 375 97 +3 156 542 1214 +3 479 232 345 +3 35 82 13 +3 147 620 29 +3 102 186 58 +3 64 102 58 +3 363 479 345 +3 21 413 479 +3 652 413 21 +3 372 388 233 +3 216 43 5 +3 61 171 52 +3 413 349 479 +3 186 114 10 +3 619 288 1039 +3 697 1221 412 +3 171 61 363 +3 212 717 0 +3 1236 1242 1256 +3 607 408 417 +3 92 21 149 +3 279 42 147 +3 1221 1222 412 +3 697 1217 457 +3 156 1214 1213 +3 453 717 1 +3 552 829 868 +3 114 276 263 +3 570 734 701 +3 324 29 325 +3 1 717 212 +3 214 102 101 +3 2 364 213 +3 95 364 2 +3 74 97 68 +3 108 58 1265 +3 196 241 504 +3 416 325 326 +3 1346 900 767 +3 642 1205 1249 +3 71 135 6 +3 665 261 260 +3 389 43 216 +3 108 64 58 +3 1255 1236 1250 +3 7 1261 71 +3 1261 135 71 +3 83 737 17 +3 165 380 327 +3 147 29 324 +3 279 717 281 +3 417 1218 607 +3 1218 247 607 +3 83 573 737 +3 737 1239 7 +3 1239 1261 7 +3 42 620 147 +3 1215 697 1214 +3 1221 1242 1236 +3 1261 172 135 +3 651 62 6 +3 117 332 6 +3 62 117 6 +3 416 324 325 +3 157 324 416 +3 40 5 43 +3 1227 1239 737 +3 573 1227 737 +3 1261 1262 172 +3 172 651 6 +3 135 172 6 +3 62 807 117 +3 0 25 160 +3 364 388 643 +3 345 95 94 +3 1214 909 1215 +3 336 149 180 +3 233 388 364 +3 807 832 117 +3 1243 1262 1261 +3 1239 1243 1261 +3 42 150 620 +3 1215 1217 697 +3 1214 412 198 +3 1213 1214 198 +3 293 1227 573 +3 172 62 651 +3 878 1591 67 +3 1214 697 412 +3 1228 1243 1239 +3 1227 1228 1239 +3 96 45 438 +3 40 704 5 +3 59 92 181 +3 172 9 62 +3 643 22 158 +3 388 22 643 +3 92 149 181 +3 345 94 334 +3 652 21 92 +3 345 232 95 +3 214 101 362 +3 535 171 713 +3 1262 678 172 +3 678 9 172 +3 9 592 62 +3 479 349 233 +3 326 325 333 +3 117 832 332 +3 347 345 334 +3 234 1216 706 +3 486 62 592 +3 486 807 62 +3 884 1340 1884 +3 1270 1381 1372 +3 348 157 299 +3 1320 1418 1395 +3 1243 452 1262 +3 1262 452 678 +3 343 592 9 +3 149 61 52 +3 1224 1230 1228 +3 1246 1253 1243 +3 1243 1253 452 +3 163 486 592 +3 163 96 486 +3 2 87 54 +3 1474 1497 1496 +3 1488 1474 1496 +3 525 115 731 +3 1230 1246 1243 +3 1228 1230 1243 +3 452 343 9 +3 678 452 9 +3 31 592 343 +3 31 163 592 +3 743 226 437 +3 334 256 347 +3 149 52 180 +3 6 875 248 +3 1482 1474 1488 +3 1246 1230 1253 +3 452 31 343 +3 45 96 163 +3 364 158 521 +3 737 7 103 +3 213 73 87 +3 1063 533 584 +3 45 44 438 +3 42 436 150 +3 1244 1240 1092 +3 211 445 23 +3 1459 1465 1482 +3 1440 988 1442 +3 163 44 45 +3 1418 1354 1863 +3 436 1241 150 +3 453 1027 42 +3 108 1265 1249 +3 230 454 59 +3 1465 1474 1482 +3 311 1329 1319 +3 677 1234 1230 +3 1230 1234 1253 +3 452 374 31 +3 163 323 44 +3 282 214 230 +3 214 282 230 +3 1258 374 452 +3 1253 1258 452 +3 1215 909 1217 +3 1354 1418 1320 +3 1234 1240 1253 +3 294 418 853 +3 558 234 226 +3 11 103 71 +3 1240 1258 1253 +3 31 77 163 +3 77 323 163 +3 558 280 234 +3 214 224 186 +3 1205 1250 1249 +3 586 1296 1282 +3 1240 1234 677 +3 114 230 276 +3 1125 47 32 +3 308 77 31 +3 868 780 340 +3 1250 108 1249 +3 694 226 707 +3 288 1125 32 +3 319 31 374 +3 31 319 308 +3 529 323 77 +3 323 24 44 +3 280 309 234 +3 234 309 1216 +3 1491 1012 183 +3 77 308 529 +3 323 41 24 +3 225 361 1313 +3 6 248 71 +3 1258 669 374 +3 669 319 374 +3 249 41 323 +3 529 249 323 +3 115 444 782 +3 146 90 3 +3 309 705 1216 +3 669 1258 1240 +3 1264 109 636 +3 1302 185 1293 +3 1217 909 960 +3 237 265 1302 +3 337 1337 1336 +3 547 541 205 +3 1313 691 705 +3 286 352 337 +3 1327 1332 370 +3 798 846 901 +3 337 1338 1337 +3 361 225 611 +3 451 439 484 +3 677 1092 1240 +3 225 1313 109 +3 264 228 277 +3 352 1334 337 +3 785 783 1340 +3 309 1313 705 +3 674 683 682 +3 663 623 602 +3 622 663 710 +3 995 1591 806 +3 450 206 1047 +3 1283 99 215 +3 611 563 593 +3 475 246 664 +3 1294 1264 636 +3 442 1337 1347 +3 465 527 227 +3 659 630 636 +3 1454 1499 1527 +3 602 674 663 +3 107 1293 185 +3 1829 1851 1850 +3 109 690 660 +3 1313 690 109 +3 563 611 1264 +3 362 101 1237 +3 337 1334 1338 +3 206 450 517 +3 1347 471 503 +3 167 554 1323 +3 1468 1472 1489 +3 1091 1141 702 +3 471 563 1294 +3 715 1167 821 +3 1264 611 225 +3 1332 337 1336 +3 1004 1887 399 +3 586 1283 215 +3 1023 1252 1400 +3 1179 1370 1383 +3 1313 726 1324 +3 471 636 630 +3 352 420 1334 +3 1047 39 450 +3 99 1283 586 +3 237 1302 107 +3 14 446 330 +3 1313 361 645 +3 530 525 784 +3 1338 553 1348 +3 1337 1338 1348 +3 370 1332 442 +3 1332 1336 442 +3 715 821 414 +3 237 283 1322 +3 362 1237 282 +3 187 1303 237 +3 257 27 131 +3 801 430 1335 +3 1287 36 213 +3 554 167 338 +3 335 1331 1330 +3 311 335 1330 +3 1331 439 451 +3 506 420 421 +3 1330 1331 451 +3 663 674 1284 +3 674 385 1284 +3 184 107 185 +3 1322 283 314 +3 14 27 446 +3 439 520 484 +3 265 185 1302 +3 420 553 1338 +3 554 338 916 +3 1400 1298 1023 +3 553 563 471 +3 1324 726 1313 +3 1285 14 446 +3 434 435 451 +3 338 167 175 +3 277 311 1319 +3 546 783 244 +3 801 1335 1274 +3 338 1297 916 +3 1294 563 1264 +3 420 1338 1334 +3 783 606 244 +3 1337 1348 1347 +3 1313 1324 690 +3 311 312 335 +3 220 1285 1310 +3 1284 385 1278 +3 1128 1023 1252 +3 1285 220 14 +3 622 623 663 +3 109 660 636 +3 524 446 330 +3 1589 1402 1403 +3 338 220 1310 +3 674 682 385 +3 284 337 1332 +3 107 1302 1293 +3 663 1284 710 +3 1888 517 1067 +3 350 1251 69 +3 435 434 415 +3 435 415 428 +3 1297 338 1310 +3 682 307 385 +3 1306 1305 1280 +3 1276 1306 1280 +3 313 367 312 +3 1327 284 1332 +3 1336 1337 442 +3 1264 225 109 +3 180 169 1229 +3 475 801 246 +3 352 267 353 +3 1403 1404 1589 +3 1285 1292 1310 +3 307 682 748 +3 682 718 748 +3 1277 1276 1275 +3 1158 237 107 +3 1067 517 511 +3 1271 1282 1270 +3 489 125 443 +3 446 14 330 +3 586 1282 1271 +3 1292 1285 446 +3 446 330 1287 +3 443 125 489 +3 108 116 735 +3 813 100 99 +3 1276 1307 1306 +3 1483 1260 1317 +3 1272 586 1271 +3 1348 553 471 +3 1287 213 219 +3 330 446 1287 +3 443 231 489 +3 330 36 1287 +3 86 35 955 +3 450 785 1560 +3 1312 1304 1260 +3 1329 435 428 +3 1289 1276 1277 +3 1289 1290 1276 +3 1158 187 237 +3 1311 556 1248 +3 558 226 743 +3 1323 554 993 +3 1292 446 524 +3 273 443 489 +3 1290 1289 1277 +3 1290 1307 1276 +3 215 264 1296 +3 1304 1286 1273 +3 1260 1304 1273 +3 1311 1248 1273 +3 1286 1311 1273 +3 246 801 250 +3 1322 314 278 +3 1019 1572 1036 +3 307 748 608 +3 182 307 608 +3 1321 443 273 +3 471 1294 636 +3 215 1296 586 +3 1322 278 265 +3 542 701 1129 +3 1101 1284 1278 +3 39 783 785 +3 1304 400 1286 +3 400 1311 1286 +3 1339 244 1200 +3 1324 309 726 +3 674 602 683 +3 265 237 1322 +3 1653 1487 1470 +3 446 36 330 +3 1321 22 443 +3 1277 1267 1290 +3 1290 1308 1307 +3 1313 309 1324 +3 467 68 97 +3 1312 1279 1304 +3 367 1331 335 +3 524 330 1287 +3 1347 1348 471 +3 1308 1315 1307 +3 1365 1529 1108 +3 531 530 784 +3 123 531 784 +3 1041 556 1311 +3 666 1041 1311 +3 312 367 335 +3 1705 1707 1711 +3 690 1324 725 +3 1331 367 439 +3 710 1284 1101 +3 608 748 758 +3 170 699 169 +3 1308 1309 1315 +3 1368 1362 1371 +3 306 1200 244 +3 1279 1299 1304 +3 1304 1299 400 +3 666 1311 400 +3 251 283 237 +3 1853 1866 1871 +3 1312 963 1279 +3 1101 1279 963 +3 1314 1321 273 +3 699 1229 169 +3 1268 1290 1267 +3 1290 1309 1308 +3 386 1320 1315 +3 1320 386 1315 +3 314 1327 370 +3 542 156 701 +3 475 1486 1684 +3 1297 1185 528 +3 1031 916 60 +3 1297 1310 1185 +3 158 1321 1314 +3 1379 1305 1306 +3 553 420 506 +3 291 1342 782 +3 608 758 1041 +3 666 608 1041 +3 1635 1452 1453 +3 60 916 528 +3 916 1297 528 +3 1314 1287 158 +3 601 471 630 +3 1291 1290 1268 +3 1316 1315 1309 +3 1316 1320 1315 +3 400 608 666 +3 1292 524 1185 +3 187 189 188 +3 68 467 1318 +3 187 188 1303 +3 1281 1291 1268 +3 1290 1291 1309 +3 1320 1316 386 +3 1278 385 1299 +3 1279 1278 1299 +3 385 307 400 +3 1299 385 400 +3 307 182 400 +3 400 182 608 +3 801 208 430 +3 243 547 205 +3 1292 1185 1310 +3 1324 726 725 +3 699 170 105 +3 105 68 1318 +3 699 105 1318 +3 1316 1325 386 +3 1325 1187 386 +3 1096 1587 1114 +3 515 208 801 +3 1287 1314 524 +3 1287 219 158 +3 1541 1546 1545 +3 1540 1541 1545 +3 1361 519 1520 +3 570 1129 701 +3 785 1340 884 +3 176 903 127 +3 1232 1226 1233 +3 570 1366 1129 +3 1571 884 1560 +3 378 533 1432 +3 210 570 533 +3 378 210 533 +3 570 210 1366 +3 210 290 1129 +3 1366 210 1129 +3 1129 290 542 +3 290 909 542 +3 290 960 909 +3 124 697 290 +3 210 124 290 +3 697 457 290 +3 290 457 960 +3 960 457 1217 +3 378 124 210 +3 1477 1420 1006 +3 591 378 597 +3 1165 591 597 +3 378 591 124 +3 124 457 697 +3 124 1394 457 +3 1653 1470 1452 +3 1377 1378 1388 +3 1199 1048 1231 +3 124 350 1394 +3 1394 350 457 +3 1048 1165 1231 +3 1048 671 591 +3 1165 1048 591 +3 671 350 124 +3 591 671 124 +3 350 69 457 +3 98 467 97 +3 827 155 1880 +3 1544 1545 1157 +3 176 173 18 +3 1273 700 1260 +3 1369 1048 1199 +3 671 588 350 +3 1545 1546 1204 +3 1546 640 1204 +3 607 247 231 +3 1278 1279 1101 +3 154 1081 1513 +3 1777 1770 1785 +3 1295 499 143 +3 1850 1849 1834 +3 1199 732 1369 +3 732 1183 1369 +3 926 1048 1369 +3 1183 926 1369 +3 926 635 671 +3 1048 926 671 +3 671 635 588 +3 635 1251 350 +3 588 635 350 +3 1449 1472 1468 +3 1490 1489 1472 +3 1425 1074 1389 +3 1198 494 1065 +3 758 718 759 +3 1449 1468 1472 +3 1260 700 1317 +3 732 926 1183 +3 1449 1451 1468 +3 1468 1451 1472 +3 1490 538 1489 +3 272 406 952 +3 1183 926 732 +3 926 1183 635 +3 1426 1435 1434 +3 1449 1450 1451 +3 1421 1422 1426 +3 1426 1422 1435 +3 1469 1486 1490 +3 1472 1469 1490 +3 1183 455 635 +3 1435 1450 1449 +3 1434 1435 1449 +3 1451 1469 1472 +3 475 538 1490 +3 1486 475 1490 +3 475 664 538 +3 250 289 538 +3 664 250 538 +3 306 260 575 +3 455 1183 732 +3 1169 455 732 +3 455 469 635 +3 469 1256 1251 +3 635 469 1251 +3 1204 1389 1074 +3 1319 1381 1382 +3 1364 1370 1085 +3 1329 1396 1381 +3 1330 435 1329 +3 1444 1451 1450 +3 1435 1444 1450 +3 1520 519 1120 +3 1505 1120 1326 +3 640 883 1425 +3 1357 1364 1355 +3 1357 1370 1364 +3 1357 1211 1370 +3 1225 1245 1448 +3 1408 1423 1422 +3 1411 1408 1422 +3 1423 1436 1435 +3 1422 1423 1435 +3 1436 1437 1444 +3 1435 1436 1444 +3 1437 1452 1451 +3 1444 1437 1451 +3 1452 1470 1469 +3 1451 1452 1469 +3 1469 1470 1486 +3 1486 1674 1487 +3 1413 980 1420 +3 1470 1487 1486 +3 1537 154 1105 +3 1393 1054 1169 +3 668 455 1169 +3 1054 668 1169 +3 668 735 469 +3 455 668 469 +3 1455 1445 1446 +3 1185 524 298 +3 459 552 38 +3 1731 1739 1722 +3 1376 1211 1357 +3 1409 1408 1398 +3 1427 1437 1436 +3 1423 1427 1436 +3 1403 1388 1404 +3 84 1367 1363 +3 596 556 1041 +3 714 1185 298 +3 1004 1054 1393 +3 1210 574 399 +3 1320 1307 1315 +3 1635 1453 1438 +3 1359 1357 1356 +3 1358 1359 1356 +3 1377 1376 1357 +3 1359 1377 1357 +3 1388 1211 1376 +3 1377 1388 1376 +3 1402 1409 1398 +3 1388 1398 1211 +3 1402 1408 1409 +3 1402 1424 1423 +3 1408 1402 1423 +3 1423 1424 1427 +3 1424 1438 1437 +3 1427 1424 1437 +3 1438 1453 1452 +3 1437 1438 1452 +3 1197 828 650 +3 1111 1511 1510 +3 1300 1319 1382 +3 1010 808 539 +3 208 1198 430 +3 1200 459 38 +3 1539 1540 1544 +3 1507 1094 1405 +3 1094 976 1405 +3 475 515 801 +3 533 378 1432 +3 744 491 668 +3 1054 744 668 +3 491 101 735 +3 668 491 735 +3 384 459 1200 +3 306 384 1200 +3 1512 1197 650 +3 7 71 103 +3 1466 1295 1074 +3 1325 1328 1187 +3 1329 428 1328 +3 1507 1405 1397 +3 1120 897 1184 +3 1388 1403 1402 +3 1110 859 576 +3 1431 1110 576 +3 399 1212 744 +3 1363 800 153 +3 575 384 306 +3 1178 1100 1512 +3 1425 883 1074 +3 733 84 1363 +3 55 54 87 +3 1296 1300 1282 +3 1378 1377 1359 +3 1004 715 414 +3 1462 1479 1478 +3 1479 1492 222 +3 1478 1479 222 +3 1492 30 179 +3 222 1492 179 +3 30 351 179 +3 1544 1157 154 +3 429 297 709 +3 1110 1483 1475 +3 86 306 391 +3 700 159 1498 +3 1317 700 1498 +3 205 467 540 +3 828 518 650 +3 1672 1462 1473 +3 399 574 1212 +3 574 634 744 +3 1212 574 744 +3 634 1237 491 +3 744 634 491 +3 1367 714 1363 +3 375 606 112 +3 375 82 606 +3 82 86 391 +3 1457 1181 640 +3 1546 1457 640 +3 1479 1493 1492 +3 1493 258 30 +3 1492 1493 30 +3 429 1248 297 +3 39 375 199 +3 336 181 149 +3 1439 1511 1111 +3 1684 515 475 +3 1483 1317 1475 +3 1317 1498 1475 +3 429 342 159 +3 700 429 159 +3 1510 1052 1179 +3 1181 1130 883 +3 640 1181 883 +3 1405 980 1413 +3 1140 964 1181 +3 1509 1439 1517 +3 1479 1480 1493 +3 403 351 30 +3 258 403 30 +3 390 389 1121 +3 1400 897 1298 +3 604 272 709 +3 1460 749 603 +3 403 523 351 +3 1249 329 642 +3 1390 1466 883 +3 1382 1381 1270 +3 1363 714 800 +3 342 429 709 +3 540 375 1047 +3 297 604 709 +3 1467 1461 1201 +3 1130 1390 883 +3 1374 1454 1515 +3 1462 1480 1479 +3 1136 523 403 +3 964 1441 1181 +3 1059 1522 1128 +3 1003 221 500 +3 976 1003 500 +3 1100 1197 1512 +3 390 25 43 +3 1407 1416 1415 +3 1406 1407 1415 +3 1455 1446 1458 +3 1446 1463 1462 +3 1458 1446 1462 +3 1463 1464 1462 +3 1464 1481 1480 +3 1462 1464 1480 +3 1481 1494 1493 +3 1480 1481 1493 +3 1494 994 258 +3 1493 1494 258 +3 456 403 258 +3 994 456 258 +3 621 1136 403 +3 456 621 403 +3 621 523 1136 +3 621 745 523 +3 141 473 523 +3 745 141 523 +3 1516 1524 1476 +3 1128 245 1471 +3 1155 321 634 +3 574 1155 634 +3 599 681 202 +3 298 524 273 +3 681 236 202 +3 1368 1371 1527 +3 1263 1254 1540 +3 1502 1524 1476 +3 1476 1046 1115 +3 321 454 1237 +3 634 321 1237 +3 541 467 205 +3 467 97 540 +3 98 97 467 +3 236 84 733 +3 1446 1464 1463 +3 621 141 745 +3 1516 1476 1503 +3 1467 1201 828 +3 174 639 142 +3 202 236 733 +3 1686 1703 1702 +3 1494 1495 994 +3 1495 1123 994 +3 516 141 621 +3 1037 1059 1128 +3 590 467 541 +3 701 156 1164 +3 1398 1408 1383 +3 493 1301 322 +3 639 321 1155 +3 1429 1446 1445 +3 1481 1495 1494 +3 1220 456 994 +3 1123 1220 994 +3 954 322 495 +3 1373 493 322 +3 987 321 639 +3 260 306 86 +3 1370 1384 1383 +3 1280 1305 1362 +3 1305 1371 1362 +3 1305 1379 1371 +3 1392 1386 1371 +3 1392 1395 1386 +3 1395 1407 1386 +3 1395 1417 1416 +3 1407 1395 1416 +3 1703 1694 1704 +3 1428 1430 1429 +3 1430 1442 1446 +3 1429 1430 1446 +3 1442 1459 1464 +3 1446 1442 1464 +3 1459 1482 1481 +3 1464 1459 1481 +3 1482 1488 1481 +3 1488 1496 1495 +3 1481 1488 1495 +3 1496 468 1123 +3 1495 1496 1123 +3 637 1220 1123 +3 468 637 1123 +3 637 456 1220 +3 637 1203 456 +3 161 621 456 +3 1203 161 456 +3 75 516 621 +3 161 75 621 +3 1687 1694 1703 +3 75 34 495 +3 954 495 34 +3 34 32 322 +3 954 34 322 +3 32 47 322 +3 47 1373 322 +3 47 493 1373 +3 47 183 493 +3 183 1055 493 +3 1055 1012 174 +3 1012 639 174 +3 959 987 639 +3 1012 959 639 +3 959 321 987 +3 959 346 321 +3 346 454 321 +3 1341 1229 541 +3 1229 699 541 +3 699 1318 590 +3 541 699 590 +3 637 161 1203 +3 1615 1635 1438 +3 1300 1296 1319 +3 1379 1395 1392 +3 1615 1438 1424 +3 1613 1615 1424 +3 75 1007 34 +3 1229 1341 336 +3 700 1273 1248 +3 1392 1395 1379 +3 70 161 637 +3 183 1012 1055 +3 1673 1184 1504 +3 1159 1504 1184 +3 1266 346 959 +3 1604 1613 1603 +3 1459 1442 1456 +3 1075 1502 1503 +3 221 1100 500 +3 677 1084 1092 +3 1230 1224 677 +3 1537 1544 154 +3 1105 1097 1088 +3 1121 1105 1088 +3 1146 1346 767 +3 1087 293 176 +3 1100 1467 1197 +3 1154 585 1209 +3 962 1032 1065 +3 1765 1759 1024 +3 1408 1501 1383 +3 1516 1502 1524 +3 143 499 519 +3 1147 1142 1126 +3 1074 1094 680 +3 1399 897 1400 +3 1087 176 366 +3 235 1087 653 +3 897 1399 1184 +3 1149 1135 1061 +3 1685 1687 1360 +3 1379 1392 1371 +3 1810 259 242 +3 293 448 176 +3 1521 1537 1105 +3 235 653 677 +3 1100 1361 1467 +3 373 1538 1537 +3 1514 585 1059 +3 1059 585 341 +3 462 796 1023 +3 964 1106 1419 +3 1505 1326 1201 +3 711 63 1514 +3 964 1140 1092 +3 340 780 868 +3 796 1037 1128 +3 1037 127 796 +3 127 1037 796 +3 18 903 127 +3 1059 341 1522 +3 1508 366 1098 +3 1410 176 127 +3 293 1087 235 +3 1117 187 1876 +3 366 1508 1106 +3 1399 1159 1184 +3 1399 1400 1252 +3 1170 1099 1142 +3 1410 1037 1098 +3 903 18 127 +3 1383 1384 1211 +3 1522 341 1154 +3 1120 1505 1201 +3 1087 366 653 +3 1060 1135 1485 +3 964 1419 1130 +3 293 235 1224 +3 1244 1092 1457 +3 1545 1204 1157 +3 1252 1471 1399 +3 366 964 653 +3 1525 1126 1142 +3 160 360 1173 +3 366 176 1098 +3 499 1401 1298 +3 1539 1544 1537 +3 677 653 1084 +3 176 18 903 +3 199 375 112 +3 1520 1120 1461 +3 644 1539 1538 +3 80 1535 216 +3 176 1410 1098 +3 1140 1181 1457 +3 462 1098 796 +3 1541 1457 1546 +3 1361 1520 1467 +3 1467 1520 1461 +3 373 644 1538 +3 1106 462 781 +3 1591 834 67 +3 390 594 360 +3 160 390 360 +3 1254 1247 1541 +3 1075 1503 980 +3 903 711 127 +3 181 263 276 +3 444 1083 291 +3 1538 1539 1537 +3 1419 1106 1390 +3 519 1361 143 +3 216 1535 1521 +3 1094 976 680 +3 1441 1130 1181 +3 1006 672 1385 +3 1060 1485 1149 +3 43 389 390 +3 181 809 263 +3 1120 1201 1461 +3 1130 1419 1390 +3 1081 680 1507 +3 1231 1165 597 +3 809 1083 263 +3 964 366 1106 +3 809 181 336 +3 809 291 1083 +3 496 1506 1046 +3 650 496 1046 +3 390 1121 594 +3 1295 1003 1074 +3 1832 1845 1831 +3 1204 640 1389 +3 341 585 1154 +3 1081 1507 1082 +3 511 1884 569 +3 1197 1467 828 +3 1341 809 336 +3 1094 680 976 +3 1540 1545 1544 +3 1398 1388 1402 +3 594 1121 1088 +3 1233 1099 1189 +3 1502 1516 1503 +3 1506 1344 1115 +3 291 1137 1342 +3 1097 1513 1082 +3 1412 812 123 +3 498 831 812 +3 1412 498 812 +3 883 1466 1074 +3 1006 1420 962 +3 1399 1471 1159 +3 962 672 1006 +3 1118 1091 702 +3 1686 1687 1703 +3 653 964 1084 +3 1735 1756 1747 +3 1 470 1536 +3 127 1059 1037 +3 1046 1506 1115 +3 1288 1006 1385 +3 1044 1288 1385 +3 1147 1171 1170 +3 1170 1142 1147 +3 1137 291 1346 +3 808 1008 1011 +3 1159 245 1504 +3 672 962 1065 +3 1390 1106 781 +3 1390 1156 1466 +3 1466 1156 1295 +3 1015 1016 1021 +3 644 1540 1539 +3 1137 1533 1542 +3 1088 1089 1288 +3 594 1088 1288 +3 1721 1746 1729 +3 360 594 1044 +3 594 1288 1044 +3 245 1108 1504 +3 216 1521 389 +3 1370 1211 1384 +3 1089 1006 1288 +3 461 587 513 +3 513 587 1351 +3 1351 1414 1412 +3 1091 498 1412 +3 1414 1091 1412 +3 1115 1530 538 +3 1092 1140 1457 +3 1509 1090 1534 +3 1137 1146 1533 +3 1349 461 1547 +3 767 1 1064 +3 1529 1365 1195 +3 964 1130 1441 +3 1351 587 1414 +3 1115 538 289 +3 1405 1413 1397 +3 1513 1081 1082 +3 980 514 1420 +3 680 1094 1507 +3 461 1414 587 +3 1106 1508 462 +3 1052 1370 1179 +3 1457 1541 1247 +3 587 1414 461 +3 1420 514 962 +3 545 1201 1326 +3 63 585 1514 +3 1105 154 1097 +3 1064 1533 1146 +3 1414 587 461 +3 973 1414 587 +3 1414 973 587 +3 250 1476 289 +3 1157 1204 680 +3 1398 1383 1211 +3 1507 1397 1082 +3 1543 1349 1533 +3 1536 1543 1533 +3 1543 410 461 +3 1349 1543 461 +3 973 1141 1414 +3 1141 1091 1414 +3 1476 1115 289 +3 1084 964 1092 +3 373 1537 1521 +3 1521 1105 1121 +3 1476 250 1274 +3 1149 1525 1142 +3 1254 1541 1540 +3 1064 1 1533 +3 1082 1397 1089 +3 1088 1082 1089 +3 80 373 1521 +3 1535 80 1521 +3 1341 541 547 +3 39 199 783 +3 1536 1533 1 +3 973 1414 461 +3 410 973 461 +3 1397 1413 1420 +3 1089 1397 1420 +3 1111 1383 1501 +3 1503 1476 1274 +3 606 82 391 +3 780 38 868 +3 1135 1104 1061 +3 711 1514 1059 +3 1365 1194 1195 +3 1111 1510 1179 +3 1485 1135 1149 +3 796 1128 1252 +3 1228 293 1224 +3 644 1263 1540 +3 390 160 25 +3 63 33 104 +3 391 306 606 +3 306 244 606 +3 1097 154 1513 +3 494 672 1065 +3 1543 618 410 +3 537 973 410 +3 618 537 410 +3 1141 1352 702 +3 972 992 991 +3 1509 1534 1439 +3 1088 1097 1082 +3 1401 1023 1298 +3 53 569 1884 +3 1536 470 1543 +3 1410 127 1037 +3 1227 293 1228 +3 1128 1522 245 +3 1522 1154 245 +3 1850 1870 1849 +3 796 1252 1023 +3 173 83 33 +3 1543 470 618 +3 1242 69 1251 +3 1515 1527 1371 +3 1162 1135 1060 +3 1188 537 618 +3 1109 973 537 +3 1109 1141 973 +3 1109 1352 1141 +3 545 518 828 +3 1201 545 828 +3 1244 1457 1247 +3 1386 1515 1371 +3 1454 1518 1499 +3 1089 1477 1006 +3 462 1401 781 +3 1401 499 781 +3 63 433 585 +3 1886 1066 304 +3 1204 1074 680 +3 127 711 1059 +3 640 1425 1389 +3 1188 618 537 +3 499 1298 519 +3 1226 1060 1099 +3 1233 1226 1099 +3 1515 1454 1386 +3 1298 897 1120 +3 519 1298 1120 +3 1188 537 618 +3 1524 1502 1046 +3 1178 980 550 +3 1178 1512 1075 +3 1515 1386 1391 +3 1386 1454 1515 +3 1149 1142 1099 +3 1060 1149 1099 +3 1508 1098 462 +3 1401 462 1023 +3 1178 1075 980 +3 552 868 459 +3 1061 1525 1149 +3 1098 1037 796 +3 1524 1502 1476 +3 1476 1524 1046 +3 1828 1829 1834 +3 1089 1420 1477 +3 1352 672 494 +3 1502 1512 650 +3 1252 1128 1471 +3 1531 1518 1454 +3 1374 1531 1454 +3 1512 1502 1075 +3 1173 618 470 +3 160 1173 470 +3 1173 1188 618 +3 1173 360 1188 +3 1188 360 537 +3 360 1044 537 +3 537 1044 1109 +3 1044 1385 1109 +3 672 1352 1109 +3 1385 672 1109 +3 511 517 1560 +3 1390 781 1156 +3 223 222 178 +3 831 123 812 +3 141 1333 1618 +3 1812 1829 1828 +3 115 1005 1210 +3 1636 1637 1656 +3 1515 1454 1527 +3 1682 538 1530 +3 1637 1657 1656 +3 1072 1525 1061 +3 1071 1072 1061 +3 548 1350 142 +3 1072 1592 1525 +3 1487 1674 1684 +3 67 937 1010 +3 1754 1784 1762 +3 1462 1478 1473 +3 1137 1542 778 +3 1614 1637 1616 +3 1036 1572 1049 +3 1049 1584 1072 +3 1072 1584 1592 +3 1126 1525 1592 +3 1584 1126 1592 +3 199 606 783 +3 1499 1362 1368 +3 1680 1678 1679 +3 1049 1586 1584 +3 799 178 1558 +3 702 494 1198 +3 1499 1368 1527 +3 868 552 459 +3 1486 1487 1674 +3 1572 1584 1586 +3 1049 1572 1586 +3 779 702 1198 +3 1799 1812 1795 +3 1618 1333 141 +3 1662 1676 1675 +3 805 1350 548 +3 1026 1570 1572 +3 1572 1073 1584 +3 1073 1078 1584 +3 1112 1126 1584 +3 1078 1112 1584 +3 1617 1620 1416 +3 1676 560 483 +3 1675 1676 483 +3 1659 1678 1663 +3 1572 1570 1073 +3 1054 1004 399 +3 827 1880 1870 +3 1404 1590 1604 +3 1374 1515 1391 +3 1345 472 498 +3 802 1555 1519 +3 1655 1675 1674 +3 1416 1614 1415 +3 1407 1406 1386 +3 482 560 1676 +3 1678 1677 1663 +3 1146 1137 1346 +3 1026 1562 1570 +3 1562 1570 1572 +3 1570 1562 1572 +3 1677 482 1676 +3 547 1556 798 +3 701 734 570 +3 1589 1404 1603 +3 1641 1638 1634 +3 1639 1641 1634 +3 1657 1658 1662 +3 260 261 575 +3 156 701 1164 +3 1639 1634 1621 +3 1638 1658 1657 +3 1637 1638 1657 +3 1519 1118 702 +3 1415 1605 1590 +3 779 1519 702 +3 1406 1415 1590 +3 1663 1677 1662 +3 1641 1659 1638 +3 1658 1663 1662 +3 1635 1636 1654 +3 1562 1073 1570 +3 1687 1686 1439 +3 1047 375 39 +3 1621 1620 1617 +3 738 1519 779 +3 483 515 1674 +3 473 1333 531 +3 481 473 531 +3 1155 142 639 +3 1662 1675 1655 +3 1656 1662 1655 +3 1038 1045 1073 +3 1562 1038 1073 +3 222 179 178 +3 1428 1621 1617 +3 1675 483 1674 +3 1159 1471 245 +3 1365 245 1154 +3 1209 1365 1154 +3 245 1365 1108 +3 1637 1636 1616 +3 1416 1620 1614 +3 1638 1637 1614 +3 884 1340 1884 +3 1049 1043 1036 +3 1605 1616 1607 +3 1620 1638 1614 +3 1455 1428 1445 +3 1622 1529 1195 +3 1177 1622 1195 +3 550 976 500 +3 1587 1523 1119 +3 1428 1455 1639 +3 1096 1079 1080 +3 553 536 563 +3 1404 1604 1603 +3 1153 1622 1177 +3 641 638 661 +3 1013 1020 1038 +3 1051 1114 1096 +3 1080 1051 1096 +3 1114 1587 1096 +3 1556 243 798 +3 1532 1623 1622 +3 1153 1532 1622 +3 1642 1529 1622 +3 1623 1642 1622 +3 1642 1504 1108 +3 1529 1642 1108 +3 1378 1404 1388 +3 178 179 1559 +3 1455 1473 1641 +3 1653 1655 1674 +3 805 530 531 +3 33 18 173 +3 1605 1604 1590 +3 179 1259 1559 +3 1051 1587 1114 +3 1118 1345 1091 +3 851 523 532 +3 715 732 1167 +3 1636 1655 1654 +3 1621 1634 1620 +3 1093 1280 1362 +3 1051 1114 1587 +3 1604 1605 1607 +3 1022 1563 1051 +3 1030 1022 1051 +3 1563 1573 1114 +3 1051 1563 1114 +3 1573 1585 1587 +3 1114 1573 1587 +3 1585 1599 1523 +3 1587 1585 1523 +3 1599 1608 1532 +3 1523 1599 1532 +3 1608 1624 1623 +3 1532 1608 1623 +3 1643 1642 1623 +3 1624 1643 1623 +3 1643 1673 1504 +3 1642 1643 1504 +3 551 547 798 +3 1014 1016 1015 +3 1306 1307 1379 +3 805 548 525 +3 1656 1655 1636 +3 1333 805 531 +3 1683 1184 1673 +3 1608 1625 1624 +3 1644 1643 1624 +3 1625 1644 1624 +3 1664 1673 1643 +3 1644 1664 1643 +3 1023 1128 1252 +3 585 854 1209 +3 1351 1412 123 +3 322 1301 495 +3 799 844 474 +3 516 495 141 +3 1555 1345 1118 +3 495 1618 141 +3 1047 205 540 +3 141 1333 473 +3 1433 1426 1434 +3 597 378 1063 +3 1528 1564 1563 +3 1022 1528 1563 +3 1564 1574 1573 +3 1563 1564 1573 +3 1573 1574 1585 +3 1574 1576 1585 +3 1585 1576 1599 +3 1576 1600 1599 +3 1600 1609 1608 +3 1599 1600 1608 +3 1609 1626 1625 +3 1608 1609 1625 +3 1645 1644 1625 +3 1626 1645 1625 +3 1645 1665 1664 +3 1644 1645 1664 +3 1665 1673 1664 +3 1665 1326 1683 +3 1673 1665 1683 +3 1326 1184 1683 +3 1590 1404 1378 +3 1614 1616 1605 +3 1415 1614 1605 +3 495 1333 1618 +3 738 802 1519 +3 1473 1659 1641 +3 1301 805 1333 +3 205 206 517 +3 1405 976 550 +3 495 1301 1333 +3 1593 1601 1600 +3 1576 1593 1600 +3 1600 1601 1609 +3 716 208 515 +3 500 1178 550 +3 1259 523 851 +3 1559 1259 851 +3 831 481 812 +3 513 1349 1547 +3 1616 1636 1635 +3 222 223 1680 +3 1301 493 1350 +3 805 1301 1350 +3 1548 1552 1528 +3 1552 1565 1564 +3 1528 1552 1564 +3 1564 1565 1574 +3 1574 1565 1576 +3 1565 1577 1576 +3 1594 1593 1576 +3 1577 1594 1576 +3 1602 1601 1593 +3 1594 1602 1593 +3 1602 1610 1609 +3 1601 1602 1609 +3 1610 1627 1626 +3 1609 1610 1626 +3 1627 1646 1645 +3 1626 1627 1645 +3 1666 1665 1645 +3 1646 1666 1645 +3 1666 545 1326 +3 1665 1666 1326 +3 483 716 515 +3 547 243 1556 +3 221 1003 1295 +3 143 221 1295 +3 809 1341 547 +3 551 809 547 +3 782 1342 778 +3 731 782 778 +3 1458 1660 1455 +3 752 309 753 +3 1424 1402 1603 +3 1519 1555 1118 +3 1549 1553 1552 +3 1552 1553 1565 +3 1775 1799 1784 +3 1406 1590 1378 +3 493 174 142 +3 1350 493 142 +3 1656 1657 1662 +3 291 809 551 +3 731 778 513 +3 523 473 481 +3 1365 1209 1194 +3 1346 291 551 +3 784 731 513 +3 1550 1554 1553 +3 1549 1550 1553 +3 1566 1565 1553 +3 1554 1566 1553 +3 1566 1578 1577 +3 1565 1566 1577 +3 1578 1579 1577 +3 1577 1579 1594 +3 1579 1595 1602 +3 1594 1579 1602 +3 1595 1611 1610 +3 1602 1595 1610 +3 1628 1627 1610 +3 1611 1628 1610 +3 1628 1647 1646 +3 1627 1628 1646 +3 1647 1667 1666 +3 1646 1647 1666 +3 1667 1668 1666 +3 518 545 1666 +3 1668 518 1666 +3 1074 1003 1094 +3 1607 1616 1615 +3 123 784 513 +3 1499 1527 1454 +3 1604 1607 1615 +3 1566 1579 1578 +3 1628 1648 1647 +3 1648 1668 1667 +3 1647 1648 1667 +3 1681 518 1668 +3 778 1533 1349 +3 513 778 1349 +3 496 650 497 +3 1615 1616 1635 +3 1429 1445 1428 +3 718 758 748 +3 1678 1680 474 +3 1680 223 474 +3 778 1542 1533 +3 206 205 1047 +3 1478 222 1680 +3 1679 1678 1659 +3 857 831 498 +3 1386 1406 1391 +3 1360 1090 1554 +3 1550 1360 1554 +3 1567 1566 1554 +3 1090 1567 1554 +3 1567 1580 1579 +3 1566 1567 1579 +3 1580 1596 1595 +3 1579 1580 1595 +3 1596 1606 1611 +3 1595 1596 1611 +3 1606 1629 1628 +3 1611 1606 1628 +3 1629 1630 1628 +3 1630 1649 1648 +3 1628 1630 1648 +3 1649 1526 1668 +3 1648 1649 1668 +3 496 1681 1668 +3 1526 496 1668 +3 497 518 1681 +3 496 497 1681 +3 518 497 650 +3 1005 574 1210 +3 123 513 1351 +3 1877 1876 1865 +3 1558 1555 802 +3 799 1558 802 +3 472 857 498 +3 1455 1641 1639 +3 1634 1638 1620 +3 482 802 738 +3 1248 429 700 +3 1654 1655 1653 +3 1606 1630 1629 +3 1473 1478 1680 +3 1362 1499 1557 +3 1558 857 472 +3 1120 1184 1326 +3 857 851 831 +3 844 802 482 +3 474 844 482 +3 1555 1558 472 +3 844 799 802 +3 1342 1137 778 +3 1649 1669 1526 +3 1669 1506 496 +3 1526 1669 496 +3 1421 1411 1422 +3 851 532 481 +3 780 340 383 +3 1008 780 383 +3 1568 1567 1090 +3 1509 1568 1090 +3 1568 1581 1580 +3 1567 1568 1580 +3 1597 1596 1580 +3 1581 1597 1580 +3 1596 1597 1606 +3 1597 1612 1606 +3 1612 1631 1630 +3 1606 1612 1630 +3 1631 1650 1649 +3 1630 1631 1649 +3 1649 1650 1669 +3 1678 482 1677 +3 560 738 716 +3 1345 498 1091 +3 500 1100 1178 +3 1678 474 482 +3 1009 878 53 +3 1841 1855 1851 +3 1454 1527 1499 +3 827 107 1864 +3 495 516 75 +3 208 716 1198 +3 1428 1639 1621 +3 1771 1280 1093 +3 842 1008 808 +3 378 533 1063 +3 1582 1581 1568 +3 1659 1663 1658 +3 1865 1864 1851 +3 1503 514 980 +3 1583 1582 1568 +3 1588 1581 1582 +3 1583 1588 1582 +3 1598 1597 1581 +3 1588 1598 1581 +3 1433 1612 1597 +3 1433 1619 1612 +3 1632 1631 1612 +3 1619 1632 1612 +3 1651 1650 1631 +3 1632 1651 1631 +3 1651 1670 1669 +3 1650 1651 1669 +3 1670 1344 1506 +3 1669 1670 1506 +3 1660 1473 1455 +3 1353 842 808 +3 995 1353 808 +3 1353 1008 842 +3 1353 842 1008 +3 38 780 1008 +3 842 38 1008 +3 1517 1569 1568 +3 1509 1517 1568 +3 1569 1583 1568 +3 716 779 1198 +3 716 738 779 +3 560 482 738 +3 1360 1687 1534 +3 1353 38 842 +3 1111 1179 1383 +3 1598 1433 1597 +3 868 38 552 +3 1045 1078 1073 +3 1124 406 272 +3 1433 1632 1619 +3 474 223 1122 +3 1033 1765 1024 +3 1378 1359 1374 +3 1269 1270 1281 +3 291 782 444 +3 483 560 716 +3 1462 1473 1660 +3 499 1156 781 +3 1214 542 909 +3 1555 472 1345 +3 178 1559 1558 +3 851 481 831 +3 1269 1281 1268 +3 824 1856 1846 +3 53 1884 1009 +3 1439 1111 1517 +3 1111 1501 1569 +3 1517 1111 1569 +3 1411 1583 1569 +3 1411 1588 1583 +3 1411 1421 1588 +3 1421 1598 1588 +3 1421 1426 1598 +3 1426 1433 1598 +3 1434 1433 1598 +3 1433 1434 1598 +3 1633 1632 1433 +3 1434 1633 1433 +3 1633 1640 1632 +3 1652 1651 1632 +3 1640 1652 1632 +3 1671 1670 1651 +3 1652 1671 1651 +3 1671 1682 1344 +3 1670 1671 1344 +3 1274 1032 514 +3 1503 1274 514 +3 532 523 481 +3 1319 264 277 +3 546 806 1591 +3 546 995 806 +3 546 746 995 +3 1339 1353 995 +3 746 1339 995 +3 1339 1200 38 +3 1353 1339 38 +3 223 178 799 +3 1530 1344 1682 +3 1449 1633 1434 +3 399 744 1054 +3 831 812 123 +3 1122 223 799 +3 243 205 517 +3 1473 1679 1659 +3 1024 1034 1033 +3 1591 1340 546 +3 1501 1411 1569 +3 1156 499 1295 +3 1449 1640 1633 +3 1209 953 854 +3 1458 1462 1660 +3 1224 235 677 +3 1523 1153 1119 +3 1085 1355 1364 +3 1468 1652 1640 +3 1449 1468 1640 +3 1489 1671 1652 +3 1468 1489 1652 +3 1671 1489 1682 +3 1489 538 1682 +3 1836 1857 1844 +3 803 189 1117 +3 1685 1696 1695 +3 1785 1791 1801 +3 1808 1801 1791 +3 1791 1792 1815 +3 1751 1750 1735 +3 1843 1862 1842 +3 1210 444 115 +3 1800 1816 1799 +3 1803 1821 1802 +3 995 834 1591 +3 758 759 1182 +3 1836 1858 1857 +3 810 168 1857 +3 1858 810 1857 +3 1740 1757 1764 +3 873 872 865 +3 1808 1815 1801 +3 1815 1819 1801 +3 804 803 1117 +3 1741 1757 1740 +3 1793 865 1788 +3 1812 1816 1830 +3 804 1117 1878 +3 1561 1725 1726 +3 1857 168 824 +3 1757 1779 1764 +3 1764 1779 1786 +3 78 815 1868 +3 1822 1821 1803 +3 1717 1737 1721 +3 1844 1857 1846 +3 1725 1724 1013 +3 824 168 79 +3 1713 1718 1696 +3 1715 1714 1699 +3 1722 1730 1711 +3 1843 1842 1825 +3 1819 1843 1825 +3 1857 824 1846 +3 1821 1827 1826 +3 1809 1821 1826 +3 1815 1843 1819 +3 1821 1809 1802 +3 1548 1689 1549 +3 1733 1561 1562 +3 1733 1725 1561 +3 604 599 406 +3 406 599 202 +3 1822 1836 1821 +3 815 1881 1867 +3 1852 1855 1830 +3 1699 1706 1016 +3 54 55 845 +3 158 219 521 +3 1742 1741 1725 +3 1733 1742 1725 +3 1763 1777 1785 +3 1033 1788 1765 +3 1769 1776 1749 +3 1749 1755 1734 +3 1756 1769 1747 +3 1732 1751 1735 +3 1707 1714 1722 +3 1738 1754 1737 +3 1876 1864 1865 +3 1722 1714 1731 +3 865 1810 1787 +3 1788 865 1787 +3 1715 1732 1714 +3 1742 1757 1741 +3 1804 1803 1786 +3 1779 1804 1786 +3 1770 1791 1785 +3 1806 1810 242 +3 1722 1747 1730 +3 1705 1706 1707 +3 1804 1805 1803 +3 1835 1843 1815 +3 1346 551 1883 +3 1802 1809 1792 +3 1837 1836 1822 +3 1017 1837 1822 +3 1878 1117 1877 +3 1711 1730 1713 +3 1690 1706 1705 +3 1837 136 1836 +3 1830 1855 1841 +3 1868 1867 1856 +3 599 20 681 +3 136 1858 1836 +3 1791 1815 1808 +3 1024 1759 1018 +3 1730 1734 1713 +3 1785 1790 1756 +3 20 596 681 +3 1831 1830 1817 +3 1797 1802 1792 +3 1864 1876 827 +3 1881 815 814 +3 1787 1806 1781 +3 1116 916 1031 +3 814 1882 1872 +3 1711 1713 1697 +3 1110 1475 859 +3 1690 1705 1698 +3 1785 1801 1790 +3 1765 1787 1759 +3 596 20 556 +3 596 1180 681 +3 681 1180 1031 +3 1882 804 1872 +3 1698 1711 1697 +3 1759 1781 1758 +3 900 1883 979 +3 1696 1717 1704 +3 1026 1561 1562 +3 1769 1796 1776 +3 1013 1723 1715 +3 1734 1717 1718 +3 1832 1831 1813 +3 1180 316 1116 +3 1031 1180 1116 +3 1561 1742 1733 +3 1882 814 804 +3 1820 1835 1815 +3 1442 988 1447 +3 710 577 622 +3 1810 1806 1787 +3 596 1752 1180 +3 1180 316 1116 +3 316 1180 1116 +3 316 993 916 +3 1116 316 916 +3 1759 1787 1781 +3 1776 1800 1775 +3 1732 1735 1714 +3 1886 409 821 +3 1703 1729 1710 +3 1693 1685 1550 +3 1016 1706 1690 +3 1693 1689 1697 +3 1842 1862 1861 +3 1694 1695 1704 +3 1687 1685 1694 +3 988 382 1447 +3 1447 382 576 +3 747 797 120 +3 1776 1775 1755 +3 1199 1167 732 +3 1041 758 596 +3 596 758 1752 +3 1876 1158 107 +3 1685 1695 1694 +3 1858 818 810 +3 382 1431 576 +3 1693 1697 1696 +3 243 1888 798 +3 1117 189 187 +3 1823 1822 1803 +3 1805 1823 1803 +3 1442 1430 1443 +3 818 1858 136 +3 356 477 424 +3 382 1575 1431 +3 916 993 554 +3 467 590 1318 +3 1685 1693 1696 +3 1845 1866 1853 +3 1431 1575 1110 +3 1182 1752 758 +3 1182 1180 1752 +3 1182 825 1180 +3 1180 825 316 +3 1017 136 1837 +3 1430 1440 1443 +3 1440 908 988 +3 988 908 382 +3 1575 549 1110 +3 549 1150 963 +3 1110 549 963 +3 1825 1813 1814 +3 1796 1817 1800 +3 825 633 316 +3 1699 1714 1706 +3 633 993 316 +3 633 1323 993 +3 1430 1869 1440 +3 908 1575 382 +3 1101 963 1150 +3 1734 1738 1717 +3 1819 1825 1814 +3 1801 1819 1814 +3 633 825 1182 +3 1440 1869 908 +3 908 996 1575 +3 759 787 786 +3 1809 1826 1820 +3 1869 1145 908 +3 549 1101 1150 +3 1723 1732 1715 +3 1428 1847 1430 +3 1145 56 908 +3 908 56 996 +3 1144 1101 549 +3 1809 1820 1815 +3 1793 1788 1033 +3 797 633 1182 +3 759 797 1182 +3 1735 1750 1756 +3 996 56 1575 +3 56 549 1575 +3 1750 1763 1756 +3 1847 1848 1430 +3 1848 1859 1430 +3 1430 1859 1869 +3 56 1168 549 +3 1690 1689 1548 +3 1758 1779 1757 +3 786 797 759 +3 747 633 797 +3 633 747 1323 +3 1323 747 167 +3 865 866 873 +3 1778 1791 1770 +3 78 1868 824 +3 1805 1804 1779 +3 1428 1848 1847 +3 56 1053 1168 +3 1168 1131 1144 +3 549 1168 1144 +3 1877 1117 1876 +3 1707 1722 1711 +3 1731 1735 1739 +3 830 1823 1805 +3 830 1822 1823 +3 1859 1873 1145 +3 1869 1859 1145 +3 1131 1101 1144 +3 1814 1813 1790 +3 830 1017 1822 +3 207 562 561 +3 1772 1771 1093 +3 1557 1772 1093 +3 866 1033 1042 +3 1617 1417 1428 +3 1428 1417 1848 +3 1734 1755 1738 +3 1821 1836 1844 +3 1801 1814 1790 +3 895 797 786 +3 787 759 760 +3 1873 961 1145 +3 1145 961 56 +3 1053 1131 1168 +3 1833 1101 1131 +3 1833 710 1101 +3 1853 1871 1852 +3 1689 1690 1698 +3 1772 1275 1771 +3 1848 1417 1859 +3 242 830 1806 +3 1713 1734 1718 +3 1800 1799 1775 +3 1695 1696 1704 +3 1518 1557 1499 +3 1794 1275 1772 +3 1809 1815 1792 +3 1417 1418 1859 +3 961 951 56 +3 56 951 1053 +3 1833 1131 710 +3 1019 1742 1561 +3 1758 1757 1742 +3 1780 1779 1758 +3 1748 1557 1518 +3 1794 1277 1275 +3 1873 1879 961 +3 951 559 1053 +3 1053 559 1131 +3 1876 107 827 +3 1747 1769 1749 +3 1267 1277 1794 +3 1418 1863 1859 +3 1859 1863 1873 +3 1868 815 1867 +3 1766 1772 1557 +3 1748 1766 1557 +3 866 1793 1033 +3 559 1196 1131 +3 1196 1343 1131 +3 1131 1343 710 +3 1766 1794 1772 +3 180 1229 336 +3 415 1879 1873 +3 415 961 1879 +3 1343 577 710 +3 866 865 1793 +3 1362 1557 1093 +3 1789 1794 1766 +3 1873 1863 415 +3 1456 1442 1447 +3 1018 1742 1019 +3 1743 1748 1518 +3 1531 1743 1518 +3 1789 1267 1794 +3 434 961 415 +3 434 951 961 +3 1781 1779 1780 +3 1811 1267 1789 +3 1781 1805 1779 +3 404 522 438 +3 434 736 951 +3 736 559 951 +3 1743 1766 1748 +3 559 736 1196 +3 1722 1739 1747 +3 715 1393 1169 +3 1534 1090 1360 +3 1269 1271 1270 +3 604 1124 272 +3 1358 1531 1500 +3 1824 1268 1267 +3 1811 1824 1267 +3 155 813 1880 +3 736 480 1196 +3 1196 480 1343 +3 1343 480 577 +3 1790 1813 1796 +3 1782 1789 1766 +3 1760 1782 1766 +3 1803 1802 1797 +3 1777 1770 1785 +3 1719 1743 1531 +3 1760 1766 1743 +3 1838 1269 1268 +3 1824 1838 1268 +3 1750 1770 1777 +3 480 578 577 +3 1689 1693 1550 +3 1763 1750 1777 +3 1770 1777 1785 +3 1691 1358 1356 +3 1719 1531 1358 +3 736 1062 480 +3 1813 1831 1817 +3 1549 1689 1550 +3 1756 1763 1785 +3 1691 1356 1355 +3 1085 1691 1355 +3 1761 1760 1743 +3 1744 1761 1743 +3 1807 1811 1789 +3 1838 1271 1269 +3 78 824 79 +3 1876 187 1158 +3 1821 1844 1827 +3 1708 1719 1358 +3 1744 1743 1719 +3 1782 1807 1789 +3 1807 1824 1811 +3 1860 1271 1838 +3 736 451 1062 +3 1756 1790 1769 +3 1725 1740 1724 +3 1698 1705 1711 +3 1510 1691 1085 +3 1708 1358 1691 +3 1761 1782 1760 +3 1818 1824 1807 +3 1860 1272 1271 +3 1718 1717 1696 +3 451 207 480 +3 1062 451 480 +3 1817 1830 1816 +3 1796 1800 1776 +3 1510 1085 1052 +3 1818 1838 1824 +3 1875 1272 1860 +3 1813 1817 1796 +3 1720 1719 1708 +3 1736 1744 1719 +3 1839 1838 1818 +3 96 807 486 +3 1018 1758 1742 +3 1842 1861 1845 +3 1881 814 1872 +3 1781 1780 1758 +3 1867 1881 1872 +3 1692 1691 1510 +3 1720 1736 1719 +3 1783 1782 1761 +3 1839 1860 1838 +3 1875 1661 586 +3 1272 1875 586 +3 1806 1805 1781 +3 1712 1716 1708 +3 1727 1720 1708 +3 1716 1727 1708 +3 1854 1860 1839 +3 1143 1661 1875 +3 1661 99 586 +3 1143 99 1661 +3 1031 60 236 +3 1709 1708 1691 +3 1692 1709 1691 +3 1709 1712 1708 +3 1709 1716 1712 +3 1709 1727 1716 +3 1727 1728 1720 +3 1786 1803 1797 +3 747 120 167 +3 484 207 451 +3 1736 1753 1744 +3 1753 1761 1744 +3 1753 1783 1761 +3 1874 1860 1854 +3 1874 1875 1860 +3 1792 1791 1778 +3 824 1868 1856 +3 1817 1816 1800 +3 520 207 484 +3 1692 1700 1709 +3 1728 1727 1709 +3 1728 1745 1727 +3 1511 1688 1510 +3 1688 1692 1510 +3 1874 1143 1875 +3 1013 1715 1699 +3 1749 1776 1755 +3 1759 1758 1018 +3 1688 1701 1700 +3 1692 1688 1700 +3 1773 1783 1753 +3 1849 1854 1839 +3 813 1143 1874 +3 813 99 1143 +3 1842 1845 1832 +3 1710 1709 1700 +3 1701 1710 1700 +3 1872 804 1878 +3 1825 1842 1832 +3 1853 1852 1830 +3 1730 1749 1734 +3 1689 1698 1697 +3 1805 1806 830 +3 1710 1728 1709 +3 1840 1849 1839 +3 1831 1853 1830 +3 1724 1723 1013 +3 1729 1728 1710 +3 1849 1874 1854 +3 1849 1870 1874 +3 1741 1740 1725 +3 1755 1775 1754 +3 1731 1714 1735 +3 1747 1749 1730 +3 1706 1714 1707 +3 1729 1745 1728 +3 1767 1773 1753 +3 1880 813 1874 +3 1870 1880 1874 +3 865 858 1810 +3 1810 858 259 +3 1861 1866 1845 +3 1790 1796 1769 +3 1755 1754 1738 +3 1739 1735 1747 +3 1686 1688 1511 +3 1439 1686 1511 +3 1746 1745 1729 +3 1774 1773 1767 +3 1834 1849 1840 +3 1016 1690 1548 +3 1788 1787 1765 +3 1551 1016 1548 +3 1686 1702 1701 +3 1688 1686 1701 +3 1703 1710 1701 +3 1702 1703 1701 +3 1795 1798 1773 +3 1825 1832 1813 +3 1697 1713 1696 +3 1762 1745 1746 +3 1762 1768 1745 +3 1795 1773 1774 diff --git a/samples/cpp/tutorial_code/viz/creating_widgets.cpp b/samples/cpp/tutorial_code/viz/creating_widgets.cpp index 636650252..63f572e56 100644 --- a/samples/cpp/tutorial_code/viz/creating_widgets.cpp +++ b/samples/cpp/tutorial_code/viz/creating_widgets.cpp @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include @@ -42,7 +42,7 @@ void help() class WTriangle : public viz::Widget3D { public: - WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); }; /** @@ -56,22 +56,22 @@ WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, points->InsertNextPoint(pt1.x, pt1.y, pt1.z); points->InsertNextPoint(pt2.x, pt2.y, pt2.z); points->InsertNextPoint(pt3.x, pt3.y, pt3.z); - + vtkSmartPointer triangle = vtkSmartPointer::New(); triangle->GetPointIds()->SetId(0,0); triangle->GetPointIds()->SetId(1,1); triangle->GetPointIds()->SetId(2,2); - + vtkSmartPointer cells = vtkSmartPointer::New(); cells->InsertNextCell(triangle); - + // Create a polydata object vtkSmartPointer polyData = vtkSmartPointer::New(); - + // Add the geometry and topology to the polydata polyData->SetPoints(points); polyData->SetPolys(cells); - + // Create mapper and actor vtkSmartPointer mapper = vtkSmartPointer::New(); #if VTK_MAJOR_VERSION <= 5 @@ -79,13 +79,13 @@ WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, #else mapper->SetInputData(polyData); #endif - + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); - + // Store this actor in the widget in order that visualizer can access it viz::WidgetAccessor::setProp(*this, actor); - + // Set the color of the widget. This has to be called after WidgetAccessor. setColor(color); } @@ -96,18 +96,18 @@ WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, int main() { help(); - + /// Create a window viz::Viz3d myWindow("Creating Widgets"); - + /// Create a triangle widget WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); - + /// Show widget in the visualizer window myWindow.showWidget("TRIANGLE", tw); - + /// Start event loop myWindow.spin(); - + return 0; } diff --git a/samples/cpp/tutorial_code/viz/launching_viz.cpp b/samples/cpp/tutorial_code/viz/launching_viz.cpp index 8dc9a617f..d19967e4b 100644 --- a/samples/cpp/tutorial_code/viz/launching_viz.cpp +++ b/samples/cpp/tutorial_code/viz/launching_viz.cpp @@ -33,33 +33,33 @@ int main() help(); /// Create a window viz::Viz3d myWindow("Viz Demo"); - + /// Start event loop myWindow.spin(); - + /// Event loop is over when pressed q, Q, e, E cout << "First event loop is over" << endl; - + /// Access window via its name viz::Viz3d sameWindow = viz::get("Viz Demo"); - + /// Start event loop sameWindow.spin(); - + /// Event loop is over when pressed q, Q, e, E cout << "Second event loop is over" << endl; - + /// Event loop is over when pressed q, Q, e, E /// Start event loop once for 1 millisecond sameWindow.spinOnce(1, true); while(!sameWindow.wasStopped()) { /// Interact with window - + /// Event loop for 1 millisecond sameWindow.spinOnce(1, true); } - + /// Once more event loop is stopped cout << "Last event loop is over" << endl; return 0; diff --git a/samples/cpp/tutorial_code/viz/transformations.cpp b/samples/cpp/tutorial_code/viz/transformations.cpp index 1748cd5d1..0d7450a63 100644 --- a/samples/cpp/tutorial_code/viz/transformations.cpp +++ b/samples/cpp/tutorial_code/viz/transformations.cpp @@ -44,7 +44,7 @@ Mat cvcloud_load() float dummy1, dummy2; for(size_t i = 0; i < 1889; ++i) ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2; - + cloud *= 5.0f; return cloud; } @@ -55,40 +55,40 @@ Mat cvcloud_load() int main(int argn, char **argv) { help(); - + if (argn < 2) { cout << "Missing arguments." << endl; return 1; } - + bool camera_pov = (argv[1][0] == 'C'); - + /// Create a window viz::Viz3d myWindow("Coordinate Frame"); - + /// Add coordinate axes myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); - + /// Let's assume camera has the following properties Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); - + /// We can get the pose of the cam using makeCameraPose Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); - + /// We can get the transformation matrix from camera coordinate system to global using /// - makeTransformToGlobal. We need the axes of the camera Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); - + /// Create a cloud widget. Mat bunny_cloud = cvcloud_load(); viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); - + /// Pose of the widget in camera frame Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); /// Pose of the widget in global frame Affine3f cloud_pose_global = transform * cloud_pose; - + /// Visualize camera frame if (!camera_pov) { @@ -97,16 +97,16 @@ int main(int argn, char **argv) myWindow.showWidget("CPW", cpw, cam_pose); myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); } - + /// Visualize widget myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); - + /// Set the viewer pose to that of camera if (camera_pov) myWindow.setViewerPose(cam_pose); - + /// Start event loop. myWindow.spin(); - + return 0; } diff --git a/samples/cpp/tutorial_code/viz/widget_pose.cpp b/samples/cpp/tutorial_code/viz/widget_pose.cpp index 03c88109f..0fe9d8174 100644 --- a/samples/cpp/tutorial_code/viz/widget_pose.cpp +++ b/samples/cpp/tutorial_code/viz/widget_pose.cpp @@ -32,23 +32,23 @@ void help() int main() { help(); - + /// 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); - myWindow.showWidget("Cube Widget", cube_widget); - + 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; @@ -59,21 +59,21 @@ int main() rot_vec.at(0,0) += CV_PI * 0.01f; rot_vec.at(0,1) += CV_PI * 0.01f; rot_vec.at(0,2) += CV_PI * 0.01f; - + /// Shift on (1,1,1) translation_phase += CV_PI * 0.01f; translation = sin(translation_phase); - + Mat rot_mat; - Rodrigues(rot_vec, rot_mat); - + Rodrigues(rot_vec, rot_mat); + /// Construct pose Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); - + myWindow.setWidgetPose("Cube Widget", pose); - + myWindow.spinOnce(1, true); } - + return 0; } From 5780b418c943e20d7ade40311cc776afb5738197 Mon Sep 17 00:00:00 2001 From: Ozan Tonkal Date: Wed, 18 Sep 2013 13:46:43 +0100 Subject: [PATCH 201/205] delete duplicate bunny.ply, remove tabs and extra lines --- modules/viz/CMakeLists.txt | 2 - modules/viz/doc/viz.rst | 6 +- modules/viz/doc/viz3d.rst | 1 - modules/viz/doc/widget.rst | 4 - samples/cpp/bunny.ply | 5752 ------------------------------------ 5 files changed, 3 insertions(+), 5762 deletions(-) delete mode 100644 samples/cpp/bunny.ply diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 140f916f9..ee6354dc9 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -55,5 +55,3 @@ if(DEFINED BUILD_opencv_viz AND BUILD_opencv_viz AND DEFINED HAVE_VTK AND HAVE_V target_link_libraries(opencv_viz "-framework Cocoa") endif() endif() - - diff --git a/modules/viz/doc/viz.rst b/modules/viz/doc/viz.rst index 3cf550253..1d8c743ad 100644 --- a/modules/viz/doc/viz.rst +++ b/modules/viz/doc/viz.rst @@ -3,7 +3,7 @@ viz. 3D Visualizer *********************** .. toctree:: - :maxdepth: 2 + :maxdepth: 2 - viz3d.rst - widget.rst + viz3d.rst + widget.rst diff --git a/modules/viz/doc/viz3d.rst b/modules/viz/doc/viz3d.rst index dbe243890..79e262bb9 100644 --- a/modules/viz/doc/viz3d.rst +++ b/modules/viz/doc/viz3d.rst @@ -716,4 +716,3 @@ Creates a Kinect Camera. .. ocv:function:: static Camera KinectCamera(const Size &window_size) :param window_size: Size of the window. This together with intrinsic matrix of a Kinect Camera determines the field of view. - diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index 4986b3ac3..6ceccf0cb 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -942,7 +942,3 @@ Constructs a WMesh. .. ocv:function:: WMesh(const Mesh3d &mesh) :param mesh: :ocv:class:`Mesh3d` object that will be displayed. - - - - diff --git a/samples/cpp/bunny.ply b/samples/cpp/bunny.ply deleted file mode 100644 index 10ae64fc3..000000000 --- a/samples/cpp/bunny.ply +++ /dev/null @@ -1,5752 +0,0 @@ -ply -format ascii 1.0 -comment zipper output -element vertex 1889 -property float x -property float y -property float z -property float confidence -property float intensity -element face 3851 -property list uchar int vertex_indices -end_header --0.0369122 0.127512 0.00276757 0.850855 0.5 --0.0457707 0.130327 0.00306785 0.900159 0.5 --0.0708847 0.149834 0.0388672 0.398443 0.5 --0.00331557 0.130403 0.0212208 0.85268 0.5 --0.0211979 0.1272 0.00915278 0.675938 0.5 --0.0265255 0.12592 0.00874866 0.711533 0.5 -0.0339261 0.112038 0.0269672 0.652757 0.5 -0.0376485 0.110455 0.0145481 0.708171 0.5 --0.0259368 0.111118 0.0379115 0.454541 0.437538 -0.027952 0.120939 0.0215377 0.533079 0.5 --0.0628308 0.155987 -0.0150105 0.404517 0.5 -0.0390029 0.106711 0.0215202 0.535542 0.5 -0.0447976 0.0950477 0.00866471 0.579563 0.425995 --0.0330636 0.173619 -0.0031267 0.365607 0.5 --0.0808069 0.136243 0.0495014 0.499575 0.5 --0.0705086 0.12445 0.0526685 0.564827 0.5 -0.00874873 0.131225 0.0145345 0.748371 0.5 -0.0401015 0.106711 0.00874166 0.680399 0.5 -0.0379483 0.100145 -0.00827134 0.600054 0.5 --0.0906538 0.137201 0.0207305 0.824561 0.5 --0.0841655 0.110667 0.0275273 0.690889 0.5 --0.0705214 0.156214 0.0144536 0.807492 0.5 --0.083872 0.15212 0.0282652 0.248168 0.41865 -0.00305028 0.12432 0.0332425 0.555044 0.354559 -0.00870828 0.124165 0.0330348 0.653433 0.5 --0.0328896 0.12613 0.00300653 0.898771 0.5 --0.0506302 0.143065 0.0150611 0.691477 0.5 --0.0757863 0.13637 0.050172 0.566256 0.5 --0.0027191 0.128962 0.0264678 0.271491 0.462815 --0.0460961 0.125118 0.0263142 0.539149 0.5 --0.0785104 0.0942728 -0.0109192 0.710999 0.5 -0.0216915 0.125373 0.0211452 0.530957 0.5 --0.0888469 0.124305 0.00237041 0.635593 0.5 -0.040386 0.100825 -0.00303043 0.574857 0.5 --0.0884145 0.117791 0.00268555 0.487167 0.430737 --0.0319074 0.177421 -0.00491879 0.269231 0.447035 --0.0765825 0.143224 0.0455148 0.414139 0.5 --0.0209748 0.112544 0.0388613 0.482541 0.5 --0.020836 0.179425 -0.0221622 0.341071 0.440034 --0.0377039 0.167987 -0.0130391 0.396317 0.473039 --0.0331765 0.12681 0.00839958 0.896274 0.5 -0.00893926 0.127114 0.0292916 0.350014 0.41288 --0.044944 0.131083 0.0147963 0.599596 0.5 --0.0266041 0.12515 0.00282384 0.73687 0.5 -0.0144285 0.12328 0.0319185 0.625269 0.5 -0.019244 0.122284 0.0308314 0.611204 0.34486 --0.0390225 0.167317 0.00215527 0.413994 0.469929 --0.08808 0.129976 0.00206377 0.625486 0.5 --0.0537203 0.142608 0.0266058 0.696873 0.5 -0.043095 0.0980072 0.0191617 0.665192 0.5 -0.0432138 0.100117 0.00866473 0.691828 0.5 -0.0415448 0.0944954 0.0275695 0.671611 0.5 --0.0578726 0.155337 0.0149245 0.394763 0.437313 --0.0231577 0.157375 -0.0046304 0.136389 0.380194 --0.0683123 0.145735 0.0420568 0.751812 0.5 --0.0708351 0.142847 0.0451248 0.627973 0.5 --0.070664 0.0642894 0.0209789 0.413051 0.5 --0.0761519 0.130581 0.0525324 0.629117 0.5 --0.0640036 0.161784 -0.0208118 0.449093 0.5 --0.0706461 0.155711 0.00252406 0.855717 0.5 --0.0924366 0.118434 0.0399838 0.673877 0.5 --0.0635349 0.156052 0.0148814 0.798496 0.5 -0.0282675 0.118192 0.0274382 0.635485 0.5 -0.0392736 0.0938857 -0.00915453 0.585857 0.459742 --0.0695973 0.164844 -0.0174846 0.548789 0.5 --0.00892354 0.123904 0.0330319 0.602316 0.374044 -0.0269099 0.0942476 0.0444911 0.649753 0.5 --0.0146258 0.162377 -0.0144398 0.338176 0.5 --0.0450983 0.167072 0.00289327 0.449091 0.5 --0.0761536 0.172742 -0.0384391 0.256591 0.4298 --0.0858274 0.105458 0.00472318 0.523819 0.297125 -0.0370431 0.110443 0.0207229 0.52623 0.448558 -0.0321593 0.0994027 0.0380657 0.733041 0.5 --0.075287 0.146433 0.0428582 0.424358 0.5 --0.0395145 0.171107 0.000531747 0.452893 0.5 --0.0839586 0.11215 0.00148754 0.436727 0.419097 -0.0446848 0.0883378 0.0216285 0.487783 0.481728 -0.0161783 0.127819 0.0220535 0.481793 0.5 --0.00251635 0.0397232 0.0474087 0.280725 0.5 -0.00303163 0.0406968 0.0460422 0.331809 0.5 --0.0143059 0.128197 0.00333856 0.693854 0.5 --0.0526117 0.155596 0.0109972 0.561042 0.5 --0.0332043 0.17776 -0.00906223 0.212789 0.5 -0.0394391 0.106654 0.00306577 0.522321 0.489889 --0.0923799 0.1249 0.0327641 0.848517 0.5 -0.0454681 0.0882959 0.0146642 0.575503 0.5 --0.0274495 0.179802 -0.00925837 0.258799 0.457369 --0.072504 0.146297 0.0429682 0.549207 0.5 --0.0579959 0.129793 0.0383118 0.658867 0.444043 -0.043117 0.0923689 0.0251649 0.622686 0.5 --0.00865718 0.130323 0.0149721 0.633691 0.5 --0.0141304 0.129188 0.0147431 0.547632 0.5 --0.0707877 0.15583 0.00921954 0.739059 0.5 --0.00952731 0.127041 0.0281475 0.375412 0.377874 --0.0646289 0.153404 0.0329146 0.855321 0.5 --0.0706939 0.15347 0.0328596 0.444959 0.455263 -0.0208126 0.118434 0.0336393 0.519282 0.5 --0.0396566 0.173008 -0.00299705 0.274377 0.177706 --0.0442176 0.170815 -0.00391429 0.245926 0.5 --0.0582565 0.0395149 0.0457796 0.417977 0.459314 --0.0523033 0.0401501 0.04623 0.454776 0.456044 --0.0760211 0.161274 -0.0145891 0.267801 0.372187 --0.0693983 0.163016 -0.0140293 0.403228 0.45768 -0.0399663 0.106491 0.014952 0.713602 0.5 -0.041536 0.0950084 -0.00475737 0.490139 0.464008 --0.0470079 0.163779 0.00528295 0.432857 0.486946 --0.0402546 0.161678 0.00298655 0.447592 0.5 --0.0386569 0.0389805 0.0441153 0.509262 0.5 --0.0704175 0.166991 -0.0216976 0.332592 0.447054 --0.0254201 0.0886622 0.0503827 0.608282 0.5 --0.0886334 0.137429 0.00876953 0.549009 0.5 --0.014179 0.12627 0.0266417 0.420759 0.5 --0.0360017 0.17408 -0.0118959 0.409753 0.289042 --0.0886251 0.0937834 0.00823534 0.753697 0.5 --0.0648672 0.155874 -0.00891497 0.595216 0.5 --0.0704508 0.137752 -0.00774011 0.446131 0.5 --0.0750154 0.166247 -0.0219558 0.263106 0.5 -0.0299465 0.114869 0.0300239 0.642356 0.5 -0.0398138 0.0998788 0.0273101 0.51725 0.5 --0.015242 0.111698 0.0407424 0.605597 0.5 --0.0700387 0.118219 0.0524379 0.585543 0.5 -0.0149973 0.112399 0.0386082 0.669811 0.5 --0.036487 0.171225 0.000545037 0.438578 0.5 --0.0641664 0.118551 -0.00968333 0.569796 0.5 --0.071817 0.166979 -0.0463822 0.381568 0.451091 --0.0913559 0.14534 0.0246937 0.648478 0.5 -0.00903703 0.112569 0.0396571 0.549283 0.408623 -0.0324674 0.0997396 -0.0141603 0.732658 0.5 -0.0417911 0.101845 0.00188609 0.547756 0.5 -0.00302992 0.112517 0.0415434 0.592572 0.5 --0.0650368 0.148485 0.0382561 0.62562 0.5 --0.0706519 0.13063 0.0502497 0.563116 0.5 --0.0144471 0.128935 0.00903509 0.682121 0.5 -0.00292575 0.131541 0.00912318 0.795238 0.5 --0.0625682 0.151125 0.035875 0.463512 0.5 -0.0349829 0.113328 0.0214487 0.620597 0.5 -0.021327 0.0385664 0.0392992 0.259499 0.426724 -0.0145125 0.093771 0.0501571 0.654705 0.5 --0.00923752 0.112849 0.0413907 0.615633 0.5 -0.0415329 0.100906 0.0210277 0.662312 0.5 -0.0422859 0.101486 0.0146614 0.569693 0.490777 --0.0773783 0.112839 -0.00448759 0.505277 0.5 --0.078035 0.137641 -0.00517379 0.466714 0.5 -0.00873437 0.106347 -0.0202193 0.792948 0.5 -0.0090324 0.13035 0.0211569 0.465873 0.5 -0.00301322 0.130902 0.0206741 0.592486 0.5 --0.00286342 0.13115 0.0147367 0.587804 0.5 --0.0391578 0.12569 0.0207996 0.438744 0.464814 --0.0205725 0.123523 0.0265579 0.445477 0.415699 --0.0644194 0.155634 0.00928477 0.611624 0.331941 --0.0463385 0.131411 0.0207671 0.674928 0.5 --0.0532034 0.0439067 0.044658 0.417403 0.440199 --0.00297651 0.131046 0.00884967 0.738924 0.5 --0.089664 0.137755 0.0263925 0.80362 0.5 --0.00888731 0.124273 -0.00880284 0.767738 0.284429 --0.0460971 0.0385107 0.0446891 0.654962 0.5 --0.0649255 0.178874 -0.0579325 0.245129 0.411885 --0.0329347 0.124601 0.0211235 0.32811 0.5 --0.0831301 0.149901 0.0334123 0.331963 0.314683 --0.0895652 0.093948 0.0149303 0.603378 0.5 --0.0328901 0.124518 -0.00282055 0.63839 0.5 --0.0845271 0.106161 0.00204328 0.338681 0.43162 --0.0469341 0.155816 0.00872921 0.470367 0.484595 -0.0206202 0.123943 0.0267275 0.477255 0.5 --0.026256 0.117499 0.0321672 0.543293 0.5 --0.021392 0.118632 0.0336445 0.468887 0.429556 --0.0195069 0.116132 0.0368525 0.534732 0.411301 --0.0761618 0.118382 0.0520923 0.490413 0.5 -0.00889281 0.0395765 0.0451727 0.476347 0.38769 --0.0534736 0.159548 0.00753828 0.476667 0.5 --0.0469464 0.161226 0.00680216 0.495992 0.483766 --0.0574886 0.154862 0.0204748 0.677314 0.5 -0.0317199 0.117635 0.0202007 0.579556 0.5 -0.0378683 0.105514 -0.00259159 0.588286 0.5 --0.0811847 0.137693 -0.00253994 0.641736 0.5 --0.0764348 0.124515 0.0528345 0.65366 0.5 -0.0343816 0.106104 -0.00900254 0.534403 0.5 -0.0457922 0.088316 0.00867097 0.586292 0.439394 --0.0703288 0.0944195 -0.0159143 0.511499 0.5 --0.0756048 0.0937947 -0.0135536 0.429902 0.5 --0.058657 0.156369 0.0093256 0.31374 0.5 --0.0637335 0.153848 0.00222718 0.478676 0.5 --0.0777278 0.0960024 0.0363437 0.678588 0.5 --0.0868519 0.136556 0.00309926 0.517441 0.5 --0.0455299 0.0432404 0.0432162 0.712662 0.5 --0.0402011 0.045749 0.0408051 0.669165 0.320516 --0.0654123 0.160403 -0.0149066 0.335302 0.5 --0.0318898 0.0387174 0.0510004 0.553401 0.5 --0.0267997 0.0453977 0.0509311 0.501112 0.5 --0.0271043 0.0396972 0.0535379 0.487956 0.5 --0.0215575 0.0460868 0.0517209 0.709553 0.5 --0.0143078 0.0445295 0.0504368 0.575852 0.5 --0.00981594 0.043264 0.0493162 0.448927 0.393067 --0.00348436 0.044054 0.0472086 0.598081 0.5 -0.009577 0.0458139 0.0465877 0.519814 0.433928 -0.02048 0.111086 0.0379569 0.681163 0.5 --0.0141831 0.128547 0.0200007 0.293349 0.5 --0.0526702 0.144108 0.0210347 0.639643 0.5 --0.0634838 0.17384 -0.0527131 0.549906 0.5 --0.0366553 0.171999 -0.0125745 0.436075 0.5 --0.0525548 0.131228 0.0328277 0.727547 0.5 --0.0659567 0.132023 0.0442925 0.724494 0.5 --0.0921726 0.11832 0.0267606 0.794672 0.5 -0.0452792 0.0882737 0.00268175 0.507794 0.5 --0.00305651 0.112889 0.0417789 0.635396 0.5 --0.0451955 0.161396 -0.00871567 0.424682 0.5 --0.0402914 0.160933 -0.0115368 0.411895 0.405943 --0.0521414 0.0701165 0.0389584 0.682177 0.456916 --0.0383315 0.093604 -0.0232581 0.72469 0.5 --0.0690556 0.137374 0.046352 0.61723 0.5 --0.0695996 0.167401 -0.0516299 0.518552 0.5 --0.00246047 0.124102 0.0337609 0.444043 0.5 --0.0398624 0.128204 0.00299348 0.864483 0.5 --0.0753331 0.149032 0.0395625 0.432149 0.5 --0.0701432 0.160618 -0.00917801 0.464361 0.5 --0.0589378 0.0440425 0.0434222 0.437887 0.447715 --0.0207164 0.126445 0.00312493 0.710427 0.5 --0.00850666 0.0467286 0.0481052 0.613173 0.5 -0.00300323 0.0450308 0.0469911 0.464978 0.5 --0.0802174 0.148665 0.0379438 0.47939 0.5 --0.0819961 0.130698 0.0513437 0.54405 0.5 -0.00273088 0.106333 -0.0209927 0.733954 0.5 --0.0757273 0.0885687 -0.0138399 0.397424 0.5 --0.0698477 0.0882875 -0.0167823 0.420617 0.5 --0.0668508 0.159243 -0.0102161 0.42216 0.440727 --0.0226988 0.0885773 0.0536309 0.546444 0.5 --0.00281419 0.0990077 0.0505614 0.455087 0.5 -0.0452902 0.0696213 0.0253974 0.33948 0.5 --0.0525629 0.0472823 0.040482 0.279548 0.5 --0.046959 0.0466581 0.0408127 0.43714 0.5 --0.0691348 0.156682 -0.00276369 0.629099 0.5 --0.0897599 0.150073 0.0220744 0.276354 0.5 --0.0702883 0.155637 0.0263654 0.47565 0.441038 --0.0765031 0.154893 0.0266005 0.799832 0.5 --0.00804843 0.0987379 0.0505998 0.327523 0.438474 -0.0300791 0.11567 -0.00430465 0.66246 0.5 --0.0923054 0.117757 0.0334441 0.476916 0.5 --0.0331192 0.0449511 0.0462474 0.432059 0.466683 --0.0337794 0.113308 0.034612 0.683562 0.5 --0.0521291 0.113769 0.0349566 0.515399 0.5 -0.0437636 0.0825382 -0.0027974 0.568535 0.5 --0.0202819 0.126016 0.0210507 0.374818 0.437592 -0.0327872 0.043925 0.0295904 0.650152 0.5 --0.0453372 0.155266 -0.0075525 0.386286 0.5 --0.0284609 0.173987 -0.0175958 0.379432 0.418735 -0.0268448 0.0881755 -0.0223077 0.715629 0.5 --0.0308231 0.0923023 -0.0246377 0.474586 0.431409 --0.0899732 0.149975 0.0141115 0.257143 0.5 -0.0381804 0.105121 0.0266947 0.534482 0.490368 -0.00842001 0.12907 0.0258154 0.374593 0.448613 --0.0266549 0.0942999 -0.0265555 0.294426 0.332222 --0.0279896 0.0475815 0.0485532 0.381268 0.5 --0.0150037 0.048073 0.0483203 0.576068 0.5 --0.00298993 0.0473817 0.0491102 0.446744 0.431743 -0.00376754 0.0477551 0.0502037 0.495901 0.44823 -0.00748504 0.0473851 0.0493363 0.494952 0.5 --0.0581651 0.149751 0.032858 0.470966 0.5 --0.0720688 0.136456 0.0490662 0.625357 0.5 --0.0810638 0.0939541 -0.0082617 0.685573 0.5 -0.0380863 0.0458646 0.0307423 0.807573 0.5 --0.0253234 0.182998 -0.0108168 0.245054 0.5 --0.0230508 0.183235 -0.0110157 0.246322 0.458572 -0.00323317 0.129146 0.0263855 0.347796 0.441746 --0.0626125 0.149788 -0.00343342 0.691705 0.5 --0.0591471 0.0466998 0.0395843 0.0883466 0.213805 --0.0353862 0.0471292 0.0414241 0.656538 0.5 --0.0194948 0.0486404 0.0485565 0.373069 0.5 --0.00849455 0.0521633 0.0517688 0.61481 0.5 --0.00296485 0.051429 0.0527827 0.53012 0.5 -0.00279019 0.0517664 0.0528352 0.560812 0.423049 -0.00904034 0.0517165 0.051222 0.558244 0.5 -0.0443839 0.0943042 0.00268377 0.582116 0.455816 --0.0886145 0.111113 0.0148415 0.604102 0.5 --0.0885219 0.144027 0.0329221 0.623335 0.5 -0.0440719 0.0937787 0.0206165 0.493368 0.454688 -0.0436531 0.0980341 0.0146596 0.668233 0.5 --0.0650976 0.153799 -0.00285808 0.715743 0.5 --0.0517297 0.0490759 0.0371355 0 0 --0.0331222 0.0518259 0.0385377 0.676102 0.5 --0.0377352 0.127448 0.0152358 0.612182 0.5 --0.00906608 0.100701 0.0460122 0.338462 0.5 --0.0410683 0.128416 0.0134054 0.417331 0.5 --0.0712056 0.158724 -0.00521868 0.246338 0.5 --0.0266313 0.0501544 0.044695 0.182016 0.5 --0.0211065 0.0519946 0.0455753 0.195646 0.404388 --0.0168667 0.0505241 0.0476889 0.520032 0.5 --0.0147601 0.0527687 0.050103 0.451613 0.5 --0.0626395 0.149972 -0.00897733 0.363787 0.461156 --0.090861 0.124732 0.00627835 0.587249 0.5 --0.0255786 0.0923499 -0.0315595 0.294527 0.5 --0.0709738 0.172947 -0.052768 0.460427 0.5 --0.0588974 0.143232 -0.00327646 0.48145 0.5 --0.0943643 0.12436 0.0216467 0.570519 0.5 -0.0337044 0.112449 -0.00269877 0.532211 0.5 --0.0515051 0.136557 0.0263185 0.72719 0.5 --0.00886593 0.121199 0.0360577 0.614897 0.5 --0.061729 0.155665 -0.0259512 0.690546 0.5 --0.0862637 0.10567 0.0206042 0.519516 0.5 --0.0895584 0.138606 0.032689 0.685876 0.5 --0.0268168 0.123904 0.0208113 0.428255 0.5 -0.0341937 0.0515433 0.033081 0.609925 0.5 -0.0401268 0.0512743 0.0322702 0.669803 0.5 -0.0449306 0.0526595 0.0319582 0.655209 0.5 --0.0405348 0.117168 0.0319438 0.657986 0.5 --0.0636902 0.155546 -0.0390642 0.523327 0.5 -0.0278663 0.100401 0.0410064 0.689793 0.5 --0.0275828 0.179275 -0.0157605 0.314049 0.5 --0.0758871 0.0942302 0.0383961 0.647987 0.457049 -0.0138371 0.129201 0.0203961 0.412341 0.5 --0.0152723 0.0998429 0.0451638 0.271215 0.427554 --0.00916763 0.129718 0.0206646 0.438679 0.430152 --0.0512444 0.0516901 0.0334801 0.192432 0.5 --0.0461563 0.0523184 0.0379981 0.311543 0.5 --0.0410001 0.05272 0.0393793 0.629588 0.477809 --0.0270993 0.0526642 0.0393104 0.155274 0.5 -0.0434924 0.0931097 -0.00154028 0.576953 0.480183 --0.0823819 0.112683 0.045427 0.438131 0.5 --0.092066 0.118055 0.00909937 0.325678 0.5 --0.00448884 0.121713 0.0362976 0.591545 0.5 -0.0147346 0.129423 0.0143146 0.840212 0.5 --0.0158113 0.161888 -0.00973584 0.202865 0.5 --0.0778838 0.149704 -0.00337488 0.403345 0.5 --0.0865357 0.12477 -0.00166991 0.677311 0.5 -0.0153656 0.126058 0.0275381 0.479299 0.429147 --0.0388913 0.123761 0.0249778 0.514489 0.5 --0.0390351 0.121238 0.0283673 0.510424 0.470651 --0.0324963 0.120237 0.0283344 0.568849 0.348087 --0.0149052 0.12311 0.0316417 0.446842 0.5 --0.0582873 0.117688 0.0386719 0.634635 0.5 --0.0626536 0.161861 -0.0264031 0.685413 0.5 --0.0818147 0.141639 0.0444825 0.392929 0.5 -0.0350734 0.100071 0.0345975 0.716199 0.5 -0.0311856 0.11215 0.0310216 0.689434 0.5 --0.0335778 0.11743 0.031458 0.525408 0.5 --0.059637 0.153475 0.031348 0.93076 0.5 --0.0481256 0.0536625 0.0362191 0.58186 0.5 --0.059026 0.156388 0.00269852 0.133166 0.5 --0.0211187 0.0578754 0.0461125 0.660553 0.5 --0.082738 0.124721 0.050554 0.665202 0.5 --0.0466997 0.11363 0.0348133 0.568902 0.5 --0.0107262 0.179662 -0.0277472 0.400699 0.458536 -0.0347725 0.0894441 -0.0170339 0.702331 0.5 --0.0891825 0.100351 0.0148945 0.574286 0.477791 -0.0257275 0.122894 0.0207337 0.498278 0.5 --0.0883949 0.100277 0.00841226 0.477822 0.5 --0.0649858 0.155518 0.0263367 0.864791 0.5 --0.0768402 0.154073 0.00257877 0.57436 0.5 --0.0576877 0.154146 0.0262123 0.402162 0.5 --0.0266966 0.125729 0.0145923 0.393422 0.5 --0.076376 0.155782 0.0208875 0.505065 0.5 --0.0763295 0.167188 -0.039594 0.405226 0.426366 --0.0771877 0.100229 -0.0103313 0.528684 0.5 --0.0153681 0.0590839 0.0519909 0.652683 0.5 --0.010206 0.0576345 0.0535443 0.781548 0.413019 --0.00350044 0.0578672 0.0543757 0.774384 0.5 -0.00300818 0.0568916 0.0538692 0.704357 0.5 -0.0088308 0.0580497 0.0529859 0.692645 0.5 -0.0410915 0.0820775 -0.00893411 0.500391 0.430286 -0.0395449 0.0576373 0.0318985 0.612032 0.4505 --0.0762443 0.139336 0.0484763 0.588653 0.42756 --0.0324306 0.120379 -0.00955344 0.656019 0.5 --0.0194451 0.0881559 0.0557639 0.449983 0.473992 --0.074787 0.159471 -0.00898201 0.281303 0.5 --0.0639935 0.15611 0.0210031 0.687157 0.5 --0.0762438 0.153101 0.0322442 0.323875 0.45561 --0.00876679 0.128727 0.025102 0.735708 0.5 -0.0282216 0.112237 -0.00983067 0.567922 0.385391 --0.0451341 0.0593225 0.0387559 0.511245 0.5 --0.0405005 0.0579499 0.040202 0.540369 0.5 --0.033993 0.0584028 0.038704 0.646744 0.5 --0.0272756 0.0585468 0.0382285 0.571263 0.5 --0.0248608 0.122913 0.0245429 0.379391 0.5 --0.0825276 0.154355 0.0206132 0.385494 0.444119 --0.00884271 0.129403 0.00305159 0.702319 0.5 -0.0207587 0.126654 0.0147646 0.624434 0.5 --0.0394868 0.173351 -0.00839443 0.199648 0.251821 --0.028421 0.114019 0.0347746 0.603313 0.5 --0.0193575 0.122009 0.0306737 0.55532 0.5 --0.0691626 0.161675 -0.0514614 0.38665 0.5 --0.0516736 0.15006 0.0148119 0.716684 0.5 --0.0156325 0.120151 0.0349054 0.470635 0.336572 -0.0467454 0.0582319 0.0314404 0.576429 0.5 --0.0770165 0.0685425 0.0147863 0.703257 0.5 --0.00967101 0.173225 -0.0264945 0.379771 0.5 --0.0213141 0.184813 -0.0151112 0.186313 0.403961 --0.0766524 0.0882188 0.0382876 0.650646 0.5 --0.0540219 0.0521463 0.0110698 0.270787 0.5 --0.0219451 0.126821 0.0155536 0.534695 0.5 --0.0820391 0.153392 0.0264506 0.292051 0.4047 --0.0213183 0.124468 -0.00290836 0.782181 0.5 --0.0268364 0.123465 -0.00321538 0.727949 0.5 --0.0312035 0.177796 -0.0133521 0.371348 0.5 --0.00749945 0.0598042 0.0553302 0.778631 0.5 --0.00108951 0.0601245 0.0554892 0.776353 0.5 -0.00280202 0.0599746 0.0555283 0.768603 0.5 --0.051797 0.118119 0.033678 0.677092 0.438456 -0.00302464 0.131618 0.0149353 0.692956 0.5 -0.0446005 0.0942619 0.0151198 0.554026 0.5 --0.0880636 0.111855 0.00852285 0.304511 0.3924 --0.0704321 0.144096 -0.0148369 0.130446 0.5 --0.0820967 0.0943634 0.0322765 0.629357 0.5 --0.0269642 0.120812 0.0275676 0.345323 0.386314 --0.0540164 0.149968 0.0253393 0.49489 0.5 --0.0800337 0.0995053 -0.00770139 0.499264 0.5 -0.00922138 0.12038 0.0360924 0.562107 0.5 -0.00286056 0.117968 0.0387331 0.649494 0.5 --0.0936229 0.118494 0.0206524 0.664933 0.5 --0.0409923 0.113229 0.035109 0.667726 0.5 --0.0822185 0.154488 0.0146661 0.500539 0.5 --0.0625956 0.155202 -0.0329876 0.814083 0.5 --0.0462511 0.124621 -0.00898124 0.590842 0.5 --0.0220336 0.160676 -0.00426008 0.309766 0.47069 --0.065621 0.172767 -0.0466049 0.613718 0.5 --0.0762614 0.155884 0.0148687 0.717415 0.5 --0.0644988 0.149044 -0.0265159 0.690046 0.5 --0.0581979 0.0593456 0.0210895 0.079935 0 --0.0335439 0.122618 0.0254024 0.514037 0.5 --0.0826578 0.153434 0.00921403 0.601617 0.5 --0.049999 0.132417 0.0286961 0.650903 0.5 -0.0088217 0.131096 0.00864908 0.834131 0.5 --0.0154842 0.0644282 0.0533754 0.608033 0.445048 --0.00871951 0.065015 0.0556827 0.650491 0.470895 --0.00324815 0.0640003 0.0562816 0.762387 0.5 -0.00292601 0.0643094 0.0563956 0.748671 0.5 -0.00738462 0.0651614 0.0553402 0.488299 0.46872 --0.0143174 0.116971 0.037836 0.441459 0.5 --0.00299223 0.118083 0.0390751 0.65526 0.5 --0.00864301 0.117816 0.0385662 0.681198 0.5 --0.0532884 0.0571719 0.0206631 0.106703 0 --0.0882588 0.100387 0.0210097 0.535268 0.5 --0.0324377 0.099703 -0.0227313 0.620611 0.5 -0.0425072 0.0603725 0.0302275 0.744481 0.5 -0.0523383 0.0580401 0.0290457 0.405493 0.41666 -0.0413612 0.0877503 -0.00929235 0.635782 0.5 --0.0581547 0.0620148 0.0270981 0.448705 0.5 --0.0530328 0.0590503 0.0266933 0.136202 0.5 --0.0477227 0.135526 0.0148654 0.740469 0.5 -0.00323512 0.0983053 0.0504424 0.395048 0.366076 -0.0150627 0.119642 0.034806 0.696033 0.374342 --0.0453373 0.0643061 0.0391142 0.587502 0.5 --0.0394097 0.0644278 0.0414133 0.715885 0.5 --0.033068 0.0642666 0.0396407 0.650585 0.5 --0.0270237 0.0644489 0.0395335 0.617817 0.5 --0.0881604 0.149479 0.0268507 0.265855 0.5 --0.0640727 0.143434 -0.00894036 0.668887 0.5 -0.00286033 0.121151 0.036139 0.623932 0.5 --0.0827306 0.138152 0.0466993 0.412428 0.5 --0.00261511 0.127006 0.030132 0.335862 0.5 -0.0355841 0.108498 -0.00452523 0.461807 0.466834 -0.0219203 0.114136 0.0356941 0.554683 0.5 --0.0379555 0.161954 -0.0128021 0.499753 0.5 --0.0526362 0.0643632 0.0340621 0.277414 0.5 -0.025874 0.123374 0.0143811 0.506732 0.5 --0.0451406 0.131184 0.00901599 0.493237 0.5 --0.075778 0.155361 -0.00310678 0.708579 0.5 --0.0739145 0.156437 -0.0274945 0.645327 0.5 --0.0833056 0.100778 -0.00354288 0.490806 0.397415 --0.0767099 0.173942 -0.0452732 0.259897 0.5 -0.00846106 0.116985 0.038033 0.66824 0.5 --0.0200899 0.184788 -0.020546 0.237973 0.106197 --0.046571 0.120413 0.0285524 0.752764 0.5 --0.0515313 0.123718 -0.0088569 0.538005 0.5 -0.0212116 0.105804 -0.0171101 0.576137 0.468722 --0.0938613 0.124487 0.0151416 0.737559 0.5 -0.0414591 0.064577 0.0290352 0.617794 0.5 -0.0466725 0.0643471 0.0285539 0.486488 0.5 -0.0526423 0.0634018 0.0283831 0.501229 0.5 --0.0468141 0.168322 -0.00285433 0.371444 0.5 --0.0869152 0.0944156 0.00293118 0.494536 0.346642 --0.0773713 0.161559 -0.0267238 0.476378 0.5 --0.0396095 0.126677 -0.00334699 0.853498 0.5 --0.0271315 0.0764239 0.0455715 0.693464 0.5 --0.0587953 0.107012 -0.0177177 0.484023 0.5 --0.0748314 0.11156 -0.00720996 0.44421 0.5 --0.0642623 0.0888181 -0.018733 0.676741 0.5 --0.0325172 0.0881157 -0.0255424 0.370176 0.330832 -0.00325654 0.0700086 0.0561047 0.731659 0.5 -0.0103151 0.0636713 0.0537558 0.477793 0.458716 -0.0432701 0.0979967 0.00267804 0.544182 0.465461 --0.0708223 0.156244 0.021207 0.768676 0.5 --0.0584176 0.0702277 0.0384322 0.673529 0.5 --0.0703207 0.112305 -0.00963846 0.530989 0.5 --0.0581653 0.0881983 -0.0208369 0.619673 0.5 --0.0443038 0.0877156 -0.0218942 0.693083 0.5 --0.0488091 0.0660127 0.0373959 0.829801 0.5 -0.00269411 0.126911 0.030114 0.419275 0.5 -0.0239692 0.12105 0.0288706 0.523768 0.5 --0.0469203 0.117468 0.0314407 0.649888 0.5 --0.091552 0.143361 0.0201623 0.515231 0.5 --0.0907563 0.143859 0.0263089 0.504684 0.469425 --0.0495713 0.144022 0.00976642 0.636632 0.45621 --0.0770934 0.15583 -0.0147903 0.519503 0.5 --0.0868322 0.105634 0.00887573 0.731519 0.5 --0.082848 0.131648 -0.00299747 0.386393 0.5 --0.0384249 0.106407 -0.0201393 0.79815 0.5 --0.0823953 0.118841 -0.00336022 0.540306 0.5 --0.0102333 0.0876697 -0.0375101 0.564234 0.5 --0.00789361 0.089842 -0.0363492 0.755212 0.5 --0.0579097 0.111769 -0.0161856 0.463258 0.5 -0.0140074 0.105793 -0.0193841 0.554632 0.5 --0.00328561 0.105435 -0.0225198 0.740261 0.5 --0.0409613 0.070972 0.0419904 0.795206 0.5 --0.033501 0.0710512 0.0409793 0.706864 0.5 --0.0272732 0.0701361 0.0410332 0.726443 0.5 --0.0161963 0.127121 0.0228897 0.305628 0.5 --0.0190644 0.127936 0.0133818 0.519435 0.5 --0.0149926 0.0694778 0.0545159 0.595577 0.5 --0.00932719 0.0707313 0.0562936 0.785998 0.5 --0.002994 0.0710941 0.0575426 0.779773 0.5 -0.00838831 0.0714267 0.0556585 0.671976 0.5 -0.0102531 0.0693533 0.0547665 0.525573 0.5 --0.0323939 0.153399 -0.00240332 0.209483 0.5 -0.0435981 0.0881514 0.0254203 0.603121 0.478265 --0.0586529 0.124882 -0.00781093 0.700525 0.5 --0.0204287 0.107045 -0.022046 0.723165 0.5 --0.0382961 0.0879422 -0.0229335 0.629507 0.5 --0.081573 0.113394 -0.00173083 0.508624 0.426711 --0.0380811 0.154778 -0.00889149 0.748063 0.5 --0.00212588 0.0889926 -0.0354677 0.782073 0.5 -0.00904065 0.100193 -0.0222794 0.54652 0.5 --0.0467068 0.0700493 0.0405769 0.710023 0.5 --0.0779974 0.151244 0.0352264 0.347296 0.5 -0.0149019 0.116126 0.0367849 0.635361 0.5 --0.07603 0.106301 -0.0087688 0.520423 0.5 --0.0885261 0.137839 0.0393964 0.651389 0.5 --0.0703112 0.131278 -0.00857724 0.737784 0.5 -0.0419377 0.0703605 0.0288832 0.54196 0.5 -0.0514194 0.0684326 0.0256968 0.512602 0.5 --0.0922548 0.124813 0.0393757 0.806636 0.5 -0.0135035 0.128105 0.0250558 0.487288 0.424656 --0.0704618 0.125421 -0.00881334 0.801453 0.5 --0.0703931 0.118731 -0.00840961 0.381625 0.5 --0.0719685 0.106305 -0.0114493 0.499561 0.5 --0.0646972 0.161498 -0.0573125 0.41682 0.5 -0.0463693 0.0715128 0.0216754 0.461473 0.448797 --0.0538246 0.153497 0.0152346 0.602795 0.402362 --0.0142869 0.0724666 0.0554243 0.617853 0.5 --0.0394057 0.118512 -0.01336 0.602235 0.5 --0.0280509 0.0880065 -0.0330858 0.33771 0.5 --0.00957701 0.168254 -0.0212321 0.359593 0.5 --0.0445856 0.167324 -0.00782662 0.413138 0.327414 --0.0513101 0.161594 -0.00355965 0.292939 0.5 --0.0702356 0.179304 -0.0569867 0.253404 0.5 --0.0644695 0.168402 -0.0398946 0.676128 0.5 --0.0089459 0.130139 0.00911776 0.703889 0.5 -0.00219503 0.0880369 -0.0342201 0.75972 0.5 --0.0268891 0.16726 -0.0174204 0.847505 0.5 --0.0525985 0.155054 -0.00368706 0.37123 0.419006 --0.0761618 0.131736 -0.00696723 0.42394 0.44361 --0.0759576 0.07099 0.0265672 0.757943 0.5 --0.00875341 0.10588 -0.02285 0.71177 0.5 --0.0519242 0.1493 -0.00277595 0.483301 0.5 --0.016371 0.18465 -0.0214272 0.271878 0.5 --0.020548 0.0705632 0.0520411 0.601639 0.5 --0.0813371 0.120073 0.049533 0.662828 0.5 --0.0625087 0.149934 -0.0150319 0.415531 0.480025 --0.0831098 0.10651 0.0273461 0.515033 0.5 --0.011119 0.163582 -0.018751 0.17813 0.5 --0.00291057 0.101147 0.0456419 0.307462 0.5 --0.0635467 0.0660523 0.0318653 0.49936 0.45677 --0.0511979 0.0873878 -0.0217212 0.75515 0.5 --0.0530335 0.0740367 0.0417219 0.727079 0.5 --0.0465007 0.0756701 0.0421325 0.696934 0.5 --0.022314 0.0760359 0.0530306 0.607912 0.5 --0.0151351 0.0764056 0.0563566 0.616605 0.5 --0.00900601 0.0766621 0.0575852 0.791265 0.5 --0.00299732 0.0767339 0.0584651 0.678647 0.450838 -0.00347424 0.0769755 0.0565905 0.523043 0.5 -0.00860763 0.0767538 0.0557293 0.612782 0.5 --0.0271239 0.156216 -0.00302734 0.139755 0.329034 --0.0633091 0.16738 -0.0580906 0.358909 0.45373 --0.0873943 0.144225 0.00902371 0.583528 0.5 --0.0626891 0.162297 -0.0470925 0.70746 0.5 -0.0370111 0.110397 0.00265294 0.516602 0.481774 --0.0744006 0.144062 -0.00864565 0.417075 0.5 --0.0244124 0.183841 -0.0135068 0.166659 0.5 --0.0803381 0.0715473 0.0150483 0.5669 0.5 --0.0644528 0.0761561 0.040638 0.610448 0.476331 --0.0588413 0.0753794 0.0421022 0.634349 0.5 --0.0524294 0.077372 0.0433357 0.774603 0.5 --0.0484981 0.0769334 0.043281 0.674446 0.5 --0.0414954 0.0773856 0.0429005 0.752035 0.5 --0.0395008 0.0754808 0.0425134 0.72256 0.5 --0.033488 0.0764759 0.0414605 0.748994 0.5 --0.0627838 0.162163 -0.0530538 0.691143 0.5 -0.0381456 0.0881056 -0.0138675 0.676152 0.5 --0.0642837 0.0396418 0.039624 0.532543 0.5 --0.0526672 0.121335 -0.010917 0.523608 0.5 --0.0738104 0.162942 -0.037093 0.458525 0.324439 --0.0490869 0.13938 0.00889895 0.657159 0.5 --0.0495771 0.166027 -0.00171113 0.322064 0.5 --0.0709736 0.161609 -0.0450808 0.365011 0.420984 -0.0251847 0.12195 0.0254854 0.524179 0.5 --0.0193615 0.0781018 0.0558163 0.595703 0.4544 --0.0265458 0.120645 -0.00911332 0.52669 0.5 --0.061796 0.155741 -0.0207923 0.443336 0.5 --0.082476 0.110295 0.0324103 0.745977 0.5 --0.0691674 0.156314 -0.050857 0.360984 0.5 --0.0622848 0.16236 -0.0396288 0.427869 0.464762 --0.088248 0.113803 0.0264606 0.595923 0.5 --0.0575392 0.0787026 0.0436363 0.801201 0.5 --0.0298439 0.0782596 0.0421168 0.771067 0.5 --0.0677617 0.0876701 0.0434928 0.59211 0.5 --0.0921939 0.131884 0.015227 0.781723 0.5 --0.0878987 0.111742 0.0209206 0.698028 0.5 --0.049353 0.139298 0.0147955 0.761861 0.5 --0.0327071 0.173321 -0.0149209 0.384317 0.5 --0.0866298 0.152851 0.0149144 0.267781 0.5 --0.0779646 0.100025 0.035185 0.697079 0.5 --0.0935537 0.118404 0.0151524 0.667612 0.5 --0.084908 0.10801 0.0228537 0.694681 0.5 --0.0210677 0.0821213 0.0562096 0.557699 0.5 --0.0149957 0.082187 0.0572635 0.665194 0.5 --0.00899671 0.0822178 0.0576875 0.71377 0.5 --0.00299966 0.0822055 0.0574653 0.668024 0.472979 -0.0034748 0.0817533 0.0567544 0.69456 0.5 -0.00824833 0.082992 0.0556315 0.615627 0.5 -0.0102414 0.0812949 0.0546523 0.424956 0.485927 --0.0398496 0.123966 -0.00878898 0.60318 0.5 --0.092257 0.124769 0.00902091 0.309094 0.468872 --0.0436728 0.126191 0.0209533 0.472028 0.413108 --0.0820425 0.105873 -0.00271871 0.341089 0.347157 --0.0663016 0.0807623 0.0424437 0.632223 0.5 --0.0639939 0.0836688 0.0439754 0.778832 0.5 --0.058539 0.0825906 0.0439671 0.770991 0.5 --0.0521209 0.0822523 0.0446262 0.782751 0.5 --0.0467559 0.0828569 0.0439458 0.699516 0.399968 --0.0424962 0.0810729 0.0423266 0.617938 0.5 --0.0404903 0.0830123 0.0430984 0.712874 0.5 --0.0365108 0.0825773 0.0434355 0.675696 0.5 --0.032204 0.0824171 0.0421121 0.529763 0.5 --0.0864005 0.152981 0.0204492 0.250247 0.416029 --0.0235661 0.115415 0.0353667 0.518805 0.471584 --0.0764871 0.111685 0.0461598 0.498936 0.5 --0.0763895 0.14977 -0.00829972 0.604451 0.5 --0.0754801 0.161855 -0.0327796 0.39691 0.5 --0.0285733 0.0828247 0.0462702 0.636794 0.5 --0.0862819 0.100797 0.0028483 0.65379 0.5 -0.021088 0.08242 0.0504086 0.491924 0.475524 --0.0801892 0.143128 -0.00230055 0.641961 0.5 -0.00844098 0.124407 -0.00878569 0.555015 0.5 -0.0147552 0.0825883 0.0529115 0.480476 0.5 --0.061995 0.161169 -0.032654 0.499509 0.5 --0.0807571 0.1525 0.0307996 0.295115 0.454522 --0.00295953 0.130272 0.00279699 0.742188 0.5 --0.0153619 0.0884791 0.0565599 0.818561 0.5 --0.00899729 0.0878977 0.0570287 0.818958 0.5 --0.00299611 0.0880658 0.0568489 0.695384 0.5 -0.00301457 0.0885291 0.0562756 0.81087 0.5 -0.00834267 0.0873808 0.0555541 0.577038 0.479545 --0.00897481 0.0941651 -0.0338408 0.678465 0.5 -0.0314278 0.11673 0.0250113 0.597807 0.5 --0.0760602 0.155337 0.0093949 0.68566 0.5 -0.0257808 0.116776 -0.00728909 0.54747 0.36626 --0.0646577 0.0882843 0.0447113 0.69894 0.5 --0.058996 0.0882997 0.0449149 0.778337 0.5 --0.0529958 0.0883132 0.0451395 0.696869 0.45083 --0.0465421 0.0881579 0.0443187 0.605881 0.5 --0.0404961 0.0876863 0.0430941 0.556958 0.5 --0.0331792 0.0885648 0.04366 0.668172 0.5 --0.0280482 0.0879652 0.046363 0.699915 0.5 -0.0150626 0.0881784 0.0517745 0.702815 0.5 -0.0205955 0.087113 0.0492325 0.678548 0.5 --0.0702712 0.0823874 0.0409431 0.628092 0.5 --0.0296926 0.0896882 -0.0286839 0.317989 0.390463 --0.0236137 0.179242 -0.0115629 0.264741 0.5 --0.0809391 0.100029 0.0323433 0.683272 0.5 --0.0928336 0.130683 0.0207107 0.62518 0.472282 --0.0761771 0.156201 -0.0204165 0.612769 0.5 -0.0146577 0.129396 0.00843576 0.595962 0.5 -0.0104845 0.089766 0.0542005 0.46622 0.5 --0.072579 0.161253 -0.0389447 0.482103 0.5 --0.0322741 0.110391 -0.0184574 0.809584 0.5 --0.0550172 0.150108 0.027792 0.412797 0.5 --0.071635 0.0883254 0.0414652 0.604622 0.463567 --0.0424904 0.0895336 0.0426086 0.959715 0.5 -0.0207945 0.0897491 0.0484315 0.669841 0.5 -0.0273189 0.118845 -0.00265658 0.615055 0.5 -0.0285218 0.121112 0.0162366 0.593248 0.434231 --0.00899735 0.0930598 0.0559298 0.639163 0.5 --0.00291176 0.118727 -0.0144021 0.826286 0.5 --0.0885191 0.113233 0.0327948 0.447552 0.461926 --0.0713744 0.0938304 0.0415269 0.544171 0.444972 --0.0641029 0.0935514 0.0439488 0.597795 0.395518 --0.0584965 0.0944146 0.0446213 0.678752 0.5 --0.0515853 0.0939836 0.0442383 0.634435 0.477778 --0.0465591 0.0937901 0.0436103 0.714507 0.5 --0.0414914 0.0942416 0.0425268 0.490492 0.46307 --0.0377723 0.0933327 0.0434889 0.620752 0.5 --0.0332864 0.0945766 0.0443868 0.723538 0.5 --0.0263807 0.094318 0.0450568 0.620324 0.5 --0.0141606 0.0929618 0.0553898 0.503825 0.5 --0.00319641 0.0930898 0.0557853 0.624082 0.5 -0.00150357 0.0931879 0.0551544 0.492015 0.5 -0.00367616 0.0950752 0.0535295 0.508462 0.5 -0.00915739 0.0941794 0.0519212 0.597357 0.452723 -0.0216553 0.0937794 0.0473202 0.671835 0.5 --0.0702968 0.174481 -0.045888 0.43732 0.455145 --0.0305889 0.168899 -0.00702359 0.59106 0.5 --0.0528191 0.162649 0.00296711 0.343566 0.5 --0.0890968 0.0940104 0.0208024 0.539357 0.478012 --0.0626249 0.173112 -0.0586131 0.353011 0.447085 --0.0443835 0.105923 -0.0201903 0.683228 0.5 --0.0664958 0.0951776 0.0424531 0.672396 0.5 --0.0324384 0.126415 0.0146752 0.445893 0.463327 --0.0152469 0.0961657 0.0518098 0.323594 0.5 --0.0097537 0.0960506 0.0535818 0.446732 0.426556 --0.00304601 0.0963367 0.0537791 0.579525 0.5 -0.01642 0.0957081 0.0480381 0.687032 0.5 --0.0876548 0.105191 0.0148253 0.774556 0.5 --0.0699417 0.0763232 0.0381496 0.596573 0.5 -0.0358078 0.0958594 -0.0120328 0.738943 0.5 -0.0374966 0.100154 0.031249 0.720944 0.5 --0.0530195 0.150059 0.0207323 0.696139 0.5 --0.0905911 0.131765 0.0328667 0.816274 0.5 --0.0709717 0.147309 -0.0268389 0.224341 0.389051 --0.0443321 0.0935075 -0.0222668 0.709831 0.5 --0.0400911 0.128618 0.00909496 0.81345 0.5 --0.0710054 0.100275 0.0398128 0.481571 0.5 --0.0653063 0.100124 0.0417262 0.670525 0.470095 --0.0589969 0.0980495 0.0430328 0.779482 0.5 --0.0529938 0.0980631 0.0432952 0.836255 0.5 --0.0469951 0.0980659 0.043235 0.637806 0.5 --0.0408476 0.100401 0.0414668 0.648927 0.395789 --0.0323344 0.0988071 0.0435216 0.652032 0.5 --0.0259464 0.0998425 0.0438947 0.737424 0.5 --0.0212066 0.0999849 0.0444194 0.576924 0.5 -0.00749586 0.09835 0.0488255 0.46146 0.5 -0.0090271 0.101109 0.0469975 0.470012 0.5 -0.0153076 0.100008 0.0472449 0.600016 0.5 -0.0208175 0.100067 0.0453866 0.595024 0.46889 --0.0648326 0.131509 -0.00838673 0.790869 0.5 --0.0740297 0.150832 -0.0323367 0.406089 0.5 --0.0932444 0.124885 0.026841 0.802537 0.5 --0.0633239 0.169093 -0.0610358 0.362406 0.5 --0.0771158 0.162488 -0.0202679 0.465605 0.5 --0.0585669 0.0647555 0.0323611 0.494963 0.328305 -0.0377689 0.110383 0.00969065 0.710008 0.5 --0.0503559 0.0935892 -0.0218956 0.807094 0.5 --0.0589961 0.101543 0.042437 0.529374 0.5 --0.0516647 0.101981 0.0417488 0.647378 0.5 --0.0469248 0.101325 0.0421166 0.608323 0.5 --0.0352173 0.101965 0.0413638 0.751982 0.5 -0.00285015 0.100935 0.0464433 0.395489 0.5 --0.075479 0.150312 -0.0143808 0.730394 0.5 --0.078936 0.108126 -0.00525459 0.540251 0.381971 --0.0251472 0.168981 -0.0187156 0.757996 0.5 --0.071457 0.113692 0.0499983 0.429195 0.5 --0.0747771 0.0997536 0.0377868 0.551123 0.5 --0.0902919 0.137212 0.0146286 0.495279 0.5 --0.0264568 0.105883 0.0411765 0.58994 0.471484 --0.0209966 0.1044 0.0429589 0.797197 0.5 --0.0145208 0.105597 0.0430511 0.780555 0.5 --0.00899316 0.10622 0.0435541 0.510194 0.5 --0.00289533 0.105882 0.0438861 0.384284 0.5 -0.00245231 0.105621 0.0429868 0.332307 0.5 -0.00945613 0.104903 0.0439002 0.435482 0.5 -0.0149913 0.104769 0.0443348 0.548532 0.5 --0.0772186 0.106139 0.0350601 0.430274 0.367589 --0.0708601 0.106945 0.0381598 0.402417 0.5 --0.0652985 0.106577 0.0390805 0.558067 0.398761 --0.0583896 0.105623 0.0405326 0.594554 0.5 --0.0529341 0.106445 0.0398435 0.644542 0.398207 --0.0461638 0.105797 0.0404843 0.759883 0.5 --0.0400204 0.106789 0.0388993 0.653599 0.5 --0.03311 0.106322 0.0394461 0.532024 0.5 -0.0193026 0.10477 0.0431964 0.486674 0.480281 --0.0501412 0.13774 0.00286739 0.569746 0.5 -0.0266104 0.105911 0.0384052 0.650339 0.5 -0.0438719 0.088439 -0.0031027 0.506353 0.478726 --0.0590381 0.113203 0.0362299 0.87726 0.5 --0.021499 0.107851 0.0414162 0.584043 0.5 --0.0164951 0.107881 0.0420289 0.633836 0.5 -0.00450524 0.107918 0.0419336 0.79888 0.5 -0.00856234 0.108229 0.0410531 0.820786 0.5 -0.0149994 0.10779 0.0412845 0.598409 0.5 -0.0213049 0.106041 0.0409433 0.561561 0.479574 --0.0336665 0.167843 -0.00338268 0.478764 0.5 --0.0587789 0.131705 -0.00671001 0.673026 0.5 --0.0443517 0.100306 -0.0215281 0.825942 0.5 --0.0147306 0.179604 -0.0266222 0.40888 0.5 -0.0159582 0.108177 -0.0177822 0.564672 0.468958 --0.0638447 0.138119 -0.00733006 0.633194 0.5 --0.0330953 0.167861 -0.0155539 0.527374 0.428366 --0.0643684 0.125359 -0.00876153 0.813046 0.5 --0.032583 0.161992 -0.0142418 0.852313 0.5 --0.068568 0.110392 0.0392194 0.353622 0.364353 --0.0643494 0.112195 0.0388907 0.34696 0.5 --0.0593722 0.112082 0.0373875 0.588374 0.5 --0.0529986 0.110472 0.0373551 0.513233 0.408461 --0.0468613 0.11028 0.0378862 0.569336 0.5 --0.040984 0.110496 0.0370883 0.553647 0.5 --0.0320055 0.110468 0.0370438 0.565129 0.5 --0.0074871 0.110717 0.042649 0.617568 0.5 --0.00449218 0.110714 0.0426582 0.621679 0.5 -0.0250033 0.110611 0.0368459 0.631257 0.5 -0.025919 0.0995286 -0.0189206 0.684181 0.5 --0.06973 0.112153 0.0457184 0.746569 0.5 --0.045604 0.148834 -0.00329924 0.521986 0.5 --0.0653006 0.0947889 -0.0177657 0.582853 0.5 --0.0906677 0.13318 0.0277848 0.773217 0.5 --0.0331508 0.094474 -0.0237799 0.742 0.5 --0.0575764 0.0941613 -0.0208023 0.703326 0.5 --0.0200586 0.0397198 0.0532237 0.447203 0.5 --0.0203685 0.0352888 0.051184 0.291685 0.457265 --0.0764163 0.125947 -0.00745144 0.524375 0.5 --0.0205906 0.167551 -0.0139677 0.809186 0.5 -0.025858 0.116851 0.0315289 0.660225 0.5 --0.0139279 0.167191 -0.021044 0.669958 0.5 --0.0587481 0.149802 -0.00133886 0.562881 0.5 -0.0144191 0.0395247 0.0443396 0.266796 0.5 -0.0332953 0.105473 0.0329627 0.721815 0.5 --0.0647461 0.114313 -0.0115219 0.592211 0.5 --0.0520818 0.0353771 0.0449331 0.341981 0.5 --0.015004 0.0392095 0.0513548 0.312679 0.5 --0.0094925 0.0384962 0.049554 0.302651 0.5 --0.0638496 0.117631 0.0454477 0.559641 0.5 --0.0573025 0.136864 0.033162 0.554568 0.5 -0.0189101 0.0400942 0.0428502 0.270107 0.5 --0.0508192 0.124393 0.0332635 0.581555 0.5 --0.0182623 0.180885 -0.017743 0.594618 0.5 --0.0651271 0.150343 -0.0325707 0.505808 0.5 -0.0332966 0.0936886 0.0400216 0.637373 0.5 --0.0463011 0.149493 0.00833001 0.611316 0.5 -0.00260773 0.0354887 0.0450013 0.261253 0.345588 --0.0780807 0.10971 0.0423535 0.916894 0.5 --0.0542262 0.124756 0.0369858 0.64506 0.5 --0.0402584 0.0361447 0.0436625 0.193197 0.5 --0.00317483 0.0942874 -0.0331049 0.71511 0.325502 --0.0151032 0.179716 -0.0207621 0.731902 0.5 -0.026141 0.0403246 0.0327265 0.294647 0.339561 --0.0640247 0.111376 -0.0136272 0.608847 0.5 -0.027817 0.112309 0.0339118 0.692282 0.5 --0.0586332 0.142774 0.0334953 0.761767 0.5 --0.0146622 0.167501 -0.0154455 0.61604 0.5 --0.0270893 0.167298 -0.00866399 0.642638 0.5 -0.0152056 0.045813 0.0442638 0.487785 0.5 -0.0190988 0.0442996 0.0429 0.362689 0.463942 -0.0215694 0.0456112 0.041209 0.479281 0.5 -0.0257452 0.0459137 0.0381185 0.444171 0.5 -0.0387365 0.0944447 0.0327088 0.718127 0.5 -0.0287308 0.0456722 0.0347466 0.335561 0.431941 --0.0151805 0.173809 -0.0213305 0.730436 0.5 --0.0658903 0.118253 0.0498126 0.307185 0.5 --0.0628345 0.093206 -0.0188544 0.659442 0.5 --0.0643065 0.142451 0.0394123 0.621016 0.5 --0.040079 0.150283 0.00280951 0.491474 0.5 --0.026851 0.173268 -0.00983852 0.620534 0.5 --0.0207913 0.173767 -0.0147826 0.653794 0.5 --0.0582334 0.124238 0.0403406 0.70004 0.5 --0.0683337 0.131545 0.0479709 0.732904 0.5 --0.0693547 0.10637 -0.012803 0.472443 0.5 --0.0428668 0.157627 0.0050419 0.670804 0.5 --0.0476449 0.130368 0.0258834 0.623828 0.5 -0.0379451 0.0817167 -0.0141547 0.644934 0.5 -0.0312298 0.0470286 0.0324465 0.426433 0.5 --0.0662284 0.138149 0.042896 0.72515 0.5 --0.0644094 0.105575 -0.0158634 0.566501 0.5 -0.0411271 0.0443713 0.0285474 0.466284 0.5 --0.0830031 0.0762361 0.0150296 0.67606 0.5 --0.0660167 0.123488 0.0501643 0.718404 0.5 --0.0416352 0.155329 0.00636435 0.466436 0.5 --0.0388456 0.155994 0.00477206 0.438555 0.402124 --0.0551732 0.116538 0.0359195 0.457649 0.5 --0.0600069 0.134082 0.0369434 0.682472 0.5 -0.0452816 0.0453284 0.0263124 0.471094 0.5 -0.0513161 0.0463154 0.0204963 0.342211 0.398387 --0.0106687 0.172847 -0.0215627 0.69267 0.5 --0.0147735 0.18419 -0.0259341 0.309641 0.5 -0.0301064 0.106776 0.0358091 0.72383 0.5 --0.063709 0.125122 0.0457451 0.712215 0.420475 -0.0473431 0.0499217 0.0295077 0.554948 0.5 -0.0497106 0.0482066 0.0259506 0.48379 0.5 -0.0518484 0.0518415 0.0267161 0.416499 0.5 --0.0162732 0.172938 -0.0174582 0.719256 0.5 -0.0355097 0.107304 0.0291151 0.718782 0.5 --0.0552656 0.143077 0.0300537 0.622521 0.5 --0.0637191 0.136482 0.0388176 0.603354 0.5 --0.0199086 0.161072 -0.00863325 0.350317 0.5 --0.0209172 0.179282 -0.0148523 0.455842 0.5 -0.014511 0.0513519 0.0474271 0.589102 0.5 --0.0610259 0.126912 0.0416133 0.698375 0.5 -0.0539905 0.0494141 0.0219114 0.418448 0.5 -0.00925922 0.118865 -0.0148674 0.54369 0.457314 --0.0268384 0.162091 -0.00836699 0.546076 0.486591 --0.0367024 0.163198 -0.00107067 0.680811 0.5 --0.0336432 0.155948 0.00188963 0.445666 0.44081 --0.0280966 0.159587 0.000483069 0.431301 0.5 --0.026491 0.16163 -0.00321758 0.537982 0.323001 -0.0206613 0.0528733 0.0451655 0.647628 0.324331 -0.0231576 0.0513069 0.0414753 0.507052 0.5 -0.0266044 0.0526516 0.039853 0.635463 0.446542 -0.0309772 0.0527823 0.0371348 0.671735 0.5 -0.0239371 0.103424 0.0418106 0.654526 0.5 -0.0568895 0.0527484 0.0209204 0.474964 0.5 --0.0664209 0.11329 0.0441331 0.212624 0.5 --0.0326789 0.162384 -0.00243762 0.543585 0.5 -0.0145199 0.0932586 -0.026363 0.546403 0.5 --0.0543983 0.119186 0.0365781 0.502204 0.44785 --0.0564272 0.132376 0.0357966 0.720059 0.5 --0.0501636 0.142911 0.00230897 0.376445 0.5 --0.043714 0.147707 0.0038501 0.245798 0.5 --0.0291346 0.177171 -0.00534178 0.371295 0.5 -0.0357304 0.100363 -0.0111604 0.61591 0.5 -0.0133943 0.0541536 0.0499521 0.532724 0.5 -0.0551089 0.0545007 0.0253961 0.545646 0.5 -0.0291033 0.0572886 0.0407089 0.633826 0.5 -0.0585723 0.0583402 0.0214893 0.549998 0.477428 --0.0740322 0.0656952 0.0144875 0.594594 0.5 --0.0749844 0.179305 -0.0518221 0.216638 0.5 -0.0145778 0.0585769 0.0501691 0.387785 0.5 -0.0214876 0.058332 0.0470549 0.596242 0.5 -0.0259507 0.0590004 0.0437762 0.663038 0.5 -0.032833 0.0585633 0.0387158 0.630786 0.5 -0.0358218 0.0578374 0.0350365 0.591179 0.5 -0.0360585 0.0951301 0.0364902 0.726421 0.5 --0.0886806 0.118283 0.0459142 0.444358 0.5 -0.0562736 0.0586365 0.0253398 0.57284 0.5 -0.0303311 0.0951295 0.0419589 0.717458 0.5 --0.0222315 0.167389 -0.0110472 0.688671 0.5 --0.0543257 0.136577 0.0307959 0.688078 0.5 --0.0500074 0.150447 0.0117579 0.563476 0.5 --0.0616289 0.137406 0.0354744 0.592141 0.5 --0.0319367 0.159507 0.00191749 0.44862 0.5 --0.0634458 0.132148 0.0406867 0.731705 0.5 -0.0368678 0.0921989 0.0367449 0.708135 0.5 --0.0728433 0.156137 -0.0339112 0.713518 0.5 -0.0389872 0.0640689 0.0330299 0.521361 0.5 --0.0636611 0.1488 -0.0205996 0.618447 0.5 -0.0153938 0.0648444 0.0513036 0.554385 0.463079 -0.0213958 0.0645506 0.0473078 0.414803 0.412252 -0.0265105 0.0649235 0.0439721 0.611901 0.5 -0.0302364 0.0650657 0.0415975 0.600683 0.487653 -0.0331295 0.0642221 0.0397381 0.500385 0.490901 -0.0367885 0.065027 0.0366867 0.593561 0.5 -0.0563131 0.0650782 0.0252208 0.639437 0.5 -0.0591364 0.0644742 0.0211357 0.550839 0.448044 --0.0110683 0.167098 -0.0167807 0.360187 0.5 --0.0605202 0.146205 0.0366666 0.591479 0.5 -0.0194528 0.0665736 0.0491642 0.603282 0.5 --0.0286777 0.158132 0.000508817 0.402765 0.431383 -0.0253025 0.0989569 0.0434277 0.623394 0.5 --0.0349979 0.152158 8.20736e-05 0.217633 0.5 -0.014665 0.070627 0.0528306 0.52613 0.5 -0.0202908 0.071041 0.0498828 0.634288 0.435356 -0.0230702 0.0702991 0.0473835 0.571849 0.5 -0.0263693 0.0706238 0.0441789 0.622852 0.474797 -0.0328306 0.0707606 0.0401362 0.612279 0.409693 -0.0368832 0.070672 0.0365953 0.662199 0.5 -0.0398878 0.0705632 0.0325808 0.656566 0.5 -0.0579544 0.0694794 0.0198345 0.6125 0.5 --0.0641704 0.063724 0.0268682 0.425507 0.418571 --0.0919499 0.114216 0.0149265 0.530043 0.5 -0.0351624 0.0819076 -0.0172502 0.760295 0.5 --0.0862408 0.119271 -0.00117534 0.455279 0.5 --0.0294401 0.174958 -0.00579982 0.562984 0.5 --0.0175288 0.165418 -0.0114925 0.675539 0.5 --0.0617869 0.117789 0.0409144 0.40334 0.5 -0.0301891 0.0723658 0.0418804 0.606777 0.5 --0.0822099 0.149486 0.00288044 0.385889 0.468811 --0.0760271 0.175704 -0.0506937 0.340571 0.5 --0.0652343 0.0614738 0.0211346 0.414933 0.425841 --0.0266574 0.110394 -0.019007 0.783101 0.5 --0.0813538 0.0779161 0.0268055 0.756683 0.5 -0.021417 0.118723 -0.00893569 0.549 0.5 -0.0149346 0.0759297 0.0536191 0.48671 0.476705 -0.0209886 0.0761609 0.0506055 0.575091 0.5 -0.0268396 0.0762089 0.0459193 0.572664 0.5 -0.0336785 0.0760737 0.0405166 0.630563 0.5 -0.0373422 0.0760306 0.0366776 0.505468 0.5 -0.0400324 0.0763062 0.0328345 0.645662 0.5 -0.0419048 0.076876 0.0296092 0.673034 0.5 -0.0438094 0.0763805 0.0258638 0.624347 0.5 --0.0452412 0.118472 -0.0142046 0.833781 0.5 -0.0456773 0.0768089 0.0208187 0.458504 0.467907 --0.050165 0.137714 0.0207618 0.606401 0.481088 --0.00327054 0.111563 -0.0203549 0.551699 0.482404 --0.0483236 0.145111 0.00757835 0.59165 0.5 -0.0310833 0.0775315 0.0432282 0.624343 0.5 --0.046855 0.145222 0.00288431 0.195425 0.432502 --0.0141716 0.10541 -0.0225802 0.672132 0.5 -0.0470348 0.0753979 0.0148736 0.455861 0.5 --0.0611433 0.140542 0.0356184 0.646306 0.5 -0.0272779 0.0823714 0.0459243 0.61663 0.478488 -0.0309212 0.08255 0.0430252 0.611382 0.5 -0.0343037 0.0825412 0.0402907 0.613309 0.465282 -0.0370354 0.0824663 0.0369099 0.642585 0.5 --0.0799946 0.147989 -0.000835337 0.484293 0.5 --0.0774435 0.0690153 0.00961977 0.704234 0.277826 -0.0404363 0.0826995 0.0326021 0.686672 0.5 -0.0417479 0.0827335 0.0302524 0.63553 0.5 -0.0436887 0.0825508 0.0263844 0.61829 0.5 -0.0454407 0.0825465 0.0207137 0.601475 0.480065 --0.0822812 0.116295 0.0482855 0.66926 0.5 --0.0844726 0.0947391 -0.00345192 0.592061 0.5 --0.020271 0.168003 -0.0193935 0.821267 0.5 --0.0742716 0.0668501 0.0190414 0.706894 0.5 -0.026747 0.0882417 0.0458314 0.539865 0.389736 -0.0308722 0.0882572 0.0430146 0.948814 0.5 -0.0344922 0.0883047 0.0403697 0.638338 0.5 -0.0372481 0.0881263 0.0366393 0.643327 0.5 -0.039927 0.088094 0.0326668 0.711283 0.5 -0.0419027 0.0877782 0.0290815 0.667656 0.5 -0.00264738 0.112302 -0.019871 0.766242 0.5 --0.0703315 0.1455 -0.0205576 0.136819 0.239158 --0.0749446 0.137879 -0.00653312 0.459033 0.397283 --0.0266967 0.114299 -0.0159903 0.856895 0.5 --0.0869924 0.113518 0.00410409 0.344807 0.5 --0.0142186 0.174013 -0.0259807 0.439072 0.5 --0.0221564 0.157852 -0.00861651 0.254248 0.5 --0.011587 0.164129 -0.0163045 0.228563 0.367524 --0.00997381 0.169338 -0.0247765 0.42189 0.5 --0.082875 0.143405 0.00186692 0.494272 0.5 -0.0203757 0.0354405 -0.00287175 0 0 -0.0191274 0.0363337 -0.00917714 0.174536 0.5 -0.0184456 0.036388 -0.013479 0.173751 0.5 -0.0149535 0.0347732 -0.0154937 0.144529 0.253209 -0.0221204 0.0372026 0.0342324 0.156956 0.287305 -0.039271 0.0382866 0.00854708 0.245023 0.5 -0.0397549 0.0398545 0.002614 0.276002 0.5 -0.0221892 0.0380614 -0.00446361 0.173629 0.5 -0.0179901 0.0369066 -0.0161835 0.336518 0.5 -0.0154148 0.0392444 -0.0212861 0.367832 0.5 -0.0208023 0.100118 -0.0213392 0.648293 0.46589 -0.0446004 0.0409064 0.00927401 0.208963 0.5 -0.0435625 0.0411355 0.00427044 0.357471 0.452104 -0.0381381 0.0411139 -0.00147908 0.514406 0.5 --0.0478807 0.135207 0.00885778 0.482359 0.5 -0.0217274 0.0404287 -0.00964433 0.311593 0.5 -0.0206744 0.0405956 -0.0144437 0.473825 0.5 -0.0192578 0.0411681 -0.0195074 0.414351 0.5 --0.0885736 0.112913 0.0395856 0.488806 0.5 --0.026793 0.106457 -0.0218501 0.617481 0.5 -0.0481487 0.0428585 0.0145594 0.265572 0.5 -0.0521212 0.0461655 0.0089655 0.199267 0.5 -0.0480438 0.0430647 0.00724585 0.412258 0.5 -0.0460936 0.0434131 0.00284357 0.566688 0.5 -0.0285003 0.100485 -0.0168103 0.728425 0.5 -0.0269462 0.0395833 -0.00334578 0.464947 0.5 --0.0907856 0.117838 0.00647331 0.421552 0.5 --0.062721 0.167567 -0.0470628 0.645866 0.5 --0.0799532 0.106813 0.0316838 0.420249 0.5 -0.0527437 0.0462125 0.0139554 0.286197 0.5 -0.0504533 0.0466263 0.00264513 0.57721 0.5 --0.0322581 0.117324 -0.0133273 0.811815 0.5 -0.0272475 0.0455966 -0.00927071 0.533119 0.5 --0.0146455 0.0942084 -0.0337341 0.520871 0.5 --0.0411545 0.16722 -0.010818 0.48116 0.5 --0.0721385 0.156112 -0.0384102 0.511983 0.468875 -0.0456803 0.0474217 -0.00311192 0.412576 0.5 -0.0239407 0.0433254 -0.00969837 0.651864 0.5 -0.021084 0.0462585 -0.0205303 0.476548 0.5 --0.0348527 0.0351549 -0.0307351 0.16856 0.5 --0.0699867 0.0663066 0.0259153 0.590849 0.43032 --0.0747071 0.149891 -0.0201453 0.5851 0.5 --0.0845448 0.13725 0.000743181 0.580039 0.5 -0.0549514 0.0484178 0.0163982 0.295573 0.5 -0.0264565 0.0466261 -0.0141039 0.515417 0.5 -0.0225276 0.0444655 -0.0157683 0.505631 0.5 -0.0330538 0.0938135 -0.0160538 0.699679 0.5 -0.0526476 0.0694992 0.00297306 0.629664 0.372945 -0.0528544 0.0581339 -0.00277966 0.592036 0.5 --0.0571464 0.0671799 0.0361705 0.503626 0.472266 --0.0651544 0.157167 -0.0515491 0.708429 0.5 --0.0493189 0.133682 0.00119868 0.355836 0.438333 --0.032962 0.10595 -0.0206729 0.810434 0.5 --0.0649538 0.155656 -0.045631 0.820472 0.5 --0.0390456 0.150445 -0.00354536 0.204281 0.5 -0.0574365 0.051618 0.0145183 0.351624 0.5 -0.0574129 0.0522531 0.00903377 0.511629 0.5 -0.0536112 0.0500965 0.00204174 0.768402 0.5 -0.0512204 0.0520121 -0.00218354 0.534755 0.5 -0.0471226 0.0515811 -0.00481298 0.434179 0.5 -0.033443 0.047576 -0.0063817 0.557462 0.465257 -0.00280933 0.118297 -0.0158208 0.570337 0.473222 --0.0147841 0.10125 -0.0238408 0.771507 0.5 --0.0620037 0.167422 -0.0527165 0.538383 0.466596 -0.0559147 0.0528382 0.00339683 0.824166 0.5 -0.0334801 0.0518506 -0.00825293 0.591066 0.5 -0.0287814 0.0501171 -0.0157926 0.574224 0.5 -0.0256197 0.0485542 -0.0190548 0.421586 0.5 --0.00863537 0.118406 -0.0146114 0.827086 0.5 --0.0148322 0.117675 -0.014701 0.559736 0.5 --0.0615138 0.145712 -0.00481276 0.466074 0.5 -0.0232531 0.12083 -0.00456186 0.617393 0.5 --0.0401535 0.0342718 -0.0275149 0.0979878 0.5 -0.0302657 0.0496868 -0.0107289 0.647285 0.5 -0.0320066 0.111334 -0.00737407 0.536101 0.5 --0.0211003 0.120417 -0.0102482 0.732965 0.5 --0.0204991 0.117125 -0.0140803 0.767014 0.5 --0.00910263 0.0383602 -0.025776 0.274297 0.5 --0.0525144 0.11229 -0.0171034 0.442719 0.484227 -0.0202353 0.123713 -0.00247094 0.59012 0.5 --0.0701749 0.0347541 -0.0017891 0.135623 0.5 --0.00340266 0.114844 -0.0176928 0.826111 0.5 -0.0310248 0.053713 -0.0140522 0.572913 0.5 -0.0268191 0.0528482 -0.020339 0.412387 0.455219 --0.0147458 0.120673 -0.0105853 0.653192 0.5 -0.0270905 0.106214 -0.0146756 0.603346 0.5 -0.0465541 0.0697991 0.00228503 0.590477 0.5 --0.00300122 0.100676 -0.0235814 0.77298 0.5 --0.0755874 0.076212 0.033468 0.651011 0.5 -0.059738 0.0572998 0.0151736 0.624329 0.5 -0.0595394 0.0578717 0.00861672 0.650231 0.5 -0.0572091 0.0580526 0.00253507 0.577167 0.5 --0.0142907 0.123147 -0.00746744 0.689207 0.5 -0.0211831 0.112303 -0.0140834 0.636933 0.5 -0.0347455 0.0565046 -0.010714 0.517615 0.5 -0.0249138 0.0825163 -0.0245877 0.759593 0.5 --0.0382227 0.114521 -0.016178 0.845616 0.5 --0.0819485 0.0761672 0.0208322 0.76776 0.5 --0.0269557 0.0392251 -0.0293943 0.537642 0.5 -0.0377037 0.0593401 -0.00852013 0.537798 0.5 -0.0330295 0.0586306 -0.014729 0.60439 0.5 -0.0218121 0.0515865 -0.0236492 0.56032 0.5 --0.0204953 0.0935908 -0.0331675 0.485557 0.5 --0.0872217 0.113521 0.0440666 0.448078 0.427651 --0.0271537 0.0351608 0.0509267 0.96808 0.5 --0.0503825 0.106302 -0.0194598 0.649024 0.5 -0.0266611 0.0585067 -0.0219134 0.622435 0.5 -0.00975018 0.0945932 -0.0280451 0.504262 0.457756 --0.0205524 0.122391 -0.00754739 0.498583 0.5 --0.0668021 0.0909191 -0.0174744 0.566525 0.5 --0.0856155 0.0942099 -0.00109094 0.420789 0.436678 --0.0915274 0.11444 0.0204492 0.759207 0.5 --0.0909048 0.131701 0.00809159 0.558083 0.5 -0.0404851 0.0578886 -0.0051698 0.425865 0.437223 -0.0295964 0.0580473 -0.0178274 0.608291 0.460655 -0.0266986 0.0941359 -0.0205949 0.662934 0.5 --0.0677104 0.172869 -0.0572602 0.695141 0.5 -0.0142001 0.118043 -0.013917 0.45799 0.403894 --0.0698171 0.0699687 0.0326375 0.529959 0.5 -0.0607097 0.0648802 0.0151632 0.434757 0.451533 -0.0609346 0.0630505 0.0131585 0.526971 0.5 -0.0602205 0.0643718 0.00864139 0.443146 0.456896 -0.0574055 0.0638877 0.00271573 0.413274 0.5 --0.0797793 0.103858 -0.00660016 0.553637 0.5 --0.0563867 0.137359 -0.00421998 0.659682 0.5 -0.0344512 0.0638263 -0.0152012 0.581486 0.5 -0.0307139 0.0605317 -0.0184589 0.617611 0.449874 -0.0185684 0.121789 -0.00725624 0.61441 0.349043 --0.0456617 0.112414 -0.0169658 0.70381 0.5 -0.0456177 0.0644845 -0.00162168 0.572144 0.5 --0.0584268 0.0349015 0.0441202 0.767369 0.5 --0.0747982 0.0723674 0.0308514 0.656357 0.5 --0.0699373 0.0621854 0.0151778 0.587415 0.5 --0.052889 0.136519 -0.00170821 0.593683 0.5 -0.0410205 0.0644886 -0.00476733 0.363401 0.5 -0.0388712 0.0646166 -0.00976797 0.384344 0.5 -0.0514871 0.0637279 -0.00174794 0.518067 0.5 --0.0787297 0.0744551 0.0267421 0.809934 0.5 --0.0850281 0.144269 0.00618082 0.578063 0.5 -0.0313094 0.064487 -0.0188936 0.672704 0.5 -0.0267274 0.0646171 -0.0220842 0.752591 0.5 -0.0318737 0.0877439 -0.0192705 0.740422 0.5 --0.0772455 0.143995 -0.00470939 0.452269 0.5 -0.0132576 0.110443 -0.0183541 0.539267 0.5 --0.00289343 0.124723 -0.00863032 0.516883 0.5 --0.0342868 0.038582 0.0485461 0.546061 0.5 -0.0200397 0.0876233 -0.0261205 0.735721 0.5 -0.0585453 0.0705354 0.0146976 0.608535 0.5 -0.0581405 0.0699819 0.00856199 0.483528 0.5 -0.056099 0.069436 0.00424359 0.385578 0.5 -0.0370479 0.0665186 -0.0132637 0.645736 0.5 --0.062561 0.172971 -0.0616721 0.43069 0.5 --0.0702718 0.15494 -0.0455472 0.29179 0.457421 --0.0916259 0.130499 0.00930481 0.432982 0.472725 --0.070021 0.148229 -0.0328231 0.322588 0.195946 --0.0721274 0.0680183 0.0267753 0.656727 0.5 --0.0745337 0.15067 -0.0264303 0.331486 0.5 -0.0431087 0.0713461 -0.002764 0.390428 0.45538 -0.0421659 0.0692525 -0.00466106 0.55545 0.5 -0.0345404 0.0699378 -0.0160391 0.727409 0.5 --0.0342368 0.122912 -0.00708584 0.432969 0.5 -0.0401518 0.070932 -0.00951127 0.706551 0.5 -0.0370706 0.0707408 -0.013301 0.722628 0.5 -0.0310856 0.0702175 -0.0192905 0.761897 0.5 -0.0283004 0.0705453 -0.0222447 0.701199 0.5 --0.00859023 0.101699 -0.0237897 0.731824 0.5 --0.0328234 0.0400139 -0.029875 0.413461 0.5 --0.0830588 0.11047 0.0397334 0.931001 0.5 -0.0142724 0.123237 -0.00806485 0.479991 0.484444 --0.0760443 0.108637 0.0389078 0.769887 0.5 --0.0732762 0.154939 -0.0321392 0.640327 0.5 -0.0160324 0.0889232 -0.0282477 0.595959 0.5 --0.0901677 0.131361 0.0394374 0.633972 0.457764 -0.0455828 0.0768365 0.00270178 0.323813 0.5 --0.0516717 0.0553965 0.014906 0.168077 0.5 --0.0376545 0.121002 -0.0109724 0.599451 0.451266 -0.0466318 0.0762885 0.00910629 0.334003 0.5 -0.0437303 0.0769241 -0.00295564 0.541016 0.5 -0.0405043 0.0766784 -0.0084913 0.540094 0.5 -0.0369463 0.0762836 -0.0128837 0.716695 0.5 -0.0349351 0.0766648 -0.0155944 0.687304 0.5 -0.0319237 0.0763904 -0.0194186 0.722365 0.5 -0.0285208 0.0758075 -0.0225233 0.729644 0.5 --0.0646857 0.068809 0.0348219 0.518098 0.396839 --0.00335573 0.0986136 -0.0269283 0.762285 0.5 --0.0383606 0.100112 -0.0217661 0.633523 0.5 --0.0705433 0.149897 -0.0387319 0.143598 0.5 --0.0247871 0.179215 -0.0188356 0.466421 0.5 -0.00339058 0.0937023 -0.0318365 0.697748 0.5 --0.09099 0.142689 0.0226645 0.743514 0.5 --0.0851088 0.102115 0.000391121 0.420019 0.403283 -0.00299202 0.124707 -0.00864775 0.631346 0.5 --0.0649459 0.167336 -0.0329944 0.692397 0.5 -0.045975 0.0827243 0.0146716 0.494123 0.463874 -0.0461931 0.0827376 0.00867911 0.540283 0.443947 -0.0453461 0.0826602 0.00269811 0.520808 0.5 -0.032594 0.082231 -0.0190597 0.700575 0.5 --0.0707752 0.142011 -0.00901143 0.440829 0.5 --0.0396694 0.045239 -0.0210351 0.371561 0.5 --0.0736488 0.145787 -0.0131048 0.298566 0.5 --0.0661855 0.1779 -0.0529018 0.456268 0.5 --0.0698006 0.179227 -0.0517285 0.330383 0.5 --0.0719677 0.177848 -0.0474604 0.498199 0.393806 --0.0131817 0.0974247 0.0509808 0.29677 0.5 --0.0760529 0.177651 -0.0471457 0.200482 0.341482 --0.0875274 0.149451 0.00937476 0.260452 0.5 --0.0847504 0.149536 0.00652369 0.220089 0.5 --0.0853843 0.0980412 -0.000554198 0.453316 0.5 --0.070162 0.172945 -0.0393132 0.377002 0.42015 --0.0669053 0.17136 -0.0404187 0.587367 0.5 --0.0915765 0.114644 0.0108349 0.335405 0.476851 -0.0311175 0.116345 -0.00142056 0.524001 0.485056 --0.09039 0.144074 0.0142555 0.571623 0.5 -0.0533752 0.0724173 0.00805773 0.504643 0.5 -0.0348115 0.113636 0.00289967 0.517745 0.5 -0.0321047 0.117128 0.00373672 0.512637 0.481334 --0.0558554 0.16013 0.00226313 0.176407 0.35978 -0.0284127 0.12005 0.00266093 0.800124 0.5 --0.0693417 0.151526 -0.0443255 0.162625 0.220555 -0.0509143 0.0733396 0.0112131 0.81315 0.5 -0.0485286 0.0726358 0.00856732 0.779683 0.5 -0.0251471 0.122517 0.00254898 0.804299 0.5 --0.0684168 0.170157 -0.0319531 0.535557 0.5 --0.071028 0.171274 -0.0325886 0.712016 0.5 --0.0765634 0.155757 -0.00874762 0.256295 0.5 -0.0525206 0.0734678 0.0148876 0.468908 0.45355 -0.035521 0.113454 0.00908801 0.654915 0.5 -0.0208324 0.125627 0.00327965 0.76886 0.5 --0.0476722 0.134348 0.0194434 0.579216 0.488505 --0.0746083 0.171229 -0.0326516 0.439107 0.422901 -0.0322027 0.117616 0.0093642 0.646061 0.5 -0.0162523 0.127588 0.00132734 0.679655 0.445027 --0.0914669 0.142805 0.0167223 0.344959 0.5 -0.0290775 0.120474 0.00686894 0.798143 0.5 -0.0135909 0.12914 0.00336546 0.632038 0.474565 --0.0861635 0.100458 0.025719 0.514874 0.431291 --0.0653051 0.165945 -0.0269849 0.665887 0.5 --0.0698492 0.16889 -0.0268648 0.536219 0.5 --0.07827 0.167473 -0.032496 0.259817 0.452429 -0.0215557 0.0945234 -0.0226594 0.630702 0.48336 -0.0260612 0.123082 0.00873766 0.803075 0.5 -0.00920342 0.130081 0.00248247 0.641161 0.5 --0.0709934 0.170517 -0.0295248 0.566905 0.409383 --0.0760202 0.167938 -0.0272636 0.242234 0.5 -0.0525229 0.0716654 0.0211203 0.349876 0.431389 -0.0207167 0.126566 0.00922145 0.763786 0.5 --0.0746025 0.0998033 -0.0126456 0.503102 0.5 --0.0864333 0.0890874 0.0257055 0.752441 0.5 -0.0354941 0.113435 0.0150848 0.708057 0.5 -0.0320737 0.117698 0.0146262 0.694886 0.5 -0.00294754 0.130714 0.00292443 0.849802 0.5 --0.0256391 0.0823957 0.0519489 0.764034 0.5 --0.0666258 0.165416 -0.0221631 0.534987 0.5 --0.0804177 0.153092 0.00488677 0.321879 0.39417 --0.0645623 0.0350017 0.0151892 0.352362 0.5 --0.0627936 0.0352479 0.02012 0.616295 0.5 --0.0642932 0.0349381 0.0264604 0.161121 0.384305 --0.0642421 0.0397497 0.0267659 0.206373 0.5 --0.0652419 0.0352202 0.0324357 0.167045 0.5 --0.06432 0.0352261 0.0387914 0.349097 0.5 --0.0869014 0.0944088 0.0260869 0.722262 0.5 --0.026376 0.100403 -0.0237519 0.527518 0.47737 --0.0704394 0.0348288 0.00888692 0.228898 0.5 --0.0696375 0.039673 0.0091864 0.30841 0.5 --0.0678064 0.035728 0.013362 0.509091 0.5 --0.0778433 0.0819732 0.0354617 0.774608 0.5 --0.0809318 0.0827942 0.0325 0.767831 0.5 --0.0712316 0.038974 0.00275642 0.155719 0.237906 --0.0616101 0.0379618 0.0219344 0 0 --0.0653778 0.0407054 0.0323415 0.379158 0.5 --0.0612949 0.040108 0.0438783 0.388361 0.5 --0.0748891 0.0826916 0.0381154 0.772848 0.5 --0.0841641 0.133769 0.0486564 0.546232 0.467433 --0.0849106 0.0945271 0.0290479 0.754258 0.5 --0.082994 0.144712 0.0404065 0.382972 0.420138 --0.0265479 0.117619 -0.0132781 0.755106 0.5 --0.0679678 0.0383221 0.0123903 0.271535 0.306541 --0.0639259 0.0401146 0.0151101 0.258252 0.450399 --0.0588527 0.0407802 0.0202136 0.51937 0.5 --0.0869621 0.135589 0.0440584 0.520567 0.5 --0.038827 0.0398484 0.042564 0.570175 0.5 --0.0253238 0.0773437 0.0501603 0.646885 0.5 -0.00864855 0.111878 -0.0192252 0.821439 0.5 --0.0625014 0.04424 0.0388616 0.455153 0.47063 --0.088493 0.125258 0.0461673 0.674925 0.5 -0.0150785 0.10107 -0.0220372 0.749486 0.5 --0.0810533 0.0876325 0.0334622 0.750019 0.5 --0.0636602 0.0439221 0.0322355 0.437404 0.5 --0.0823757 0.12585 -0.00459555 0.376136 0.464207 --0.0374554 0.042873 0.0429512 0.492581 0.5 --0.031328 0.0432863 0.0501185 0.483275 0.5 --0.0841802 0.0875016 0.0285815 0.671149 0.464325 --0.0690099 0.0427216 0.00298087 0.372436 0.5 --0.0690323 0.0427133 0.00739115 0.277083 0.5 --0.0642007 0.0449178 0.00895163 0.562755 0.5 --0.0630005 0.0427497 0.0133004 0.520064 0.348086 --0.0580777 0.0444032 0.0143596 0.493924 0.5 --0.087476 0.130712 0.0458544 0.531379 0.477045 --0.0837712 0.0999337 0.029339 0.668895 0.5 --0.083719 0.0822846 0.0270932 0.660348 0.5 --0.0209183 0.0934772 0.0512134 0.479975 0.5 --0.0868983 0.142651 0.0383505 0.486766 0.469754 --0.0588984 0.0467651 0.00989959 0.460736 0.319245 --0.0529144 0.0464475 0.0158024 0.381525 0.5 --0.0881654 0.0882094 0.0209192 0.624947 0.5 --0.0494075 0.165901 0.000731671 0.369742 0.391777 --0.0586114 0.0473978 0.0337061 0.152377 0.410418 --0.05614 0.0517476 0.00835186 0.396733 0.5 --0.0865231 0.148073 0.0321271 0.367072 0.452379 --0.0308497 0.0493297 0.0429654 0.330168 0.454747 --0.0769102 0.114994 0.0501188 0.653806 0.5 --0.0209065 0.0959579 0.0474195 0.622864 0.5 --0.0509947 0.0509637 0.0150799 0.759028 0.5 -0.00842415 0.0889657 -0.0320537 0.627702 0.5 --0.0240561 0.0544386 0.0416973 0.433194 0.5 --0.0510392 0.0524223 0.0203213 0.262945 0.5 --0.0526208 0.0518271 0.027021 0.695325 0.5 --0.0504022 0.0591186 0.0326891 0.768296 0.5 --0.0478821 0.0590694 0.0363134 0.800191 0.5 --0.0239128 0.0586553 0.0421308 0.768223 0.5 --0.0759314 0.119228 -0.00697007 0.568703 0.5 --0.0183181 0.0604564 0.0506182 0.70539 0.5 --0.0298441 0.0972531 -0.0235715 0.830462 0.5 --0.0241926 0.0628773 0.0422936 0.709715 0.5 --0.0223998 0.06467 0.045979 0.606456 0.5 --0.0192899 0.0641483 0.0503928 0.754401 0.5 --0.0260109 0.172925 -0.0191453 0.51739 0.5 --0.0265331 0.161574 -0.0144318 0.84044 0.5 --0.0558556 0.15572 -0.00121016 0.41523 0.5 --0.0599028 0.136466 -0.0064456 0.660892 0.5 --0.063538 0.071665 0.0379463 0.556494 0.5 --0.0200417 0.0869862 -0.0378876 0.500126 0.449734 --0.0557176 0.105745 -0.0186241 0.707273 0.5 --0.0530691 0.143914 -0.00100898 0.728895 0.5 --0.0256688 0.0704637 0.0438935 0.717372 0.393932 --0.0235577 0.0693774 0.0470203 0.657726 0.5 --0.0525759 0.127247 -0.00521525 0.567734 0.5 --0.0787859 0.131858 -0.00545913 0.44224 0.460808 --0.0580212 0.120088 -0.0102747 0.564344 0.455328 --0.0396294 0.110441 -0.0186258 0.62346 0.5 --0.0210282 0.173113 -0.0214922 0.42389 0.352327 --0.0547593 0.0563289 0.0107147 0.179388 0.5 --0.0435534 0.0345758 -0.024752 0.176398 0.205782 --0.0449833 0.0346921 -0.0207483 0.159962 0.261208 --0.0443576 0.0390403 -0.0217491 0.178142 0.5 --0.0462855 0.0345037 -0.0153112 0.189574 0.5 --0.046619 0.0396457 -0.0141457 0.194812 0.5 --0.00904923 0.0343826 -0.0246429 0.15305 0.5 -0.00311748 0.100303 -0.0227929 0.684313 0.5 --0.0690809 0.0392217 -0.00181724 0.169982 0.409113 --0.0920289 0.131041 0.0262349 0.856795 0.5 --0.043414 0.0372487 -0.0253064 0.219927 0.5 -0.0280974 0.0818294 -0.0220931 0.752623 0.5 --0.067702 0.169446 -0.0560134 0.487347 0.455218 --0.0915377 0.129674 0.0312365 0.601516 0.48259 --0.0663086 0.0411162 -0.00443149 0.346306 0.5 --0.0731255 0.151935 -0.0368879 0.40925 0.5 --0.0390145 0.0394889 -0.027598 0.3765 0.5 --0.0637372 0.0437827 -0.00264533 0.37233 0.5 --0.0605427 0.0425565 0.0246975 0.23689 0.5 --0.0857603 0.130763 -0.000714461 0.66754 0.5 --0.0520472 0.0403573 -0.0107411 0.62257 0.5 --0.0568522 0.0434504 0.0224413 0.404188 0.5 --0.043239 0.0429342 -0.0193166 0.339314 0.38382 --0.0438787 0.0441322 -0.0144222 0.427488 0.468839 --0.0457505 0.046486 -0.0105694 0.340556 0.5 --0.0645938 0.0456897 0.00313082 0.3549 0.5 --0.0525978 0.0464843 0.0207116 0.3335 0.5 --0.0572578 0.0459489 0.026887 0.439332 0.5 --0.0618962 0.0443648 0.0286813 0.302557 0.45843 --0.0331467 0.0453179 -0.0267282 0.481653 0.5 --0.0377669 0.0443547 -0.0252099 0.392631 0.5 --0.0320922 0.114425 -0.0162304 0.853943 0.5 --0.0578027 0.0470669 -0.0032674 0.530144 0.5 --0.0914954 0.147994 0.0205137 0.478387 0.480384 --0.0400067 0.0471536 -0.0151042 0.224844 0.33752 -0.00454895 0.121869 -0.0124797 0.622385 0.5 -0.0151282 0.112708 -0.0165496 0.634759 0.463552 --0.0525787 0.0463291 -0.00775444 0.598118 0.5 --0.0599276 0.0475112 0.00267117 0.286734 0.429608 --0.0726458 0.147126 -0.0218625 0.235551 0.5 --0.0740924 0.168686 -0.0440312 0.451963 0.347747 --0.057494 0.0515426 0.00319413 0.311918 0.5 --0.0536918 0.0483048 0.0264945 0.447469 0.5 --0.0147156 0.114453 -0.0172255 0.634887 0.5 --0.0335191 0.0480424 -0.021246 0.299501 0.5 -0.019461 0.0924333 -0.0244344 0.636237 0.5 -0.0169402 0.0952065 -0.0238278 0.793707 0.5 -0.0201047 0.104156 -0.0188197 0.859301 0.5 --0.0319642 0.0516657 -0.0152509 0.265727 0.5 --0.0368448 0.0488256 -0.0131071 0.109826 0.5 --0.0391265 0.0518909 -0.0109467 0.555432 0.5 --0.00892221 0.111576 -0.0202733 0.785262 0.5 --0.0515659 0.0515158 -0.00751393 0.527245 0.5 --0.0557028 0.05294 -0.00268598 0.514955 0.5 --0.0293421 0.0526398 -0.0213991 0.356317 0.5 --0.0314453 0.0496351 -0.0193539 0.306544 0.5 -0.0322381 0.10409 -0.0128482 0.653044 0.5 --0.0261025 0.0525801 -0.0264669 0.366688 0.5 --0.0583031 0.116733 -0.0130038 0.568329 0.5 --0.014851 0.111599 -0.0191484 0.630253 0.463696 --0.0521348 0.118189 -0.0137451 0.464136 0.474515 --0.0517493 0.0582798 -0.00896954 0.683087 0.5 --0.0561982 0.0582462 -0.00310645 0.618759 0.5 --0.0587989 0.0586119 0.00276734 0.328771 0.427166 --0.0585564 0.0578416 0.00857596 0.293131 0.5 -0.019026 0.11614 -0.0131686 0.497701 0.5 --0.0211893 0.111662 -0.0190883 0.650648 0.5 --0.0239176 0.0561149 -0.030057 0.484351 0.5 --0.0272603 0.058548 -0.027478 0.457773 0.5 --0.0295766 0.0582799 -0.0217551 0.550969 0.5 --0.0320928 0.0589382 -0.0147618 0.534177 0.453646 -0.0073938 0.121789 -0.0126555 0.654152 0.5 --0.0251946 0.0595227 -0.0308632 0.509396 0.5 --0.0307167 0.06013 -0.0194181 0.549851 0.422118 --0.0650113 0.0632174 -0.00293095 0.168435 0.5 --0.0696479 0.065751 -0.00198101 0.165663 0.5 --0.0699926 0.0635013 0.00374106 0.275779 0.5 --0.0799435 0.0724812 0.0191514 0.599916 0.5 --0.0676844 0.160922 -0.0559942 0.35716 0.5 --0.0215435 0.0636559 -0.0350431 0.45692 0.5 --0.0258325 0.0648252 -0.0322087 0.452259 0.5 --0.028982 0.0636438 -0.0274997 0.410415 0.5 --0.0304226 0.0629368 -0.0224261 0.908229 0.5 --0.0319042 0.0651819 -0.0201942 0.518875 0.434998 --0.0332741 0.0636337 -0.0160032 0.40837 0.447765 --0.0205547 0.034111 -0.026401 0.174612 0.215481 --0.0743367 0.0658286 0.00833126 0.649876 0.5 -0.016103 0.120745 -0.0103843 0.509865 0.5 --0.0770212 0.0700544 0.00316631 0.305775 0.384345 --0.0748219 0.06693 0.00451345 0.433069 0.463791 --0.0306317 0.0657524 -0.025453 0.517895 0.5 --0.0711433 0.0687078 -0.00390291 0.256016 0.135401 --0.0762625 0.0716316 -0.00295918 0.293636 0.296358 --0.0802204 0.0713935 0.00991267 0.507181 0.5 --0.0913413 0.148143 0.0161458 0.474933 0.5 --0.0273736 0.0700052 -0.0335323 0.445714 0.5 --0.0300274 0.0692073 -0.0289677 0.511122 0.5 --0.0316277 0.0711218 -0.0266514 0.502235 0.5 --0.0330629 0.0699765 -0.0212743 0.929225 0.5 --0.0353642 0.0705896 -0.0177097 0.263666 0.5 --0.0587004 0.0391044 -0.0090027 0.295521 0.5 --0.0697696 0.0703857 -0.00808666 0.238472 0.5 --0.0804832 0.0726462 0.00472466 0.630221 0.5 -0.0151616 0.126104 -0.00266395 0.542796 0.5 --0.0745721 0.072883 -0.00757069 0.303203 0.5 --0.0823908 0.076277 0.00270117 0.615888 0.5 --0.0912831 0.133698 0.0142161 0.68945 0.5 -0.00371049 0.0968817 -0.0280931 0.670854 0.5 --0.0761392 0.0766258 -0.00859487 0.260107 0.5 --0.0784749 0.0748827 -0.00523624 0.238143 0.440892 --0.0806781 0.0771902 -0.00290803 0.36458 0.43512 --0.0834622 0.0765209 0.00927112 0.562933 0.5 -0.00983826 0.11402 -0.0178612 0.519736 0.475688 -0.00210649 0.0981565 -0.0261244 0.689185 0.5 --0.0285085 0.0757575 -0.0348118 0.64535 0.304239 --0.0330874 0.0761249 -0.0270661 0.564742 0.5 --0.0346568 0.0757906 -0.0215029 0.930953 0.5 -0.0231104 0.0892807 -0.0240236 0.697809 0.45449 --0.0312132 0.0771357 -0.0320416 0.687582 0.5 --0.0700425 0.0763633 -0.0141464 0.485274 0.5 --0.0861137 0.0814707 0.00908143 0.590509 0.5 --0.086319 0.08152 0.0149936 0.698173 0.5 --0.0208042 0.0963182 -0.0270563 0.75553 0.5 --0.0211078 0.114391 -0.0171285 0.793027 0.5 --0.0746162 0.0828529 -0.0139325 0.683447 0.5 --0.077295 0.081216 -0.0100568 0.47673 0.5 --0.0800127 0.0821605 -0.00722237 0.637376 0.5 --0.0826334 0.0820868 -0.00324616 0.569954 0.5 --0.0844667 0.0817669 0.00249573 0.601403 0.5 --0.0860445 0.0832591 0.0203255 0.630527 0.5 --0.084816 0.0816746 0.0219849 0.638209 0.5 -0.0545549 0.0661692 0.000765649 0.628404 0.43579 --0.0331604 0.0828369 -0.0270493 0.417784 0.5 --0.0358028 0.0829047 -0.0227723 0.112354 0 --0.0861942 0.0842505 0.00298565 0.418742 0.5 --0.0287072 0.0827267 -0.0349537 0.48086 0.471486 --0.0311601 0.0822387 -0.0315627 0.627475 0.5 --0.085403 0.141865 0.00516647 0.463398 0.5 --0.0785169 0.0885628 -0.0107607 0.69884 0.5 --0.0807046 0.0887676 -0.00826584 0.689404 0.5 --0.0843972 0.0878743 -0.00349923 0.402052 0.5 --0.0855708 0.0882073 -0.00109946 0.425364 0.422235 --0.0876157 0.0881286 0.00369184 0.414972 0.435161 --0.0885339 0.0876942 0.00897158 0.630733 0.5 --0.0885791 0.0877213 0.0149616 0.665472 0.5 --0.0643854 0.0348576 -0.00775085 0.279509 0.5 --0.0512932 0.034227 -0.0129013 0.159841 0.5 --0.0266839 0.0458556 -0.027274 0.610127 0.5 --0.0146368 0.0981541 -0.0264318 0.44201 0.5 --0.0213468 0.10077 -0.0239588 0.58675 0.5 -0.020932 0.0825954 -0.0267347 0.750174 0.5 -0.00759225 0.0928541 -0.0309237 0.580726 0.5 --0.0144478 0.0879274 -0.0380297 0.689122 0.5 --0.00859724 0.11451 -0.0173132 0.77831 0.5 -0.0264818 0.109935 -0.0126182 0.652634 0.5 --0.0145855 0.0385179 -0.0267991 0.230538 0.5 --0.0330054 0.0337044 -0.0272991 0.262513 0.5 --0.0267872 0.0340475 -0.0271901 0.244173 0 --0.00849157 0.0985859 -0.0270535 0.53889 0.411612 --0.0110954 0.120824 -0.0120135 0.770076 0.5 -0.0367379 0.0925992 -0.0129888 0.684003 0.5 --0.0571635 0.0435755 -0.00717607 0.581004 0.404197 --0.0193328 0.0979251 -0.024792 0.661276 0.5 --0.0203798 0.0385467 -0.0283088 0.392689 0.5 --0.0587681 0.0337133 -0.00871891 0.1361 0.5 --0.0517919 0.100655 -0.0213258 0.798237 0.5 -0.00702627 0.0978418 -0.0246055 0.732067 0.326346 --0.0148892 0.126068 -0.00252126 0.467449 0.5 -0.0307578 0.092446 -0.0188519 0.704525 0.5 -0.0211049 0.0578126 -0.0266116 0.685576 0.5 --0.0169237 0.0970481 -0.0278718 0.775366 0.5 -0.0460004 0.0581866 -0.00508589 0.612698 0.5 --0.00944331 0.0822271 -0.0381067 0.670336 0.467319 --0.0635881 0.0392124 -0.00717766 0.572252 0.5 -0.00864227 0.0386371 -0.0233053 0.540697 0.5 -0.0252935 0.0769557 -0.0248407 0.75695 0.5 --0.0229653 0.0895159 -0.036199 0.454072 0.467569 --0.0523791 0.0341193 -0.00994653 0.132813 0.5 -0.0211693 0.0643935 -0.0268578 0.690366 0.5 --0.0515867 0.13164 -0.0028092 0.545448 0.5 --0.0149669 0.0345529 -0.0254273 0.17846 0.5 --0.0161167 0.127288 0.00169291 0.694465 0.5 --0.0469232 0.128515 -0.00163965 0.389857 0.5 --0.00961381 0.127158 -0.00378809 0.714685 0.5 --0.0074566 0.128562 -0.00130751 0.72817 0.5 --0.00304493 0.128909 -0.00174857 0.778769 0.5 -0.0028379 0.129022 -0.00194723 0.574275 0.5 -0.00903363 0.128674 -0.00165013 0.617309 0.5 --0.0561607 0.131588 -0.00571429 0.687735 0.5 --0.0457551 0.127167 -0.00484962 0.645893 0.5 --0.00304746 0.127678 -0.00456004 0.562309 0.5 -0.00303811 0.12768 -0.00442 0.624596 0.5 -0.0101526 0.126812 -0.00466464 0.64326 0.5 --0.0553259 0.126836 -0.00601308 0.517644 0.5 -0.00799473 0.034846 -0.0206913 0.278473 0.5 -0.0027179 0.0342191 -0.0204737 0.322372 0.5 --0.00295804 0.0342418 -0.0216222 0.194059 0.5 -0.0134674 0.0353221 -0.0196961 0.466171 0.5 -0.00440963 0.0383063 -0.0240776 0.3469 0.5 -0.00140752 0.0383474 -0.0246147 0.361099 0.5 --0.00309177 0.0383877 -0.0251866 0.314174 0.5 --0.0575023 0.100661 -0.0195211 0.459895 0.452391 --0.0485739 0.15316 -0.00547278 0.691758 0.5 --0.0646573 0.0334831 -0.00296009 0.187639 0.5 --0.0640796 0.100426 -0.0173936 0.44544 0.466101 --0.0704415 0.100139 -0.0146037 0.499781 0.478548 --0.0326376 0.155806 -0.00949884 0.828995 0.5 -0.0336094 0.0373624 0.00273412 0.290019 0.5 -0.0320943 0.0397885 -0.00195136 0.323719 0.5 -0.0158502 0.0449602 -0.0237212 0.910511 0.5 -0.00889467 0.0426449 -0.0242659 0.891863 0.5 -0.00312499 0.0452721 -0.026588 0.665265 0.460024 --0.00298345 0.044686 -0.0272222 0.905955 0.5 --0.00912346 0.0448524 -0.0280671 0.895801 0.5 --0.0145351 0.0443266 -0.0277771 0.887903 0.5 --0.0209223 0.0460913 -0.0281918 0.705844 0.5 -0.034052 0.0448434 -0.00540113 0.626363 0.5 --0.0312646 0.158257 -0.01223 0.732334 0.5 -0.0401509 0.0448981 -0.00354586 0.446696 0.5 -0.0143253 0.0473484 -0.0251513 0.546545 0.456757 -0.00937888 0.0466526 -0.0261685 0.907397 0.5 --0.0766531 0.0695423 0.0207982 0.774152 0.5 -0.0087246 0.0517916 -0.0291615 0.840924 0.5 -0.00299372 0.0506927 -0.0298557 0.901259 0.5 --0.00164566 0.0489436 -0.0304144 0.872257 0.5 --0.00321397 0.0522596 -0.0314075 0.634884 0.475184 --0.00915341 0.0509217 -0.0318681 0.650022 0.5 --0.0146018 0.0513752 -0.0319045 0.891033 0.5 --0.0161558 0.0488543 -0.0303763 0.808351 0.5 --0.0205843 0.0508011 -0.0296435 0.813106 0.5 -0.0405252 0.0518855 -0.00654453 0.65569 0.5 -0.0149309 0.0520772 -0.0273859 0.655547 0.5 -0.041884 0.0490868 -0.00604367 0.898378 0.5 -0.019962 0.0529908 -0.0261219 0.592286 0.5 --0.0198501 0.0534234 -0.0312267 0.768335 0.5 --0.0336273 0.0527187 -0.0106243 0.102172 0.5 --0.0461112 0.0529158 -0.0101664 0.636429 0.372142 --0.0204 0.161875 -0.014658 0.822907 0.5 -0.0449924 0.0530898 -0.00614891 0.575737 0.5 -0.00733679 0.0546532 -0.0305038 0.688621 0.5 -0.00283568 0.0546532 -0.0307468 0.611749 0.5 --0.00302245 0.0577 -0.0331477 0.67582 0.5 --0.00914668 0.0576676 -0.0341165 0.698389 0.5 --0.01517 0.058199 -0.0349877 0.856637 0.5 --0.0202707 0.0581031 -0.0333681 0.552506 0.5 -0.0140844 0.057965 -0.028983 0.564173 0.483714 -0.0103301 0.0588553 -0.0299472 0.602031 0.489059 -0.00732823 0.0588898 -0.0306117 0.710141 0.5 -0.0027369 0.0590151 -0.0321928 0.690932 0.5 --0.0337187 0.0579742 -0.0115824 0.143826 0.5 --0.0390711 0.0582467 -0.0115033 0.780735 0.5 --0.0460474 0.0579124 -0.0115174 0.472305 0.5 --0.00961439 0.0642168 -0.0358564 0.670518 0.457134 --0.044157 0.0599825 -0.0123877 0.830365 0.5 -0.015251 0.0645803 -0.029567 0.626368 0.396114 -0.00839294 0.0649214 -0.0316957 0.79033 0.385997 -0.00325858 0.0643529 -0.0332439 0.728322 0.418376 --0.00361257 0.0645861 -0.034907 0.670644 0.5 --0.0144709 0.065006 -0.0371603 0.712311 0.5 --0.0366623 0.060679 -0.0122791 0.525705 0.5 --0.0526404 0.0636402 -0.0101297 0.452904 0.5 --0.0381866 0.0648919 -0.0142073 0.543504 0.5 --0.0452495 0.0647856 -0.0139819 0.883769 0.5 --0.0599262 0.0622966 -0.00429285 0.195385 0.344922 --0.0778641 0.117463 -0.00576778 0.523105 0.5 --0.0187447 0.0664151 -0.0374779 0.820087 0.5 --0.0577616 0.0644884 -0.00779097 0.472929 0.5 --0.0625778 0.0655353 -0.00741131 0.379588 0.453283 -0.0251088 0.0710945 -0.0248604 0.704567 0.5 -0.021457 0.0702729 -0.0273415 0.740248 0.5 -0.0166747 0.0701586 -0.0297203 0.658948 0.5 -0.0132745 0.0702643 -0.0312074 0.651019 0.5 -0.00867525 0.0703509 -0.0324278 0.818076 0.5 -0.00229643 0.0708694 -0.0343123 0.73028 0.5 --0.0030646 0.070381 -0.0353565 0.764349 0.5 --0.00773679 0.0691749 -0.0362051 0.757441 0.5 --0.0101988 0.0715122 -0.0373778 0.76291 0.5 --0.0147454 0.0704429 -0.0382943 0.581028 0.470136 --0.0203984 0.0706516 -0.038158 0.645161 0.5 --0.0240967 0.0693418 -0.0362521 0.4533 0.5 --0.0605175 0.0673597 -0.0108259 0.635082 0.5 --0.0387293 0.0706355 -0.0168457 0.666323 0.5 --0.0451347 0.0705064 -0.0164504 0.875899 0.5 --0.0523435 0.0697862 -0.0145984 0.401473 0.5 --0.0591515 0.0702891 -0.0147203 0.639534 0.5 --0.0652515 0.0688492 -0.00993982 0.422384 0.422462 --0.0247614 0.0719777 -0.0368317 0.497524 0.5 --0.0637884 0.0712697 -0.0138535 0.437166 0.5 -0.0211454 0.0769268 -0.0268772 0.737516 0.5 -0.0162128 0.0765268 -0.0293784 0.712202 0.5 -0.0133247 0.0760196 -0.0306715 0.679361 0.5 -0.00907695 0.076038 -0.0330382 0.719764 0.5 -0.00245085 0.0760857 -0.0351615 0.721395 0.5 --0.00176321 0.0762288 -0.0360688 0.799862 0.5 --0.00476487 0.076286 -0.0369742 0.814155 0.377247 --0.00962992 0.0765936 -0.0378651 0.627364 0.487104 --0.0144481 0.0764118 -0.0385775 0.832444 0.5 --0.021453 0.0763574 -0.038668 0.751656 0.5 --0.024977 0.0762484 -0.0374518 0.39297 0.457854 --0.0377453 0.0766164 -0.0189124 0.273711 0.5 --0.0397395 0.0746623 -0.0180255 0.973337 0.5 --0.0437423 0.0765905 -0.0187922 0.595439 0.440211 --0.0466377 0.0744845 -0.0173668 0.538698 0.468502 --0.0518623 0.0745812 -0.0175084 0.855826 0.5 --0.0589866 0.0745368 -0.01766 0.879682 0.5 --0.0644081 0.0756279 -0.0167529 0.562234 0.481782 --0.0721295 0.0740256 -0.0105719 0.341576 0.432723 --0.0615233 0.0354132 0.043881 0.499903 0.5 --0.0524971 0.0769872 -0.0189536 0.873913 0.5 --0.0587482 0.0767445 -0.0187462 0.882838 0.5 -0.013102 0.0809953 -0.0307917 0.69611 0.5 -0.00892296 0.0820652 -0.0325478 0.700162 0.5 -0.0022917 0.0820297 -0.0349279 0.829579 0.5 --0.00177837 0.0804805 -0.0364471 0.647084 0.379833 --0.00379684 0.0824193 -0.037328 0.824332 0.5 --0.0142988 0.0820384 -0.0390211 0.832022 0.373406 --0.0207708 0.0823862 -0.0387335 0.805306 0.5 --0.0248089 0.0818968 -0.0377031 0.470046 0.439483 --0.0735819 0.0777026 -0.0122023 0.445372 0.5 -0.015425 0.0831288 -0.0295207 0.735694 0.5 --0.0383994 0.0817919 -0.0209596 0.290803 0.5 --0.0451184 0.0815526 -0.020434 0.548777 0.45056 --0.051814 0.0818472 -0.0211348 0.886135 0.5 --0.0583689 0.0812724 -0.0202975 0.847354 0.5 --0.063949 0.082768 -0.0188935 0.606874 0.5 --0.0662709 0.080065 -0.0177832 0.593549 0.449354 --0.0695594 0.0830593 -0.0170582 0.4495 0.5 --0.00481814 0.086841 -0.0367951 0.827149 0.5 --0.0248206 0.0867524 -0.0367639 0.487957 0.5 -0.0132046 0.0871602 -0.0305473 0.663835 0.5 --0.0360837 0.0867076 -0.023791 0.366486 0.5 --0.00877843 0.0340556 -0.0204927 0 0 --0.0207128 0.0342382 -0.0208728 0.319674 0.5 --0.0147915 0.0341096 -0.0207616 0.312592 0.5 --0.0265767 0.0342963 -0.0210989 0.482378 0.5 -0.00282685 0.0351053 -0.0158136 0.508357 0.5 -0.00885967 0.034471 -0.0147487 0.490133 0.5 --0.0390848 0.0337228 -0.0202617 0.628543 0.5 --0.0326656 0.0345334 -0.0201874 0.788348 0.5 --0.00224535 0.0351539 -0.0166234 0.756398 0.5 --0.0149096 0.0357313 -0.0180956 0.933106 0.5 --0.0114808 0.0353662 -0.0177045 0.933613 0.5 --0.00921575 0.0380183 -0.0149732 0.909294 0.5 --0.00282494 0.0382292 -0.0140636 0.920543 0.5 -0.00285919 0.0377324 -0.0134715 0.965028 0.5 -0.0159109 0.0347098 -0.00882204 0.420938 0.5 --0.0306839 0.036693 -0.0184598 0.875112 0.5 --0.0265216 0.0367471 -0.0188177 0.84266 0.5 --0.0218341 0.0369718 -0.0184303 0.873319 0.5 --0.0203027 0.0382765 -0.0152577 0.887215 0.5 --0.0152596 0.0382328 -0.0156428 0.873575 0.5 -0.00738356 0.0366172 -0.0125003 0.962688 0.5 -0.00992361 0.0351979 -0.00924624 0.9642 0.5 -0.00702596 0.0378387 -0.00879015 0.927286 0.5 --0.0396958 0.0342843 -0.014578 0.76643 0.5 --0.0329517 0.0382154 -0.014678 0.654319 0.5 --0.0263862 0.0385778 -0.0153644 0.924592 0.5 -0.00320835 0.0389424 -0.00953857 0.945732 0.5 --0.0364387 0.0357946 -0.0155844 0.543249 0.5 --0.00301526 0.0391061 -0.00886496 0.816802 0.5 -0.00831664 0.0348156 -0.00321961 0.671683 0.5 -0.0145039 0.0343685 -0.0028433 0.748562 0.5 --0.0365752 0.0370276 -0.0136534 0.498247 0.5 --0.0146234 0.0388055 -0.00887465 0.759701 0.5 --0.00886749 0.0389394 -0.00890173 0.761944 0.5 --0.0451032 0.0336721 -0.00848668 0.772585 0.5 --0.040313 0.0350801 -0.00861758 0.462745 0.5 --0.0206235 0.0386 -0.00878063 0.747754 0.5 -0.00267879 0.038424 -0.00319748 0.448355 0.5 -0.015044 0.0350517 0.00289039 0.579133 0.5 -0.0201479 0.0347806 0.00348327 0.403273 0.5 -0.027119 0.0353514 0.00366834 0.0909279 0.5 -0.0280785 0.0365531 0.000826759 0 0 --0.0376066 0.0375692 -0.00942418 0.22755 0.5 --0.0332748 0.0384549 -0.00855692 0.752109 0.5 --0.0264541 0.0384497 -0.00886193 0.729343 0.5 --0.00299262 0.0389582 -0.00292437 0.746846 0.5 -0.00451408 0.0356078 -0.00103635 0.413486 0.5 -0.00881079 0.0350428 0.00356828 0.588251 0.5 -0.0314184 0.0360255 0.00457907 0.187967 0.5 --0.00888202 0.0387884 -0.00299409 0.73859 0.5 -0.00271787 0.0349091 0.00339755 0.645421 0.5 --0.041199 0.0341471 -0.00327644 0 0 --0.0205479 0.0384259 -0.00283766 0.741413 0.5 --0.0146618 0.0385908 -0.00288739 0.718901 0.5 -0.00103528 0.0375917 0.000952222 0.441385 0.5 -0.0215747 0.0354906 0.0086194 0.395945 0.5 -0.0264794 0.0346514 0.00870654 0.414057 0.5 -0.0322391 0.0355412 0.00882378 0.515667 0.5 --0.0521057 0.0334794 -0.00318207 0.614129 0.5 --0.0455078 0.0336572 -0.00225818 0.757211 0.5 --0.0334104 0.0383259 -0.00292317 0.611245 0.5 --0.0265122 0.0383343 -0.00296504 0.763748 0.5 --0.00224847 0.0383354 0.00320971 0.728422 0.5 --0.0589386 0.0334143 -0.00291301 0.444064 0.5 --0.00874044 0.0385976 0.00291227 0.735039 0.5 -0.00273457 0.0342734 0.0088248 0.796819 0.5 -0.00621941 0.0351341 0.00654928 0 0 --0.080018 0.109279 0.0373655 0.503151 0.426569 --0.0393178 0.0336443 0.00354096 0.266658 0.5 --0.0213111 0.0382973 0.00334866 0.753895 0.5 --0.0146196 0.0384265 0.00290922 0.762157 0.5 --0.00353554 0.0379644 0.00874752 0.658939 0.5 -0.0276681 0.0349662 0.0149532 0.360666 0.5 -0.03282 0.0359255 0.0147037 0.719837 0.5 -0.0389763 0.0383079 0.0145025 0.635106 0.5 --0.0523961 0.0335249 0.00326874 0.742717 0.5 --0.0462346 0.0335696 0.00267776 0.743661 0.5 --0.0277984 0.0382296 0.00286126 0.456211 0.5 --0.000947006 0.0357374 0.0103469 0.779853 0.5 -0.0222276 0.0358262 0.0160256 0.180494 0.5 -0.0448051 0.0411192 0.0150961 0.294679 0.5 --0.0581064 0.033504 0.00272997 0.775526 0.5 --0.0352323 0.0337248 0.00491425 0.152905 0 --0.0312985 0.0381858 0.00167702 0 0 --0.0088641 0.03847 0.00876261 0.73345 0.5 -0.0028919 0.0342894 0.0147059 0.676527 0.5 --0.0703332 0.0340583 0.00286723 0.639535 0.5 --0.0648245 0.0334924 0.00301734 0.793089 0.5 --0.0387963 0.034763 0.00935652 0.458758 0.5 --0.0332327 0.0337932 0.00943608 0.151116 0.5 --0.0203456 0.0382265 0.00836296 0.759992 0.5 --0.0152156 0.0383161 0.00935801 0.755179 0.5 --0.000385714 0.0351459 0.0134171 0.848157 0.5 -0.00663645 0.0342324 0.0159688 0 0 -0.0268074 0.0356469 0.0204126 0.619176 0.5 -0.0309391 0.0362152 0.0189937 0.762661 0.5 -0.0334119 0.0376179 0.0210082 0.70177 0.5 --0.0515734 0.0338904 0.00817232 0.493124 0.5 --0.0454999 0.0352808 0.00804865 0.53914 0.5 --0.0263229 0.0380313 0.00871732 0.143858 0.5 --0.0031858 0.0377098 0.014513 0.797449 0.5 -0.0211051 0.0351552 0.0207004 0.432057 0.5 -0.0391983 0.0395969 0.0205879 0.670001 0.5 -0.0441778 0.0418755 0.0204802 0.609797 0.5 --0.0580282 0.0335624 0.00918162 0.776077 0.5 --0.00922404 0.0383488 0.0150261 0.754001 0.5 -0.00313746 0.0352426 0.0204176 0.692001 0.5 -0.00877508 0.0346179 0.020856 0.290121 0.5 -0.0468489 0.0434226 0.0210936 0.239557 0.5 --0.0648031 0.0337402 0.00884817 0.802283 0.5 --0.0338156 0.0345063 0.0150293 0.572312 0.5 --0.0149173 0.0382498 0.0147214 0.753708 0.5 -0.0146344 0.0345628 0.0222588 0.157065 0.5 --0.0365655 0.0357926 0.0130139 0.391807 0.5 --0.0262153 0.0376693 0.0148666 0.146481 0.5 --0.0205165 0.0381248 0.0146779 0.715632 0.5 --0.00229335 0.0382456 0.020565 0.923102 0.5 -0.014723 0.0347707 0.0263935 0.310145 0.5 -0.0210245 0.0353476 0.0265418 0.313898 0.5 -0.0250756 0.0364517 0.0246847 0.678097 0.5 -0.0273584 0.0381522 0.0267127 0.778478 0.5 -0.0321164 0.0401984 0.026762 0.778536 0.5 --0.053829 0.0335431 0.0139547 0.458851 0.5 -0.00114114 0.037661 0.0223414 0.978558 0.5 -0.00915473 0.0353589 0.0262457 0.701449 0.5 -0.0380552 0.0412819 0.02589 0.374179 0.417844 --0.0588034 0.0336951 0.0146283 0.798139 0.5 --0.0339319 0.0346253 0.0202274 0.513983 0.5 --0.0152545 0.0382629 0.0204704 0.75125 0.5 --0.00888844 0.0384087 0.0207206 0.746481 0.5 -0.00307272 0.0384964 0.0264151 0.996029 0.5 --0.0261643 0.0378491 0.0205422 0.603577 0.5 --0.0205429 0.0381473 0.0213758 0.772551 0.5 --0.0538188 0.0335608 0.0210581 0 0 --0.00301594 0.03875 0.0263901 0.805634 0.5 -0.00756209 0.0380712 0.0285007 0.978659 0.5 -0.0143741 0.0348327 0.0331833 0.915728 0.5 -0.0198279 0.03555 0.0321213 0.749506 0.5 -0.0236875 0.0373106 0.0299772 0.517201 0.5 --0.0588476 0.033906 0.020465 0.657735 0.5 --0.00882687 0.0386047 0.0265705 0.756827 0.5 -0.00847025 0.0383344 0.0315598 0.739987 0.5 -0.0108958 0.035647 0.0330663 0.649316 0.5 --0.0366651 0.0353042 0.023032 0.153172 0.5 --0.0340084 0.0344659 0.0266224 0.263742 0.5 --0.0270447 0.0379104 0.0270529 0.074682 0.5 --0.0210471 0.0383013 0.026282 0.782021 0.5 --0.0147317 0.0384888 0.0265233 0.791552 0.5 --0.0712786 0.0733348 0.0355839 0.683322 0.427231 --0.0388887 0.0346255 0.0265538 0.109729 0 -0.00290004 0.0393205 0.032168 0.626516 0.5 -0.0155389 0.0350901 0.0393977 0.759188 0.5 -0.0195159 0.0358111 0.0367948 0.405286 0.5 --0.0589139 0.0341314 0.0264586 0.808252 0.5 --0.052234 0.0340737 0.0268887 0.497915 0.5 --0.0447866 0.0339274 0.0274346 0.154159 0.5 --0.0310127 0.0369382 0.02848 0.240675 0.5 --0.00908756 0.0390146 0.0330901 0.79352 0.5 --0.00293287 0.039209 0.03365 0.804769 0.5 -0.00861952 0.0346654 0.0391536 0.125418 0.5 --0.0149144 0.0388312 0.0324344 0.795183 0.5 -0.00392423 0.0347398 0.0399064 0.146347 0.5 --0.0657827 0.0618455 0.00187562 0.442355 0.5 --0.0640051 0.0606097 0.00361345 0.333039 0.5 --0.0455164 0.0345095 0.0326748 0.510388 0.5 --0.0385699 0.0344168 0.033204 0.485482 0.5 --0.0342024 0.0351611 0.0325685 0.248514 0.5 --0.0270303 0.0384799 0.0326469 0.783767 0.5 --0.0209433 0.0387397 0.0332273 0.806699 0.5 --0.0520994 0.0344582 0.0326775 0.466807 0.5 --0.0313489 0.0377268 0.0321213 0.178238 0.5 --0.00219023 0.0348305 0.0410082 0.139343 0 -0.00818206 0.0355366 0.0443043 0.642932 0.5 -0.014947 0.0361331 0.0431407 0.796588 0.5 --0.0642564 0.0597236 0.0092932 0.716255 0.5 --0.0584732 0.0343588 0.0331559 0.775713 0.5 --0.0145859 0.0393004 0.0380317 0.483641 0.5 --0.00937548 0.0394517 0.037871 0.328321 0.5 --0.0588297 0.0579582 0.0145443 0 0 --0.038732 0.0346956 0.0400227 0.628019 0.5 --0.0331487 0.034492 0.0390527 0.154826 0.5 --0.0201914 0.0391628 0.0381696 0.483919 0.5 --0.00878985 0.0348233 0.0452949 0.139305 0.5 --0.0031441 0.0351515 0.045825 0.295611 0.5 --0.0701619 0.0622789 0.00863964 0.42197 0.408074 --0.0451191 0.034688 0.0396457 0.766116 0.5 --0.0256628 0.0389081 0.0373249 0 0 --0.0146115 0.0348173 0.0458198 0.143796 0.5 --0.0636462 0.0593677 0.014889 0.807508 0.5 --0.0531671 0.0345191 0.0391729 0.74918 0.5 --0.0595372 0.034497 0.0397515 0.783724 0.5 --0.0329555 0.0349777 0.045552 0.474674 0.5 --0.0262436 0.034809 0.0452831 0.162616 0.5 --0.0215554 0.0348112 0.0459347 0.152356 0 --0.0633407 0.0601272 0.0190813 0.939061 0.5 --0.0471 0.0351015 0.0434178 0.627709 0.5 --0.0120723 0.0353434 0.0494553 0.877126 0.5 --0.016313 0.0351836 0.0504037 0.67915 0.5 --0.0483699 0.146034 -0.00115148 0.583019 0.5 --0.0264335 0.156562 -0.00835956 0.469485 0.437523 --0.065003 0.144791 -0.0142909 0.400803 0.470167 --0.066228 0.151547 -0.0394609 0.538048 0.5 --0.0663323 0.145309 -0.018858 0.764025 0.5 --0.0412403 0.152108 -0.00674014 0.633348 0.5 -3 4 132 80 -3 80 132 544 -3 373 80 544 -3 387 299 241 -3 859 1475 1474 -3 371 299 401 -3 401 326 333 -3 347 673 402 -3 1187 1354 386 -3 1221 457 69 -3 186 224 114 -3 1250 1256 116 -3 164 333 376 -3 19 488 1245 -3 749 19 1245 -3 667 19 749 -3 1040 412 543 -3 1359 1358 1500 -3 216 4 80 -3 152 544 146 -3 4 387 505 -3 543 1235 1205 -3 610 604 297 -3 250 801 1274 -3 504 148 111 -3 387 348 299 -3 401 333 164 -3 1484 1483 1110 -3 91 196 310 -3 90 91 310 -3 952 406 609 -3 1244 1247 1240 -3 93 327 65 -3 373 544 152 -3 373 152 644 -3 1321 158 22 -3 401 416 326 -3 644 152 1263 -3 276 59 181 -3 294 853 150 -3 308 249 529 -3 406 1124 604 -3 609 406 463 -3 146 3 145 -3 90 310 3 -3 58 186 10 -3 575 261 384 -3 25 40 43 -3 379 535 713 -3 348 704 157 -3 388 443 22 -3 396 146 145 -3 152 133 1263 -3 1830 1829 1812 -3 214 114 224 -3 157 147 324 -3 1335 430 1274 -3 282 230 214 -3 92 346 652 -3 1151 1012 1491 -3 571 1151 1491 -3 571 1491 183 -3 310 196 111 -3 91 4 505 -3 1250 116 108 -3 110 183 47 -3 1209 854 953 -3 132 4 91 -3 111 148 327 -3 93 111 327 -3 110 571 183 -3 713 171 402 -3 294 920 200 -3 81 180 52 -3 525 731 784 -3 347 256 673 -3 175 57 220 -3 338 175 220 -3 27 14 220 -3 57 27 220 -3 359 446 27 -3 359 36 446 -3 145 28 262 -3 133 16 419 -3 1447 576 1465 -3 1885 287 444 -3 133 396 16 -3 598 543 1205 -3 447 93 65 -3 73 213 36 -3 1236 1255 1250 -3 1235 1236 1250 -3 115 782 731 -3 28 93 447 -3 525 548 115 -3 299 416 401 -3 667 603 463 -3 292 667 463 -3 492 70 637 -3 133 146 396 -3 1166 1125 619 -3 1151 1219 959 -3 821 304 409 -3 1486 1487 1684 -3 15 175 167 -3 120 15 167 -3 15 131 57 -3 175 15 57 -3 57 131 27 -3 257 209 359 -3 27 257 359 -3 209 55 36 -3 359 209 36 -3 55 87 73 -3 36 55 73 -3 101 108 735 -3 108 101 64 -3 310 365 3 -3 576 859 1465 -3 262 28 447 -3 102 64 101 -3 544 91 90 -3 262 447 485 -3 485 447 211 -3 1443 1440 1442 -3 697 457 1221 -3 1008 383 1011 -3 451 435 1330 -3 129 405 426 -3 70 75 161 -3 648 693 692 -3 204 129 426 -3 812 481 123 -3 406 292 463 -3 878 1591 1009 -3 478 128 50 -3 900 979 977 -3 490 900 977 -3 241 299 371 -3 1164 701 734 -3 683 703 682 -3 719 718 682 -3 703 719 682 -3 760 759 718 -3 719 760 718 -3 137 729 728 -3 54 130 2 -3 302 358 301 -3 566 567 614 -3 1069 1103 1068 -3 1186 1190 1208 -3 4 348 387 -3 277 311 228 -3 707 226 706 -3 355 394 393 -3 773 129 755 -3 646 647 679 -3 356 355 269 -3 270 356 269 -3 424 394 356 -3 623 654 602 -3 654 683 602 -3 193 217 192 -3 1677 1676 1662 -3 1018 1019 1025 -3 597 1231 1165 -3 490 26 605 -3 299 157 416 -3 504 241 148 -3 84 528 714 -3 1247 669 1240 -3 683 719 703 -3 1886 1231 1066 -3 79 168 218 -3 211 318 426 -3 165 377 148 -3 91 505 387 -3 577 623 622 -3 692 693 707 -3 255 254 218 -3 194 270 255 -3 695 137 728 -3 1475 1498 1474 -3 67 808 1010 -3 1190 240 1208 -3 242 259 300 -3 476 509 567 -3 743 755 558 -3 1025 1024 1018 -3 194 255 218 -3 270 269 254 -3 203 271 12 -3 603 667 749 -3 1379 1395 1392 -3 783 546 1340 -3 578 600 577 -3 624 623 577 -3 600 624 577 -3 655 654 623 -3 684 683 654 -3 655 684 654 -3 720 719 683 -3 684 720 683 -3 720 739 719 -3 761 760 719 -3 739 761 719 -3 218 254 253 -3 694 695 437 -3 255 270 254 -3 1202 488 19 -3 412 1222 543 -3 60 528 84 -3 1352 494 702 -3 624 655 623 -3 1361 221 143 -3 755 129 204 -3 132 91 544 -3 543 1221 1235 -3 216 5 4 -3 1221 1236 1235 -3 754 755 204 -3 1169 732 715 -3 756 755 743 -3 1036 1035 1024 -3 728 756 743 -3 476 567 508 -3 4 5 348 -3 244 1339 546 -3 405 445 211 -3 254 269 268 -3 253 254 268 -3 381 358 302 -3 346 92 59 -3 517 450 1560 -3 1618 1333 141 -3 1498 1497 1474 -3 1231 597 1165 -3 228 264 215 -3 100 151 99 -3 151 215 99 -3 151 228 215 -3 1864 827 1870 -3 561 578 480 -3 207 561 480 -3 579 600 578 -3 561 579 578 -3 600 625 624 -3 656 655 624 -3 625 656 624 -3 685 684 655 -3 656 685 655 -3 685 721 720 -3 684 685 720 -3 721 740 739 -3 720 721 739 -3 739 740 761 -3 762 789 788 -3 761 762 788 -3 789 239 770 -3 788 789 770 -3 328 770 239 -3 423 424 476 -3 121 195 522 -3 423 476 422 -3 381 431 358 -3 148 371 401 -3 579 625 600 -3 465 464 431 -3 381 465 431 -3 464 465 227 -3 248 11 71 -3 548 142 1005 -3 740 762 761 -3 767 900 490 -3 728 743 437 -3 776 195 121 -3 1177 1176 1153 -3 1043 1034 1035 -3 137 708 729 -3 91 387 196 -3 1721 1729 1703 -3 728 729 756 -3 727 728 437 -3 196 387 241 -3 404 458 522 -3 355 354 268 -3 647 648 692 -3 979 846 901 -3 241 371 148 -3 142 1155 574 -3 269 355 268 -3 358 301 300 -3 301 358 300 -3 753 754 793 -3 184 229 228 -3 229 277 228 -3 312 311 277 -3 1845 1853 1831 -3 1523 1532 1153 -3 580 579 561 -3 1276 1280 1771 -3 580 626 625 -3 579 580 625 -3 626 657 656 -3 625 626 656 -3 656 657 685 -3 722 721 685 -3 741 740 721 -3 722 741 721 -3 740 763 762 -3 790 789 762 -3 763 790 762 -3 790 339 239 -3 789 790 239 -3 377 165 327 -3 476 508 422 -3 259 301 300 -3 162 170 169 -3 81 162 169 -3 580 561 562 -3 657 686 685 -3 229 312 277 -3 28 365 93 -3 1263 419 1254 -3 396 145 144 -3 685 686 722 -3 741 763 740 -3 133 152 146 -3 1263 133 419 -3 207 520 562 -3 520 562 580 -3 562 520 580 -3 562 626 580 -3 239 339 487 -3 597 1063 1066 -3 3 365 28 -3 649 648 615 -3 108 64 116 -3 571 1225 1218 -3 184 185 229 -3 313 312 229 -3 185 313 229 -3 439 501 520 -3 501 581 562 -3 520 501 562 -3 627 626 562 -3 581 627 562 -3 627 628 626 -3 658 657 626 -3 628 658 626 -3 658 675 657 -3 687 686 657 -3 675 687 657 -3 723 722 686 -3 687 723 686 -3 722 723 741 -3 741 723 763 -3 764 791 790 -3 763 764 790 -3 791 407 339 -3 790 791 339 -3 407 303 339 -3 303 487 339 -3 303 460 487 -3 303 325 460 -3 170 106 105 -3 105 106 68 -3 439 440 501 -3 723 764 763 -3 1 1027 453 -3 1067 511 942 -3 775 121 774 -3 1281 1270 1291 -3 368 440 439 -3 367 368 439 -3 582 581 501 -3 628 627 581 -3 658 688 687 -3 675 658 687 -3 1733 1562 1561 -3 757 775 756 -3 74 68 46 -3 398 1223 317 -3 631 607 231 -3 1465 859 1474 -3 1775 1784 1754 -3 204 138 793 -3 74 122 97 -3 584 533 570 -3 278 313 185 -3 265 278 185 -3 369 368 313 -3 278 369 313 -3 369 440 368 -3 502 501 440 -3 583 582 501 -3 502 583 501 -3 583 581 582 -3 629 628 581 -3 583 629 581 -3 629 659 658 -3 628 629 658 -3 658 659 688 -3 724 723 687 -3 688 724 687 -3 724 742 723 -3 742 765 764 -3 723 742 764 -3 764 238 791 -3 791 238 407 -3 407 238 303 -3 238 333 303 -3 333 325 303 -3 614 615 647 -3 46 122 74 -3 606 199 112 -3 441 440 369 -3 83 173 573 -3 775 776 121 -3 846 979 901 -3 441 502 440 -3 659 689 688 -3 84 714 1367 -3 535 52 171 -3 551 798 1883 -3 630 629 583 -3 629 630 659 -3 689 724 688 -3 792 238 764 -3 765 792 764 -3 1207 1208 177 -3 195 96 522 -3 122 13 97 -3 344 492 637 -3 1025 1036 1024 -3 775 774 756 -3 1012 1151 959 -3 1270 1372 1291 -3 145 3 28 -3 649 670 695 -3 517 1888 243 -3 444 399 1885 -3 370 369 278 -3 724 765 742 -3 376 333 238 -3 1372 1375 1291 -3 1060 1161 1162 -3 16 396 144 -3 369 442 441 -3 583 601 630 -3 690 689 659 -3 318 295 427 -3 138 204 427 -3 693 694 707 -3 310 111 365 -3 365 111 93 -3 636 660 659 -3 567 566 508 -3 426 405 211 -3 121 126 774 -3 471 601 583 -3 251 237 188 -3 1303 188 237 -3 278 314 370 -3 370 442 369 -3 442 503 502 -3 441 442 502 -3 503 471 583 -3 502 503 583 -3 858 302 259 -3 16 144 319 -3 660 690 659 -3 690 725 724 -3 689 690 724 -3 750 765 724 -3 725 750 724 -3 8 792 765 -3 750 8 765 -3 376 238 792 -3 8 376 792 -3 164 376 238 -3 376 164 238 -3 1381 1380 1375 -3 1135 1134 1103 -3 1104 1135 1103 -3 794 204 793 -3 447 65 211 -3 442 1347 503 -3 249 262 485 -3 1036 1043 1035 -3 522 96 438 -3 204 426 427 -3 188 283 251 -3 1235 1250 1205 -3 485 262 23 -3 597 1066 1165 -3 144 308 319 -3 1027 767 589 -3 648 649 694 -3 567 615 614 -3 821 409 304 -3 63 711 903 -3 8 164 376 -3 12 478 50 -3 171 347 402 -3 284 1327 314 -3 1447 1465 1459 -3 1456 1447 1459 -3 1329 1328 1380 -3 755 756 773 -3 756 774 773 -3 193 218 253 -3 648 694 693 -3 168 194 218 -3 190 188 189 -3 284 283 188 -3 190 284 188 -3 283 284 314 -3 262 485 23 -3 108 116 64 -3 751 750 725 -3 726 751 725 -3 751 771 750 -3 37 8 750 -3 771 37 750 -3 632 164 8 -3 569 53 411 -3 511 1560 1884 -3 386 1354 1320 -3 165 632 8 -3 37 165 8 -3 165 164 632 -3 662 661 638 -3 354 393 422 -3 401 165 148 -3 979 1883 798 -3 144 145 262 -3 413 408 349 -3 16 319 669 -3 318 211 295 -3 156 1213 198 -3 1153 1152 1119 -3 1225 1448 247 -3 190 266 284 -3 419 669 1247 -3 479 233 232 -3 166 165 37 -3 709 492 344 -3 567 568 615 -3 107 827 1864 -3 695 727 437 -3 485 211 23 -3 1254 419 1247 -3 419 16 669 -3 1884 1591 1009 -3 249 485 24 -3 41 249 24 -3 1103 1134 1133 -3 272 398 492 -3 754 204 794 -3 1498 159 113 -3 24 485 23 -3 1102 1103 1133 -3 308 144 249 -3 164 165 401 -3 692 707 706 -3 509 568 567 -3 191 252 190 -3 190 252 266 -3 252 285 284 -3 266 252 284 -3 285 286 284 -3 284 286 337 -3 144 262 249 -3 536 564 563 -3 563 564 593 -3 564 612 611 -3 593 564 611 -3 645 361 611 -3 612 645 611 -3 645 691 1313 -3 309 752 751 -3 726 309 751 -3 752 772 771 -3 751 752 771 -3 119 37 771 -3 772 119 771 -3 425 166 37 -3 119 425 37 -3 380 165 166 -3 425 380 166 -3 128 83 17 -3 50 128 17 -3 729 757 756 -3 394 423 422 -3 589 767 490 -3 424 509 476 -3 1374 1359 1531 -3 408 372 349 -3 679 692 706 -3 855 242 300 -3 766 757 730 -3 354 355 393 -3 79 218 193 -3 129 126 405 -3 126 458 405 -3 647 692 679 -3 757 766 775 -3 766 776 775 -3 1699 1014 1013 -3 393 394 422 -3 252 286 285 -3 752 119 772 -3 425 327 380 -3 696 730 729 -3 708 696 729 -3 649 695 694 -3 78 79 193 -3 1497 1498 113 -3 901 979 798 -3 404 24 445 -3 24 23 445 -3 776 795 195 -3 1340 1591 1884 -3 1035 1034 1024 -3 177 203 12 -3 380 327 425 -3 510 509 424 -3 477 510 424 -3 458 404 405 -3 192 217 252 -3 191 192 252 -3 217 267 286 -3 252 217 286 -3 286 267 352 -3 353 421 420 -3 352 353 420 -3 421 507 506 -3 506 507 536 -3 507 565 564 -3 536 507 564 -3 565 613 612 -3 564 565 612 -3 646 645 612 -3 613 646 612 -3 646 679 691 -3 645 646 691 -3 706 705 691 -3 679 706 691 -3 753 309 280 -3 138 119 752 -3 753 138 752 -3 427 425 119 -3 138 427 119 -3 295 380 425 -3 427 295 425 -3 65 327 380 -3 295 65 380 -3 769 104 315 -3 426 318 427 -3 568 616 615 -3 695 728 727 -3 404 445 405 -3 1635 1653 1453 -3 271 478 12 -3 839 136 830 -3 615 648 647 -3 311 277 228 -3 749 1245 1225 -3 353 392 421 -3 793 138 753 -3 315 104 33 -3 432 466 465 -3 381 432 465 -3 465 466 527 -3 1170 1190 1099 -3 754 794 793 -3 558 754 280 -3 193 253 217 -3 253 268 267 -3 217 253 267 -3 268 354 353 -3 267 268 353 -3 354 392 353 -3 422 421 392 -3 354 422 392 -3 422 508 507 -3 421 422 507 -3 508 566 565 -3 507 508 565 -3 614 613 565 -3 566 614 565 -3 614 647 646 -3 613 614 646 -3 168 810 194 -3 886 940 923 -3 946 945 930 -3 929 939 944 -3 940 569 887 -3 661 649 616 -3 320 919 878 -3 227 526 464 -3 882 873 866 -3 552 384 820 -3 464 927 358 -3 917 432 905 -3 879 829 820 -3 194 836 880 -3 935 466 432 -3 917 935 432 -3 1038 1725 1013 -3 1378 1391 1406 -3 173 448 293 -3 477 943 510 -3 616 568 617 -3 1405 550 980 -3 665 86 847 -3 891 906 912 -3 845 130 54 -3 999 925 822 -3 1885 928 555 -3 904 910 270 -3 315 33 478 -3 1033 1034 1042 -3 490 921 26 -3 850 257 131 -3 1070 1077 1034 -3 843 860 15 -3 120 843 15 -3 850 209 257 -3 914 913 300 -3 880 911 910 -3 641 661 616 -3 843 120 797 -3 860 870 15 -3 870 131 15 -3 870 850 131 -3 894 873 882 -3 811 248 875 -3 974 981 992 -3 850 201 131 -3 131 201 850 -3 850 201 209 -3 907 917 905 -3 694 437 226 -3 895 843 797 -3 870 860 843 -3 816 870 843 -3 870 201 850 -3 913 933 932 -3 968 969 986 -3 840 118 712 -3 816 843 895 -3 201 856 209 -3 856 845 55 -3 209 856 55 -3 931 930 911 -3 228 151 184 -3 1340 884 1884 -3 553 506 536 -3 539 867 842 -3 870 924 201 -3 977 823 490 -3 868 829 780 -3 999 1000 925 -3 198 701 156 -3 787 816 895 -3 924 877 856 -3 201 924 856 -3 877 845 856 -3 66 305 941 -3 769 203 1208 -3 848 847 919 -3 880 889 911 -3 1027 589 605 -3 957 816 787 -3 849 870 816 -3 957 849 816 -3 414 821 409 -3 1887 1004 928 -3 569 888 887 -3 459 384 552 -3 891 889 890 -3 839 892 891 -3 1080 1057 1051 -3 957 328 816 -3 328 957 816 -3 849 881 870 -3 881 849 870 -3 870 849 924 -3 481 531 123 -3 777 835 698 -3 891 892 906 -3 912 911 889 -3 891 912 889 -3 546 1339 746 -3 328 849 957 -3 849 88 924 -3 1043 1070 1034 -3 777 122 46 -3 477 929 943 -3 617 641 616 -3 822 915 72 -3 915 331 72 -3 834 806 956 -3 788 957 787 -3 770 788 787 -3 788 328 957 -3 864 877 924 -3 833 938 130 -3 845 833 130 -3 938 256 130 -3 1005 142 574 -3 661 676 137 -3 730 305 776 -3 1186 1208 1207 -3 1189 1186 1207 -3 798 1888 1067 -3 864 924 88 -3 864 922 877 -3 982 845 877 -3 922 982 877 -3 982 833 845 -3 894 905 873 -3 879 665 86 -3 879 665 847 -3 817 922 864 -3 833 982 922 -3 817 833 922 -3 894 907 905 -3 1562 1561 1038 -3 305 893 776 -3 899 864 88 -3 1071 1049 1072 -3 788 770 328 -3 776 768 795 -3 835 919 847 -3 817 864 899 -3 833 256 938 -3 1177 1195 1176 -3 1276 1771 1275 -3 155 100 813 -3 832 96 449 -3 879 384 665 -3 879 86 665 -3 834 956 320 -3 863 898 328 -3 826 849 328 -3 898 826 328 -3 849 826 88 -3 826 899 88 -3 1346 1883 900 -3 930 945 944 -3 939 930 944 -3 810 818 836 -3 838 836 837 -3 1077 1069 1034 -3 891 890 838 -3 1473 1680 1679 -3 44 24 438 -3 899 200 817 -3 1374 1391 1378 -3 466 935 527 -3 66 941 730 -3 913 906 912 -3 956 919 320 -3 662 676 661 -3 239 395 863 -3 395 898 863 -3 819 826 898 -3 826 200 899 -3 35 86 82 -3 880 270 194 -3 935 950 527 -3 670 661 695 -3 134 256 94 -3 818 837 836 -3 848 879 847 -3 395 819 898 -3 826 819 200 -3 200 920 817 -3 920 876 833 -3 817 920 833 -3 833 876 256 -3 1034 1069 1068 -3 932 933 947 -3 997 676 662 -3 836 889 880 -3 757 729 730 -3 956 806 919 -3 603 749 1460 -3 876 48 256 -3 827 107 155 -3 107 184 155 -3 830 855 841 -3 1042 1034 1068 -3 832 449 795 -3 997 662 638 -3 384 261 665 -3 997 696 676 -3 294 48 876 -3 920 294 876 -3 925 915 822 -3 1199 1231 1886 -3 941 305 730 -3 200 418 294 -3 569 940 886 -3 100 155 184 -3 840 712 331 -3 921 379 26 -3 1016 1014 1699 -3 776 766 730 -3 983 997 638 -3 676 696 137 -3 487 395 239 -3 487 819 395 -3 569 886 511 -3 940 887 923 -3 986 1000 985 -3 1125 110 47 -3 947 968 958 -3 842 874 834 -3 822 918 66 -3 985 999 998 -3 984 985 998 -3 999 822 998 -3 983 984 997 -3 984 998 997 -3 819 418 200 -3 177 85 1206 -3 12 275 397 -3 1231 1165 1066 -3 240 769 1208 -3 1000 999 985 -3 943 965 568 -3 906 913 932 -3 300 913 892 -3 997 998 66 -3 998 822 66 -3 478 33 128 -3 570 701 1076 -3 305 72 768 -3 72 811 768 -3 878 884 411 -3 878 835 884 -3 930 939 929 -3 968 978 967 -3 958 968 967 -3 946 958 967 -3 819 853 418 -3 510 943 509 -3 509 943 568 -3 151 100 184 -3 978 984 983 -3 967 978 983 -3 474 1122 799 -3 932 931 912 -3 487 460 819 -3 460 29 819 -3 819 29 853 -3 340 867 383 -3 1134 1135 1161 -3 947 946 931 -3 1411 1501 1408 -3 300 892 855 -3 356 910 929 -3 136 838 837 -3 1259 351 523 -3 887 896 923 -3 260 86 665 -3 774 129 773 -3 872 873 871 -3 906 932 912 -3 661 137 695 -3 511 886 942 -3 985 984 978 -3 968 985 978 -3 818 136 837 -3 1559 851 857 -3 872 871 865 -3 1222 1221 543 -3 548 1005 115 -3 430 1198 1065 -3 768 811 832 -3 945 967 944 -3 1132 1134 1160 -3 1019 1036 1025 -3 1134 1161 1160 -3 615 616 649 -3 1560 884 1884 -3 884 835 888 -3 214 230 114 -3 811 332 832 -3 878 411 53 -3 848 842 879 -3 842 829 879 -3 48 673 256 -3 869 811 768 -3 912 931 911 -3 935 936 950 -3 871 302 381 -3 972 991 971 -3 708 137 696 -3 1225 571 110 -3 847 955 13 -3 803 190 189 -3 865 871 858 -3 986 985 968 -3 929 944 943 -3 227 972 526 -3 888 835 896 -3 1001 1002 840 -3 1830 1841 1829 -3 50 140 275 -3 394 424 423 -3 411 884 888 -3 936 935 917 -3 907 936 917 -3 835 847 698 -3 811 6 332 -3 842 867 829 -3 1161 1060 1226 -3 1885 399 1887 -3 808 834 995 -3 1659 1658 1638 -3 65 295 211 -3 918 822 305 -3 302 871 381 -3 847 86 955 -3 1001 840 925 -3 1010 937 834 -3 1208 203 177 -3 1135 1162 1161 -3 921 81 379 -3 271 315 478 -3 948 969 947 -3 464 526 927 -3 834 848 806 -3 409 296 414 -3 302 873 432 -3 885 896 777 -3 841 892 839 -3 811 875 6 -3 1077 1104 1069 -3 1104 1103 1069 -3 68 106 46 -3 823 921 490 -3 162 81 921 -3 823 162 921 -3 989 1001 1000 -3 986 989 1000 -3 1000 1001 925 -3 888 896 887 -3 929 477 356 -3 974 972 534 -3 87 2 213 -3 915 840 331 -3 970 969 948 -3 965 641 568 -3 1207 177 1206 -3 1726 1725 1038 -3 1002 51 840 -3 814 191 803 -3 191 190 803 -3 855 892 841 -3 302 432 381 -3 173 293 573 -3 880 904 270 -3 871 873 302 -3 358 914 300 -3 239 863 328 -3 910 911 929 -3 331 712 811 -3 438 24 404 -3 892 913 906 -3 991 1002 990 -3 128 33 83 -3 810 836 194 -3 788 770 787 -3 814 803 804 -3 774 126 129 -3 242 855 830 -3 981 1189 1206 -3 927 934 914 -3 847 13 777 -3 301 358 300 -3 822 72 305 -3 641 617 568 -3 839 838 136 -3 904 880 910 -3 1850 1864 1870 -3 118 248 811 -3 949 970 948 -3 970 989 986 -3 1328 1325 1316 -3 358 927 914 -3 867 340 829 -3 943 944 966 -3 1100 221 1361 -3 530 805 525 -3 327 148 377 -3 1259 179 351 -3 1029 1028 1014 -3 969 968 947 -3 970 986 969 -3 832 795 768 -3 888 569 411 -3 342 344 113 -3 458 126 121 -3 943 966 965 -3 979 901 823 -3 823 861 162 -3 701 198 1076 -3 966 638 641 -3 769 315 271 -3 760 761 787 -3 965 966 641 -3 927 949 934 -3 949 948 934 -3 558 755 754 -3 919 835 878 -3 270 910 356 -3 852 162 861 -3 106 170 162 -3 852 106 162 -3 947 958 946 -3 815 192 191 -3 814 815 191 -3 820 384 879 -3 305 768 893 -3 698 847 777 -3 829 340 780 -3 534 972 227 -3 121 522 458 -3 1071 1077 1070 -3 846 823 901 -3 846 861 823 -3 918 305 66 -3 893 768 776 -3 1190 1186 1099 -3 67 1010 937 -3 925 840 915 -3 862 861 846 -3 862 852 861 -3 835 777 896 -3 946 945 944 -3 862 106 852 -3 1885 1887 928 -3 464 358 431 -3 526 949 927 -3 946 944 945 -3 890 889 838 -3 66 696 997 -3 1019 1561 1026 -3 1375 1380 1291 -3 1071 1061 1077 -3 712 118 811 -3 806 848 919 -3 971 990 970 -3 661 670 649 -3 971 970 949 -3 749 1225 110 -3 122 777 13 -3 35 13 955 -3 734 701 1164 -3 795 449 195 -3 874 842 848 -3 990 1002 989 -3 977 979 823 -3 526 971 949 -3 78 193 192 -3 815 78 192 -3 990 989 970 -3 834 539 842 -3 839 891 838 -3 1146 767 1064 -3 1002 1001 989 -3 840 51 118 -3 886 862 846 -3 280 754 753 -3 811 869 768 -3 906 913 912 -3 967 966 944 -3 931 946 930 -3 829 552 820 -3 886 106 862 -3 885 46 106 -3 1061 1104 1077 -3 320 67 834 -3 905 432 873 -3 874 848 834 -3 911 930 929 -3 1026 1572 1019 -3 972 974 992 -3 934 933 913 -3 914 934 913 -3 923 106 886 -3 777 46 885 -3 355 356 394 -3 449 96 195 -3 66 730 696 -3 807 96 832 -3 72 331 811 -3 896 106 923 -3 896 885 106 -3 1071 1070 1043 -3 932 947 931 -3 1049 1071 1043 -3 450 39 785 -3 946 967 945 -3 836 838 889 -3 787 761 788 -3 967 983 638 -3 966 967 638 -3 991 990 971 -3 597 1165 1231 -3 937 539 834 -3 934 948 947 -3 933 934 947 -3 886 846 942 -3 972 971 526 -3 1737 1762 1746 -3 1841 1851 1829 -3 417 1219 1218 -3 1166 110 1125 -3 159 342 113 -3 1065 1032 1274 -3 430 1065 1274 -3 1307 1320 1395 -3 767 1027 1 -3 846 798 1067 -3 735 1256 469 -3 1829 1850 1834 -3 398 317 1039 -3 288 32 34 -3 1051 1057 1058 -3 515 1684 1674 -3 1080 1079 1057 -3 1051 1058 1029 -3 1039 288 34 -3 1561 1726 1038 -3 1379 1307 1395 -3 304 642 409 -3 1396 1380 1381 -3 1030 1051 1029 -3 1219 1218 959 -3 598 1205 642 -3 1604 1615 1613 -3 1209 953 1193 -3 389 1521 1121 -3 398 75 70 -3 1314 273 524 -3 1022 1030 1021 -3 1022 1021 1016 -3 1030 1029 1021 -3 598 642 304 -3 528 1185 714 -3 1194 1209 1193 -3 177 12 397 -3 878 67 320 -3 1057 1045 1028 -3 1096 1095 1079 -3 1296 264 1319 -3 101 491 1237 -3 834 808 67 -3 1312 1484 1110 -3 963 1312 1110 -3 113 344 637 -3 1497 113 1496 -3 1119 1127 1113 -3 1312 1483 1484 -3 1799 1816 1812 -3 1079 1095 1057 -3 854 357 1191 -3 399 444 1210 -3 539 1011 383 -3 246 250 664 -3 1028 1038 1020 -3 1058 1057 1029 -3 311 1329 1396 -3 1260 1483 1312 -3 1187 1328 428 -3 1851 1864 1850 -3 317 609 619 -3 609 463 619 -3 1223 952 317 -3 603 1166 619 -3 1003 976 1094 -3 1248 556 297 -3 287 1885 555 -3 1138 1172 1163 -3 297 556 610 -3 1591 878 1009 -3 463 603 619 -3 749 110 1166 -3 1157 680 1081 -3 1886 304 409 -3 436 1027 605 -3 1015 1029 1014 -3 556 20 610 -3 20 604 610 -3 1099 1186 1189 -3 20 599 604 -3 1209 854 953 -3 1360 1550 1685 -3 492 398 70 -3 1172 1193 1192 -3 1175 1172 1192 -3 733 292 406 -3 202 733 406 -3 1010 834 67 -3 468 113 637 -3 154 1157 1081 -3 1172 1175 1163 -3 1193 854 1192 -3 953 854 1193 -3 1055 174 493 -3 1502 650 1046 -3 236 60 84 -3 1195 1194 1176 -3 85 177 397 -3 1163 1175 1148 -3 585 433 357 -3 1050 1045 1028 -3 1138 1148 1112 -3 1603 1402 1589 -3 1174 1192 1191 -3 1170 1174 1190 -3 1416 1417 1617 -3 398 1039 34 -3 75 398 1007 -3 1095 1107 1078 -3 1133 1134 1132 -3 1528 1022 1551 -3 1066 598 304 -3 292 733 667 -3 63 903 18 -3 619 1125 288 -3 1357 1355 1356 -3 733 1363 667 -3 470 1 212 -3 1017 830 136 -3 1119 1113 1095 -3 1387 231 247 -3 1107 1112 1078 -3 113 468 1496 -3 1028 1045 1050 -3 1014 1028 1013 -3 808 1011 539 -3 830 841 839 -3 12 50 275 -3 1344 1530 1115 -3 1363 153 19 -3 667 1363 19 -3 1103 1102 1068 -3 952 609 317 -3 1175 1174 1148 -3 1031 236 681 -3 595 10 555 -3 1119 1114 1587 -3 1114 1119 1096 -3 709 272 492 -3 451 736 434 -3 1174 1175 1192 -3 1380 1328 1316 -3 928 595 555 -3 153 489 1202 -3 572 598 1066 -3 19 153 1202 -3 1737 1746 1721 -3 1418 1417 1395 -3 1148 1147 1126 -3 488 1387 1448 -3 1245 488 1448 -3 1040 543 598 -3 572 1040 598 -3 1021 1029 1015 -3 1654 1653 1635 -3 329 58 595 -3 489 125 488 -3 1163 1148 1138 -3 1534 1687 1439 -3 342 709 344 -3 1112 1148 1126 -3 1202 489 488 -3 125 231 1387 -3 488 125 1387 -3 398 272 1223 -3 383 867 539 -3 414 296 928 -3 1176 1194 1172 -3 1028 1020 1013 -3 173 176 448 -3 1591 878 1009 -3 444 287 263 -3 1083 444 263 -3 272 952 1223 -3 1192 854 1191 -3 854 585 357 -3 1119 1152 1139 -3 1547 461 513 -3 296 329 595 -3 296 595 928 -3 603 749 1166 -3 1319 1329 1381 -3 1138 1152 1172 -3 63 18 33 -3 433 63 104 -3 769 433 104 -3 1174 1171 1147 -3 1372 1381 1375 -3 1613 1424 1603 -3 1113 1138 1107 -3 571 1218 1219 -3 1528 1551 1548 -3 1007 398 34 -3 1738 1737 1717 -3 1396 1329 1380 -3 1063 572 1066 -3 1153 1176 1152 -3 1139 1113 1127 -3 1119 1139 1127 -3 1191 357 1190 -3 357 240 1190 -3 1148 1174 1147 -3 29 460 325 -3 317 619 1039 -3 1754 1762 1737 -3 1329 311 1396 -3 1309 1380 1316 -3 1225 247 1218 -3 1448 1387 247 -3 1028 1045 1038 -3 1635 1453 1452 -3 116 1256 735 -3 514 1032 962 -3 1095 1078 1086 -3 1079 1095 1086 -3 357 433 240 -3 1174 1170 1171 -3 1218 1219 959 -3 1067 942 846 -3 1057 1095 1079 -3 10 114 287 -3 150 853 620 -3 555 10 287 -3 1152 1138 1139 -3 1052 1085 1370 -3 1704 1721 1703 -3 89 51 1002 -3 512 89 1002 -3 1152 1176 1172 -3 981 1206 992 -3 991 512 1002 -3 402 673 48 -3 1016 1551 1022 -3 1151 571 1219 -3 433 769 240 -3 1291 1380 1309 -3 1571 785 884 -3 589 490 605 -3 584 572 1063 -3 1057 1079 1045 -3 1138 1112 1107 -3 1045 1086 1078 -3 1095 1113 1107 -3 76 512 991 -3 1549 1552 1548 -3 203 769 271 -3 992 76 991 -3 274 89 512 -3 76 274 512 -3 274 51 89 -3 139 118 51 -3 274 139 51 -3 11 248 118 -3 139 11 118 -3 1056 1042 1068 -3 737 103 17 -3 871 302 858 -3 273 489 153 -3 1826 1835 1820 -3 197 48 294 -3 975 197 294 -3 197 713 402 -3 48 197 402 -3 584 1076 1040 -3 1079 1086 1045 -3 1029 1057 1028 -3 1139 1138 1113 -3 572 584 1040 -3 198 412 1040 -3 1076 198 1040 -3 298 273 153 -3 1500 1531 1359 -3 1096 1119 1095 -3 1194 1193 1172 -3 1560 785 1571 -3 882 866 894 -3 49 139 274 -3 1189 1207 1206 -3 1102 1133 1132 -3 1717 1721 1704 -3 1674 1487 1653 -3 584 570 1076 -3 894 1102 907 -3 821 1167 1199 -3 17 103 140 -3 50 17 140 -3 1042 1056 866 -3 1056 1068 894 -3 866 1056 894 -3 894 1068 1102 -3 1102 1132 936 -3 907 1102 936 -3 1160 950 936 -3 1132 1160 936 -3 1174 1191 1190 -3 1206 85 76 -3 992 1206 76 -3 397 274 76 -3 85 397 76 -3 275 49 274 -3 397 275 274 -3 140 139 49 -3 275 140 49 -3 103 11 139 -3 140 103 139 -3 409 642 329 -3 296 409 329 -3 436 975 1241 -3 436 605 975 -3 605 26 975 -3 26 197 975 -3 26 379 713 -3 197 26 713 -3 1010 539 937 -3 59 454 346 -3 652 408 413 -3 21 61 149 -3 171 345 347 -3 94 2 130 -3 130 256 134 -3 1004 1393 715 -3 313 368 367 -3 544 90 146 -3 81 535 379 -3 1257 527 950 -3 1257 950 1160 -3 302 301 259 -3 1004 414 928 -3 1160 1238 1257 -3 102 214 186 -3 1238 1160 1161 -3 1226 1238 1161 -3 1257 227 527 -3 95 233 364 -3 620 853 29 -3 1257 534 227 -3 282 454 230 -3 1453 1653 1452 -3 232 233 95 -3 821 1199 1886 -3 1232 1238 1226 -3 1238 981 1257 -3 1257 981 534 -3 417 408 652 -3 1233 1238 1232 -3 1027 436 42 -3 196 504 111 -3 169 180 81 -3 61 21 479 -3 631 231 388 -3 372 631 388 -3 1300 1382 1270 -3 1558 1559 857 -3 714 298 800 -3 298 153 800 -3 981 974 534 -3 704 348 5 -3 706 226 234 -3 388 231 443 -3 311 1330 1329 -3 1282 1300 1270 -3 1189 981 1238 -3 1233 1189 1238 -3 334 94 256 -3 1462 1672 1473 -3 895 786 787 -3 595 58 10 -3 1242 1251 1256 -3 489 231 125 -3 1236 1256 1250 -3 0 717 40 -3 470 212 0 -3 717 279 40 -3 276 230 59 -3 454 282 1237 -3 521 219 213 -3 417 652 346 -3 1266 417 346 -3 364 521 213 -3 171 363 345 -3 279 704 40 -3 470 0 160 -3 94 95 2 -3 42 281 717 -3 97 375 540 -3 61 479 363 -3 1216 705 706 -3 349 372 233 -3 453 42 717 -3 1241 975 150 -3 150 975 294 -3 214 362 282 -3 959 417 1266 -3 959 1219 417 -3 281 42 279 -3 408 607 372 -3 372 607 631 -3 0 40 25 -3 1221 69 1242 -3 287 114 263 -3 279 147 157 -3 704 279 157 -3 134 94 130 -3 81 52 535 -3 1265 58 329 -3 1249 1265 329 -3 82 97 13 -3 364 643 158 -3 82 375 97 -3 156 542 1214 -3 479 232 345 -3 35 82 13 -3 147 620 29 -3 102 186 58 -3 64 102 58 -3 363 479 345 -3 21 413 479 -3 652 413 21 -3 372 388 233 -3 216 43 5 -3 61 171 52 -3 413 349 479 -3 186 114 10 -3 619 288 1039 -3 697 1221 412 -3 171 61 363 -3 212 717 0 -3 1236 1242 1256 -3 607 408 417 -3 92 21 149 -3 279 42 147 -3 1221 1222 412 -3 697 1217 457 -3 156 1214 1213 -3 453 717 1 -3 552 829 868 -3 114 276 263 -3 570 734 701 -3 324 29 325 -3 1 717 212 -3 214 102 101 -3 2 364 213 -3 95 364 2 -3 74 97 68 -3 108 58 1265 -3 196 241 504 -3 416 325 326 -3 1346 900 767 -3 642 1205 1249 -3 71 135 6 -3 665 261 260 -3 389 43 216 -3 108 64 58 -3 1255 1236 1250 -3 7 1261 71 -3 1261 135 71 -3 83 737 17 -3 165 380 327 -3 147 29 324 -3 279 717 281 -3 417 1218 607 -3 1218 247 607 -3 83 573 737 -3 737 1239 7 -3 1239 1261 7 -3 42 620 147 -3 1215 697 1214 -3 1221 1242 1236 -3 1261 172 135 -3 651 62 6 -3 117 332 6 -3 62 117 6 -3 416 324 325 -3 157 324 416 -3 40 5 43 -3 1227 1239 737 -3 573 1227 737 -3 1261 1262 172 -3 172 651 6 -3 135 172 6 -3 62 807 117 -3 0 25 160 -3 364 388 643 -3 345 95 94 -3 1214 909 1215 -3 336 149 180 -3 233 388 364 -3 807 832 117 -3 1243 1262 1261 -3 1239 1243 1261 -3 42 150 620 -3 1215 1217 697 -3 1214 412 198 -3 1213 1214 198 -3 293 1227 573 -3 172 62 651 -3 878 1591 67 -3 1214 697 412 -3 1228 1243 1239 -3 1227 1228 1239 -3 96 45 438 -3 40 704 5 -3 59 92 181 -3 172 9 62 -3 643 22 158 -3 388 22 643 -3 92 149 181 -3 345 94 334 -3 652 21 92 -3 345 232 95 -3 214 101 362 -3 535 171 713 -3 1262 678 172 -3 678 9 172 -3 9 592 62 -3 479 349 233 -3 326 325 333 -3 117 832 332 -3 347 345 334 -3 234 1216 706 -3 486 62 592 -3 486 807 62 -3 884 1340 1884 -3 1270 1381 1372 -3 348 157 299 -3 1320 1418 1395 -3 1243 452 1262 -3 1262 452 678 -3 343 592 9 -3 149 61 52 -3 1224 1230 1228 -3 1246 1253 1243 -3 1243 1253 452 -3 163 486 592 -3 163 96 486 -3 2 87 54 -3 1474 1497 1496 -3 1488 1474 1496 -3 525 115 731 -3 1230 1246 1243 -3 1228 1230 1243 -3 452 343 9 -3 678 452 9 -3 31 592 343 -3 31 163 592 -3 743 226 437 -3 334 256 347 -3 149 52 180 -3 6 875 248 -3 1482 1474 1488 -3 1246 1230 1253 -3 452 31 343 -3 45 96 163 -3 364 158 521 -3 737 7 103 -3 213 73 87 -3 1063 533 584 -3 45 44 438 -3 42 436 150 -3 1244 1240 1092 -3 211 445 23 -3 1459 1465 1482 -3 1440 988 1442 -3 163 44 45 -3 1418 1354 1863 -3 436 1241 150 -3 453 1027 42 -3 108 1265 1249 -3 230 454 59 -3 1465 1474 1482 -3 311 1329 1319 -3 677 1234 1230 -3 1230 1234 1253 -3 452 374 31 -3 163 323 44 -3 282 214 230 -3 214 282 230 -3 1258 374 452 -3 1253 1258 452 -3 1215 909 1217 -3 1354 1418 1320 -3 1234 1240 1253 -3 294 418 853 -3 558 234 226 -3 11 103 71 -3 1240 1258 1253 -3 31 77 163 -3 77 323 163 -3 558 280 234 -3 214 224 186 -3 1205 1250 1249 -3 586 1296 1282 -3 1240 1234 677 -3 114 230 276 -3 1125 47 32 -3 308 77 31 -3 868 780 340 -3 1250 108 1249 -3 694 226 707 -3 288 1125 32 -3 319 31 374 -3 31 319 308 -3 529 323 77 -3 323 24 44 -3 280 309 234 -3 234 309 1216 -3 1491 1012 183 -3 77 308 529 -3 323 41 24 -3 225 361 1313 -3 6 248 71 -3 1258 669 374 -3 669 319 374 -3 249 41 323 -3 529 249 323 -3 115 444 782 -3 146 90 3 -3 309 705 1216 -3 669 1258 1240 -3 1264 109 636 -3 1302 185 1293 -3 1217 909 960 -3 237 265 1302 -3 337 1337 1336 -3 547 541 205 -3 1313 691 705 -3 286 352 337 -3 1327 1332 370 -3 798 846 901 -3 337 1338 1337 -3 361 225 611 -3 451 439 484 -3 677 1092 1240 -3 225 1313 109 -3 264 228 277 -3 352 1334 337 -3 785 783 1340 -3 309 1313 705 -3 674 683 682 -3 663 623 602 -3 622 663 710 -3 995 1591 806 -3 450 206 1047 -3 1283 99 215 -3 611 563 593 -3 475 246 664 -3 1294 1264 636 -3 442 1337 1347 -3 465 527 227 -3 659 630 636 -3 1454 1499 1527 -3 602 674 663 -3 107 1293 185 -3 1829 1851 1850 -3 109 690 660 -3 1313 690 109 -3 563 611 1264 -3 362 101 1237 -3 337 1334 1338 -3 206 450 517 -3 1347 471 503 -3 167 554 1323 -3 1468 1472 1489 -3 1091 1141 702 -3 471 563 1294 -3 715 1167 821 -3 1264 611 225 -3 1332 337 1336 -3 1004 1887 399 -3 586 1283 215 -3 1023 1252 1400 -3 1179 1370 1383 -3 1313 726 1324 -3 471 636 630 -3 352 420 1334 -3 1047 39 450 -3 99 1283 586 -3 237 1302 107 -3 14 446 330 -3 1313 361 645 -3 530 525 784 -3 1338 553 1348 -3 1337 1338 1348 -3 370 1332 442 -3 1332 1336 442 -3 715 821 414 -3 237 283 1322 -3 362 1237 282 -3 187 1303 237 -3 257 27 131 -3 801 430 1335 -3 1287 36 213 -3 554 167 338 -3 335 1331 1330 -3 311 335 1330 -3 1331 439 451 -3 506 420 421 -3 1330 1331 451 -3 663 674 1284 -3 674 385 1284 -3 184 107 185 -3 1322 283 314 -3 14 27 446 -3 439 520 484 -3 265 185 1302 -3 420 553 1338 -3 554 338 916 -3 1400 1298 1023 -3 553 563 471 -3 1324 726 1313 -3 1285 14 446 -3 434 435 451 -3 338 167 175 -3 277 311 1319 -3 546 783 244 -3 801 1335 1274 -3 338 1297 916 -3 1294 563 1264 -3 420 1338 1334 -3 783 606 244 -3 1337 1348 1347 -3 1313 1324 690 -3 311 312 335 -3 220 1285 1310 -3 1284 385 1278 -3 1128 1023 1252 -3 1285 220 14 -3 622 623 663 -3 109 660 636 -3 524 446 330 -3 1589 1402 1403 -3 338 220 1310 -3 674 682 385 -3 284 337 1332 -3 107 1302 1293 -3 663 1284 710 -3 1888 517 1067 -3 350 1251 69 -3 435 434 415 -3 435 415 428 -3 1297 338 1310 -3 682 307 385 -3 1306 1305 1280 -3 1276 1306 1280 -3 313 367 312 -3 1327 284 1332 -3 1336 1337 442 -3 1264 225 109 -3 180 169 1229 -3 475 801 246 -3 352 267 353 -3 1403 1404 1589 -3 1285 1292 1310 -3 307 682 748 -3 682 718 748 -3 1277 1276 1275 -3 1158 237 107 -3 1067 517 511 -3 1271 1282 1270 -3 489 125 443 -3 446 14 330 -3 586 1282 1271 -3 1292 1285 446 -3 446 330 1287 -3 443 125 489 -3 108 116 735 -3 813 100 99 -3 1276 1307 1306 -3 1483 1260 1317 -3 1272 586 1271 -3 1348 553 471 -3 1287 213 219 -3 330 446 1287 -3 443 231 489 -3 330 36 1287 -3 86 35 955 -3 450 785 1560 -3 1312 1304 1260 -3 1329 435 428 -3 1289 1276 1277 -3 1289 1290 1276 -3 1158 187 237 -3 1311 556 1248 -3 558 226 743 -3 1323 554 993 -3 1292 446 524 -3 273 443 489 -3 1290 1289 1277 -3 1290 1307 1276 -3 215 264 1296 -3 1304 1286 1273 -3 1260 1304 1273 -3 1311 1248 1273 -3 1286 1311 1273 -3 246 801 250 -3 1322 314 278 -3 1019 1572 1036 -3 307 748 608 -3 182 307 608 -3 1321 443 273 -3 471 1294 636 -3 215 1296 586 -3 1322 278 265 -3 542 701 1129 -3 1101 1284 1278 -3 39 783 785 -3 1304 400 1286 -3 400 1311 1286 -3 1339 244 1200 -3 1324 309 726 -3 674 602 683 -3 265 237 1322 -3 1653 1487 1470 -3 446 36 330 -3 1321 22 443 -3 1277 1267 1290 -3 1290 1308 1307 -3 1313 309 1324 -3 467 68 97 -3 1312 1279 1304 -3 367 1331 335 -3 524 330 1287 -3 1347 1348 471 -3 1308 1315 1307 -3 1365 1529 1108 -3 531 530 784 -3 123 531 784 -3 1041 556 1311 -3 666 1041 1311 -3 312 367 335 -3 1705 1707 1711 -3 690 1324 725 -3 1331 367 439 -3 710 1284 1101 -3 608 748 758 -3 170 699 169 -3 1308 1309 1315 -3 1368 1362 1371 -3 306 1200 244 -3 1279 1299 1304 -3 1304 1299 400 -3 666 1311 400 -3 251 283 237 -3 1853 1866 1871 -3 1312 963 1279 -3 1101 1279 963 -3 1314 1321 273 -3 699 1229 169 -3 1268 1290 1267 -3 1290 1309 1308 -3 386 1320 1315 -3 1320 386 1315 -3 314 1327 370 -3 542 156 701 -3 475 1486 1684 -3 1297 1185 528 -3 1031 916 60 -3 1297 1310 1185 -3 158 1321 1314 -3 1379 1305 1306 -3 553 420 506 -3 291 1342 782 -3 608 758 1041 -3 666 608 1041 -3 1635 1452 1453 -3 60 916 528 -3 916 1297 528 -3 1314 1287 158 -3 601 471 630 -3 1291 1290 1268 -3 1316 1315 1309 -3 1316 1320 1315 -3 400 608 666 -3 1292 524 1185 -3 187 189 188 -3 68 467 1318 -3 187 188 1303 -3 1281 1291 1268 -3 1290 1291 1309 -3 1320 1316 386 -3 1278 385 1299 -3 1279 1278 1299 -3 385 307 400 -3 1299 385 400 -3 307 182 400 -3 400 182 608 -3 801 208 430 -3 243 547 205 -3 1292 1185 1310 -3 1324 726 725 -3 699 170 105 -3 105 68 1318 -3 699 105 1318 -3 1316 1325 386 -3 1325 1187 386 -3 1096 1587 1114 -3 515 208 801 -3 1287 1314 524 -3 1287 219 158 -3 1541 1546 1545 -3 1540 1541 1545 -3 1361 519 1520 -3 570 1129 701 -3 785 1340 884 -3 176 903 127 -3 1232 1226 1233 -3 570 1366 1129 -3 1571 884 1560 -3 378 533 1432 -3 210 570 533 -3 378 210 533 -3 570 210 1366 -3 210 290 1129 -3 1366 210 1129 -3 1129 290 542 -3 290 909 542 -3 290 960 909 -3 124 697 290 -3 210 124 290 -3 697 457 290 -3 290 457 960 -3 960 457 1217 -3 378 124 210 -3 1477 1420 1006 -3 591 378 597 -3 1165 591 597 -3 378 591 124 -3 124 457 697 -3 124 1394 457 -3 1653 1470 1452 -3 1377 1378 1388 -3 1199 1048 1231 -3 124 350 1394 -3 1394 350 457 -3 1048 1165 1231 -3 1048 671 591 -3 1165 1048 591 -3 671 350 124 -3 591 671 124 -3 350 69 457 -3 98 467 97 -3 827 155 1880 -3 1544 1545 1157 -3 176 173 18 -3 1273 700 1260 -3 1369 1048 1199 -3 671 588 350 -3 1545 1546 1204 -3 1546 640 1204 -3 607 247 231 -3 1278 1279 1101 -3 154 1081 1513 -3 1777 1770 1785 -3 1295 499 143 -3 1850 1849 1834 -3 1199 732 1369 -3 732 1183 1369 -3 926 1048 1369 -3 1183 926 1369 -3 926 635 671 -3 1048 926 671 -3 671 635 588 -3 635 1251 350 -3 588 635 350 -3 1449 1472 1468 -3 1490 1489 1472 -3 1425 1074 1389 -3 1198 494 1065 -3 758 718 759 -3 1449 1468 1472 -3 1260 700 1317 -3 732 926 1183 -3 1449 1451 1468 -3 1468 1451 1472 -3 1490 538 1489 -3 272 406 952 -3 1183 926 732 -3 926 1183 635 -3 1426 1435 1434 -3 1449 1450 1451 -3 1421 1422 1426 -3 1426 1422 1435 -3 1469 1486 1490 -3 1472 1469 1490 -3 1183 455 635 -3 1435 1450 1449 -3 1434 1435 1449 -3 1451 1469 1472 -3 475 538 1490 -3 1486 475 1490 -3 475 664 538 -3 250 289 538 -3 664 250 538 -3 306 260 575 -3 455 1183 732 -3 1169 455 732 -3 455 469 635 -3 469 1256 1251 -3 635 469 1251 -3 1204 1389 1074 -3 1319 1381 1382 -3 1364 1370 1085 -3 1329 1396 1381 -3 1330 435 1329 -3 1444 1451 1450 -3 1435 1444 1450 -3 1520 519 1120 -3 1505 1120 1326 -3 640 883 1425 -3 1357 1364 1355 -3 1357 1370 1364 -3 1357 1211 1370 -3 1225 1245 1448 -3 1408 1423 1422 -3 1411 1408 1422 -3 1423 1436 1435 -3 1422 1423 1435 -3 1436 1437 1444 -3 1435 1436 1444 -3 1437 1452 1451 -3 1444 1437 1451 -3 1452 1470 1469 -3 1451 1452 1469 -3 1469 1470 1486 -3 1486 1674 1487 -3 1413 980 1420 -3 1470 1487 1486 -3 1537 154 1105 -3 1393 1054 1169 -3 668 455 1169 -3 1054 668 1169 -3 668 735 469 -3 455 668 469 -3 1455 1445 1446 -3 1185 524 298 -3 459 552 38 -3 1731 1739 1722 -3 1376 1211 1357 -3 1409 1408 1398 -3 1427 1437 1436 -3 1423 1427 1436 -3 1403 1388 1404 -3 84 1367 1363 -3 596 556 1041 -3 714 1185 298 -3 1004 1054 1393 -3 1210 574 399 -3 1320 1307 1315 -3 1635 1453 1438 -3 1359 1357 1356 -3 1358 1359 1356 -3 1377 1376 1357 -3 1359 1377 1357 -3 1388 1211 1376 -3 1377 1388 1376 -3 1402 1409 1398 -3 1388 1398 1211 -3 1402 1408 1409 -3 1402 1424 1423 -3 1408 1402 1423 -3 1423 1424 1427 -3 1424 1438 1437 -3 1427 1424 1437 -3 1438 1453 1452 -3 1437 1438 1452 -3 1197 828 650 -3 1111 1511 1510 -3 1300 1319 1382 -3 1010 808 539 -3 208 1198 430 -3 1200 459 38 -3 1539 1540 1544 -3 1507 1094 1405 -3 1094 976 1405 -3 475 515 801 -3 533 378 1432 -3 744 491 668 -3 1054 744 668 -3 491 101 735 -3 668 491 735 -3 384 459 1200 -3 306 384 1200 -3 1512 1197 650 -3 7 71 103 -3 1466 1295 1074 -3 1325 1328 1187 -3 1329 428 1328 -3 1507 1405 1397 -3 1120 897 1184 -3 1388 1403 1402 -3 1110 859 576 -3 1431 1110 576 -3 399 1212 744 -3 1363 800 153 -3 575 384 306 -3 1178 1100 1512 -3 1425 883 1074 -3 733 84 1363 -3 55 54 87 -3 1296 1300 1282 -3 1378 1377 1359 -3 1004 715 414 -3 1462 1479 1478 -3 1479 1492 222 -3 1478 1479 222 -3 1492 30 179 -3 222 1492 179 -3 30 351 179 -3 1544 1157 154 -3 429 297 709 -3 1110 1483 1475 -3 86 306 391 -3 700 159 1498 -3 1317 700 1498 -3 205 467 540 -3 828 518 650 -3 1672 1462 1473 -3 399 574 1212 -3 574 634 744 -3 1212 574 744 -3 634 1237 491 -3 744 634 491 -3 1367 714 1363 -3 375 606 112 -3 375 82 606 -3 82 86 391 -3 1457 1181 640 -3 1546 1457 640 -3 1479 1493 1492 -3 1493 258 30 -3 1492 1493 30 -3 429 1248 297 -3 39 375 199 -3 336 181 149 -3 1439 1511 1111 -3 1684 515 475 -3 1483 1317 1475 -3 1317 1498 1475 -3 429 342 159 -3 700 429 159 -3 1510 1052 1179 -3 1181 1130 883 -3 640 1181 883 -3 1405 980 1413 -3 1140 964 1181 -3 1509 1439 1517 -3 1479 1480 1493 -3 403 351 30 -3 258 403 30 -3 390 389 1121 -3 1400 897 1298 -3 604 272 709 -3 1460 749 603 -3 403 523 351 -3 1249 329 642 -3 1390 1466 883 -3 1382 1381 1270 -3 1363 714 800 -3 342 429 709 -3 540 375 1047 -3 297 604 709 -3 1467 1461 1201 -3 1130 1390 883 -3 1374 1454 1515 -3 1462 1480 1479 -3 1136 523 403 -3 964 1441 1181 -3 1059 1522 1128 -3 1003 221 500 -3 976 1003 500 -3 1100 1197 1512 -3 390 25 43 -3 1407 1416 1415 -3 1406 1407 1415 -3 1455 1446 1458 -3 1446 1463 1462 -3 1458 1446 1462 -3 1463 1464 1462 -3 1464 1481 1480 -3 1462 1464 1480 -3 1481 1494 1493 -3 1480 1481 1493 -3 1494 994 258 -3 1493 1494 258 -3 456 403 258 -3 994 456 258 -3 621 1136 403 -3 456 621 403 -3 621 523 1136 -3 621 745 523 -3 141 473 523 -3 745 141 523 -3 1516 1524 1476 -3 1128 245 1471 -3 1155 321 634 -3 574 1155 634 -3 599 681 202 -3 298 524 273 -3 681 236 202 -3 1368 1371 1527 -3 1263 1254 1540 -3 1502 1524 1476 -3 1476 1046 1115 -3 321 454 1237 -3 634 321 1237 -3 541 467 205 -3 467 97 540 -3 98 97 467 -3 236 84 733 -3 1446 1464 1463 -3 621 141 745 -3 1516 1476 1503 -3 1467 1201 828 -3 174 639 142 -3 202 236 733 -3 1686 1703 1702 -3 1494 1495 994 -3 1495 1123 994 -3 516 141 621 -3 1037 1059 1128 -3 590 467 541 -3 701 156 1164 -3 1398 1408 1383 -3 493 1301 322 -3 639 321 1155 -3 1429 1446 1445 -3 1481 1495 1494 -3 1220 456 994 -3 1123 1220 994 -3 954 322 495 -3 1373 493 322 -3 987 321 639 -3 260 306 86 -3 1370 1384 1383 -3 1280 1305 1362 -3 1305 1371 1362 -3 1305 1379 1371 -3 1392 1386 1371 -3 1392 1395 1386 -3 1395 1407 1386 -3 1395 1417 1416 -3 1407 1395 1416 -3 1703 1694 1704 -3 1428 1430 1429 -3 1430 1442 1446 -3 1429 1430 1446 -3 1442 1459 1464 -3 1446 1442 1464 -3 1459 1482 1481 -3 1464 1459 1481 -3 1482 1488 1481 -3 1488 1496 1495 -3 1481 1488 1495 -3 1496 468 1123 -3 1495 1496 1123 -3 637 1220 1123 -3 468 637 1123 -3 637 456 1220 -3 637 1203 456 -3 161 621 456 -3 1203 161 456 -3 75 516 621 -3 161 75 621 -3 1687 1694 1703 -3 75 34 495 -3 954 495 34 -3 34 32 322 -3 954 34 322 -3 32 47 322 -3 47 1373 322 -3 47 493 1373 -3 47 183 493 -3 183 1055 493 -3 1055 1012 174 -3 1012 639 174 -3 959 987 639 -3 1012 959 639 -3 959 321 987 -3 959 346 321 -3 346 454 321 -3 1341 1229 541 -3 1229 699 541 -3 699 1318 590 -3 541 699 590 -3 637 161 1203 -3 1615 1635 1438 -3 1300 1296 1319 -3 1379 1395 1392 -3 1615 1438 1424 -3 1613 1615 1424 -3 75 1007 34 -3 1229 1341 336 -3 700 1273 1248 -3 1392 1395 1379 -3 70 161 637 -3 183 1012 1055 -3 1673 1184 1504 -3 1159 1504 1184 -3 1266 346 959 -3 1604 1613 1603 -3 1459 1442 1456 -3 1075 1502 1503 -3 221 1100 500 -3 677 1084 1092 -3 1230 1224 677 -3 1537 1544 154 -3 1105 1097 1088 -3 1121 1105 1088 -3 1146 1346 767 -3 1087 293 176 -3 1100 1467 1197 -3 1154 585 1209 -3 962 1032 1065 -3 1765 1759 1024 -3 1408 1501 1383 -3 1516 1502 1524 -3 143 499 519 -3 1147 1142 1126 -3 1074 1094 680 -3 1399 897 1400 -3 1087 176 366 -3 235 1087 653 -3 897 1399 1184 -3 1149 1135 1061 -3 1685 1687 1360 -3 1379 1392 1371 -3 1810 259 242 -3 293 448 176 -3 1521 1537 1105 -3 235 653 677 -3 1100 1361 1467 -3 373 1538 1537 -3 1514 585 1059 -3 1059 585 341 -3 462 796 1023 -3 964 1106 1419 -3 1505 1326 1201 -3 711 63 1514 -3 964 1140 1092 -3 340 780 868 -3 796 1037 1128 -3 1037 127 796 -3 127 1037 796 -3 18 903 127 -3 1059 341 1522 -3 1508 366 1098 -3 1410 176 127 -3 293 1087 235 -3 1117 187 1876 -3 366 1508 1106 -3 1399 1159 1184 -3 1399 1400 1252 -3 1170 1099 1142 -3 1410 1037 1098 -3 903 18 127 -3 1383 1384 1211 -3 1522 341 1154 -3 1120 1505 1201 -3 1087 366 653 -3 1060 1135 1485 -3 964 1419 1130 -3 293 235 1224 -3 1244 1092 1457 -3 1545 1204 1157 -3 1252 1471 1399 -3 366 964 653 -3 1525 1126 1142 -3 160 360 1173 -3 366 176 1098 -3 499 1401 1298 -3 1539 1544 1537 -3 677 653 1084 -3 176 18 903 -3 199 375 112 -3 1520 1120 1461 -3 644 1539 1538 -3 80 1535 216 -3 176 1410 1098 -3 1140 1181 1457 -3 462 1098 796 -3 1541 1457 1546 -3 1361 1520 1467 -3 1467 1520 1461 -3 373 644 1538 -3 1106 462 781 -3 1591 834 67 -3 390 594 360 -3 160 390 360 -3 1254 1247 1541 -3 1075 1503 980 -3 903 711 127 -3 181 263 276 -3 444 1083 291 -3 1538 1539 1537 -3 1419 1106 1390 -3 519 1361 143 -3 216 1535 1521 -3 1094 976 680 -3 1441 1130 1181 -3 1006 672 1385 -3 1060 1485 1149 -3 43 389 390 -3 181 809 263 -3 1120 1201 1461 -3 1130 1419 1390 -3 1081 680 1507 -3 1231 1165 597 -3 809 1083 263 -3 964 366 1106 -3 809 181 336 -3 809 291 1083 -3 496 1506 1046 -3 650 496 1046 -3 390 1121 594 -3 1295 1003 1074 -3 1832 1845 1831 -3 1204 640 1389 -3 341 585 1154 -3 1081 1507 1082 -3 511 1884 569 -3 1197 1467 828 -3 1341 809 336 -3 1094 680 976 -3 1540 1545 1544 -3 1398 1388 1402 -3 594 1121 1088 -3 1233 1099 1189 -3 1502 1516 1503 -3 1506 1344 1115 -3 291 1137 1342 -3 1097 1513 1082 -3 1412 812 123 -3 498 831 812 -3 1412 498 812 -3 883 1466 1074 -3 1006 1420 962 -3 1399 1471 1159 -3 962 672 1006 -3 1118 1091 702 -3 1686 1687 1703 -3 653 964 1084 -3 1735 1756 1747 -3 1 470 1536 -3 127 1059 1037 -3 1046 1506 1115 -3 1288 1006 1385 -3 1044 1288 1385 -3 1147 1171 1170 -3 1170 1142 1147 -3 1137 291 1346 -3 808 1008 1011 -3 1159 245 1504 -3 672 962 1065 -3 1390 1106 781 -3 1390 1156 1466 -3 1466 1156 1295 -3 1015 1016 1021 -3 644 1540 1539 -3 1137 1533 1542 -3 1088 1089 1288 -3 594 1088 1288 -3 1721 1746 1729 -3 360 594 1044 -3 594 1288 1044 -3 245 1108 1504 -3 216 1521 389 -3 1370 1211 1384 -3 1089 1006 1288 -3 461 587 513 -3 513 587 1351 -3 1351 1414 1412 -3 1091 498 1412 -3 1414 1091 1412 -3 1115 1530 538 -3 1092 1140 1457 -3 1509 1090 1534 -3 1137 1146 1533 -3 1349 461 1547 -3 767 1 1064 -3 1529 1365 1195 -3 964 1130 1441 -3 1351 587 1414 -3 1115 538 289 -3 1405 1413 1397 -3 1513 1081 1082 -3 980 514 1420 -3 680 1094 1507 -3 461 1414 587 -3 1106 1508 462 -3 1052 1370 1179 -3 1457 1541 1247 -3 587 1414 461 -3 1420 514 962 -3 545 1201 1326 -3 63 585 1514 -3 1105 154 1097 -3 1064 1533 1146 -3 1414 587 461 -3 973 1414 587 -3 1414 973 587 -3 250 1476 289 -3 1157 1204 680 -3 1398 1383 1211 -3 1507 1397 1082 -3 1543 1349 1533 -3 1536 1543 1533 -3 1543 410 461 -3 1349 1543 461 -3 973 1141 1414 -3 1141 1091 1414 -3 1476 1115 289 -3 1084 964 1092 -3 373 1537 1521 -3 1521 1105 1121 -3 1476 250 1274 -3 1149 1525 1142 -3 1254 1541 1540 -3 1064 1 1533 -3 1082 1397 1089 -3 1088 1082 1089 -3 80 373 1521 -3 1535 80 1521 -3 1341 541 547 -3 39 199 783 -3 1536 1533 1 -3 973 1414 461 -3 410 973 461 -3 1397 1413 1420 -3 1089 1397 1420 -3 1111 1383 1501 -3 1503 1476 1274 -3 606 82 391 -3 780 38 868 -3 1135 1104 1061 -3 711 1514 1059 -3 1365 1194 1195 -3 1111 1510 1179 -3 1485 1135 1149 -3 796 1128 1252 -3 1228 293 1224 -3 644 1263 1540 -3 390 160 25 -3 63 33 104 -3 391 306 606 -3 306 244 606 -3 1097 154 1513 -3 494 672 1065 -3 1543 618 410 -3 537 973 410 -3 618 537 410 -3 1141 1352 702 -3 972 992 991 -3 1509 1534 1439 -3 1088 1097 1082 -3 1401 1023 1298 -3 53 569 1884 -3 1536 470 1543 -3 1410 127 1037 -3 1227 293 1228 -3 1128 1522 245 -3 1522 1154 245 -3 1850 1870 1849 -3 796 1252 1023 -3 173 83 33 -3 1543 470 618 -3 1242 69 1251 -3 1515 1527 1371 -3 1162 1135 1060 -3 1188 537 618 -3 1109 973 537 -3 1109 1141 973 -3 1109 1352 1141 -3 545 518 828 -3 1201 545 828 -3 1244 1457 1247 -3 1386 1515 1371 -3 1454 1518 1499 -3 1089 1477 1006 -3 462 1401 781 -3 1401 499 781 -3 63 433 585 -3 1886 1066 304 -3 1204 1074 680 -3 127 711 1059 -3 640 1425 1389 -3 1188 618 537 -3 499 1298 519 -3 1226 1060 1099 -3 1233 1226 1099 -3 1515 1454 1386 -3 1298 897 1120 -3 519 1298 1120 -3 1188 537 618 -3 1524 1502 1046 -3 1178 980 550 -3 1178 1512 1075 -3 1515 1386 1391 -3 1386 1454 1515 -3 1149 1142 1099 -3 1060 1149 1099 -3 1508 1098 462 -3 1401 462 1023 -3 1178 1075 980 -3 552 868 459 -3 1061 1525 1149 -3 1098 1037 796 -3 1524 1502 1476 -3 1476 1524 1046 -3 1828 1829 1834 -3 1089 1420 1477 -3 1352 672 494 -3 1502 1512 650 -3 1252 1128 1471 -3 1531 1518 1454 -3 1374 1531 1454 -3 1512 1502 1075 -3 1173 618 470 -3 160 1173 470 -3 1173 1188 618 -3 1173 360 1188 -3 1188 360 537 -3 360 1044 537 -3 537 1044 1109 -3 1044 1385 1109 -3 672 1352 1109 -3 1385 672 1109 -3 511 517 1560 -3 1390 781 1156 -3 223 222 178 -3 831 123 812 -3 141 1333 1618 -3 1812 1829 1828 -3 115 1005 1210 -3 1636 1637 1656 -3 1515 1454 1527 -3 1682 538 1530 -3 1637 1657 1656 -3 1072 1525 1061 -3 1071 1072 1061 -3 548 1350 142 -3 1072 1592 1525 -3 1487 1674 1684 -3 67 937 1010 -3 1754 1784 1762 -3 1462 1478 1473 -3 1137 1542 778 -3 1614 1637 1616 -3 1036 1572 1049 -3 1049 1584 1072 -3 1072 1584 1592 -3 1126 1525 1592 -3 1584 1126 1592 -3 199 606 783 -3 1499 1362 1368 -3 1680 1678 1679 -3 1049 1586 1584 -3 799 178 1558 -3 702 494 1198 -3 1499 1368 1527 -3 868 552 459 -3 1486 1487 1674 -3 1572 1584 1586 -3 1049 1572 1586 -3 779 702 1198 -3 1799 1812 1795 -3 1618 1333 141 -3 1662 1676 1675 -3 805 1350 548 -3 1026 1570 1572 -3 1572 1073 1584 -3 1073 1078 1584 -3 1112 1126 1584 -3 1078 1112 1584 -3 1617 1620 1416 -3 1676 560 483 -3 1675 1676 483 -3 1659 1678 1663 -3 1572 1570 1073 -3 1054 1004 399 -3 827 1880 1870 -3 1404 1590 1604 -3 1374 1515 1391 -3 1345 472 498 -3 802 1555 1519 -3 1655 1675 1674 -3 1416 1614 1415 -3 1407 1406 1386 -3 482 560 1676 -3 1678 1677 1663 -3 1146 1137 1346 -3 1026 1562 1570 -3 1562 1570 1572 -3 1570 1562 1572 -3 1677 482 1676 -3 547 1556 798 -3 701 734 570 -3 1589 1404 1603 -3 1641 1638 1634 -3 1639 1641 1634 -3 1657 1658 1662 -3 260 261 575 -3 156 701 1164 -3 1639 1634 1621 -3 1638 1658 1657 -3 1637 1638 1657 -3 1519 1118 702 -3 1415 1605 1590 -3 779 1519 702 -3 1406 1415 1590 -3 1663 1677 1662 -3 1641 1659 1638 -3 1658 1663 1662 -3 1635 1636 1654 -3 1562 1073 1570 -3 1687 1686 1439 -3 1047 375 39 -3 1621 1620 1617 -3 738 1519 779 -3 483 515 1674 -3 473 1333 531 -3 481 473 531 -3 1155 142 639 -3 1662 1675 1655 -3 1656 1662 1655 -3 1038 1045 1073 -3 1562 1038 1073 -3 222 179 178 -3 1428 1621 1617 -3 1675 483 1674 -3 1159 1471 245 -3 1365 245 1154 -3 1209 1365 1154 -3 245 1365 1108 -3 1637 1636 1616 -3 1416 1620 1614 -3 1638 1637 1614 -3 884 1340 1884 -3 1049 1043 1036 -3 1605 1616 1607 -3 1620 1638 1614 -3 1455 1428 1445 -3 1622 1529 1195 -3 1177 1622 1195 -3 550 976 500 -3 1587 1523 1119 -3 1428 1455 1639 -3 1096 1079 1080 -3 553 536 563 -3 1404 1604 1603 -3 1153 1622 1177 -3 641 638 661 -3 1013 1020 1038 -3 1051 1114 1096 -3 1080 1051 1096 -3 1114 1587 1096 -3 1556 243 798 -3 1532 1623 1622 -3 1153 1532 1622 -3 1642 1529 1622 -3 1623 1642 1622 -3 1642 1504 1108 -3 1529 1642 1108 -3 1378 1404 1388 -3 178 179 1559 -3 1455 1473 1641 -3 1653 1655 1674 -3 805 530 531 -3 33 18 173 -3 1605 1604 1590 -3 179 1259 1559 -3 1051 1587 1114 -3 1118 1345 1091 -3 851 523 532 -3 715 732 1167 -3 1636 1655 1654 -3 1621 1634 1620 -3 1093 1280 1362 -3 1051 1114 1587 -3 1604 1605 1607 -3 1022 1563 1051 -3 1030 1022 1051 -3 1563 1573 1114 -3 1051 1563 1114 -3 1573 1585 1587 -3 1114 1573 1587 -3 1585 1599 1523 -3 1587 1585 1523 -3 1599 1608 1532 -3 1523 1599 1532 -3 1608 1624 1623 -3 1532 1608 1623 -3 1643 1642 1623 -3 1624 1643 1623 -3 1643 1673 1504 -3 1642 1643 1504 -3 551 547 798 -3 1014 1016 1015 -3 1306 1307 1379 -3 805 548 525 -3 1656 1655 1636 -3 1333 805 531 -3 1683 1184 1673 -3 1608 1625 1624 -3 1644 1643 1624 -3 1625 1644 1624 -3 1664 1673 1643 -3 1644 1664 1643 -3 1023 1128 1252 -3 585 854 1209 -3 1351 1412 123 -3 322 1301 495 -3 799 844 474 -3 516 495 141 -3 1555 1345 1118 -3 495 1618 141 -3 1047 205 540 -3 141 1333 473 -3 1433 1426 1434 -3 597 378 1063 -3 1528 1564 1563 -3 1022 1528 1563 -3 1564 1574 1573 -3 1563 1564 1573 -3 1573 1574 1585 -3 1574 1576 1585 -3 1585 1576 1599 -3 1576 1600 1599 -3 1600 1609 1608 -3 1599 1600 1608 -3 1609 1626 1625 -3 1608 1609 1625 -3 1645 1644 1625 -3 1626 1645 1625 -3 1645 1665 1664 -3 1644 1645 1664 -3 1665 1673 1664 -3 1665 1326 1683 -3 1673 1665 1683 -3 1326 1184 1683 -3 1590 1404 1378 -3 1614 1616 1605 -3 1415 1614 1605 -3 495 1333 1618 -3 738 802 1519 -3 1473 1659 1641 -3 1301 805 1333 -3 205 206 517 -3 1405 976 550 -3 495 1301 1333 -3 1593 1601 1600 -3 1576 1593 1600 -3 1600 1601 1609 -3 716 208 515 -3 500 1178 550 -3 1259 523 851 -3 1559 1259 851 -3 831 481 812 -3 513 1349 1547 -3 1616 1636 1635 -3 222 223 1680 -3 1301 493 1350 -3 805 1301 1350 -3 1548 1552 1528 -3 1552 1565 1564 -3 1528 1552 1564 -3 1564 1565 1574 -3 1574 1565 1576 -3 1565 1577 1576 -3 1594 1593 1576 -3 1577 1594 1576 -3 1602 1601 1593 -3 1594 1602 1593 -3 1602 1610 1609 -3 1601 1602 1609 -3 1610 1627 1626 -3 1609 1610 1626 -3 1627 1646 1645 -3 1626 1627 1645 -3 1666 1665 1645 -3 1646 1666 1645 -3 1666 545 1326 -3 1665 1666 1326 -3 483 716 515 -3 547 243 1556 -3 221 1003 1295 -3 143 221 1295 -3 809 1341 547 -3 551 809 547 -3 782 1342 778 -3 731 782 778 -3 1458 1660 1455 -3 752 309 753 -3 1424 1402 1603 -3 1519 1555 1118 -3 1549 1553 1552 -3 1552 1553 1565 -3 1775 1799 1784 -3 1406 1590 1378 -3 493 174 142 -3 1350 493 142 -3 1656 1657 1662 -3 291 809 551 -3 731 778 513 -3 523 473 481 -3 1365 1209 1194 -3 1346 291 551 -3 784 731 513 -3 1550 1554 1553 -3 1549 1550 1553 -3 1566 1565 1553 -3 1554 1566 1553 -3 1566 1578 1577 -3 1565 1566 1577 -3 1578 1579 1577 -3 1577 1579 1594 -3 1579 1595 1602 -3 1594 1579 1602 -3 1595 1611 1610 -3 1602 1595 1610 -3 1628 1627 1610 -3 1611 1628 1610 -3 1628 1647 1646 -3 1627 1628 1646 -3 1647 1667 1666 -3 1646 1647 1666 -3 1667 1668 1666 -3 518 545 1666 -3 1668 518 1666 -3 1074 1003 1094 -3 1607 1616 1615 -3 123 784 513 -3 1499 1527 1454 -3 1604 1607 1615 -3 1566 1579 1578 -3 1628 1648 1647 -3 1648 1668 1667 -3 1647 1648 1667 -3 1681 518 1668 -3 778 1533 1349 -3 513 778 1349 -3 496 650 497 -3 1615 1616 1635 -3 1429 1445 1428 -3 718 758 748 -3 1678 1680 474 -3 1680 223 474 -3 778 1542 1533 -3 206 205 1047 -3 1478 222 1680 -3 1679 1678 1659 -3 857 831 498 -3 1386 1406 1391 -3 1360 1090 1554 -3 1550 1360 1554 -3 1567 1566 1554 -3 1090 1567 1554 -3 1567 1580 1579 -3 1566 1567 1579 -3 1580 1596 1595 -3 1579 1580 1595 -3 1596 1606 1611 -3 1595 1596 1611 -3 1606 1629 1628 -3 1611 1606 1628 -3 1629 1630 1628 -3 1630 1649 1648 -3 1628 1630 1648 -3 1649 1526 1668 -3 1648 1649 1668 -3 496 1681 1668 -3 1526 496 1668 -3 497 518 1681 -3 496 497 1681 -3 518 497 650 -3 1005 574 1210 -3 123 513 1351 -3 1877 1876 1865 -3 1558 1555 802 -3 799 1558 802 -3 472 857 498 -3 1455 1641 1639 -3 1634 1638 1620 -3 482 802 738 -3 1248 429 700 -3 1654 1655 1653 -3 1606 1630 1629 -3 1473 1478 1680 -3 1362 1499 1557 -3 1558 857 472 -3 1120 1184 1326 -3 857 851 831 -3 844 802 482 -3 474 844 482 -3 1555 1558 472 -3 844 799 802 -3 1342 1137 778 -3 1649 1669 1526 -3 1669 1506 496 -3 1526 1669 496 -3 1421 1411 1422 -3 851 532 481 -3 780 340 383 -3 1008 780 383 -3 1568 1567 1090 -3 1509 1568 1090 -3 1568 1581 1580 -3 1567 1568 1580 -3 1597 1596 1580 -3 1581 1597 1580 -3 1596 1597 1606 -3 1597 1612 1606 -3 1612 1631 1630 -3 1606 1612 1630 -3 1631 1650 1649 -3 1630 1631 1649 -3 1649 1650 1669 -3 1678 482 1677 -3 560 738 716 -3 1345 498 1091 -3 500 1100 1178 -3 1678 474 482 -3 1009 878 53 -3 1841 1855 1851 -3 1454 1527 1499 -3 827 107 1864 -3 495 516 75 -3 208 716 1198 -3 1428 1639 1621 -3 1771 1280 1093 -3 842 1008 808 -3 378 533 1063 -3 1582 1581 1568 -3 1659 1663 1658 -3 1865 1864 1851 -3 1503 514 980 -3 1583 1582 1568 -3 1588 1581 1582 -3 1583 1588 1582 -3 1598 1597 1581 -3 1588 1598 1581 -3 1433 1612 1597 -3 1433 1619 1612 -3 1632 1631 1612 -3 1619 1632 1612 -3 1651 1650 1631 -3 1632 1651 1631 -3 1651 1670 1669 -3 1650 1651 1669 -3 1670 1344 1506 -3 1669 1670 1506 -3 1660 1473 1455 -3 1353 842 808 -3 995 1353 808 -3 1353 1008 842 -3 1353 842 1008 -3 38 780 1008 -3 842 38 1008 -3 1517 1569 1568 -3 1509 1517 1568 -3 1569 1583 1568 -3 716 779 1198 -3 716 738 779 -3 560 482 738 -3 1360 1687 1534 -3 1353 38 842 -3 1111 1179 1383 -3 1598 1433 1597 -3 868 38 552 -3 1045 1078 1073 -3 1124 406 272 -3 1433 1632 1619 -3 474 223 1122 -3 1033 1765 1024 -3 1378 1359 1374 -3 1269 1270 1281 -3 291 782 444 -3 483 560 716 -3 1462 1473 1660 -3 499 1156 781 -3 1214 542 909 -3 1555 472 1345 -3 178 1559 1558 -3 851 481 831 -3 1269 1281 1268 -3 824 1856 1846 -3 53 1884 1009 -3 1439 1111 1517 -3 1111 1501 1569 -3 1517 1111 1569 -3 1411 1583 1569 -3 1411 1588 1583 -3 1411 1421 1588 -3 1421 1598 1588 -3 1421 1426 1598 -3 1426 1433 1598 -3 1434 1433 1598 -3 1433 1434 1598 -3 1633 1632 1433 -3 1434 1633 1433 -3 1633 1640 1632 -3 1652 1651 1632 -3 1640 1652 1632 -3 1671 1670 1651 -3 1652 1671 1651 -3 1671 1682 1344 -3 1670 1671 1344 -3 1274 1032 514 -3 1503 1274 514 -3 532 523 481 -3 1319 264 277 -3 546 806 1591 -3 546 995 806 -3 546 746 995 -3 1339 1353 995 -3 746 1339 995 -3 1339 1200 38 -3 1353 1339 38 -3 223 178 799 -3 1530 1344 1682 -3 1449 1633 1434 -3 399 744 1054 -3 831 812 123 -3 1122 223 799 -3 243 205 517 -3 1473 1679 1659 -3 1024 1034 1033 -3 1591 1340 546 -3 1501 1411 1569 -3 1156 499 1295 -3 1449 1640 1633 -3 1209 953 854 -3 1458 1462 1660 -3 1224 235 677 -3 1523 1153 1119 -3 1085 1355 1364 -3 1468 1652 1640 -3 1449 1468 1640 -3 1489 1671 1652 -3 1468 1489 1652 -3 1671 1489 1682 -3 1489 538 1682 -3 1836 1857 1844 -3 803 189 1117 -3 1685 1696 1695 -3 1785 1791 1801 -3 1808 1801 1791 -3 1791 1792 1815 -3 1751 1750 1735 -3 1843 1862 1842 -3 1210 444 115 -3 1800 1816 1799 -3 1803 1821 1802 -3 995 834 1591 -3 758 759 1182 -3 1836 1858 1857 -3 810 168 1857 -3 1858 810 1857 -3 1740 1757 1764 -3 873 872 865 -3 1808 1815 1801 -3 1815 1819 1801 -3 804 803 1117 -3 1741 1757 1740 -3 1793 865 1788 -3 1812 1816 1830 -3 804 1117 1878 -3 1561 1725 1726 -3 1857 168 824 -3 1757 1779 1764 -3 1764 1779 1786 -3 78 815 1868 -3 1822 1821 1803 -3 1717 1737 1721 -3 1844 1857 1846 -3 1725 1724 1013 -3 824 168 79 -3 1713 1718 1696 -3 1715 1714 1699 -3 1722 1730 1711 -3 1843 1842 1825 -3 1819 1843 1825 -3 1857 824 1846 -3 1821 1827 1826 -3 1809 1821 1826 -3 1815 1843 1819 -3 1821 1809 1802 -3 1548 1689 1549 -3 1733 1561 1562 -3 1733 1725 1561 -3 604 599 406 -3 406 599 202 -3 1822 1836 1821 -3 815 1881 1867 -3 1852 1855 1830 -3 1699 1706 1016 -3 54 55 845 -3 158 219 521 -3 1742 1741 1725 -3 1733 1742 1725 -3 1763 1777 1785 -3 1033 1788 1765 -3 1769 1776 1749 -3 1749 1755 1734 -3 1756 1769 1747 -3 1732 1751 1735 -3 1707 1714 1722 -3 1738 1754 1737 -3 1876 1864 1865 -3 1722 1714 1731 -3 865 1810 1787 -3 1788 865 1787 -3 1715 1732 1714 -3 1742 1757 1741 -3 1804 1803 1786 -3 1779 1804 1786 -3 1770 1791 1785 -3 1806 1810 242 -3 1722 1747 1730 -3 1705 1706 1707 -3 1804 1805 1803 -3 1835 1843 1815 -3 1346 551 1883 -3 1802 1809 1792 -3 1837 1836 1822 -3 1017 1837 1822 -3 1878 1117 1877 -3 1711 1730 1713 -3 1690 1706 1705 -3 1837 136 1836 -3 1830 1855 1841 -3 1868 1867 1856 -3 599 20 681 -3 136 1858 1836 -3 1791 1815 1808 -3 1024 1759 1018 -3 1730 1734 1713 -3 1785 1790 1756 -3 20 596 681 -3 1831 1830 1817 -3 1797 1802 1792 -3 1864 1876 827 -3 1881 815 814 -3 1787 1806 1781 -3 1116 916 1031 -3 814 1882 1872 -3 1711 1713 1697 -3 1110 1475 859 -3 1690 1705 1698 -3 1785 1801 1790 -3 1765 1787 1759 -3 596 20 556 -3 596 1180 681 -3 681 1180 1031 -3 1882 804 1872 -3 1698 1711 1697 -3 1759 1781 1758 -3 900 1883 979 -3 1696 1717 1704 -3 1026 1561 1562 -3 1769 1796 1776 -3 1013 1723 1715 -3 1734 1717 1718 -3 1832 1831 1813 -3 1180 316 1116 -3 1031 1180 1116 -3 1561 1742 1733 -3 1882 814 804 -3 1820 1835 1815 -3 1442 988 1447 -3 710 577 622 -3 1810 1806 1787 -3 596 1752 1180 -3 1180 316 1116 -3 316 1180 1116 -3 316 993 916 -3 1116 316 916 -3 1759 1787 1781 -3 1776 1800 1775 -3 1732 1735 1714 -3 1886 409 821 -3 1703 1729 1710 -3 1693 1685 1550 -3 1016 1706 1690 -3 1693 1689 1697 -3 1842 1862 1861 -3 1694 1695 1704 -3 1687 1685 1694 -3 988 382 1447 -3 1447 382 576 -3 747 797 120 -3 1776 1775 1755 -3 1199 1167 732 -3 1041 758 596 -3 596 758 1752 -3 1876 1158 107 -3 1685 1695 1694 -3 1858 818 810 -3 382 1431 576 -3 1693 1697 1696 -3 243 1888 798 -3 1117 189 187 -3 1823 1822 1803 -3 1805 1823 1803 -3 1442 1430 1443 -3 818 1858 136 -3 356 477 424 -3 382 1575 1431 -3 916 993 554 -3 467 590 1318 -3 1685 1693 1696 -3 1845 1866 1853 -3 1431 1575 1110 -3 1182 1752 758 -3 1182 1180 1752 -3 1182 825 1180 -3 1180 825 316 -3 1017 136 1837 -3 1430 1440 1443 -3 1440 908 988 -3 988 908 382 -3 1575 549 1110 -3 549 1150 963 -3 1110 549 963 -3 1825 1813 1814 -3 1796 1817 1800 -3 825 633 316 -3 1699 1714 1706 -3 633 993 316 -3 633 1323 993 -3 1430 1869 1440 -3 908 1575 382 -3 1101 963 1150 -3 1734 1738 1717 -3 1819 1825 1814 -3 1801 1819 1814 -3 633 825 1182 -3 1440 1869 908 -3 908 996 1575 -3 759 787 786 -3 1809 1826 1820 -3 1869 1145 908 -3 549 1101 1150 -3 1723 1732 1715 -3 1428 1847 1430 -3 1145 56 908 -3 908 56 996 -3 1144 1101 549 -3 1809 1820 1815 -3 1793 1788 1033 -3 797 633 1182 -3 759 797 1182 -3 1735 1750 1756 -3 996 56 1575 -3 56 549 1575 -3 1750 1763 1756 -3 1847 1848 1430 -3 1848 1859 1430 -3 1430 1859 1869 -3 56 1168 549 -3 1690 1689 1548 -3 1758 1779 1757 -3 786 797 759 -3 747 633 797 -3 633 747 1323 -3 1323 747 167 -3 865 866 873 -3 1778 1791 1770 -3 78 1868 824 -3 1805 1804 1779 -3 1428 1848 1847 -3 56 1053 1168 -3 1168 1131 1144 -3 549 1168 1144 -3 1877 1117 1876 -3 1707 1722 1711 -3 1731 1735 1739 -3 830 1823 1805 -3 830 1822 1823 -3 1859 1873 1145 -3 1869 1859 1145 -3 1131 1101 1144 -3 1814 1813 1790 -3 830 1017 1822 -3 207 562 561 -3 1772 1771 1093 -3 1557 1772 1093 -3 866 1033 1042 -3 1617 1417 1428 -3 1428 1417 1848 -3 1734 1755 1738 -3 1821 1836 1844 -3 1801 1814 1790 -3 895 797 786 -3 787 759 760 -3 1873 961 1145 -3 1145 961 56 -3 1053 1131 1168 -3 1833 1101 1131 -3 1833 710 1101 -3 1853 1871 1852 -3 1689 1690 1698 -3 1772 1275 1771 -3 1848 1417 1859 -3 242 830 1806 -3 1713 1734 1718 -3 1800 1799 1775 -3 1695 1696 1704 -3 1518 1557 1499 -3 1794 1275 1772 -3 1809 1815 1792 -3 1417 1418 1859 -3 961 951 56 -3 56 951 1053 -3 1833 1131 710 -3 1019 1742 1561 -3 1758 1757 1742 -3 1780 1779 1758 -3 1748 1557 1518 -3 1794 1277 1275 -3 1873 1879 961 -3 951 559 1053 -3 1053 559 1131 -3 1876 107 827 -3 1747 1769 1749 -3 1267 1277 1794 -3 1418 1863 1859 -3 1859 1863 1873 -3 1868 815 1867 -3 1766 1772 1557 -3 1748 1766 1557 -3 866 1793 1033 -3 559 1196 1131 -3 1196 1343 1131 -3 1131 1343 710 -3 1766 1794 1772 -3 180 1229 336 -3 415 1879 1873 -3 415 961 1879 -3 1343 577 710 -3 866 865 1793 -3 1362 1557 1093 -3 1789 1794 1766 -3 1873 1863 415 -3 1456 1442 1447 -3 1018 1742 1019 -3 1743 1748 1518 -3 1531 1743 1518 -3 1789 1267 1794 -3 434 961 415 -3 434 951 961 -3 1781 1779 1780 -3 1811 1267 1789 -3 1781 1805 1779 -3 404 522 438 -3 434 736 951 -3 736 559 951 -3 1743 1766 1748 -3 559 736 1196 -3 1722 1739 1747 -3 715 1393 1169 -3 1534 1090 1360 -3 1269 1271 1270 -3 604 1124 272 -3 1358 1531 1500 -3 1824 1268 1267 -3 1811 1824 1267 -3 155 813 1880 -3 736 480 1196 -3 1196 480 1343 -3 1343 480 577 -3 1790 1813 1796 -3 1782 1789 1766 -3 1760 1782 1766 -3 1803 1802 1797 -3 1777 1770 1785 -3 1719 1743 1531 -3 1760 1766 1743 -3 1838 1269 1268 -3 1824 1838 1268 -3 1750 1770 1777 -3 480 578 577 -3 1689 1693 1550 -3 1763 1750 1777 -3 1770 1777 1785 -3 1691 1358 1356 -3 1719 1531 1358 -3 736 1062 480 -3 1813 1831 1817 -3 1549 1689 1550 -3 1756 1763 1785 -3 1691 1356 1355 -3 1085 1691 1355 -3 1761 1760 1743 -3 1744 1761 1743 -3 1807 1811 1789 -3 1838 1271 1269 -3 78 824 79 -3 1876 187 1158 -3 1821 1844 1827 -3 1708 1719 1358 -3 1744 1743 1719 -3 1782 1807 1789 -3 1807 1824 1811 -3 1860 1271 1838 -3 736 451 1062 -3 1756 1790 1769 -3 1725 1740 1724 -3 1698 1705 1711 -3 1510 1691 1085 -3 1708 1358 1691 -3 1761 1782 1760 -3 1818 1824 1807 -3 1860 1272 1271 -3 1718 1717 1696 -3 451 207 480 -3 1062 451 480 -3 1817 1830 1816 -3 1796 1800 1776 -3 1510 1085 1052 -3 1818 1838 1824 -3 1875 1272 1860 -3 1813 1817 1796 -3 1720 1719 1708 -3 1736 1744 1719 -3 1839 1838 1818 -3 96 807 486 -3 1018 1758 1742 -3 1842 1861 1845 -3 1881 814 1872 -3 1781 1780 1758 -3 1867 1881 1872 -3 1692 1691 1510 -3 1720 1736 1719 -3 1783 1782 1761 -3 1839 1860 1838 -3 1875 1661 586 -3 1272 1875 586 -3 1806 1805 1781 -3 1712 1716 1708 -3 1727 1720 1708 -3 1716 1727 1708 -3 1854 1860 1839 -3 1143 1661 1875 -3 1661 99 586 -3 1143 99 1661 -3 1031 60 236 -3 1709 1708 1691 -3 1692 1709 1691 -3 1709 1712 1708 -3 1709 1716 1712 -3 1709 1727 1716 -3 1727 1728 1720 -3 1786 1803 1797 -3 747 120 167 -3 484 207 451 -3 1736 1753 1744 -3 1753 1761 1744 -3 1753 1783 1761 -3 1874 1860 1854 -3 1874 1875 1860 -3 1792 1791 1778 -3 824 1868 1856 -3 1817 1816 1800 -3 520 207 484 -3 1692 1700 1709 -3 1728 1727 1709 -3 1728 1745 1727 -3 1511 1688 1510 -3 1688 1692 1510 -3 1874 1143 1875 -3 1013 1715 1699 -3 1749 1776 1755 -3 1759 1758 1018 -3 1688 1701 1700 -3 1692 1688 1700 -3 1773 1783 1753 -3 1849 1854 1839 -3 813 1143 1874 -3 813 99 1143 -3 1842 1845 1832 -3 1710 1709 1700 -3 1701 1710 1700 -3 1872 804 1878 -3 1825 1842 1832 -3 1853 1852 1830 -3 1730 1749 1734 -3 1689 1698 1697 -3 1805 1806 830 -3 1710 1728 1709 -3 1840 1849 1839 -3 1831 1853 1830 -3 1724 1723 1013 -3 1729 1728 1710 -3 1849 1874 1854 -3 1849 1870 1874 -3 1741 1740 1725 -3 1755 1775 1754 -3 1731 1714 1735 -3 1747 1749 1730 -3 1706 1714 1707 -3 1729 1745 1728 -3 1767 1773 1753 -3 1880 813 1874 -3 1870 1880 1874 -3 865 858 1810 -3 1810 858 259 -3 1861 1866 1845 -3 1790 1796 1769 -3 1755 1754 1738 -3 1739 1735 1747 -3 1686 1688 1511 -3 1439 1686 1511 -3 1746 1745 1729 -3 1774 1773 1767 -3 1834 1849 1840 -3 1016 1690 1548 -3 1788 1787 1765 -3 1551 1016 1548 -3 1686 1702 1701 -3 1688 1686 1701 -3 1703 1710 1701 -3 1702 1703 1701 -3 1795 1798 1773 -3 1825 1832 1813 -3 1697 1713 1696 -3 1762 1745 1746 -3 1762 1768 1745 -3 1795 1773 1774 From 8e7eb79f6e9b1eda2ab5b1f8b418ff61c4b3eb07 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 20 Sep 2013 16:02:15 +0400 Subject: [PATCH 202/205] fixed compile errors and warnings when building master branch with IPP enabled --- modules/core/src/stat.cpp | 18 ++++++++++------ modules/imgproc/src/distransform.cpp | 6 +++--- modules/imgproc/src/samplers.cpp | 31 +++++++++++++++------------- modules/objdetect/src/haar.cpp | 2 +- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 86555fcc3..bf0788e6b 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -1616,8 +1616,10 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) size_t total_size = src.total(); int rows = src.size[0], cols = (int)(total_size/rows); - if( src.dims == 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) - && (normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR) ) + if( (src.dims == 2 || (src.isContinuous() && mask.isContinuous())) + && cols > 0 && (size_t)rows*cols == total_size + && (normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR) ) { IppiSize sz = { cols, rows }; int type = src.type(); @@ -1903,8 +1905,10 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) ); size_t total_size = src1.total(); int rows = src1.size[0], cols = (int)(total_size/rows); - if( src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) - && (normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR) ) + if( (src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous())) + && cols > 0 && (size_t)rows*cols == total_size + && (normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR) ) { IppiSize sz = { cols, rows }; int type = src1.type(); @@ -1983,8 +1987,10 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) size_t total_size = src1.total(); int rows = src1.size[0], cols = (int)(total_size/rows); - if( src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) - && (normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR) ) + if( (src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous())) + && cols > 0 && (size_t)rows*cols == total_size + && (normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR) ) { IppiSize sz = { cols, rows }; int type = src1.type(); diff --git a/modules/imgproc/src/distransform.cpp b/modules/imgproc/src/distransform.cpp index 29e3fc10a..94a559285 100644 --- a/modules/imgproc/src/distransform.cpp +++ b/modules/imgproc/src/distransform.cpp @@ -747,10 +747,10 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) if( maskSize == CV_DIST_MASK_5 ) { - IppiSize roi = { src->cols, src->rows }; + IppiSize roi = { src.cols, src.rows }; if( ippiDistanceTransform_5x5_8u32f_C1R( - src->data.ptr, src->step, - dst->data.fl, dst->step, roi, _mask) >= 0 ) + src.ptr(), (int)src.step, + dst.ptr(), (int)dst.step, roi, _mask) >= 0 ) return; } #endif diff --git a/modules/imgproc/src/samplers.cpp b/modules/imgproc/src/samplers.cpp index 64b7b6296..81cd23afc 100644 --- a/modules/imgproc/src/samplers.cpp +++ b/modules/imgproc/src/samplers.cpp @@ -267,12 +267,6 @@ static void getRectSubPix_8u32f } } -typedef CvStatus (CV_STDCALL *CvIPPGetRectSubPixFunc)( const void* src, int src_step, - CvSize src_size, void* dst, - int dst_step, CvSize win_size, - CvPoint2D32f center, - CvPoint* minpt, CvPoint* maxpt ); - static void getQuadrangleSubPix_8u32f_CnR( const uchar* src, size_t src_step, Size src_size, float* dst, size_t dst_step, Size win_size, @@ -367,6 +361,7 @@ getQuadrangleSubPix_8u32f_CnR( const uchar* src, size_t src_step, Size src_size, } + void cv::getRectSubPix( InputArray _image, Size patchSize, Point2f center, OutputArray _patch, int patchType ) { @@ -380,15 +375,23 @@ void cv::getRectSubPix( InputArray _image, Size patchSize, Point2f center, Mat patch = _patch.getMat(); #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CvPoint minpt, maxpt; - int srctype = CV_MAT_TYPE(src->type), dsttype = CV_MAT_TYPE(dst->type); - CvIPPGetRectSubPixFunc ippfunc = - srctype == CV_8UC1 && dsttype == CV_8UC1 ? (CvIPPGetRectSubPixFunc)ippiCopySubpixIntersect_8u_C1R : - srctype == CV_8UC1 && dsttype == CV_32FC1 ? (CvIPPGetRectSubPixFunc)ippiCopySubpixIntersect_8u32f_C1R : - srctype == CV_32FC1 && dsttype == CV_32FC1 ? (CvIPPGetRectSubPixFunc)ippiCopySubpixIntersect_32f_C1R : 0; + typedef IppStatus (CV_STDCALL *ippiGetRectSubPixFunc)( const void* src, int src_step, + IppiSize src_size, void* dst, + int dst_step, IppiSize win_size, + IppiPoint_32f center, + IppiPoint* minpt, IppiPoint* maxpt ); - if( ippfunc && ippfunc(src->data.ptr, src->step, src_size, dst->data.ptr, - dst->step, dst_size, center, &minpt, &maxpt) >= 0 ) + IppiPoint minpt={0,0}, maxpt={0,0}; + IppiPoint_32f icenter = {center.x, center.y}; + IppiSize src_size={image.cols, image.rows}, win_size={patch.cols, patch.rows}; + int srctype = image.type(); + ippiGetRectSubPixFunc ippfunc = + srctype == CV_8UC1 && ddepth == CV_8U ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_8u_C1R : + srctype == CV_8UC1 && ddepth == CV_32F ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_8u32f_C1R : + srctype == CV_32FC1 && ddepth == CV_32F ? (ippiGetRectSubPixFunc)ippiCopySubpixIntersect_32f_C1R : 0; + + if( ippfunc && ippfunc(image.data, (int)image.step, src_size, patch.data, + (int)patch.step, win_size, icenter, &minpt, &maxpt) >= 0 ) return; #endif diff --git a/modules/objdetect/src/haar.cpp b/modules/objdetect/src/haar.cpp index cbb60b091..a83dfa93e 100644 --- a/modules/objdetect/src/haar.cpp +++ b/modules/objdetect/src/haar.cpp @@ -1564,7 +1564,7 @@ cvHaarDetectObjectsForROC( const CvArr* _img, int use_ipp = cascade->hid_cascade->ipp_stages != 0; if( use_ipp ) - normImg = cvCreateMat( img->rows, img->cols, CV_32FC1 ); + normImg.reset(cvCreateMat( img->rows, img->cols, CV_32FC1)); #endif imgSmall.reset(cvCreateMat( img->rows + 1, img->cols + 1, CV_8UC1 )); From 4b19fda1d6d7b1d7a888188d42165c3077b10216 Mon Sep 17 00:00:00 2001 From: John Stowers Date: Tue, 10 Sep 2013 13:36:57 +0200 Subject: [PATCH 203/205] Add brisk features to python demos --- samples/python2/asift.py | 6 +++--- samples/python2/find_obj.py | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/samples/python2/asift.py b/samples/python2/asift.py index ae044d527..e522fa7ab 100755 --- a/samples/python2/asift.py +++ b/samples/python2/asift.py @@ -11,10 +11,10 @@ is used to reject outliers. Threading is used for faster affine sampling. [1] http://www.ipol.im/pub/algo/my_affine_sift/ USAGE - asift.py [--feature=[-flann]] [ ] + asift.py [--feature=[-flann]] [ ] - --feature - Feature to use. Can be sift, surf of orb. Append '-flann' to feature name - to use Flann-based matcher instead bruteforce. + --feature - Feature to use. Can be sift, surf, orb or brisk. Append '-flann' + to feature name to use Flann-based matcher instead bruteforce. Press left mouse button on a feature point to see its mathcing point. ''' diff --git a/samples/python2/find_obj.py b/samples/python2/find_obj.py index 908da68fe..ca4ee4daf 100755 --- a/samples/python2/find_obj.py +++ b/samples/python2/find_obj.py @@ -4,10 +4,10 @@ Feature-based image matching sample. USAGE - find_obj.py [--feature=[-flann]] [ ] + find_obj.py [--feature=[-flann]] [ ] - --feature - Feature to use. Can be sift, surf of orb. Append '-flann' to feature name - to use Flann-based matcher instead bruteforce. + --feature - Feature to use. Can be sift, surf, orb or brisk. Append '-flann' + to feature name to use Flann-based matcher instead bruteforce. Press left mouse button on a feature point to see its matching point. ''' @@ -31,6 +31,9 @@ def init_feature(name): elif chunks[0] == 'orb': detector = cv2.ORB(400) norm = cv2.NORM_HAMMING + elif chunks[0] == 'brisk': + detector = cv2.BRISK() + norm = cv2.NORM_HAMMING else: return None, None if 'flann' in chunks: From 720241de87a52e7c96e15d53f4dcc21650a276c5 Mon Sep 17 00:00:00 2001 From: shawke Date: Tue, 24 Sep 2013 11:48:04 +0200 Subject: [PATCH 204/205] Make similar default typedefs for Point_, Size_ and Rect_ Currently, there are different default typedefs for Point_, Size_, and Rect_. This pull request at least makes sure that default typedefs exist for int, float and double variants of each of these types. --- modules/core/include/opencv2/core/types.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/core/include/opencv2/core/types.hpp b/modules/core/include/opencv2/core/types.hpp index 9252cad14..e2b49749e 100644 --- a/modules/core/include/opencv2/core/types.hpp +++ b/modules/core/include/opencv2/core/types.hpp @@ -282,6 +282,7 @@ public: */ typedef Size_ Size2i; typedef Size_ Size2f; +typedef Size_ Size2d; typedef Size2i Size; /*! @@ -349,7 +350,10 @@ public: /*! \typedef */ -typedef Rect_ Rect; +typedef Rect_ Rect2i; +typedef Rect_ Rect2f; +typedef Rect_ Rect2d; +typedef Rect2i Rect; /*! traits From e675684c81ac8b0094b8414960473a83fd5454c2 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Tue, 24 Sep 2013 14:45:13 +0400 Subject: [PATCH 205/205] fix bug #3277 (findCirclesGrid failures): findHomagraphy can return empty Mat in master branch --- modules/calib3d/src/circlesgrid.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/calib3d/src/circlesgrid.cpp b/modules/calib3d/src/circlesgrid.cpp index 969611fbc..f44807e47 100644 --- a/modules/calib3d/src/circlesgrid.cpp +++ b/modules/calib3d/src/circlesgrid.cpp @@ -836,6 +836,9 @@ Mat CirclesGridFinder::rectifyGrid(Size detectedGridSize, const std::vector srcKeypoints; for (size_t i = 0; i < keypoints.size(); i++) {