From eb8728d72751d78342d2dbb9fb11110380cf6c50 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 2 Feb 2014 19:00:54 +0400 Subject: [PATCH 01/25] Updated cloud io functionality - removed dependency from VTK legacy --- modules/viz/src/precomp.hpp | 4 +- modules/viz/src/vizcore.cpp | 4 +- modules/viz/src/vtk/vtkCloudMatSink.cpp | 16 ++++ modules/viz/src/vtk/vtkCloudMatSink.h | 12 ++- modules/viz/src/vtk/vtkOBJWriter.cpp | 37 +++++++- modules/viz/src/vtk/vtkOBJWriter.h | 22 +++-- modules/viz/src/vtk/vtkXYZReader.cpp | 107 ++++++++++++++++++++++++ modules/viz/src/vtk/vtkXYZReader.h | 80 ++++++++++++++++++ modules/viz/src/vtk/vtkXYZWriter.cpp | 37 +++++++- modules/viz/src/vtk/vtkXYZWriter.h | 18 +++- 10 files changed, 313 insertions(+), 24 deletions(-) create mode 100644 modules/viz/src/vtk/vtkXYZReader.cpp create mode 100644 modules/viz/src/vtk/vtkXYZReader.h diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index d9681ce83..2b34f5638 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -76,7 +76,6 @@ #include #include #include -#include #include #include #include @@ -115,11 +114,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -142,6 +139,7 @@ #include #include +#include #include #include #include diff --git a/modules/viz/src/vizcore.cpp b/modules/viz/src/vizcore.cpp index b4ec83bd4..b8cad1ca6 100644 --- a/modules/viz/src/vizcore.cpp +++ b/modules/viz/src/vizcore.cpp @@ -173,8 +173,8 @@ cv::Mat cv::viz::readCloud(const String& file, OutputArray colors, OutputArray n vtkSmartPointer reader; if (extention == ".xyz") { - reader = vtkSmartPointer::New(); - vtkSimplePointsReader::SafeDownCast(reader)->SetFileName(file.c_str()); + reader = vtkSmartPointer::New(); + vtkXYZReader::SafeDownCast(reader)->SetFileName(file.c_str()); } else if (extention == ".ply") { diff --git a/modules/viz/src/vtk/vtkCloudMatSink.cpp b/modules/viz/src/vtk/vtkCloudMatSink.cpp index 09ef0cca9..7f47022c3 100644 --- a/modules/viz/src/vtk/vtkCloudMatSink.cpp +++ b/modules/viz/src/vtk/vtkCloudMatSink.cpp @@ -156,3 +156,19 @@ void cv::viz::vtkCloudMatSink::PrintSelf(ostream& os, vtkIndent indent) os << indent << "Colors: " << colors.needed() << "\n"; os << indent << "Normals: " << normals.needed() << "\n"; } + +int cv::viz::vtkCloudMatSink::FillInputPortInformation(int, vtkInformation *info) +{ + info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData"); + return 1; +} + +vtkPolyData* cv::viz::vtkCloudMatSink::GetInput() +{ + return vtkPolyData::SafeDownCast(this->Superclass::GetInput()); +} + +vtkPolyData* cv::viz::vtkCloudMatSink::GetInput(int port) +{ + return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port)); +} diff --git a/modules/viz/src/vtk/vtkCloudMatSink.h b/modules/viz/src/vtk/vtkCloudMatSink.h index 44d7e52a5..b3fd3eb71 100644 --- a/modules/viz/src/vtk/vtkCloudMatSink.h +++ b/modules/viz/src/vtk/vtkCloudMatSink.h @@ -46,26 +46,32 @@ #define __vtkCloudMatSink_h #include -#include +#include namespace cv { namespace viz { - class vtkCloudMatSink : public vtkPolyDataWriter + class vtkCloudMatSink : public vtkWriter { public: static vtkCloudMatSink *New(); - vtkTypeMacro(vtkCloudMatSink,vtkPolyDataWriter) + vtkTypeMacro(vtkCloudMatSink,vtkWriter) void PrintSelf(ostream& os, vtkIndent indent); void SetOutput(OutputArray cloud, OutputArray colors = noArray(), OutputArray normals = noArray(), OutputArray tcoords = noArray()); + // Description: + // Get the input to this writer. + vtkPolyData* GetInput(); + vtkPolyData* GetInput(int port); + protected: vtkCloudMatSink(); ~vtkCloudMatSink(); void WriteData(); + int FillInputPortInformation(int port, vtkInformation *info); _OutputArray cloud, colors, normals, tcoords; diff --git a/modules/viz/src/vtk/vtkOBJWriter.cpp b/modules/viz/src/vtk/vtkOBJWriter.cpp index 452ad19a7..e92424c66 100644 --- a/modules/viz/src/vtk/vtkOBJWriter.cpp +++ b/modules/viz/src/vtk/vtkOBJWriter.cpp @@ -54,7 +54,6 @@ cv::viz::vtkOBJWriter::vtkOBJWriter() std::ofstream fout; // only used to extract the default precision this->DecimalPrecision = fout.precision(); this->FileName = NULL; - this->FileType = VTK_ASCII; } cv::viz::vtkOBJWriter::~vtkOBJWriter(){} @@ -65,9 +64,22 @@ void cv::viz::vtkOBJWriter::WriteData() if (!input) return; - std::ostream *outfilep = this->OpenVTKFile(); - if (!outfilep) + if (!this->FileName ) + { + vtkErrorMacro(<< "No FileName specified! Can't write!"); + this->SetErrorCode(vtkErrorCode::NoFileNameError); return; + } + + vtkDebugMacro(<<"Opening vtk file for writing..."); + ostream *outfilep = new ofstream(this->FileName, ios::out); + if (outfilep->fail()) + { + vtkErrorMacro(<< "Unable to open file: "<< this->FileName); + this->SetErrorCode(vtkErrorCode::CannotOpenFileError); + delete outfilep; + return; + } std::ostream& outfile = *outfilep; @@ -224,7 +236,8 @@ void cv::viz::vtkOBJWriter::WriteData() } } /* if (input->GetNumberOfStrips() > 0) */ - this->CloseVTKFile(outfilep); + vtkDebugMacro(<<"Closing vtk file\n"); + delete outfilep; // Delete the file if an error occurred if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError) @@ -239,3 +252,19 @@ void cv::viz::vtkOBJWriter::PrintSelf(ostream& os, vtkIndent indent) Superclass::PrintSelf(os, indent); os << indent << "DecimalPrecision: " << DecimalPrecision << "\n"; } + +int cv::viz::vtkOBJWriter::FillInputPortInformation(int, vtkInformation *info) +{ + info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData"); + return 1; +} + +vtkPolyData* cv::viz::vtkOBJWriter::GetInput() +{ + return vtkPolyData::SafeDownCast(this->Superclass::GetInput()); +} + +vtkPolyData* cv::viz::vtkOBJWriter::GetInput(int port) +{ + return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port)); +} diff --git a/modules/viz/src/vtk/vtkOBJWriter.h b/modules/viz/src/vtk/vtkOBJWriter.h index f8889884d..7ad0f17b1 100644 --- a/modules/viz/src/vtk/vtkOBJWriter.h +++ b/modules/viz/src/vtk/vtkOBJWriter.h @@ -45,29 +45,41 @@ #ifndef __vtkOBJWriter_h #define __vtkOBJWriter_h -#include +#include namespace cv { namespace viz { - class vtkOBJWriter : public vtkPolyDataWriter + class vtkOBJWriter : public vtkWriter { public: static vtkOBJWriter *New(); - vtkTypeMacro(vtkOBJWriter,vtkPolyDataWriter) + vtkTypeMacro(vtkOBJWriter,vtkWriter) void PrintSelf(ostream& os, vtkIndent indent); - vtkGetMacro(DecimalPrecision, int); - vtkSetMacro(DecimalPrecision, int); + vtkGetMacro(DecimalPrecision, int) + vtkSetMacro(DecimalPrecision, int) + + // Description: + // Specify file name of data file to write. + vtkSetStringMacro(FileName) + vtkGetStringMacro(FileName) + + // Description: + // Get the input to this writer. + vtkPolyData* GetInput(); + vtkPolyData* GetInput(int port); protected: vtkOBJWriter(); ~vtkOBJWriter(); void WriteData(); + int FillInputPortInformation(int port, vtkInformation *info); int DecimalPrecision; + char *FileName; private: vtkOBJWriter(const vtkOBJWriter&); // Not implemented. diff --git a/modules/viz/src/vtk/vtkXYZReader.cpp b/modules/viz/src/vtk/vtkXYZReader.cpp new file mode 100644 index 000000000..283a59248 --- /dev/null +++ b/modules/viz/src/vtk/vtkXYZReader.cpp @@ -0,0 +1,107 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace viz +{ + vtkStandardNewMacro(vtkXYZReader); +}} + + +cv::viz::vtkXYZReader::vtkXYZReader() +{ + this->FileName = 0; + this->SetNumberOfInputPorts(0); +} + +cv::viz::vtkXYZReader::~vtkXYZReader() +{ + this->SetFileName(0); +} + +void cv::viz::vtkXYZReader::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os,indent); + os << indent << "FileName: " << (this->FileName ? this->FileName : "(none)") << "\n"; +} + +int cv::viz::vtkXYZReader::RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector) +{ + // Make sure we have a file to read. + if(!this->FileName) + { + vtkErrorMacro("A FileName must be specified."); + return 0; + } + + // Open the input file. + ifstream fin(this->FileName); + if(!fin) + { + vtkErrorMacro("Error opening file " << this->FileName); + return 0; + } + + // Allocate objects to hold points and vertex cells. + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer verts = vtkSmartPointer::New(); + + // Read points from the file. + vtkDebugMacro("Reading points from file " << this->FileName); + double x[3]; + while(fin >> x[0] >> x[1] >> x[2]) + { + vtkIdType id = points->InsertNextPoint(x); + verts->InsertNextCell(1, &id); + } + vtkDebugMacro("Read " << points->GetNumberOfPoints() << " points."); + + // Store the points and cells in the output data object. + vtkPolyData* output = vtkPolyData::GetData(outputVector); + output->SetPoints(points); + output->SetVerts(verts); + + return 1; +} diff --git a/modules/viz/src/vtk/vtkXYZReader.h b/modules/viz/src/vtk/vtkXYZReader.h new file mode 100644 index 000000000..13ae048ec --- /dev/null +++ b/modules/viz/src/vtk/vtkXYZReader.h @@ -0,0 +1,80 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __vtkXYZReader_h +#define __vtkXYZReader_h + +#include "vtkPolyDataAlgorithm.h" + +namespace cv +{ + namespace viz + { + class vtkXYZReader : public vtkPolyDataAlgorithm + { + public: + static vtkXYZReader* New(); + vtkTypeMacro(vtkXYZReader,vtkPolyDataAlgorithm) + void PrintSelf(ostream& os, vtkIndent indent); + + // Description: + // Set/Get the name of the file from which to read points. + vtkSetStringMacro(FileName) + vtkGetStringMacro(FileName) + + protected: + vtkXYZReader(); + ~vtkXYZReader(); + + char* FileName; + + int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*); + private: + vtkXYZReader(const vtkXYZReader&); // Not implemented. + void operator=(const vtkXYZReader&); // Not implemented. + }; + } +} + +#endif diff --git a/modules/viz/src/vtk/vtkXYZWriter.cpp b/modules/viz/src/vtk/vtkXYZWriter.cpp index 4518a0103..5a3d7d5c8 100644 --- a/modules/viz/src/vtk/vtkXYZWriter.cpp +++ b/modules/viz/src/vtk/vtkXYZWriter.cpp @@ -61,10 +61,22 @@ void cv::viz::vtkXYZWriter::WriteData() if (!input) return; - // OpenVTKFile() will report any errors that happen - ostream *outfilep = this->OpenVTKFile(); - if (!outfilep) + if (!this->FileName ) + { + vtkErrorMacro(<< "No FileName specified! Can't write!"); + this->SetErrorCode(vtkErrorCode::NoFileNameError); return; + } + + vtkDebugMacro(<<"Opening vtk file for writing..."); + ostream *outfilep = new ofstream(this->FileName, ios::out); + if (outfilep->fail()) + { + vtkErrorMacro(<< "Unable to open file: "<< this->FileName); + this->SetErrorCode(vtkErrorCode::CannotOpenFileError); + delete outfilep; + return; + } ostream &outfile = *outfilep; @@ -76,7 +88,8 @@ void cv::viz::vtkXYZWriter::WriteData() } // Close the file - this->CloseVTKFile(outfilep); + vtkDebugMacro(<<"Closing vtk file\n"); + delete outfilep; // Delete the file if an error occurred if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError) @@ -86,8 +99,24 @@ void cv::viz::vtkXYZWriter::WriteData() } } +int cv::viz::vtkXYZWriter::FillInputPortInformation(int, vtkInformation *info) +{ + info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData"); + return 1; +} + void cv::viz::vtkXYZWriter::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); os << indent << "DecimalPrecision: " << this->DecimalPrecision << "\n"; } + +vtkPolyData* cv::viz::vtkXYZWriter::GetInput() +{ + return vtkPolyData::SafeDownCast(this->Superclass::GetInput()); +} + +vtkPolyData* cv::viz::vtkXYZWriter::GetInput(int port) +{ + return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port)); +} diff --git a/modules/viz/src/vtk/vtkXYZWriter.h b/modules/viz/src/vtk/vtkXYZWriter.h index 3db18b793..91d0c8f6b 100644 --- a/modules/viz/src/vtk/vtkXYZWriter.h +++ b/modules/viz/src/vtk/vtkXYZWriter.h @@ -45,29 +45,41 @@ #ifndef __vtkXYZWriter_h #define __vtkXYZWriter_h -#include "vtkPolyDataWriter.h" +#include "vtkWriter.h" namespace cv { namespace viz { - class vtkXYZWriter : public vtkPolyDataWriter + class vtkXYZWriter : public vtkWriter { public: static vtkXYZWriter *New(); - vtkTypeMacro(vtkXYZWriter,vtkPolyDataWriter) + vtkTypeMacro(vtkXYZWriter,vtkWriter) void PrintSelf(ostream& os, vtkIndent indent); vtkGetMacro(DecimalPrecision, int) vtkSetMacro(DecimalPrecision, int) + // Description: + // Specify file name of data file to write. + vtkSetStringMacro(FileName) + vtkGetStringMacro(FileName) + + // Description: + // Get the input to this writer. + vtkPolyData* GetInput(); + vtkPolyData* GetInput(int port); + protected: vtkXYZWriter(); ~vtkXYZWriter(){} void WriteData(); + int FillInputPortInformation(int port, vtkInformation *info); int DecimalPrecision; + char *FileName; private: vtkXYZWriter(const vtkXYZWriter&); // Not implemented. From 975a6299fa1b1fee9454567280fbe251347512dd Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 2 Feb 2014 18:56:55 +0400 Subject: [PATCH 02/25] More proper OpneCv+Qt+Vtk issues handling (http://code.opencv.org/issues/3492) --- cmake/OpenCVDetectVTK.cmake | 55 +++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/cmake/OpenCVDetectVTK.cmake b/cmake/OpenCVDetectVTK.cmake index 78d1a73b6..2b55a9c3f 100644 --- a/cmake/OpenCVDetectVTK.cmake +++ b/cmake/OpenCVDetectVTK.cmake @@ -2,25 +2,52 @@ if(NOT WITH_VTK OR ANDROID OR IOS) return() endif() -if (HAVE_QT5) - message(STATUS "VTK is disabled because OpenCV is linked with Q5. Some VTK disributives are compiled with Q4 and therefore can't be linked together Qt5.") +# VTK 6.x components +find_package(VTK QUIET COMPONENTS vtkRenderingOpenGL vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE) + +# VTK 5.x components +if(NOT VTK_FOUND) + find_package(VTK QUIET COMPONENTS vtkCommon NO_MODULE) +endif() + +if(NOT VTK_FOUND) + set(HAVE_VTK OFF) + message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or to VTK install subdirectory with VTKConfig.cmake file") return() endif() -find_package(VTK 6.0 QUIET COMPONENTS vtkRenderingCore vtkInteractionWidgets vtkInteractionStyle vtkIOLegacy vtkIOPLY vtkRenderingFreeType vtkRenderingLOD vtkFiltersTexture vtkIOExport NO_MODULE) - -if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND) - find_package(VTK 5.10 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE) +# Don't support ealier VTKs +if(${VTK_VERSION} VERSION_LESS "5.8.0") + message(STATUS "VTK support is disabled. VTK ver. 5.8.0 is minimum required, but found VTK ver. ${VTK_VERSION}") + return() endif() -if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND) - find_package(VTK 5.8 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE) +# Different Qt versions can't be linked together +if(HAVE_QT5 AND ${VTK_VERSION} VERSION_LESS "6.0.0") + if(VTK_USE_QT) + message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4") + endif() endif() -if(VTK_FOUND) - set(HAVE_VTK ON) - message(STATUS "Found VTK ver. ${VTK_VERSION} (usefile: ${VTK_USE_FILE})") -else() - set(HAVE_VTK OFF) - message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or set $VTK_DIR enviroment variable to VTK install subdirectory with VTKConfig.cmake file (for windows)") +# Different Qt versions can't be linked together. VTK 6.0.0 doesn't provide a way to get Qt version it was linked with +if(HAVE_QT5 AND ${VTK_VERSION} VERSION_EQUAL "6.0.0" AND NOT DEFINED FORCE_VTK) + message(STATUS "VTK support is disabled. Possible incompatible combination: OpenCV+Qt5, and VTK ver.${VTK_VERSION} with Qt4") + message(STATUS "If it is known that VTK was compiled without Qt4, please define '-DFORCE_VTK=TRUE' flag in CMake") + return() endif() + +# Different Qt versions can't be linked together +if(HAVE_QT AND ${VTK_VERSION} VERSION_GREATER "6.0.0" AND NOT ${VTK_QT_VERSION} STREQUAL "") + if(HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "4") + message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4") + return() + endif() + + if(NOT HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "5") + message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt4 and VTK ver.${VTK_VERSION} + Qt5") + return() + endif() +endif() + +set(HAVE_VTK ON) +message(STATUS "Found VTK ver. ${VTK_VERSION} (usefile: ${VTK_USE_FILE})") From 998aefd1d10a5cce794cf4c81248796719b9b0e6 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 2 Feb 2014 20:43:43 +0400 Subject: [PATCH 03/25] cloud collection merges data only on rendering --- modules/viz/src/clouds.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/modules/viz/src/clouds.cpp b/modules/viz/src/clouds.cpp index 4b84e8e9e..b7c8bbb21 100644 --- a/modules/viz/src/clouds.cpp +++ b/modules/viz/src/clouds.cpp @@ -211,13 +211,16 @@ void cv::viz::WCloudCollection::addCloud(InputArray cloud, InputArray colors, co vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); if (!mapper) { + vtkSmartPointer append_filter = vtkSmartPointer::New(); + VtkUtils::AddInputData(append_filter, polydata); + // This is the first cloud mapper = vtkSmartPointer::New(); mapper->SetScalarRange(0, 255); mapper->SetScalarModeToUsePointData(); mapper->ScalarVisibilityOn(); mapper->ImmediateModeRenderingOff(); - VtkUtils::SetInputData(mapper, polydata); + mapper->SetInputConnection(append_filter->GetOutputPort()); actor->SetNumberOfCloudPoints(std::max(1, polydata->GetNumberOfPoints()/10)); actor->GetProperty()->SetInterpolationToFlat(); @@ -226,15 +229,10 @@ void cv::viz::WCloudCollection::addCloud(InputArray cloud, InputArray colors, co return; } - vtkPolyData *currdata = vtkPolyData::SafeDownCast(mapper->GetInput()); - CV_Assert("Cloud Widget without data" && currdata); - - vtkSmartPointer append_filter = vtkSmartPointer::New(); - VtkUtils::AddInputData(append_filter, currdata); + vtkSmartPointer producer = mapper->GetInputConnection(0, 0)->GetProducer(); + vtkSmartPointer append_filter = vtkAppendPolyData::SafeDownCast(producer); VtkUtils::AddInputData(append_filter, polydata); - append_filter->Update(); - - VtkUtils::SetInputData(mapper, append_filter->GetOutput()); + append_filter->Modified(); actor->SetNumberOfCloudPoints(std::max(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10)); } From 17fea0dd0ad30f06d4676eb1d4e9320b4e6e9aa4 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 2 Feb 2014 21:29:33 +0400 Subject: [PATCH 04/25] fixed size_t/int conversion warnings --- modules/viz/src/clouds.cpp | 2 +- modules/viz/src/precomp.hpp | 4 ++-- modules/viz/src/shapes.cpp | 12 ++++++------ modules/viz/src/vizcore.cpp | 4 ++-- modules/viz/src/vtk/vtkCloudMatSink.cpp | 10 +++++----- modules/viz/src/vtk/vtkCloudMatSource.cpp | 4 ++-- modules/viz/src/vtk/vtkTrajectorySource.cpp | 10 +++++----- modules/viz/test/tests_simple.cpp | 21 +++++++++++---------- 8 files changed, 34 insertions(+), 33 deletions(-) diff --git a/modules/viz/src/clouds.cpp b/modules/viz/src/clouds.cpp index b7c8bbb21..c2c78d552 100644 --- a/modules/viz/src/clouds.cpp +++ b/modules/viz/src/clouds.cpp @@ -347,7 +347,7 @@ cv::viz::WMesh::WMesh(const Mesh &mesh) source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords); source->Update(); - Mat lookup_buffer(1, mesh.cloud.total(), CV_32SC1); + Mat lookup_buffer(1, (int)mesh.cloud.total(), CV_32SC1); int *lookup = lookup_buffer.ptr(); for(int y = 0, index = 0; y < mesh.cloud.rows; ++y) { diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 2b34f5638..8329f52f1 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -267,8 +267,8 @@ namespace cv vtkSmartPointer scalars = vtkSmartPointer::New(); scalars->SetName("Colors"); scalars->SetNumberOfComponents(3); - scalars->SetNumberOfTuples(size); - scalars->SetArray(color_data->val, size * 3, 0); + scalars->SetNumberOfTuples((vtkIdType)size); + scalars->SetArray(color_data->val, (vtkIdType)(size * 3), 0); return scalars; } diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index f3d24f757..171470d81 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -390,21 +390,21 @@ cv::viz::WPolyLine::WPolyLine(InputArray _points, const Color &color) vtkSmartPointer points = vtkSmartPointer::New(); points->SetDataType(_points.depth() == CV_32F ? VTK_FLOAT : VTK_DOUBLE); - points->SetNumberOfPoints(total); + points->SetNumberOfPoints((vtkIdType)total); if (_points.depth() == CV_32F) for(size_t i = 0; i < total; ++i, fpoints += s_chs) - points->SetPoint(i, fpoints); + points->SetPoint((vtkIdType)i, fpoints); if (_points.depth() == CV_64F) for(size_t i = 0; i < total; ++i, dpoints += s_chs) - points->SetPoint(i, dpoints); + points->SetPoint((vtkIdType)i, dpoints); vtkSmartPointer cell_array = vtkSmartPointer::New(); - cell_array->Allocate(cell_array->EstimateSize(1, total)); - cell_array->InsertNextCell(total); + cell_array->Allocate(cell_array->EstimateSize(1, (int)total)); + cell_array->InsertNextCell((int)total); for(size_t i = 0; i < total; ++i) - cell_array->InsertCellPoint(i); + cell_array->InsertCellPoint((vtkIdType)i); vtkSmartPointer scalars = VtkUtils::FillScalars(total, color); diff --git a/modules/viz/src/vizcore.cpp b/modules/viz/src/vizcore.cpp index b8cad1ca6..b4332a860 100644 --- a/modules/viz/src/vizcore.cpp +++ b/modules/viz/src/vizcore.cpp @@ -278,11 +278,11 @@ void cv::viz::writeTrajectory(InputArray _traj, const String& files_format, int if (traj.depth() == CV_32F) for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) - writePose(cv::format(files_format.c_str(), index), traj.at(i), tag); + writePose(cv::format(files_format.c_str(), index), traj.at((int)i), tag); if (traj.depth() == CV_64F) for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) - writePose(cv::format(files_format.c_str(), index), traj.at(i), tag); + writePose(cv::format(files_format.c_str(), index), traj.at((int)i), tag); } CV_Assert(!"Unsupported array kind"); diff --git a/modules/viz/src/vtk/vtkCloudMatSink.cpp b/modules/viz/src/vtk/vtkCloudMatSink.cpp index 7f47022c3..8bd101132 100644 --- a/modules/viz/src/vtk/vtkCloudMatSink.cpp +++ b/modules/viz/src/vtk/vtkCloudMatSink.cpp @@ -79,11 +79,11 @@ void cv::viz::vtkCloudMatSink::WriteData() if (cloud.depth() == CV_32F) for(size_t i = 0; i < cloud.total(); ++i) - *fdata++ = Vec3d(points_Data->GetPoint(i)); + *fdata++ = Vec3d(points_Data->GetPoint((vtkIdType)i)); if (cloud.depth() == CV_64F) for(size_t i = 0; i < cloud.total(); ++i) - *ddata++ = Vec3d(points_Data->GetPoint(i)); + *ddata++ = Vec3d(points_Data->GetPoint((vtkIdType)i)); } else cloud.release(); @@ -101,7 +101,7 @@ void cv::viz::vtkCloudMatSink::WriteData() Mat buffer(cloud.size(), CV_64FC(channels)); Vec3d *cptr = buffer.ptr(); for(size_t i = 0; i < buffer.total(); ++i) - *cptr++ = Vec3d(scalars_data->GetTuple(i)); + *cptr++ = Vec3d(scalars_data->GetTuple((vtkIdType)i)); buffer.convertTo(colors, CV_8U, vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE ? 255.0 : 1.0); } @@ -121,7 +121,7 @@ void cv::viz::vtkCloudMatSink::WriteData() Mat buffer(cloud.size(), CV_64FC(channels)); Vec3d *cptr = buffer.ptr(); for(size_t i = 0; i < buffer.total(); ++i) - *cptr++ = Vec3d(normals_data->GetTuple(i)); + *cptr++ = Vec3d(normals_data->GetTuple((vtkIdType)i)); buffer.convertTo(normals, vtktype == VTK_FLOAT ? CV_32F : CV_64F); } @@ -140,7 +140,7 @@ void cv::viz::vtkCloudMatSink::WriteData() Mat buffer(cloud.size(), CV_64FC2); Vec2d *cptr = buffer.ptr(); for(size_t i = 0; i < buffer.total(); ++i) - *cptr++ = Vec2d(coords_data->GetTuple(i)); + *cptr++ = Vec2d(coords_data->GetTuple((vtkIdType)i)); buffer.convertTo(tcoords, vtktype == VTK_FLOAT ? CV_32F : CV_64F); diff --git a/modules/viz/src/vtk/vtkCloudMatSource.cpp b/modules/viz/src/vtk/vtkCloudMatSource.cpp index 74d01bbd0..1d8ab7894 100644 --- a/modules/viz/src/vtk/vtkCloudMatSource.cpp +++ b/modules/viz/src/vtk/vtkCloudMatSource.cpp @@ -185,8 +185,8 @@ int cv::viz::vtkCloudMatSource::filterNanCopy(const Mat& cloud) CV_DbgAssert(DataType<_Tp>::depth == cloud.depth()); points = vtkSmartPointer::New(); points->SetDataType(VtkDepthTraits<_Tp>::data_type); - points->Allocate(cloud.total()); - points->SetNumberOfPoints(cloud.total()); + points->Allocate((vtkIdType)cloud.total()); + points->SetNumberOfPoints((vtkIdType)cloud.total()); int s_chs = cloud.channels(); int total = 0; diff --git a/modules/viz/src/vtk/vtkTrajectorySource.cpp b/modules/viz/src/vtk/vtkTrajectorySource.cpp index e098a1d55..2036e09af 100644 --- a/modules/viz/src/vtk/vtkTrajectorySource.cpp +++ b/modules/viz/src/vtk/vtkTrajectorySource.cpp @@ -64,19 +64,19 @@ void cv::viz::vtkTrajectorySource::SetTrajectory(InputArray _traj) points = vtkSmartPointer::New(); points->SetDataType(VTK_DOUBLE); - points->SetNumberOfPoints(total); + points->SetNumberOfPoints((vtkIdType)total); tensors = vtkSmartPointer::New(); tensors->SetNumberOfComponents(9); - tensors->SetNumberOfTuples(total); + tensors->SetNumberOfTuples((vtkIdType)total); for(size_t i = 0; i < total; ++i, ++dpath) { Matx33d R = dpath->rotation().t(); // transposed because of - tensors->SetTuple(i, R.val); // column major order + tensors->SetTuple((vtkIdType)i, R.val); // column major order Vec3d p = dpath->translation(); - points->SetPoint(i, p.val); + points->SetPoint((vtkIdType)i, p.val); } } @@ -85,7 +85,7 @@ cv::Mat cv::viz::vtkTrajectorySource::ExtractPoints(InputArray _traj) CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT); CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16)); - Mat points(1, _traj.total(), CV_MAKETYPE(_traj.depth(), 3)); + Mat points(1, (int)_traj.total(), CV_MAKETYPE(_traj.depth(), 3)); const Affine3d* dpath = _traj.getMat().ptr(); const Affine3f* fpath = _traj.getMat().ptr(); diff --git a/modules/viz/test/tests_simple.cpp b/modules/viz/test/tests_simple.cpp index f84b60a47..c595affba 100644 --- a/modules/viz/test/tests_simple.cpp +++ b/modules/viz/test/tests_simple.cpp @@ -81,7 +81,7 @@ TEST(Viz, show_cloud_masked) Mat dragon_cloud = readCloud(get_dragon_ply_file_path()); Vec3f qnan = Vec3f::all(std::numeric_limits::quiet_NaN()); - for(size_t i = 0; i < dragon_cloud.total(); ++i) + for(int i = 0; i < (int)dragon_cloud.total(); ++i) if (i % 15 != 0) dragon_cloud.at(i) = qnan; @@ -170,7 +170,7 @@ TEST(Viz, show_textured_mesh) tcoords.push_back(Vec2d(1.0, i/64.0)); } - for(size_t i = 0; i < points.size()/2-1; ++i) + for(int i = 0; i < (int)points.size()/2-1; ++i) { int polys[] = {3, 2*i, 2*i+1, 2*i+2, 3, 2*i+1, 2*i+2, 2*i+3}; polygons.insert(polygons.end(), polys, polys + sizeof(polys)/sizeof(polys[0])); @@ -194,7 +194,7 @@ TEST(Viz, show_textured_mesh) TEST(Viz, show_polyline) { Mat polyline(1, 32, CV_64FC3); - for(size_t i = 0; i < polyline.total(); ++i) + for(int i = 0; i < (int)polyline.total(); ++i) polyline.at(i) = Vec3d(i/16.0, cos(i * CV_PI/6), sin(i * CV_PI/6)); Viz3d viz("show_polyline"); @@ -222,13 +222,14 @@ TEST(Viz, show_sampled_normals) TEST(Viz, show_trajectories) { std::vector path = generate_test_trajectory(), sub0, sub1, sub2, sub3, sub4, sub5; + int size =(int)path.size(); - Mat(path).rowRange(0, path.size()/10+1).copyTo(sub0); - Mat(path).rowRange(path.size()/10, path.size()/5+1).copyTo(sub1); - Mat(path).rowRange(path.size()/5, 11*path.size()/12).copyTo(sub2); - Mat(path).rowRange(11*path.size()/12, path.size()).copyTo(sub3); - Mat(path).rowRange(3*path.size()/4, 33*path.size()/40).copyTo(sub4); - Mat(path).rowRange(33*path.size()/40, 9*path.size()/10).copyTo(sub5); + Mat(path).rowRange(0, size/10+1).copyTo(sub0); + Mat(path).rowRange(size/10, size/5+1).copyTo(sub1); + Mat(path).rowRange(size/5, 11*size/12).copyTo(sub2); + Mat(path).rowRange(11*size/12, size).copyTo(sub3); + Mat(path).rowRange(3*size/4, 33*size/40).copyTo(sub4); + Mat(path).rowRange(33*size/40, 9*size/10).copyTo(sub5); Matx33d K(1024.0, 0.0, 320.0, 0.0, 1024.0, 240.0, 0.0, 0.0, 1.0); Viz3d viz("show_trajectories"); @@ -259,7 +260,7 @@ TEST(Viz, show_trajectory_reposition) Viz3d viz("show_trajectory_reposition_to_origin"); viz.showWidget("coos", WCoordinateSystem()); - viz.showWidget("sub3", WTrajectory(Mat(path).rowRange(0, path.size()/3), WTrajectory::BOTH, 0.2, Color::brown()), path.front().inv()); + viz.showWidget("sub3", WTrajectory(Mat(path).rowRange(0, (int)path.size()/3), WTrajectory::BOTH, 0.2, Color::brown()), path.front().inv()); viz.showWidget("text2d", WText("Trajectory resposition to origin", Point(20, 20), 20, Color::green())); viz.spin(); } From f8ccc115ef3f593b4b44f5efbc7c79a276e8619d Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 2 Feb 2014 22:08:18 +0400 Subject: [PATCH 05/25] proper render call order (fixes some issues with VTK6.1) --- modules/viz/src/interactor_style.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp index 75003a2b6..7fa671448 100644 --- a/modules/viz/src/interactor_style.cpp +++ b/modules/viz/src/interactor_style.cpp @@ -366,7 +366,6 @@ void cv::viz::InteractorStyle::OnKeyDown() { Interactor->GetRenderWindow()->SetSize(win_size_.val); Interactor->GetRenderWindow()->SetPosition(win_pos_.val); - Interactor->GetRenderWindow()->Render(); Interactor->Render(); } // Set to max @@ -376,7 +375,6 @@ void cv::viz::InteractorStyle::OnKeyDown() win_size_ = win_size; Interactor->GetRenderWindow()->SetSize(screen_size.val); - Interactor->GetRenderWindow()->Render(); Interactor->Render(); max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); } @@ -417,7 +415,7 @@ void cv::viz::InteractorStyle::OnKeyDown() { vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); cam->SetParallelProjection(!cam->GetParallelProjection()); - CurrentRenderer->Render(); + Interactor->Render(); break; } @@ -468,7 +466,7 @@ void cv::viz::InteractorStyle::OnKeyDown() CurrentRenderer->SetActiveCamera(cam); CurrentRenderer->ResetCameraClippingRange(); - CurrentRenderer->Render(); + Interactor->Render(); break; } @@ -594,7 +592,6 @@ void cv::viz::InteractorStyle::OnMouseWheelForward() cam->Modified(); CurrentRenderer->ResetCameraClippingRange(); CurrentRenderer->Modified(); - CurrentRenderer->Render(); Interactor->Render(); } else @@ -624,7 +621,6 @@ void cv::viz::InteractorStyle::OnMouseWheelBackward() cam->Modified(); CurrentRenderer->ResetCameraClippingRange(); CurrentRenderer->Modified(); - CurrentRenderer->Render(); Interactor->Render(); } else From 069dd8a068263f6b0cfce647d11637baaf48b745 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 8 Feb 2014 16:11:20 +0400 Subject: [PATCH 06/25] default meshlab background --- modules/viz/src/vizimpl.cpp | 3 +++ modules/viz/test/tests_simple.cpp | 1 + 2 files changed, 4 insertions(+) diff --git a/modules/viz/src/vizimpl.cpp b/modules/viz/src/vizimpl.cpp index 5fa49e2f9..cf7a25120 100644 --- a/modules/viz/src/vizimpl.cpp +++ b/modules/viz/src/vizimpl.cpp @@ -68,6 +68,8 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false), timer_callback_ = vtkSmartPointer::New(); exit_callback_ = vtkSmartPointer::New(); exit_callback_->viz = this; + + setBackgroundMeshLab(); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -114,6 +116,7 @@ void cv::viz::Viz3d::VizImpl::recreateRenderWindow() Vec2i window_size(window_->GetSize()); int fullscreen = window_->GetFullScreen(); + window_->Finalize(); window_ = vtkSmartPointer::New(); if (window_position_[0] != std::numeric_limits::min()) //also workaround window_->SetPosition(window_position_.val); diff --git a/modules/viz/test/tests_simple.cpp b/modules/viz/test/tests_simple.cpp index c595affba..4edb324f4 100644 --- a/modules/viz/test/tests_simple.cpp +++ b/modules/viz/test/tests_simple.cpp @@ -52,6 +52,7 @@ TEST(Viz, show_cloud_bluberry) Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); Viz3d viz("show_cloud_bluberry"); + viz.setBackgroundColor(Color::black()); viz.showWidget("coosys", WCoordinateSystem()); viz.showWidget("dragon", WCloud(dragon_cloud, Color::bluberry()), pose); From 5dc17f5d587b866aaee676c723a2bd30e1f710e2 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 8 Feb 2014 19:31:24 +0400 Subject: [PATCH 07/25] Fixed all OpenGL issues for Macos (via objective-C++ layer) --- cmake/OpenCVModule.cmake | 10 +- modules/viz/src/precomp.hpp | 2 + modules/viz/src/vizimpl.cpp | 11 +- modules/viz/src/vtk/vtkCocoaInteractorFix.mm | 213 +++++++++++++++++++ 4 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 modules/viz/src/vtk/vtkCocoaInteractorFix.mm diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 86a9d0c83..6f727af8d 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -484,6 +484,10 @@ macro(ocv_glob_module_sources) file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h") file(GLOB lib_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h") + file(GLOB_RECURSE lib_srcs_apple "src/*.m*") + if (APPLE) + list(APPEND lib_srcs ${lib_srcs_apple}) + endif() file(GLOB lib_cuda_srcs "src/cuda/*.cu") set(cuda_objs "") @@ -745,7 +749,11 @@ function(ocv_add_accuracy_tests) get_native_precompiled_header(${the_target} test_precomp.hpp) - add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch}) + if(APPLE AND ${the_target} STREQUAL "opencv_test_viz") + add_executable(${the_target} MACOSX_BUNDLE ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch}) + else() + add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch}) + endif() target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS}) add_dependencies(opencv_tests ${the_target}) diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 8329f52f1..f77da5a5b 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -312,6 +312,8 @@ namespace cv return transform_filter->GetOutput(); } }; + + vtkSmartPointer vtkCocoaRenderWindowInteractorNew(); } } diff --git a/modules/viz/src/vizimpl.cpp b/modules/viz/src/vizimpl.cpp index cf7a25120..3e852dd71 100644 --- a/modules/viz/src/vizimpl.cpp +++ b/modules/viz/src/vizimpl.cpp @@ -111,7 +111,7 @@ void cv::viz::Viz3d::VizImpl::close() void cv::viz::Viz3d::VizImpl::recreateRenderWindow() { -#if !defined _MSC_VER +#if !defined _MSC_VER && !defined __APPLE__ //recreating is workaround for Ubuntu -- a crash in x-server Vec2i window_size(window_->GetSize()); int fullscreen = window_->GetFullScreen(); @@ -127,12 +127,15 @@ void cv::viz::Viz3d::VizImpl::recreateRenderWindow() #endif } - ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::spin() { recreateRenderWindow(); +#if defined __APPLE__ + interactor_ = vtkCocoaRenderWindowInteractorNew(); +#else interactor_ = vtkSmartPointer::New(); +#endif interactor_->SetRenderWindow(window_); interactor_->SetInteractorStyle(style_); window_->AlphaBitPlanesOff(); @@ -154,7 +157,11 @@ void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw) { spin_once_state_ = true; recreateRenderWindow(); +#if defined __APPLE__ + interactor_ = vtkCocoaRenderWindowInteractorNew(); +#else interactor_ = vtkSmartPointer::New(); +#endif interactor_->SetRenderWindow(window_); interactor_->SetInteractorStyle(style_); interactor_->AddObserver(vtkCommand::TimerEvent, timer_callback_); diff --git a/modules/viz/src/vtk/vtkCocoaInteractorFix.mm b/modules/viz/src/vtk/vtkCocoaInteractorFix.mm new file mode 100644 index 000000000..0e55aebb0 --- /dev/null +++ b/modules/viz/src/vtk/vtkCocoaInteractorFix.mm @@ -0,0 +1,213 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +// OpenCV Viz module is complete rewrite of +// PCL visualization module (www.pointclouds.org) +// +//M*/ + +#import +#include +#include +#include +#include + +//---------------------------------------------------------------------------- +@interface vtkCocoaServerFix : NSObject +{ + vtkCocoaRenderWindow* renWin; +} + ++ (id)cocoaServerWithRenderWindow:(vtkCocoaRenderWindow*)inRenderWindow; + +- (void)start; +- (void)stop; +- (void)breakEventLoop; + +@end + +//---------------------------------------------------------------------------- +@implementation vtkCocoaServerFix + +//---------------------------------------------------------------------------- +- (id)initWithRenderWindow:(vtkCocoaRenderWindow *)inRenderWindow +{ + self = [super init]; + if (self) + renWin = inRenderWindow; + return self; +} + +//---------------------------------------------------------------------------- ++ (id)cocoaServerWithRenderWindow:(vtkCocoaRenderWindow *)inRenderWindow +{ + vtkCocoaServerFix *server = [[[vtkCocoaServerFix alloc] initWithRenderWindow:inRenderWindow] autorelease]; + return server; +} + +//---------------------------------------------------------------------------- +- (void)start +{ + // Retrieve the NSWindow. + NSWindow *win = nil; + if (renWin) + { + win = reinterpret_cast (renWin->GetRootWindow ()); + + // We don't want to be informed of every window closing, so check for nil. + if (win != nil) + { + // Register for the windowWillClose notification in order to stop the run loop if the window closes. + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:win]; + } + } + // Start the NSApplication's run loop + NSApplication* application = [NSApplication sharedApplication]; + [application run]; +} + +//---------------------------------------------------------------------------- +- (void)stop +{ + [self breakEventLoop]; +} + +//---------------------------------------------------------------------------- +- (void)breakEventLoop +{ + NSApplication* application = [NSApplication sharedApplication]; + [application stop:application]; + + NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined + location:NSMakePoint(0.0,0.0) + modifierFlags:0 + timestamp:0 + windowNumber:-1 + context:nil + subtype:0 + data1:0 + data2:0]; + [application postEvent:event atStart:YES]; +} + +//---------------------------------------------------------------------------- +- (void)windowWillClose:(NSNotification*)aNotification +{ + (void)aNotification; + + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc removeObserver:self name:NSWindowWillCloseNotification object:nil]; + + if (renWin) + { + int windowCreated = renWin->GetWindowCreated (); + if (windowCreated) + { + [self breakEventLoop]; + + // The NSWindow is closing, so prevent anyone from accidently using it + renWin->SetRootWindow(NULL); + } + } +} + +@end + +//---------------------------------------------------------------------------- + +namespace cv { namespace viz +{ + class vtkCocoaRenderWindowInteractorFix : public vtkCocoaRenderWindowInteractor + { + public: + static vtkCocoaRenderWindowInteractorFix *New (); + vtkTypeMacro (vtkCocoaRenderWindowInteractorFix, vtkCocoaRenderWindowInteractor) + + virtual void Start (); + virtual void TerminateApp (); + + protected: + vtkCocoaRenderWindowInteractorFix () {} + ~vtkCocoaRenderWindowInteractorFix () {} + + private: + vtkCocoaRenderWindowInteractorFix (const vtkCocoaRenderWindowInteractorFix&); // Not implemented. + void operator = (const vtkCocoaRenderWindowInteractorFix&); // Not implemented. + }; + + vtkStandardNewMacro (vtkCocoaRenderWindowInteractorFix) + + vtkSmartPointer vtkCocoaRenderWindowInteractorNew(); +}} + +void cv::viz::vtkCocoaRenderWindowInteractorFix::Start () +{ + vtkCocoaRenderWindow* renWin = vtkCocoaRenderWindow::SafeDownCast(this->GetRenderWindow ()); + if (renWin != NULL) + { + vtkCocoaServerFix *server = reinterpret_cast (this->GetCocoaServer ()); + if (!this->GetCocoaServer ()) + { + server = [vtkCocoaServerFix cocoaServerWithRenderWindow:renWin]; + this->SetCocoaServer (reinterpret_cast (server)); + } + + [server start]; + } +} + +void cv::viz::vtkCocoaRenderWindowInteractorFix::TerminateApp () +{ + vtkCocoaRenderWindow *renWin = vtkCocoaRenderWindow::SafeDownCast (this->RenderWindow); + if (renWin) + { + vtkCocoaServerFix *server = reinterpret_cast (this->GetCocoaServer ()); + [server stop]; + } +} + +vtkSmartPointer cv::viz::vtkCocoaRenderWindowInteractorNew() +{ + return vtkSmartPointer::New(); +} + From f1c062c30ab9eb02ea1b1bd8d221dc85ad7b2d27 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Mon, 10 Feb 2014 13:27:08 +0400 Subject: [PATCH 08/25] cloud collection finalize --- modules/viz/doc/widget.rst | 8 ++++++++ modules/viz/include/opencv2/viz/widgets.hpp | 2 ++ modules/viz/src/clouds.cpp | 18 ++++++++++++++++++ modules/viz/test/tests_simple.cpp | 1 + 4 files changed, 29 insertions(+) diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index 008e0e68a..2802edff7 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -934,6 +934,8 @@ This 3D Widget defines a collection of clouds. :: void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()); //! All points in cloud have the same color void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3d &pose = Affine3d::Identity()); + //! Repacks internal structure to sinle cloud + void finalize(); }; viz::WCloudCollection::WCloudCollection @@ -964,6 +966,12 @@ Adds a cloud to the collection. .. note:: In case there are four channels in the cloud, fourth channel is ignored. +viz::WCloudCollection::finalize +------------------------------- +Finalizes cloud data by repacking to single cloud. Useful for large cloud collections to reduce memory usage + +.. ocv:function:: void finalize() + viz::WCloudNormals ------------------ .. ocv:class:: WCloudNormals diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 2c49b9d0e..6910196c3 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -345,6 +345,8 @@ namespace cv void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()); //! All points in cloud have the same color void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity()); + //! Repacks internal structure to sinle cloud + void finalize(); }; class CV_EXPORTS WCloudNormals : public Widget3D diff --git a/modules/viz/src/clouds.cpp b/modules/viz/src/clouds.cpp index c2c78d552..349de2f5f 100644 --- a/modules/viz/src/clouds.cpp +++ b/modules/viz/src/clouds.cpp @@ -242,6 +242,24 @@ void cv::viz::WCloudCollection::addCloud(InputArray cloud, const Color &color, c addCloud(cloud, Mat(cloud.size(), CV_8UC3, color), pose); } +void cv::viz::WCloudCollection::finalize() +{ + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Incompatible widget type." && actor); + + vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + CV_Assert("Need to add at least one cloud." && mapper); + + vtkSmartPointer producer = mapper->GetInputConnection(0, 0)->GetProducer(); + vtkSmartPointer append_filter = vtkAppendPolyData::SafeDownCast(producer); + append_filter->Update(); + + vtkSmartPointer polydata = append_filter->GetOutput(); + mapper->RemoveInputConnection(0, 0); + VtkUtils::SetInputData(mapper, polydata); + mapper->Modified(); +} + template<> cv::viz::WCloudCollection cv::viz::Widget::cast() { Widget3D widget = this->cast(); diff --git a/modules/viz/test/tests_simple.cpp b/modules/viz/test/tests_simple.cpp index 4edb324f4..10c1d8180 100644 --- a/modules/viz/test/tests_simple.cpp +++ b/modules/viz/test/tests_simple.cpp @@ -103,6 +103,7 @@ TEST(Viz, show_cloud_collection) ccol.addCloud(cloud, Color::white(), Affine3d().translate(Vec3d(0, 0, 0)).rotate(Vec3d(CV_PI/2, 0, 0))); ccol.addCloud(cloud, Color::blue(), Affine3d().translate(Vec3d(1, 0, 0))); ccol.addCloud(cloud, Color::red(), Affine3d().translate(Vec3d(2, 0, 0))); + ccol.finalize(); Viz3d viz("show_cloud_collection"); viz.setBackgroundColor(Color::mlab()); From 261546f6f619bb5c77cad529e8114bdc16b5f508 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Tue, 11 Feb 2014 23:27:19 +0400 Subject: [PATCH 09/25] casting Vec3b operator for viz::Color --- modules/viz/include/opencv2/viz/types.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp index acbece2ed..3e8e87c65 100644 --- a/modules/viz/include/opencv2/viz/types.hpp +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -63,6 +63,8 @@ namespace cv Color(const Scalar& color); + operator Vec3b() const; + static Color black(); static Color blue(); static Color green(); @@ -193,6 +195,8 @@ inline cv::viz::Color::Color(double _gray) : Scalar(_gray, _gray, _gray) {} inline cv::viz::Color::Color(double _blue, double _green, double _red) : Scalar(_blue, _green, _red) {} inline cv::viz::Color::Color(const Scalar& color) : Scalar(color) {} +inline cv::viz::Color::operator cv::Vec3b() const { return cv::Vec3d(val); } + inline cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); } inline cv::viz::Color cv::viz::Color::green() { return Color( 0, 255, 0); } inline cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); } From 1a5dfe421dcbc5c2d831fff61ad7d5bc69c2c59c Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 15 Feb 2014 17:02:17 +0400 Subject: [PATCH 10/25] Added WidgetMerger, Polyline - colors support for each point independently, simple widgets now compute color array instead of setting global color --- modules/viz/doc/widget.rst | 41 +++++++ modules/viz/include/opencv2/viz/widgets.hpp | 15 +++ modules/viz/src/clouds.cpp | 114 ++++++++++++++------ modules/viz/src/precomp.hpp | 5 + modules/viz/src/shapes.cpp | 101 ++++++++--------- modules/viz/test/tests_simple.cpp | 31 +++++- 6 files changed, 222 insertions(+), 85 deletions(-) diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index 2802edff7..31546ae8e 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -1025,3 +1025,44 @@ Constructs a WMesh. :param polygons: Points of the mesh object. :param colors: Point colors. :param normals: Point normals. + +viz::WWidgetMerger +--------------------- +.. ocv:class:: WWidgetMerger + +This class allos to merge several widgets to single one. It has quite limited functionality and can't merge widgets with different attributes. For instance, +if widgetA has color array and widgetB has only global color defined, then result of merge won't have color at all. The class is suitable for merging large amount of similar widgets. + + class CV_EXPORTS WWidgetMerger : public Widget3D + { + public: + WWidgetMerger(); + + //! Add widget to merge with optional position change + void addWidget(const Widget3D& widget, const Affine3d &pose = Affine3d::Identity()); + + //! Repacks internal structure to sinle widget + void finalize(); + }; + + +viz::WWidgetMerger::WWidgetMerger +--------------------------------------- +Constructs a WWidgetMerger. + +.. ocv:WWidgetMerger:: WWidgetMerger() + +viz::WWidgetMerger::addCloud +------------------------------- +Adds a cloud to the collection. + +.. ocv:function:: void addWidget(const Widget3D& widget, const Affine3d &pose = Affine3d::Identity()) + + :param widget: Widget to merge. + :param pose: Pose of the widget. + +viz::WWidgetMerger::finalize +------------------------------- +Finalizes merger data and constructs final merged widget + +.. ocv:function:: void finalize() \ 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 6910196c3..0c2a4f705 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -201,6 +201,7 @@ namespace cv class CV_EXPORTS WPolyLine : public Widget3D { public: + WPolyLine(InputArray points, InputArray colors); WPolyLine(InputArray points, const Color &color = Color::white()); }; @@ -362,6 +363,19 @@ namespace cv WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray()); }; + + class CV_EXPORTS WWidgetMerger : public Widget3D + { + public: + WWidgetMerger(); + + //! Add widget to merge with optional position change + void addWidget(const Widget3D& widget, const Affine3d &pose = Affine3d::Identity()); + + //! Repacks internal structure to sinle widget + void finalize(); + }; + ///////////////////////////////////////////////////////////////////////////// /// Utility exports @@ -391,6 +405,7 @@ namespace cv template<> CV_EXPORTS WCloudCollection Widget::cast(); template<> CV_EXPORTS WCloudNormals Widget::cast(); template<> CV_EXPORTS WMesh Widget::cast(); + template<> CV_EXPORTS WWidgetMerger Widget::cast(); } /* namespace viz */ } /* namespace cv */ diff --git a/modules/viz/src/clouds.cpp b/modules/viz/src/clouds.cpp index 349de2f5f..eec02639e 100644 --- a/modules/viz/src/clouds.cpp +++ b/modules/viz/src/clouds.cpp @@ -193,8 +193,21 @@ template<> cv::viz::WPaintedCloud cv::viz::Widget::cast( cv::viz::WCloudCollection::WCloudCollection() { - // Just create the actor + vtkSmartPointer append_filter = vtkSmartPointer::New(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(append_filter->GetOutputPort()); + mapper->SetScalarModeToUsePointData(); + mapper->ImmediateModeRenderingOff(); + mapper->SetScalarRange(0, 255); + mapper->ScalarVisibilityOn(); + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetNumberOfCloudPoints(1); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); + WidgetAccessor::setProp(*this, actor); } @@ -206,33 +219,11 @@ void cv::viz::WCloudCollection::addCloud(InputArray cloud, InputArray colors, co vtkSmartPointer polydata = VtkUtils::TransformPolydata(source->GetOutputPort(), pose); vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); - CV_Assert("Incompatible widget type." && actor); + CV_Assert("Correctness check." && actor); - vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); - if (!mapper) - { - vtkSmartPointer append_filter = vtkSmartPointer::New(); - VtkUtils::AddInputData(append_filter, polydata); - - // This is the first cloud - mapper = vtkSmartPointer::New(); - mapper->SetScalarRange(0, 255); - mapper->SetScalarModeToUsePointData(); - mapper->ScalarVisibilityOn(); - mapper->ImmediateModeRenderingOff(); - mapper->SetInputConnection(append_filter->GetOutputPort()); - - actor->SetNumberOfCloudPoints(std::max(1, polydata->GetNumberOfPoints()/10)); - actor->GetProperty()->SetInterpolationToFlat(); - actor->GetProperty()->BackfaceCullingOn(); - actor->SetMapper(mapper); - return; - } - - vtkSmartPointer producer = mapper->GetInputConnection(0, 0)->GetProducer(); + vtkSmartPointer producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer(); vtkSmartPointer append_filter = vtkAppendPolyData::SafeDownCast(producer); VtkUtils::AddInputData(append_filter, polydata); - append_filter->Modified(); actor->SetNumberOfCloudPoints(std::max(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10)); } @@ -257,7 +248,6 @@ void cv::viz::WCloudCollection::finalize() vtkSmartPointer polydata = append_filter->GetOutput(); mapper->RemoveInputConnection(0, 0); VtkUtils::SetInputData(mapper, polydata); - mapper->Modified(); } template<> cv::viz::WCloudCollection cv::viz::Widget::cast() @@ -332,20 +322,18 @@ cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, in } } - vtkSmartPointer polyData = vtkSmartPointer::New(); - polyData->SetPoints(points); - polyData->SetLines(lines); + vtkSmartPointer polydata = vtkSmartPointer::New(); + polydata->SetPoints(points); + polydata->SetLines(lines); + VtkUtils::FillScalars(polydata, color); vtkSmartPointer mapper = vtkSmartPointer::New(); - mapper->SetColorModeToMapScalars(); - mapper->SetScalarModeToUsePointData(); - VtkUtils::SetInputData(mapper, polyData); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } template<> cv::viz::WCloudNormals cv::viz::Widget::cast() @@ -455,3 +443,63 @@ template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast() Widget3D widget = this->cast(); return static_cast(widget); } + + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Widget Merger implementation + +cv::viz::WWidgetMerger::WWidgetMerger() +{ + vtkSmartPointer append_filter = vtkSmartPointer::New(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(append_filter->GetOutputPort()); + mapper->SetScalarModeToUsePointData(); + mapper->ImmediateModeRenderingOff(); + mapper->SetScalarRange(0, 255); + mapper->ScalarVisibilityOn(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +void cv::viz::WWidgetMerger::addWidget(const Widget3D& widget, const Affine3d &pose) +{ + vtkActor *widget_actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(widget)); + CV_Assert("Widget is not 3D actor." && widget_actor); + + vtkSmartPointer widget_mapper = vtkPolyDataMapper::SafeDownCast(widget_actor->GetMapper()); + CV_Assert("Widget doesn't have a polydata mapper" && widget_mapper); + widget_mapper->Update(); + + vtkSmartPointer actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + vtkSmartPointer producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer(); + vtkSmartPointer append_filter = vtkAppendPolyData::SafeDownCast(producer); + CV_Assert("Correctness check" && append_filter); + + VtkUtils::AddInputData(append_filter, VtkUtils::TransformPolydata(widget_mapper->GetInput(), pose)); +} + +void cv::viz::WWidgetMerger::finalize() +{ + vtkSmartPointer actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + vtkSmartPointer producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer(); + vtkSmartPointer append_filter = vtkAppendPolyData::SafeDownCast(producer); + CV_Assert("Correctness check" && append_filter); + append_filter->Update(); + + vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + mapper->RemoveInputConnection(0, 0); + VtkUtils::SetInputData(mapper, append_filter->GetOutput()); + mapper->Modified(); +} + +template<> CV_EXPORTS cv::viz::WWidgetMerger cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index f77da5a5b..c59496205 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -272,6 +272,11 @@ namespace cv return scalars; } + static vtkSmartPointer FillScalars(vtkSmartPointer polydata, const Color& color) + { + return polydata->GetPointData()->SetScalars(FillScalars(polydata->GetNumberOfPoints(), color)), polydata; + } + static vtkSmartPointer ComputeNormals(vtkSmartPointer polydata) { vtkSmartPointer normals_generator = vtkSmartPointer::New(); diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index 171470d81..4dd77038e 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -54,14 +54,16 @@ cv::viz::WLine::WLine(const Point3d &pt1, const Point3d &pt2, const Color &color line->SetPoint2(pt2.x, pt2.y, pt2.z); line->Update(); + vtkSmartPointer polydata = line->GetOutput(); + VtkUtils::FillScalars(polydata, color); + vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, line->GetOutput()); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } template<> cv::viz::WLine cv::viz::Widget::cast() @@ -83,14 +85,16 @@ cv::viz::WSphere::WSphere(const Point3d ¢er, double radius, int sphere_resol sphere->LatLongTessellationOff(); sphere->Update(); + vtkSmartPointer polydata = sphere->GetOutput(); + VtkUtils::FillScalars(polydata, color); + vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, sphere->GetOutput()); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } template<> cv::viz::WSphere cv::viz::Widget::cast() @@ -110,15 +114,17 @@ cv::viz::WPlane::WPlane(const Size2d& size, const Color &color) plane->SetPoint2(-0.5 * size.width, 0.5 * size.height, 0.0); plane->Update(); + vtkSmartPointer polydata = plane->GetOutput(); + VtkUtils::FillScalars(polydata, color); + vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, plane->GetOutput()); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); actor->GetProperty()->LightingOff(); WidgetAccessor::setProp(*this, actor); - setColor(color); } cv::viz::WPlane::WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, const Size2d& size, const Color &color) @@ -161,6 +167,7 @@ cv::viz::WArrow::WArrow(const Point3d& pt1, const Point3d& pt2, double thickness Affine3d transform_with_scale(R * length, start_point); vtkSmartPointer polydata = VtkUtils::TransformPolydata(arrow_source->GetOutputPort(), transform_with_scale); + VtkUtils::FillScalars(polydata, color); vtkSmartPointer mapper = vtkSmartPointer::New(); VtkUtils::SetInputData(mapper, polydata); @@ -169,7 +176,6 @@ cv::viz::WArrow::WArrow(const Point3d& pt1, const Point3d& pt2, double thickness actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } template<> cv::viz::WArrow cv::viz::Widget::cast() @@ -189,16 +195,17 @@ cv::viz::WCircle::WCircle(double radius, double thickness, const Color &color) disk->SetOuterRadius(radius + thickness); disk->Update(); + vtkSmartPointer polydata = disk->GetOutput(); + VtkUtils::FillScalars(polydata, color); + vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, disk->GetOutput()); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->GetProperty()->LightingOff(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); - } cv::viz::WCircle::WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness, const Color &color) @@ -231,14 +238,16 @@ cv::viz::WCone::WCone(double length, double radius, int resolution, const Color cone_source->SetResolution(resolution); cone_source->Update(); + vtkSmartPointer polydata = cone_source->GetOutput(); + VtkUtils::FillScalars(polydata, color); + vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, cone_source->GetOutput()); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } cv::viz::WCone::WCone(double radius, const Point3d& center, const Point3d& tip, int resolution, const Color &color) @@ -274,14 +283,16 @@ cv::viz::WCylinder::WCylinder(const Point3d& axis_point1, const Point3d& axis_po tuber->SetRadius(radius); tuber->Update(); + vtkSmartPointer polydata = tuber->GetOutput(); + VtkUtils::FillScalars(polydata, color); + vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, tuber->GetOutput()); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } template<> cv::viz::WCylinder cv::viz::Widget::cast() @@ -315,15 +326,16 @@ cv::viz::WCube::WCube(const Point3d& min_point, const Point3d& max_point, bool w vtkCubeSource::SafeDownCast(cube)->SetBounds(bounds); } cube->Update(); + vtkSmartPointer polydata =cube->GetOutput(); + VtkUtils::FillScalars(polydata, color); vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, cube->GetOutput()); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } template<> cv::viz::WCube cv::viz::Widget::cast() @@ -379,40 +391,21 @@ template<> cv::viz::WCoordinateSystem cv::viz::Widget::cast cloud_source = vtkSmartPointer::New(); + cloud_source->SetColorCloud(points, colors); + cloud_source->Update(); - const float *fpoints = _points.getMat().ptr(); - const double *dpoints = _points.getMat().ptr(); - size_t total = _points.total(); - int s_chs = _points.channels(); - - vtkSmartPointer points = vtkSmartPointer::New(); - points->SetDataType(_points.depth() == CV_32F ? VTK_FLOAT : VTK_DOUBLE); - points->SetNumberOfPoints((vtkIdType)total); - - if (_points.depth() == CV_32F) - for(size_t i = 0; i < total; ++i, fpoints += s_chs) - points->SetPoint((vtkIdType)i, fpoints); - - if (_points.depth() == CV_64F) - for(size_t i = 0; i < total; ++i, dpoints += s_chs) - points->SetPoint((vtkIdType)i, dpoints); + vtkSmartPointer polydata = cloud_source->GetOutput(); vtkSmartPointer cell_array = vtkSmartPointer::New(); - cell_array->Allocate(cell_array->EstimateSize(1, (int)total)); - cell_array->InsertNextCell((int)total); - for(size_t i = 0; i < total; ++i) - cell_array->InsertCellPoint((vtkIdType)i); + cell_array->Allocate(cell_array->EstimateSize(1, polydata->GetNumberOfPoints())); + cell_array->InsertNextCell(polydata->GetNumberOfPoints()); + for(vtkIdType i = 0; i < polydata->GetNumberOfPoints(); ++i) + cell_array->InsertCellPoint(i); - vtkSmartPointer scalars = VtkUtils::FillScalars(total, color); - - vtkSmartPointer polydata = vtkSmartPointer::New(); - polydata->SetPoints(points); polydata->SetLines(cell_array); - polydata->GetPointData()->SetScalars(scalars); - vtkSmartPointer mapper = vtkSmartPointer::New(); VtkUtils::SetInputData(mapper, polydata); mapper->SetScalarRange(0, 255); @@ -423,6 +416,12 @@ cv::viz::WPolyLine::WPolyLine(InputArray _points, const Color &color) WidgetAccessor::setProp(*this, actor); } +cv::viz::WPolyLine::WPolyLine(InputArray points, const Color &color) +{ + WPolyLine polyline(points, Mat(points.size(), CV_8UC3, color)); + *this = polyline; +} + template<> cv::viz::WPolyLine cv::viz::Widget::cast() { Widget3D widget = this->cast(); @@ -450,14 +449,16 @@ cv::viz::WGrid::WGrid(const Vec2i &cells, const Vec2d &cells_spacing, const Colo VtkUtils::SetInputData(extract_edges, grid_data); extract_edges->Update(); + vtkSmartPointer polydata = extract_edges->GetOutput(); + VtkUtils::FillScalars(polydata, color); + vtkSmartPointer mapper = vtkSmartPointer::New(); - VtkUtils::SetInputData(mapper, extract_edges->GetOutput()); + VtkUtils::SetInputData(mapper, polydata); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } cv::viz::WGrid::WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, const Vec2i &cells, const Vec2d &cells_spacing, const Color &color) @@ -807,6 +808,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, double scale, const double aspect_ratio = f_y / f_x; vtkSmartPointer polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale); + VtkUtils::FillScalars(polydata, color); vtkSmartPointer mapper = vtkSmartPointer::New(); VtkUtils::SetInputData(mapper, polydata); @@ -815,7 +817,6 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, double scale, const actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const Color &color) @@ -824,6 +825,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const double fovy = fov[1] * 180 / CV_PI; vtkSmartPointer polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale); + VtkUtils::FillScalars(polydata, color); vtkSmartPointer mapper = vtkSmartPointer::New(); VtkUtils::SetInputData(mapper, polydata); @@ -832,7 +834,6 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, InputArray _image, double scale, const Color &color) @@ -967,6 +968,7 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Matx33 source->SetTrajectory(_path); vtkSmartPointer glyph = getPolyData(WCameraPosition(K, scale)); + VtkUtils::FillScalars(glyph, color); vtkSmartPointer tensor_glyph = vtkSmartPointer::New(); tensor_glyph->SetInputConnection(source->GetOutputPort()); @@ -984,7 +986,6 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Matx33 actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d &fov, double scale, const Color &color) @@ -993,6 +994,7 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d source->SetTrajectory(_path); vtkSmartPointer glyph = getPolyData(WCameraPosition(fov, scale)); + VtkUtils::FillScalars(glyph, color); vtkSmartPointer tensor_glyph = vtkSmartPointer::New(); tensor_glyph->SetInputConnection(source->GetOutputPort()); @@ -1010,7 +1012,6 @@ cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d actor->SetMapper(mapper); WidgetAccessor::setProp(*this, actor); - setColor(color); } template<> cv::viz::WTrajectoryFrustums cv::viz::Widget::cast() diff --git a/modules/viz/test/tests_simple.cpp b/modules/viz/test/tests_simple.cpp index 10c1d8180..d1b059cf6 100644 --- a/modules/viz/test/tests_simple.cpp +++ b/modules/viz/test/tests_simple.cpp @@ -156,6 +156,27 @@ TEST(Viz, show_mesh_random_colors) viz.spin(); } +TEST(Viz, show_widget_merger) +{ + WWidgetMerger merger; + merger.addWidget(WCube(Vec3d::all(0.0), Vec3d::all(1.0), true, Color::gold())); + + RNG& rng = theRNG(); + for(int i = 0; i < 77; ++i) + { + Vec3b c; + rng.fill(c, RNG::NORMAL, Scalar::all(128), Scalar::all(48), true); + merger.addWidget(WSphere(Vec3d(c)*(1.0/255.0), 7.0/255.0, 10, Color(c[2], c[1], c[0]))); + } + merger.finalize(); + + Viz3d viz("show_mesh_random_color"); + viz.showWidget("coo", WCoordinateSystem()); + viz.showWidget("merger", merger); + viz.showWidget("text2d", WText("Widget merger", Point(20, 20), 20, Color::green())); + viz.spin(); +} + TEST(Viz, show_textured_mesh) { Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); @@ -195,12 +216,18 @@ TEST(Viz, show_textured_mesh) TEST(Viz, show_polyline) { - Mat polyline(1, 32, CV_64FC3); + const Color palette[] = { Color::red(), Color::green(), Color::blue(), Color::gold(), Color::raspberry(), Color::bluberry(), Color::lime() }; + size_t palette_size = sizeof(palette)/sizeof(palette[0]); + + Mat polyline(1, 32, CV_64FC3), colors(1, 32, CV_8UC3); for(int i = 0; i < (int)polyline.total(); ++i) + { polyline.at(i) = Vec3d(i/16.0, cos(i * CV_PI/6), sin(i * CV_PI/6)); + colors.at(i) = palette[i & palette_size]; + } Viz3d viz("show_polyline"); - viz.showWidget("polyline", WPolyLine(Mat(polyline), Color::apricot())); + viz.showWidget("polyline", WPolyLine(polyline, colors)); viz.showWidget("coosys", WCoordinateSystem()); viz.showWidget("text2d", WText("Polyline", Point(20, 20), 20, Color::green())); viz.spin(); From 56754e907dcc40f5caa9bcae242a1d0ae5eb1932 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 15 Feb 2014 20:08:04 +0400 Subject: [PATCH 11/25] fixed crash for windows if console widow is closed or CTRL_C/CTRL_BRAK keys in console are pressed. --- modules/viz/include/opencv2/viz/viz3d.hpp | 2 + modules/viz/src/precomp.hpp | 14 +++++- modules/viz/src/viz3d.cpp | 2 + modules/viz/src/vizcore.cpp | 52 +++++++++++++++++++---- modules/viz/src/vizimpl.cpp | 2 + modules/viz/src/vizimpl.hpp | 2 +- 6 files changed, 62 insertions(+), 12 deletions(-) diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 1a137bcfb..1be748c8c 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -114,6 +114,8 @@ namespace cv double getRenderingProperty(const String &id, int property); void setRepresentation(int representation); + + void setGlobalWarnings(bool enabled = false); private: struct VizImpl; diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index c59496205..795ac16b0 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -155,7 +155,16 @@ namespace cv namespace viz { typedef std::map > WidgetActorMap; - typedef std::map VizMap; + + struct VizMap + { + typedef std::map type; + typedef type::iterator iterator; + + type m; + ~VizMap(); + void replace_clear(); + }; class VizStorage { @@ -167,7 +176,6 @@ namespace cv private: VizStorage(); // Static - ~VizStorage(); static void add(const Viz3d& window); static Viz3d& get(const String &window_name); @@ -177,6 +185,8 @@ namespace cv static VizMap storage; friend class Viz3d; + + static VizStorage init; }; template inline _Tp normalized(const _Tp& v) { return v * 1/norm(v); } diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index 56f978c0e..6e7dfcae7 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -146,3 +146,5 @@ void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { return getWidget(id).getRenderingProperty(property); } void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); } + +void cv::viz::Viz3d::setGlobalWarnings(bool enabled) { vtkObject::SetGlobalWarningDisplay(enabled ? 1 : 0); } diff --git a/modules/viz/src/vizcore.cpp b/modules/viz/src/vizcore.cpp index b4332a860..1166c0874 100644 --- a/modules/viz/src/vizcore.cpp +++ b/modules/viz/src/vizcore.cpp @@ -67,36 +67,70 @@ cv::Affine3d cv::viz::makeCameraPose(const Vec3d& position, const Vec3d& focal_p /////////////////////////////////////////////////////////////////////////////////////////////// /// VizStorage implementation +#if defined(_WIN32) && !defined(__CYGWIN__) + + #include + + static BOOL WINAPI ConsoleHandlerRoutine(DWORD /*dwCtrlType*/) + { + vtkObject::GlobalWarningDisplayOff(); + return FALSE; + } + + static void register_console_handler() + { + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO hOutInfo; + if (GetConsoleScreenBufferInfo(hOut, &hOutInfo)) + SetConsoleCtrlHandler(ConsoleHandlerRoutine, TRUE); + } + +#else + + void register_console_handler() {} + +#endif + + +cv::viz::VizStorage cv::viz::VizStorage::init; cv::viz::VizMap cv::viz::VizStorage::storage; -void cv::viz::VizStorage::unregisterAll() { storage.clear(); } + +void cv::viz::VizMap::replace_clear() { type().swap(m); } +cv::viz::VizMap::~VizMap() { replace_clear(); } + +cv::viz::VizStorage::VizStorage() +{ + register_console_handler(); +} +void cv::viz::VizStorage::unregisterAll() { storage.replace_clear(); } cv::viz::Viz3d& cv::viz::VizStorage::get(const String &window_name) { String name = generateWindowName(window_name); - VizMap::iterator vm_itr = storage.find(name); - CV_Assert(vm_itr != storage.end()); + VizMap::iterator vm_itr = storage.m.find(name); + CV_Assert(vm_itr != storage.m.end()); return vm_itr->second; } void cv::viz::VizStorage::add(const Viz3d& window) { String window_name = window.getWindowName(); - VizMap::iterator vm_itr = storage.find(window_name); - CV_Assert(vm_itr == storage.end()); - storage.insert(std::make_pair(window_name, window)); + VizMap::iterator vm_itr = storage.m.find(window_name); + CV_Assert(vm_itr == storage.m.end()); + storage.m.insert(std::make_pair(window_name, window)); } bool cv::viz::VizStorage::windowExists(const String &window_name) { String name = generateWindowName(window_name); - return storage.find(name) != storage.end(); + return storage.m.find(name) != storage.m.end(); } void cv::viz::VizStorage::removeUnreferenced() { - for(VizMap::iterator pos = storage.begin(); pos != storage.end();) + for(VizMap::iterator pos = storage.m.begin(); pos != storage.m.end();) if(pos->second.impl_->ref_counter == 1) - storage.erase(pos++); + storage.m.erase(pos++); else ++pos; } diff --git a/modules/viz/src/vizimpl.cpp b/modules/viz/src/vizimpl.cpp index 3e852dd71..37d008bc8 100644 --- a/modules/viz/src/vizimpl.cpp +++ b/modules/viz/src/vizimpl.cpp @@ -72,6 +72,8 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false), setBackgroundMeshLab(); } +cv::viz::Viz3d::VizImpl::~VizImpl() { close(); } + ///////////////////////////////////////////////////////////////////////////////////////////// void cv::viz::Viz3d::VizImpl::TimerCallback::Execute(vtkObject* caller, unsigned long event_id, void* cookie) { diff --git a/modules/viz/src/vizimpl.hpp b/modules/viz/src/vizimpl.hpp index 02675e0a5..67cab3674 100644 --- a/modules/viz/src/vizimpl.hpp +++ b/modules/viz/src/vizimpl.hpp @@ -55,7 +55,7 @@ public: int ref_counter; VizImpl(const String &name); - virtual ~VizImpl() {} + virtual ~VizImpl(); bool wasStopped() const; void close(); From 03bd82796de2278f0fac1424a255c339d214ec10 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sat, 15 Feb 2014 23:40:09 +0400 Subject: [PATCH 12/25] source compatibility with master --- modules/viz/src/vizcore.cpp | 5 +++++ modules/viz/test/test_precomp.hpp | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/modules/viz/src/vizcore.cpp b/modules/viz/src/vizcore.cpp index 1166c0874..4544f9b3c 100644 --- a/modules/viz/src/vizcore.cpp +++ b/modules/viz/src/vizcore.cpp @@ -291,7 +291,11 @@ void cv::viz::writeTrajectory(InputArray _traj, const String& files_format, int { if (_traj.kind() == _InputArray::STD_VECTOR_MAT) { +#if CV_MAJOR_VERSION < 3 std::vector& v = *(std::vector*)_traj.obj; +#else + std::vector& v = *(std::vector*)_traj.getObj(); +#endif for(size_t i = 0, index = max(0, start); i < v.size(); ++i, ++index) { @@ -317,6 +321,7 @@ void cv::viz::writeTrajectory(InputArray _traj, const String& files_format, int if (traj.depth() == CV_64F) for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) writePose(cv::format(files_format.c_str(), index), traj.at((int)i), tag); + return; } CV_Assert(!"Unsupported array kind"); diff --git a/modules/viz/test/test_precomp.hpp b/modules/viz/test/test_precomp.hpp index cd00b6e73..05914e284 100644 --- a/modules/viz/test/test_precomp.hpp +++ b/modules/viz/test/test_precomp.hpp @@ -54,12 +54,20 @@ #ifndef __OPENCV_TEST_PRECOMP_HPP__ #define __OPENCV_TEST_PRECOMP_HPP__ -#include "opencv2/ts/ts.hpp" -#include -#include -#include +#include #include +namespace cv +{ + Mat imread(const String& filename, int flags = 1); +} + +#if CV_MAJOR_VERSION < 3 + #include "opencv2/ts/ts.hpp" +#else + #include "opencv2/ts.hpp" +#endif + #include #include #include From fb7e74c511077d2307f230abf6d4508bae96535a Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 16 Feb 2014 21:27:25 +0400 Subject: [PATCH 13/25] iteractor work --- modules/viz/src/interactor_style.cpp | 635 ---------- modules/viz/src/precomp.hpp | 5 +- modules/viz/src/vizcore.cpp | 1 + modules/viz/src/vizimpl.cpp | 3 +- modules/viz/src/vizimpl.hpp | 2 +- modules/viz/src/vtk/vtkCocoaInteractorFix.mm | 3 +- modules/viz/src/vtk/vtkOBJWriter.cpp | 2 +- modules/viz/src/vtk/vtkVizInteractorStyle.cpp | 1077 +++++++++++++++++ .../vtkVizInteractorStyle.hpp} | 116 +- 9 files changed, 1168 insertions(+), 676 deletions(-) delete mode 100644 modules/viz/src/interactor_style.cpp create mode 100644 modules/viz/src/vtk/vtkVizInteractorStyle.cpp rename modules/viz/src/{interactor_style.hpp => vtk/vtkVizInteractorStyle.hpp} (61%) diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp deleted file mode 100644 index 7fa671448..000000000 --- a/modules/viz/src/interactor_style.cpp +++ /dev/null @@ -1,635 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2013, OpenCV Foundation, all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -// Authors: -// * Ozan Tonkal, ozantonkal@gmail.com -// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com -// -// OpenCV Viz module is complete rewrite of -// PCL visualization module (www.pointclouds.org) -// -//M*/ - -#include "precomp.hpp" - - -namespace cv { namespace viz -{ - vtkStandardNewMacro(InteractorStyle) -}} - - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::Initialize() -{ - // Set windows size (width, height) to unknown (-1) - win_size_ = Vec2i(-1, -1); - win_pos_ = Vec2i(0, 0); - max_win_size_ = Vec2i(-1, -1); - - init_ = true; - stereo_anaglyph_mask_default_ = true; - - // Initialize the keyboard event callback as none - keyboardCallback_ = 0; - keyboard_callback_cookie_ = 0; - - // Initialize the mouse event callback as none - mouseCallback_ = 0; - mouse_callback_cookie_ = 0; -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::saveScreenshot(const String &file) -{ - FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); - - vtkSmartPointer wif = vtkSmartPointer::New(); - wif->SetInput(Interactor->GetRenderWindow()); - - vtkSmartPointer snapshot_writer = vtkSmartPointer::New(); - snapshot_writer->SetInputConnection(wif->GetOutputPort()); - snapshot_writer->SetFileName(file.c_str()); - snapshot_writer->Write(); - - cout << "Screenshot successfully captured (" << file.c_str() << ")" << endl; -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::exportScene(const String &file) -{ - vtkSmartPointer exporter; - if (file.size() > 5 && file.substr(file.size() - 5) == ".vrml") - { - exporter = vtkSmartPointer::New(); - vtkVRMLExporter::SafeDownCast(exporter)->SetFileName(file.c_str()); - } - else - { - exporter = vtkSmartPointer::New(); - vtkOBJExporter::SafeDownCast(exporter)->SetFilePrefix(file.c_str()); - } - - exporter->SetInput(Interactor->GetRenderWindow()); - exporter->Write(); - - cout << "Scene successfully exported (" << file.c_str() << ")" << endl; -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::zoomIn() -{ - FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); - // Zoom in - StartDolly(); - double factor = 10.0 * 0.2 * .5; - Dolly(std::pow(1.1, factor)); - EndDolly(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::zoomOut() -{ - FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); - // Zoom out - StartDolly(); - double factor = 10.0 * -0.2 * .5; - Dolly(std::pow(1.1, factor)); - EndDolly(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnChar() -{ - // Make sure we ignore the same events we handle in OnKeyDown to avoid calling things twice - FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); - if (Interactor->GetKeyCode() >= '0' && Interactor->GetKeyCode() <= '9') - return; - - String key(Interactor->GetKeySym()); - if (key.find("XF86ZoomIn") != String::npos) - zoomIn(); - else if (key.find("XF86ZoomOut") != String::npos) - zoomOut(); - - int keymod = Interactor->GetAltKey(); - - switch (Interactor->GetKeyCode()) - { - // All of the options below simply exit - case 'h': case 'H': - case 'l': case 'L': - case 'p': case 'P': - case 'j': case 'J': - case 'c': case 'C': - case 43: // KEY_PLUS - case 45: // KEY_MINUS - case 'f': case 'F': - case 'g': case 'G': - case 'o': case 'O': - case 'u': case 'U': - case 'q': case 'Q': - { - break; - } - // S and R have a special !ALT case - case 'r': case 'R': - case 's': case 'S': - { - if (!keymod) - Superclass::OnChar(); - break; - } - default: - { - Superclass::OnChar(); - break; - } - } -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) -{ - // Register the callback function and store the user data - mouseCallback_ = callback; - mouse_callback_cookie_ = cookie; -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie) -{ - // Register the callback function and store the user data - keyboardCallback_ = callback; - keyboard_callback_cookie_ = cookie; -} - -////////////////////////////////////////////////////////////////////////////////////////////// -int cv::viz::InteractorStyle::getModifiers() -{ - int modifiers = KeyboardEvent::NONE; - - if (Interactor->GetAltKey()) - modifiers |= KeyboardEvent::ALT; - - if (Interactor->GetControlKey()) - modifiers |= KeyboardEvent::CTRL; - - if (Interactor->GetShiftKey()) - modifiers |= KeyboardEvent::SHIFT; - return modifiers; -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnKeyDown() -{ - CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_); - FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); - - // Save the initial windows width/height - if (win_size_[0] == -1 || win_size_[1] == -1) - win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); - - bool alt = Interactor->GetAltKey() != 0; - - std::string key(Interactor->GetKeySym()); - if (key.find("XF86ZoomIn") != std::string::npos) - zoomIn(); - else if (key.find("XF86ZoomOut") != std::string::npos) - zoomOut(); - - switch (Interactor->GetKeyCode()) - { - case 'h': case 'H': - { - std::cout << "| Help:\n" - "-------\n" - " p, P : switch to a point-based representation\n" - " w, W : switch to a wireframe-based representation (where available)\n" - " s, S : switch to a surface-based representation (where available)\n" - "\n" - " j, J : take a .PNG snapshot of the current window view\n" - " k, K : export scene to Wavefront .obj format\n" - " ALT + k, K : export scene to VRML format\n" - " c, C : display current camera/window parameters\n" - " f, F : fly to point mode, hold the key and move mouse where to fly\n" - "\n" - " e, E : exit the interactor\n" - " q, Q : stop and call VTK's TerminateApp\n" - "\n" - " +/- : increment/decrement overall point size\n" - " +/- [+ ALT] : zoom in/out \n" - "\n" - " r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n" - "\n" - " ALT + s, S : turn stereo mode on/off\n" - " ALT + f, F : switch between maximized window mode and original size\n" - "\n" - << std::endl; - break; - } - - // Switch representation to points - case 'p': case 'P': - { - vtkSmartPointer ac = CurrentRenderer->GetActors(); - vtkCollectionSimpleIterator ait; - for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) - for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) - { - vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); - apart->GetProperty()->SetRepresentationToPoints(); - } - break; - } - - // Save a PNG snapshot - case 'j': case 'J': - saveScreenshot(cv::format("screenshot-%d.png", (unsigned int)time(0))); break; - - // Export scene as in obj or vrml format - case 'k': case 'K': - { - String format = alt ? "scene-%d.vrml" : "scene-%d"; - exportScene(cv::format(format.c_str(), (unsigned int)time(0))); - break; - } - - // display current camera settings/parameters - case 'c': case 'C': - { - vtkSmartPointer cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera(); - - Vec2d clip(cam->GetClippingRange()); - Vec3d focal(cam->GetFocalPoint()), pos(cam->GetPosition()), view(cam->GetViewUp()); - Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition()); - Vec2i win_size(Interactor->GetRenderWindow()->GetSize()); - double angle = cam->GetViewAngle () / 180.0 * CV_PI; - - String data = cv::format("clip(%f,%f) focal(%f,%f,%f) pos(%f,%f,%f) view(%f,%f,%f) angle(%f) winsz(%d,%d) winpos(%d,%d)", - clip[0], clip[1], focal[0], focal[1], focal[2], pos[0], pos[1], pos[2], view[0], view[1], view[2], - angle, win_size[0], win_size[1], win_pos[0], win_pos[1]); - - std::cout << data.c_str() << std::endl; - - break; - } - case '=': - { - zoomIn(); - break; - } - case 43: // KEY_PLUS - { - if (alt) - zoomIn(); - else - { - vtkSmartPointer ac = CurrentRenderer->GetActors(); - vtkCollectionSimpleIterator ait; - for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) - for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) - { - vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); - float psize = apart->GetProperty()->GetPointSize(); - if (psize < 63.0f) - apart->GetProperty()->SetPointSize(psize + 1.0f); - } - } - break; - } - case 45: // KEY_MINUS - { - if (alt) - zoomOut(); - else - { - vtkSmartPointer ac = CurrentRenderer->GetActors(); - vtkCollectionSimpleIterator ait; - for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) - for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) - { - vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); - float psize = apart->GetProperty()->GetPointSize(); - if (psize > 1.0f) - apart->GetProperty()->SetPointSize(psize - 1.0f); - } - } - break; - } - // Switch between maximize and original window size - case 'f': case 'F': - { - if (alt) - { - Vec2i screen_size(Interactor->GetRenderWindow()->GetScreenSize()); - Vec2i win_size(Interactor->GetRenderWindow()->GetSize()); - - // Is window size = max? - if (win_size == max_win_size_) - { - Interactor->GetRenderWindow()->SetSize(win_size_.val); - Interactor->GetRenderWindow()->SetPosition(win_pos_.val); - Interactor->Render(); - } - // Set to max - else - { - win_pos_ = Vec2i(Interactor->GetRenderWindow()->GetPosition()); - win_size_ = win_size; - - Interactor->GetRenderWindow()->SetSize(screen_size.val); - Interactor->Render(); - max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); - } - } - else - { - AnimState = VTKIS_ANIM_ON; - Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer); - vtkSmartPointer picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker()); - if (picker) - if (picker->GetPath()) - Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition()); - AnimState = VTKIS_ANIM_OFF; - } - break; - } - // 's'/'S' w/out ALT - case 's': case 'S': - { - if (alt) - { - vtkSmartPointer window = Interactor->GetRenderWindow(); - if (!window->GetStereoRender()) - { - static Vec2i red_blue(4, 3), magenta_green(2, 5); - window->SetAnaglyphColorMask (stereo_anaglyph_mask_default_ ? red_blue.val : magenta_green.val); - stereo_anaglyph_mask_default_ = !stereo_anaglyph_mask_default_; - } - window->SetStereoRender(!window->GetStereoRender()); - Interactor->Render(); - } - else - Superclass::OnKeyDown(); - break; - } - - case 'o': case 'O': - { - vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); - cam->SetParallelProjection(!cam->GetParallelProjection()); - Interactor->Render(); - break; - } - - // Overwrite the camera reset - case 'r': case 'R': - { - if (!alt) - { - Superclass::OnKeyDown(); - break; - } - - WidgetActorMap::iterator it = widget_actor_map_->begin(); - // it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault. - for (; it != widget_actor_map_->end(); ++it) - { - vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); - if (actor && actor->GetUserMatrix()) - break; - } - - vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); - - // if a valid transformation was found, use it otherwise fall back to default view point. - if (it != widget_actor_map_->end()) - { - vtkMatrix4x4* m = vtkProp3D::SafeDownCast(it->second)->GetUserMatrix(); - - cam->SetFocalPoint(m->GetElement(0, 3) - m->GetElement(0, 2), - m->GetElement(1, 3) - m->GetElement(1, 2), - m->GetElement(2, 3) - m->GetElement(2, 2)); - - cam->SetViewUp (m->GetElement(0, 1), m->GetElement(1, 1), m->GetElement(2, 1)); - cam->SetPosition(m->GetElement(0, 3), m->GetElement(1, 3), m->GetElement(2, 3)); - } - else - { - cam->SetPosition(0, 0, 0); - cam->SetFocalPoint(0, 0, 1); - cam->SetViewUp(0, -1, 0); - } - - // go to the next actor for the next key-press event. - if (it != widget_actor_map_->end()) - ++it; - else - it = widget_actor_map_->begin(); - - CurrentRenderer->SetActiveCamera(cam); - CurrentRenderer->ResetCameraClippingRange(); - Interactor->Render(); - break; - } - - case 'q': case 'Q': - { - Interactor->ExitCallback(); - return; - } - default: - { - Superclass::OnKeyDown(); - break; - } - } - - KeyboardEvent event(KeyboardEvent::KEY_DOWN, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers()); - if (keyboardCallback_) - keyboardCallback_(event, keyboard_callback_cookie_); - Interactor->Render(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnKeyUp() -{ - KeyboardEvent event(KeyboardEvent::KEY_UP, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers()); - if (keyboardCallback_) - keyboardCallback_(event, keyboard_callback_cookie_); - Superclass::OnKeyUp(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMouseMove() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnMouseMove(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnLeftButtonDown() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; - MouseEvent event(type, MouseEvent::LeftButton, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnLeftButtonDown(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnLeftButtonUp() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnLeftButtonUp(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMiddleButtonDown() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; - MouseEvent event(type, MouseEvent::MiddleButton, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnMiddleButtonDown(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMiddleButtonUp() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnMiddleButtonUp(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnRightButtonDown() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; - MouseEvent event(type, MouseEvent::RightButton, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnRightButtonDown(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnRightButtonUp() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - Superclass::OnRightButtonUp(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMouseWheelForward() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - if (Interactor->GetRepeatCount() && mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - - if (Interactor->GetAltKey()) - { - // zoom - vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); - double opening_angle = cam->GetViewAngle(); - if (opening_angle > 15.0) - opening_angle -= 1.0; - - cam->SetViewAngle(opening_angle); - cam->Modified(); - CurrentRenderer->ResetCameraClippingRange(); - CurrentRenderer->Modified(); - Interactor->Render(); - } - else - Superclass::OnMouseWheelForward(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnMouseWheelBackward() -{ - Vec2i p(Interactor->GetEventPosition()); - MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getModifiers()); - if (mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - - if (Interactor->GetRepeatCount() && mouseCallback_) - mouseCallback_(event, mouse_callback_cookie_); - - if (Interactor->GetAltKey()) - { - // zoom - vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); - double opening_angle = cam->GetViewAngle(); - if (opening_angle < 170.0) - opening_angle += 1.0; - - cam->SetViewAngle(opening_angle); - cam->Modified(); - CurrentRenderer->ResetCameraClippingRange(); - CurrentRenderer->Modified(); - Interactor->Render(); - } - else - Superclass::OnMouseWheelBackward(); -} - -////////////////////////////////////////////////////////////////////////////////////////////// -void cv::viz::InteractorStyle::OnTimer() -{ - CV_Assert("Interactor style not initialized." && init_); - Interactor->Render(); -} diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 795ac16b0..feaca852e 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -130,6 +130,7 @@ #include #include #include +#include "vtkCallbackCommand.h" #if !defined(_WIN32) || defined(__CYGWIN__) # include /* unlink */ @@ -145,6 +146,7 @@ #include #include + #include #include #include @@ -332,8 +334,7 @@ namespace cv } } -#include "interactor_style.hpp" +#include "vtk/vtkVizInteractorStyle.hpp" #include "vizimpl.hpp" - #endif diff --git a/modules/viz/src/vizcore.cpp b/modules/viz/src/vizcore.cpp index 4544f9b3c..a33a192c6 100644 --- a/modules/viz/src/vizcore.cpp +++ b/modules/viz/src/vizcore.cpp @@ -87,6 +87,7 @@ cv::Affine3d cv::viz::makeCameraPose(const Vec3d& position, const Vec3d& focal_p #else + void register_console_handler(); void register_console_handler() {} #endif diff --git a/modules/viz/src/vizimpl.cpp b/modules/viz/src/vizimpl.cpp index 37d008bc8..2401e76b5 100644 --- a/modules/viz/src/vizimpl.cpp +++ b/modules/viz/src/vizimpl.cpp @@ -60,10 +60,9 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false), window_->AddRenderer(renderer_); // Create the interactor style - style_ = vtkSmartPointer::New(); + style_ = vtkSmartPointer::New(); style_->setWidgetActorMap(widget_actor_map_); style_->UseTimersOn(); - style_->Initialize(); timer_callback_ = vtkSmartPointer::New(); exit_callback_ = vtkSmartPointer::New(); diff --git a/modules/viz/src/vizimpl.hpp b/modules/viz/src/vizimpl.hpp index 67cab3674..92113afa0 100644 --- a/modules/viz/src/vizimpl.hpp +++ b/modules/viz/src/vizimpl.hpp @@ -128,7 +128,7 @@ private: vtkSmartPointer exit_callback_; vtkSmartPointer renderer_; - vtkSmartPointer style_; + vtkSmartPointer style_; Ptr widget_actor_map_; bool removeActorFromRenderer(vtkSmartPointer actor); diff --git a/modules/viz/src/vtk/vtkCocoaInteractorFix.mm b/modules/viz/src/vtk/vtkCocoaInteractorFix.mm index 0e55aebb0..23bba552d 100644 --- a/modules/viz/src/vtk/vtkCocoaInteractorFix.mm +++ b/modules/viz/src/vtk/vtkCocoaInteractorFix.mm @@ -40,8 +40,7 @@ // Authors: // * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com // -// OpenCV Viz module is complete rewrite of -// PCL visualization module (www.pointclouds.org) +// This workaround code was taken from PCL library(www.pointclouds.org) // //M*/ diff --git a/modules/viz/src/vtk/vtkOBJWriter.cpp b/modules/viz/src/vtk/vtkOBJWriter.cpp index e92424c66..7480b11ac 100644 --- a/modules/viz/src/vtk/vtkOBJWriter.cpp +++ b/modules/viz/src/vtk/vtkOBJWriter.cpp @@ -84,7 +84,7 @@ void cv::viz::vtkOBJWriter::WriteData() std::ostream& outfile = *outfilep; //write header - outfile << "# wavefront obj file written by the visualization toolkit" << std::endl << std::endl; + outfile << "# wavefront obj file written by opencv viz module" << std::endl << std::endl; outfile << "mtllib NONE" << std::endl << std::endl; // write out the points diff --git a/modules/viz/src/vtk/vtkVizInteractorStyle.cpp b/modules/viz/src/vtk/vtkVizInteractorStyle.cpp new file mode 100644 index 000000000..57aee636e --- /dev/null +++ b/modules/viz/src/vtk/vtkVizInteractorStyle.cpp @@ -0,0 +1,1077 @@ +/*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 +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace viz +{ + vtkStandardNewMacro(vtkVizInteractorStyle) +}} + +////////////////////////////////////////////////////////////////////////////////////////////// + +cv::viz::vtkVizInteractorStyle::vtkVizInteractorStyle() +{ + FlyMode = false; + MotionFactor = 10.0; + + keyboardCallback_ = 0; + keyboard_callback_cookie_ = 0; + + mouseCallback_ = 0; + mouse_callback_cookie_ = 0; + + // Set windows size (width, height) to unknown (-1) + win_size_ = Vec2i(-1, -1); + win_pos_ = Vec2i(0, 0); + max_win_size_ = Vec2i(-1, -1); + + stereo_anaglyph_redblue_ = true; + + //from fly + KeysDown = 0; + UseTimers = 1; + + DiagonalLength = 1.0; + MotionStepSize = 1.0/100.0; + MotionUserScale = 1.0; // +/- key adjustment + MotionAccelerationFactor = 10.0; + AngleStepSize = 1.0; +} + +cv::viz::vtkVizInteractorStyle::~vtkVizInteractorStyle() {} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::saveScreenshot(const String &file) +{ + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + + vtkSmartPointer wif = vtkSmartPointer::New(); + wif->SetInput(Interactor->GetRenderWindow()); + + vtkSmartPointer snapshot_writer = vtkSmartPointer::New(); + snapshot_writer->SetInputConnection(wif->GetOutputPort()); + snapshot_writer->SetFileName(file.c_str()); + snapshot_writer->Write(); + + cout << "Screenshot successfully captured (" << file.c_str() << ")" << endl; +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::exportScene(const String &file) +{ + vtkSmartPointer exporter; + if (file.size() > 5 && file.substr(file.size() - 5) == ".vrml") + { + exporter = vtkSmartPointer::New(); + vtkVRMLExporter::SafeDownCast(exporter)->SetFileName(file.c_str()); + } + else + { + exporter = vtkSmartPointer::New(); + vtkOBJExporter::SafeDownCast(exporter)->SetFilePrefix(file.c_str()); + } + + exporter->SetInput(Interactor->GetRenderWindow()); + exporter->Write(); + + cout << "Scene successfully exported (" << file.c_str() << ")" << endl; +} + +void cv::viz::vtkVizInteractorStyle::exportScene() +{ + // Export scene as in obj or vrml format + String format = Interactor->GetAltKey() ? "scene-%d.vrml" : "scene-%d"; + exportScene(cv::format(format.c_str(), (unsigned int)time(0))); +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::changePointsSize(float delta) +{ + vtkSmartPointer ac = CurrentRenderer->GetActors(); + vtkCollectionSimpleIterator ait; + + for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) + for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) + { + vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); + float psize = apart->GetProperty()->GetPointSize() + delta; + psize = std::max(1.f, std::min(63.f, psize)); + apart->GetProperty()->SetPointSize(psize); + } +} + +void cv::viz::vtkVizInteractorStyle::setRepresentationToPoints() +{ + vtkSmartPointer ac = CurrentRenderer->GetActors(); + vtkCollectionSimpleIterator ait; + for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) + for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) + { + vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); + apart->GetProperty()->SetRepresentationToPoints(); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::printCameraParams() +{ + vtkSmartPointer cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera(); + + Vec2d clip(cam->GetClippingRange()); + Vec3d focal(cam->GetFocalPoint()), pos(cam->GetPosition()), view(cam->GetViewUp()); + Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition()); + Vec2i win_size(Interactor->GetRenderWindow()->GetSize()); + double angle = cam->GetViewAngle () / 180.0 * CV_PI; + + String data = cv::format("clip(%f,%f) focal(%f,%f,%f) pos(%f,%f,%f) view(%f,%f,%f) angle(%f) winsz(%d,%d) winpos(%d,%d)", + clip[0], clip[1], focal[0], focal[1], focal[2], pos[0], pos[1], pos[2], view[0], view[1], view[2], + angle, win_size[0], win_size[1], win_pos[0], win_pos[1]); + + std::cout << data.c_str() << std::endl; +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::toggleFullScreen() +{ + 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->Render(); + } + // Set to max + else + { + win_pos_ = Vec2i(Interactor->GetRenderWindow()->GetPosition()); + win_size_ = win_size; + + Interactor->GetRenderWindow()->SetSize(screen_size.val); + Interactor->Render(); + max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::resetViewerPose() +{ + WidgetActorMap::iterator it = widget_actor_map_->begin(); + // it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault. + for (; it != widget_actor_map_->end(); ++it) + { + vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); + if (actor && actor->GetUserMatrix()) + break; + } + + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + + // if a valid transformation was found, use it otherwise fall back to default view point. + if (it != widget_actor_map_->end()) + { + vtkMatrix4x4* m = vtkProp3D::SafeDownCast(it->second)->GetUserMatrix(); + + cam->SetFocalPoint(m->GetElement(0, 3) - m->GetElement(0, 2), + m->GetElement(1, 3) - m->GetElement(1, 2), + m->GetElement(2, 3) - m->GetElement(2, 2)); + + cam->SetViewUp (m->GetElement(0, 1), m->GetElement(1, 1), m->GetElement(2, 1)); + cam->SetPosition(m->GetElement(0, 3), m->GetElement(1, 3), m->GetElement(2, 3)); + } + else + { + cam->SetPosition(0, 0, 0); + cam->SetFocalPoint(0, 0, 1); + cam->SetViewUp(0, -1, 0); + } + + // go to the next actor for the next key-press event. + if (it != widget_actor_map_->end()) + ++it; + else + it = widget_actor_map_->begin(); + + CurrentRenderer->SetActiveCamera(cam); + CurrentRenderer->ResetCameraClippingRange(); + Interactor->Render(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::toggleStereo() +{ + vtkSmartPointer window = Interactor->GetRenderWindow(); + if (!window->GetStereoRender()) + { + static Vec2i red_blue(4, 3), magenta_green(2, 5); + window->SetAnaglyphColorMask (stereo_anaglyph_redblue_ ? red_blue.val : magenta_green.val); + stereo_anaglyph_redblue_ = !stereo_anaglyph_redblue_; + } + window->SetStereoRender(!window->GetStereoRender()); + Interactor->Render(); + +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::printHelp() +{ + std::cout << "| Help:\n" + "-------\n" + " p, P : switch to a point-based representation\n" + " w, W : switch to a wireframe-based representation (where available)\n" + " s, S : switch to a surface-based representation (where available)\n" + "\n" + " j, J : take a .PNG snapshot of the current window view\n" + " k, K : export scene to Wavefront .obj format\n" + " ALT + k, K : export scene to VRML format\n" + " c, C : display current camera/window parameters\n" + " F5 : enable/disable fly mode (changes control style)\n" + "\n" + " e, E : exit the interactor\n" + " q, Q : stop and call VTK's TerminateApp\n" + "\n" + " +/- : increment/decrement overall point size\n" + " +/- [+ ALT] : zoom in/out \n" + "\n" + " r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n" + "\n" + " ALT + s, S : turn stereo mode on/off\n" + " ALT + f, F : switch between maximized window mode and original size\n" + "\n" + << std::endl; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::zoomIn() +{ + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + // Zoom in + StartDolly(); + double factor = 10.0 * 0.2 * .5; + Dolly(std::pow(1.1, factor)); + EndDolly(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::zoomOut() +{ + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + // Zoom out + StartDolly(); + double factor = 10.0 * -0.2 * .5; + Dolly(std::pow(1.1, factor)); + EndDolly(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnChar() +{ + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + + String key(Interactor->GetKeySym()); + if (key.find("XF86ZoomIn") != String::npos) + zoomIn(); + else if (key.find("XF86ZoomOut") != String::npos) + zoomOut(); + + switch (Interactor->GetKeyCode()) + { +// // All of the options below simply exit +// case 'l': case 'L': case 'j': case 'J': case 'c': case 'C': case 'q': case 'Q': +// case 'f': case 'F': case 'g': case 'G': case 'o': case 'O': case 'u': case 'U': + case 'p': case 'P': + break; + + case '+': + if (FlyMode) + MotionUserScale = std::min(16.0, MotionUserScale*2.0); + break; + case '-': + if (FlyMode) + MotionUserScale = std::max(MotionUserScale * 0.5, 0.0625); + break; + + case 'r': case 'R': case 's': case 'S': + if (!Interactor->GetAltKey()) + Superclass::OnChar(); + break; + default: + Superclass::OnChar(); + break; + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) +{ + mouseCallback_ = callback; + mouse_callback_cookie_ = cookie; +} + +void cv::viz::vtkVizInteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie) +{ + keyboardCallback_ = callback; + keyboard_callback_cookie_ = cookie; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +int cv::viz::vtkVizInteractorStyle::getModifiers() +{ + int modifiers = KeyboardEvent::NONE; + + if (Interactor->GetAltKey()) + modifiers |= KeyboardEvent::ALT; + + if (Interactor->GetControlKey()) + modifiers |= KeyboardEvent::CTRL; + + if (Interactor->GetShiftKey()) + modifiers |= KeyboardEvent::SHIFT; + return modifiers; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnKeyDown() +{ + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + + String key(Interactor->GetKeySym()); + if (key.find("XF86ZoomIn") != String::npos) + zoomIn(); + else if (key.find("XF86ZoomOut") != String::npos) + zoomOut(); + else if (key.find("F5") != String::npos) + { + FlyMode = !FlyMode; + std::cout << (FlyMode ? "Fly mode: on" : "Fly mode: off") << std::endl; + } + + // Save the initial windows width/height + if (win_size_[0] == -1 || win_size_[1] == -1) + win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); + + switch (Interactor->GetKeyCode()) + { + case 'a': case 'A' : KeysDown |=16; break; + case 'z': case 'Z' : KeysDown |=32; break; + case 'h': case 'H' : printHelp(); break; + case 'p': case 'P' : setRepresentationToPoints(); break; + case 'k': case 'K' : exportScene(); break; + case 'j': case 'J' : saveScreenshot(cv::format("screenshot-%d.png", (unsigned int)time(0))); break; + case 'c': case 'C' : printCameraParams(); break; + case '=': zoomIn(); break; + case 43: // KEY_PLUS + { + if (FlyMode) + break; + if (Interactor->GetAltKey()) + zoomIn(); + else + changePointsSize(+1.f); + break; + } + case 45: // KEY_MINUS + { + if (FlyMode) + break; + if (Interactor->GetAltKey()) + zoomOut(); + else + changePointsSize(-1.f); + break; + } + // Switch between maximize and original window size + case 'f': case 'F': + { + if (Interactor->GetAltKey()) + toggleFullScreen(); + break; + } + // 's'/'S' w/out ALT + case 's': case 'S': + { + if (Interactor->GetAltKey()) + toggleStereo(); + break; + } + + case 'o': case 'O': + { + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + cam->SetParallelProjection(!cam->GetParallelProjection()); + Interactor->Render(); + break; + } + + // Overwrite the camera reset + case 'r': case 'R': + { + if (Interactor->GetAltKey()) + resetViewerPose(); + break; + } + case 'q': case 'Q': + Interactor->ExitCallback(); return; + default: + Superclass::OnKeyDown(); break; + } + + KeyboardEvent event(KeyboardEvent::KEY_DOWN, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers()); + if (keyboardCallback_) + keyboardCallback_(event, keyboard_callback_cookie_); + + if (FlyMode && (KeysDown & (32+16)) == (32+16)) + { + if (State == VTKIS_FORWARDFLY || State == VTKIS_REVERSEFLY) + StopState(); + } + else if (FlyMode && (KeysDown & 32) == 32) + { + if (State == VTKIS_FORWARDFLY) + StopState(); + + if (State == VTKIS_NONE) + StartState(VTKIS_REVERSEFLY); + } + else if (FlyMode && (KeysDown & 16) == 16) + { + if (State == VTKIS_REVERSEFLY) + StopState(); + + if (State == VTKIS_NONE) + StartState(VTKIS_FORWARDFLY); + } + + Interactor->Render(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnKeyUp() +{ + KeyboardEvent event(KeyboardEvent::KEY_UP, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers()); + if (keyboardCallback_) + keyboardCallback_(event, keyboard_callback_cookie_); + + switch (Interactor->GetKeyCode()) + { + case 'a': case 'A' : KeysDown &= ~16; break; + case 'z': case 'Z' : KeysDown &= ~32; break; + } + + if (State == VTKIS_FORWARDFLY && (KeysDown & 16) == 0) + StopState(); + + if (State == VTKIS_REVERSEFLY && (KeysDown & 32) == 0) + StopState(); + + Superclass::OnKeyUp(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnMouseMove() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + FindPokedRenderer(p[0], p[1]); + + if (State == VTKIS_ROTATE || State == VTKIS_PAN || State == VTKIS_DOLLY || State == VTKIS_SPIN) + { + switch (State) + { + case VTKIS_ROTATE: Rotate(); break; + case VTKIS_PAN: Pan(); break; + case VTKIS_DOLLY: Dolly(); break; + case VTKIS_SPIN: Spin(); break; + } + + InvokeEvent(vtkCommand::InteractionEvent, NULL); + } + + if (State == VTKIS_FORWARDFLY || State == VTKIS_REVERSEFLY) + { + vtkCamera *cam = CurrentRenderer->GetActiveCamera(); + Vec2i thispos(Interactor->GetEventPosition()); + Vec2i lastpos(Interactor->GetLastEventPosition()); + + // we want to steer by an amount proportional to window viewangle and size + // compute dx and dy increments relative to last mouse click + Vec2i size(Interactor->GetSize()); + double scalefactor = 5*cam->GetViewAngle()/size[0]; + + double dx = - (thispos[0] - lastpos[0])*scalefactor*AngleStepSize; + double dy = (thispos[1] - lastpos[1])*scalefactor*AngleStepSize; + + // Temporary until I get smooth flight working + DeltaPitch = dy; + DeltaYaw = dx; + + InvokeEvent(vtkCommand::InteractionEvent, NULL); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnLeftButtonDown() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event(type, MouseEvent::LeftButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + FindPokedRenderer(p[0], p[1]); + if (!CurrentRenderer) + return; + + GrabFocus(EventCallbackCommand); + + if (FlyMode) + { + if(State == VTKIS_REVERSEFLY) + State = VTKIS_FORWARDFLY; + else + { + SetupMotionVars(); + if (State == VTKIS_NONE) + StartState(VTKIS_FORWARDFLY); + } + } + else + { + if (Interactor->GetShiftKey()) + { + if (Interactor->GetControlKey()) + StartDolly(); + else + StartPan(); + } + else + { + if (Interactor->GetControlKey()) + StartSpin(); + else + StartRotate(); + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnLeftButtonUp() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + switch (State) + { + case VTKIS_DOLLY: EndDolly(); break; + case VTKIS_PAN: EndPan(); break; + case VTKIS_SPIN: EndSpin(); break; + case VTKIS_ROTATE: EndRotate(); break; + case VTKIS_FORWARDFLY: StopState(); break; + } + + if (Interactor ) + ReleaseFocus(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnMiddleButtonDown() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event(type, MouseEvent::MiddleButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + FindPokedRenderer(p[0], p[1]); + if (!CurrentRenderer) + return; + + GrabFocus(EventCallbackCommand); + StartPan(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnMiddleButtonUp() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if (State == VTKIS_PAN) + { + EndPan(); + if (Interactor) + ReleaseFocus(); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnRightButtonDown() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event(type, MouseEvent::RightButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + FindPokedRenderer(p[0], p[1]); + if (!CurrentRenderer) + return; + + GrabFocus(EventCallbackCommand); + + if (FlyMode) + { + if (State == VTKIS_FORWARDFLY) + State = VTKIS_REVERSEFLY; + else + { + SetupMotionVars(); + if (State == VTKIS_NONE) + StartState(VTKIS_REVERSEFLY); + } + + } + else + StartDolly(); +} + + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnRightButtonUp() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if(State == VTKIS_DOLLY) + { + EndDolly(); + if (Interactor) + ReleaseFocus(); + } + + if (State == VTKIS_REVERSEFLY) + { + StopState(); + if (Interactor) + ReleaseFocus(); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnMouseWheelForward() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + if (Interactor->GetRepeatCount() && mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if (Interactor->GetAltKey()) + { + // zoom + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + double opening_angle = cam->GetViewAngle(); + if (opening_angle > 15.0) + opening_angle -= 1.0; + + cam->SetViewAngle(opening_angle); + cam->Modified(); + CurrentRenderer->ResetCameraClippingRange(); + CurrentRenderer->Modified(); + Interactor->Render(); + } + else + { + FindPokedRenderer(p[0], p[1]); + if (!CurrentRenderer) + return; + + GrabFocus(EventCallbackCommand); + StartDolly(); + Dolly(pow(1.1, MotionFactor * 0.2 * MouseWheelMotionFactor)); + EndDolly(); + ReleaseFocus(); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnMouseWheelBackward() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if (Interactor->GetRepeatCount() && mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if (Interactor->GetAltKey()) + { + // zoom + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + double opening_angle = cam->GetViewAngle(); + if (opening_angle < 170.0) + opening_angle += 1.0; + + cam->SetViewAngle(opening_angle); + cam->Modified(); + CurrentRenderer->ResetCameraClippingRange(); + CurrentRenderer->Modified(); + Interactor->Render(); + } + else + { + FindPokedRenderer(p[0], p[1]); + if (!CurrentRenderer) + return; + + GrabFocus(EventCallbackCommand); + StartDolly(); + Dolly(pow(1.1, MotionFactor * -0.2 * MouseWheelMotionFactor)); + EndDolly(); + ReleaseFocus(); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::OnTimer() +{ + if (State == VTKIS_FORWARDFLY || State == VTKIS_REVERSEFLY) + Fly(); + + Interactor->Render(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::Rotate() +{ + if (!CurrentRenderer) + return; + + Vec2i dxy = Vec2i(Interactor->GetEventPosition()) - Vec2i(Interactor->GetLastEventPosition()); + Vec2i size(CurrentRenderer->GetRenderWindow()->GetSize()); + + double delta_elevation = -20.0 / size[1]; + double delta_azimuth = -20.0 / size[0]; + + double rxf = dxy[0] * delta_azimuth * MotionFactor; + double ryf = dxy[1] * delta_elevation * MotionFactor; + + vtkCamera *camera = CurrentRenderer->GetActiveCamera(); + camera->Azimuth(rxf); + camera->Elevation(ryf); + camera->OrthogonalizeViewUp(); + + if (AutoAdjustCameraClippingRange) + CurrentRenderer->ResetCameraClippingRange(); + + if (Interactor->GetLightFollowCamera()) + CurrentRenderer->UpdateLightsGeometryToFollowCamera(); + + Interactor->Render(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::Spin() +{ + if (!CurrentRenderer) + return; + + vtkRenderWindowInteractor *rwi = Interactor; + + double *center = CurrentRenderer->GetCenter(); + + double newAngle = vtkMath::DegreesFromRadians( atan2( rwi->GetEventPosition()[1] - center[1], rwi->GetEventPosition()[0] - center[0] ) ); + double oldAngle = vtkMath::DegreesFromRadians( atan2( rwi->GetLastEventPosition()[1] - center[1], rwi->GetLastEventPosition()[0] - center[0] ) ); + + vtkCamera *camera = CurrentRenderer->GetActiveCamera(); + camera->Roll( newAngle - oldAngle ); + camera->OrthogonalizeViewUp(); + + rwi->Render(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::vtkVizInteractorStyle::Pan() +{ + if (!CurrentRenderer) + return; + + vtkRenderWindowInteractor *rwi = Interactor; + + double viewFocus[4], focalDepth, viewPoint[3]; + double newPickPoint[4], oldPickPoint[4], motionVector[3]; + + // Calculate the focal depth since we'll be using it a lot + + vtkCamera *camera = CurrentRenderer->GetActiveCamera(); + camera->GetFocalPoint(viewFocus); + ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2], viewFocus); + focalDepth = viewFocus[2]; + + ComputeDisplayToWorld(rwi->GetEventPosition()[0], rwi->GetEventPosition()[1], focalDepth, newPickPoint); + + // Has to recalc old mouse point since the viewport has moved, so can't move it outside the loop + ComputeDisplayToWorld(rwi->GetLastEventPosition()[0], rwi->GetLastEventPosition()[1], focalDepth, oldPickPoint); + + // Camera motion is reversed + motionVector[0] = oldPickPoint[0] - newPickPoint[0]; + motionVector[1] = oldPickPoint[1] - newPickPoint[1]; + motionVector[2] = oldPickPoint[2] - newPickPoint[2]; + + camera->GetFocalPoint(viewFocus); + camera->GetPosition(viewPoint); + camera->SetFocalPoint(motionVector[0] + viewFocus[0], motionVector[1] + viewFocus[1], motionVector[2] + viewFocus[2]); + camera->SetPosition( motionVector[0] + viewPoint[0], motionVector[1] + viewPoint[1], motionVector[2] + viewPoint[2]); + + if (Interactor->GetLightFollowCamera()) + CurrentRenderer->UpdateLightsGeometryToFollowCamera(); + + Interactor->Render(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::Dolly() +{ + if (!CurrentRenderer) + return; + + int dy = Interactor->GetEventPosition()[1] - Interactor->GetLastEventPosition()[1]; + Dolly(pow(1.1, MotionFactor * dy / CurrentRenderer->GetCenter()[1])); +} + +void cv::viz::vtkVizInteractorStyle::Dolly(double factor) +{ + if (!CurrentRenderer) + return; + + vtkCamera *camera = CurrentRenderer->GetActiveCamera(); + if (camera->GetParallelProjection()) + camera->SetParallelScale(camera->GetParallelScale() / factor); + else + { + camera->Dolly(factor); + if (AutoAdjustCameraClippingRange) + CurrentRenderer->ResetCameraClippingRange(); + } + + if (Interactor->GetLightFollowCamera()) + CurrentRenderer->UpdateLightsGeometryToFollowCamera(); + + Interactor->Render(); +} +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::Fly() +{ + if (CurrentRenderer == NULL) + return; + + if (KeysDown) + FlyByKey(); + else + FlyByMouse(); + + CurrentRenderer->GetActiveCamera()->OrthogonalizeViewUp(); + + if (AutoAdjustCameraClippingRange) + CurrentRenderer->ResetCameraClippingRange(); + + if (Interactor->GetLightFollowCamera()) + CurrentRenderer->UpdateLightsGeometryToFollowCamera(); +} + +void cv::viz::vtkVizInteractorStyle::SetupMotionVars() +{ + Vec6d bounds; + CurrentRenderer->ComputeVisiblePropBounds(bounds.val); + + if ( !vtkMath::AreBoundsInitialized(bounds.val) ) + DiagonalLength = 1.0; + else + DiagonalLength = norm(Vec3d(bounds[0], bounds[2], bounds[4]) - Vec3d(bounds[1], bounds[3], bounds[5])); +} + +void cv::viz::vtkVizInteractorStyle::MotionAlongVector(const Vec3d& vector, double amount, vtkCamera* cam) +{ + // move camera and focus along DirectionOfProjection + Vec3d campos = Vec3d(cam->GetPosition()) - amount * vector; + Vec3d camfoc = Vec3d(cam->GetFocalPoint()) - amount * vector; + + cam->SetPosition(campos.val); + cam->SetFocalPoint(camfoc.val); +} + +void cv::viz::vtkVizInteractorStyle::FlyByMouse() +{ + vtkCamera* cam = CurrentRenderer->GetActiveCamera(); + double speed = DiagonalLength * MotionStepSize * MotionUserScale; + speed = speed * ( Interactor->GetShiftKey() ? MotionAccelerationFactor : 1.0); + + // Sidestep + if (Interactor->GetAltKey()) + { + if (DeltaYaw!=0.0) + { + vtkMatrix4x4 *vtm = cam->GetViewTransformMatrix(); + Vec3d a_vector(vtm->GetElement(0,0), vtm->GetElement(0,1), vtm->GetElement(0,2)); + + MotionAlongVector(a_vector, -DeltaYaw*speed, cam); + } + if (DeltaPitch!=0.0) + { + Vec3d a_vector(cam->GetViewUp()); + MotionAlongVector(a_vector, DeltaPitch*speed, cam); + } + } + else + { + cam->Yaw(DeltaYaw); + cam->Pitch(DeltaPitch); + DeltaYaw = 0; + DeltaPitch = 0; + } + // + if (!Interactor->GetControlKey()) + { + Vec3d a_vector(cam->GetDirectionOfProjection()); // reversed (use -speed) + switch (State) + { + case VTKIS_FORWARDFLY: MotionAlongVector(a_vector, -speed, cam); break; + case VTKIS_REVERSEFLY: MotionAlongVector(a_vector, speed, cam); break; + } + } +} + +void cv::viz::vtkVizInteractorStyle::FlyByKey() +{ + vtkCamera* cam = CurrentRenderer->GetActiveCamera(); + + double speed = DiagonalLength * MotionStepSize * MotionUserScale; + speed = speed * ( Interactor->GetShiftKey() ? MotionAccelerationFactor : 1.0); + + // Left and right + if (Interactor->GetAltKey()) + { // Sidestep + vtkMatrix4x4 *vtm = cam->GetViewTransformMatrix(); + Vec3d a_vector(vtm->GetElement(0,0), vtm->GetElement(0,1), vtm->GetElement(0,2)); + + if (KeysDown & 1) + MotionAlongVector(a_vector, -speed, cam); + + if (KeysDown & 2) + MotionAlongVector(a_vector, speed, cam); + } + else + { + if (KeysDown & 1) + cam->Yaw( AngleStepSize); + + if (KeysDown & 2) + cam->Yaw(-AngleStepSize); + } + + // Up and Down + if (Interactor->GetControlKey()) + { // Sidestep + Vec3d a_vector = Vec3d(cam->GetViewUp()); + if (KeysDown & 4) + MotionAlongVector(a_vector,-speed, cam); + + if (KeysDown & 8) + MotionAlongVector(a_vector, speed, cam); + } + else + { + if (KeysDown & 4) + cam->Pitch(-AngleStepSize); + + if (KeysDown & 8) + cam->Pitch( AngleStepSize); + } + + // forward and backward + Vec3d a_vector(cam->GetDirectionOfProjection()); + if (KeysDown & 16) + MotionAlongVector(a_vector, speed, cam); + + if (KeysDown & 32) + MotionAlongVector(a_vector,-speed, cam); +} + +////////////////////////////////////////////////////////////////////////////////////////////// + +void cv::viz::vtkVizInteractorStyle::PrintSelf(ostream& os, vtkIndent indent) +{ + Superclass::PrintSelf(os, indent); + os << indent << "MotionFactor: " << MotionFactor << "\n"; + os << indent << "MotionStepSize: " << MotionStepSize << "\n"; + os << indent << "MotionAccelerationFactor: "<< MotionAccelerationFactor << "\n"; + os << indent << "AngleStepSize: " << AngleStepSize << "\n"; + os << indent << "MotionUserScale: "<< MotionUserScale << "\n"; +} + diff --git a/modules/viz/src/interactor_style.hpp b/modules/viz/src/vtk/vtkVizInteractorStyle.hpp similarity index 61% rename from modules/viz/src/interactor_style.hpp rename to modules/viz/src/vtk/vtkVizInteractorStyle.hpp index 8d01697a8..3588a3b6c 100644 --- a/modules/viz/src/interactor_style.hpp +++ b/modules/viz/src/vtk/vtkVizInteractorStyle.hpp @@ -46,46 +46,23 @@ #ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__ #define __OPENCV_VIZ_INTERACTOR_STYLE_H__ +#include + namespace cv { namespace viz { - class InteractorStyle : public vtkInteractorStyleTrackballCamera + class vtkVizInteractorStyle : public vtkInteractorStyle { public: - static InteractorStyle *New(); - virtual ~InteractorStyle() {} + static vtkVizInteractorStyle *New(); + vtkTypeMacro(vtkVizInteractorStyle, vtkInteractorStyle) + void PrintSelf(ostream& os, vtkIndent indent); - // this macro defines Superclass, the isA functionality and the safe downcast method - vtkTypeMacro(InteractorStyle, vtkInteractorStyleTrackballCamera) - - /** \brief Initialization routine. Must be called before anything else. */ - virtual void Initialize(); - - void setWidgetActorMap(const Ptr& actors) { widget_actor_map_ = actors; } - void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); - void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0); - void saveScreenshot(const String &file); - void exportScene(const String &file); - - private: - /** \brief Set to true after initialization is complete. */ - bool init_; - - Ptr widget_actor_map_; - - Vec2i win_size_; - Vec2i win_pos_; - Vec2i max_win_size_; - - /** \brief Interactor style internal method. Gets called whenever a key is pressed. */ virtual void OnChar(); - - // Keyboard events virtual void OnKeyDown(); virtual void OnKeyUp(); - // mouse button events virtual void OnMouseMove(); virtual void OnLeftButtonDown(); virtual void OnLeftButtonUp(); @@ -95,15 +72,75 @@ namespace cv 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 Rotate(); + virtual void Spin(); + virtual void Pan(); + virtual void Dolly(); + + vtkSetMacro(FlyMode,bool) + vtkGetMacro(FlyMode,bool) + + + vtkSetMacro(MotionFactor, double) + vtkGetMacro(MotionFactor, double) + + void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); + void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0); + + void setWidgetActorMap(const Ptr& actors) { widget_actor_map_ = actors; } + void saveScreenshot(const String &file); + void exportScene(const String &file); + void exportScene(); + void changePointsSize(float delta); + void setRepresentationToPoints(); + void printCameraParams(); + void toggleFullScreen(); + void resetViewerPose(); + void toggleStereo(); + void printHelp(); + + // Set the basic unit step size : by default 1/250 of bounding diagonal + vtkSetMacro(MotionStepSize,double) + vtkGetMacro(MotionStepSize,double) + + // Set acceleration factor when shift key is applied : default 10 + vtkSetMacro(MotionAccelerationFactor,double) + vtkGetMacro(MotionAccelerationFactor,double) + + // Set the basic angular unit for turning : efault 1 degree + vtkSetMacro(AngleStepSize,double) + vtkGetMacro(AngleStepSize,double) + + private: + Ptr widget_actor_map_; + + Vec2i win_size_; + Vec2i win_pos_; + Vec2i max_win_size_; + 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_; + protected: + vtkVizInteractorStyle(); + ~vtkVizInteractorStyle(); + + virtual void Dolly(double factor); + + void Fly(); + void FlyByMouse(); + void FlyByKey(); + void SetupMotionVars(); + void MotionAlongVector(const Vec3d& vector, double amount, vtkCamera* cam); + + private: + vtkVizInteractorStyle(const vtkVizInteractorStyle&); + vtkVizInteractorStyle& operator=(const vtkVizInteractorStyle&); + + //! True for red-blue colors, false for magenta-green. + bool stereo_anaglyph_redblue_; void (*keyboardCallback_)(const KeyboardEvent&, void*); void *keyboard_callback_cookie_; @@ -111,7 +148,20 @@ namespace cv void (*mouseCallback_)(const MouseEvent&, void*); void *mouse_callback_cookie_; + bool FlyMode; + double MotionFactor; + int getModifiers(); + + // from fly + unsigned char KeysDown; + double DiagonalLength; + double MotionStepSize; + double MotionUserScale; + double MotionAccelerationFactor; + double AngleStepSize; + double DeltaYaw; + double DeltaPitch; }; } } From fde0185a774b258988c9e37efbb8be14090e581a Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 16 Feb 2014 21:27:25 +0400 Subject: [PATCH 14/25] iteractor work --- modules/viz/doc/widget.rst | 9 ++++----- modules/viz/include/opencv2/viz/widgets.hpp | 5 ++--- modules/viz/src/vtk/vtkCocoaInteractorFix.mm | 3 +-- modules/viz/src/vtk/vtkVizInteractorStyle.cpp | 1 - modules/viz/test/test_viz3d.cpp | 1 - 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst index 31546ae8e..0884ecede 100644 --- a/modules/viz/doc/widget.rst +++ b/modules/viz/doc/widget.rst @@ -934,7 +934,7 @@ This 3D Widget defines a collection of clouds. :: void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()); //! All points in cloud have the same color void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3d &pose = Affine3d::Identity()); - //! Repacks internal structure to sinle cloud + //! Repacks internal structure to single cloud void finalize(); }; @@ -1030,8 +1030,8 @@ viz::WWidgetMerger --------------------- .. ocv:class:: WWidgetMerger -This class allos to merge several widgets to single one. It has quite limited functionality and can't merge widgets with different attributes. For instance, -if widgetA has color array and widgetB has only global color defined, then result of merge won't have color at all. The class is suitable for merging large amount of similar widgets. +This class allows to merge several widgets to single one. It has quite limited functionality and can't merge widgets with different attributes. For instance, +if widgetA has color array and widgetB has only global color defined, then result of merge won't have color at all. The class is suitable for merging large amount of similar widgets. :: class CV_EXPORTS WWidgetMerger : public Widget3D { @@ -1041,11 +1041,10 @@ if widgetA has color array and widgetB has only global color defined, then resul //! Add widget to merge with optional position change void addWidget(const Widget3D& widget, const Affine3d &pose = Affine3d::Identity()); - //! Repacks internal structure to sinle widget + //! Repacks internal structure to single widget void finalize(); }; - viz::WWidgetMerger::WWidgetMerger --------------------------------------- Constructs a WWidgetMerger. diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp index 0c2a4f705..2949598c5 100644 --- a/modules/viz/include/opencv2/viz/widgets.hpp +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -346,7 +346,7 @@ namespace cv void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()); //! All points in cloud have the same color void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity()); - //! Repacks internal structure to sinle cloud + //! Repacks internal structure to single cloud void finalize(); }; @@ -363,7 +363,6 @@ namespace cv WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray()); }; - class CV_EXPORTS WWidgetMerger : public Widget3D { public: @@ -372,7 +371,7 @@ namespace cv //! Add widget to merge with optional position change void addWidget(const Widget3D& widget, const Affine3d &pose = Affine3d::Identity()); - //! Repacks internal structure to sinle widget + //! Repacks internal structure to single widget void finalize(); }; diff --git a/modules/viz/src/vtk/vtkCocoaInteractorFix.mm b/modules/viz/src/vtk/vtkCocoaInteractorFix.mm index 23bba552d..dad41b073 100644 --- a/modules/viz/src/vtk/vtkCocoaInteractorFix.mm +++ b/modules/viz/src/vtk/vtkCocoaInteractorFix.mm @@ -148,7 +148,7 @@ renWin->SetRootWindow(NULL); } } -} +} @end @@ -209,4 +209,3 @@ vtkSmartPointer cv::viz::vtkCocoaRenderWindowInteract { return vtkSmartPointer::New(); } - diff --git a/modules/viz/src/vtk/vtkVizInteractorStyle.cpp b/modules/viz/src/vtk/vtkVizInteractorStyle.cpp index 57aee636e..9b5eca2b0 100644 --- a/modules/viz/src/vtk/vtkVizInteractorStyle.cpp +++ b/modules/viz/src/vtk/vtkVizInteractorStyle.cpp @@ -1074,4 +1074,3 @@ void cv::viz::vtkVizInteractorStyle::PrintSelf(ostream& os, vtkIndent indent) os << indent << "AngleStepSize: " << AngleStepSize << "\n"; os << indent << "MotionUserScale: "<< MotionUserScale << "\n"; } - diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp index 45d3cdc3c..45128df2f 100644 --- a/modules/viz/test/test_viz3d.cpp +++ b/modules/viz/test/test_viz3d.cpp @@ -59,6 +59,5 @@ TEST(Viz_viz3d, DISABLED_develop) //cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path()); //---->>>>> - viz.spin(); } From 45969bb3ae6065bc152c62e19c420ada8f6b4315 Mon Sep 17 00:00:00 2001 From: Ian Taylor Date: Mon, 10 Mar 2014 03:02:06 -0400 Subject: [PATCH 15/25] fix variable name typo in calcBlurriness --- modules/videostab/src/deblurring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/videostab/src/deblurring.cpp b/modules/videostab/src/deblurring.cpp index 813e908be..be9fd5c0f 100644 --- a/modules/videostab/src/deblurring.cpp +++ b/modules/videostab/src/deblurring.cpp @@ -57,7 +57,7 @@ float calcBlurriness(const Mat &frame) Sobel(frame, Gx, CV_32F, 1, 0); Sobel(frame, Gy, CV_32F, 0, 1); double normGx = norm(Gx); - double normGy = norm(Gx); + double normGy = norm(Gy); double sumSq = normGx*normGx + normGy*normGy; return static_cast(1. / (sumSq / frame.size().area() + 1e-6)); } From 4d7a593c254657cd41e4c1659ac5420ef7082d8f Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Wed, 12 Mar 2014 16:21:36 +0400 Subject: [PATCH 16/25] minor cmake fix fo macos --- cmake/OpenCVModule.cmake | 8 ++------ modules/viz/CMakeLists.txt | 4 ++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 6f727af8d..05faa35a2 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -484,7 +484,7 @@ macro(ocv_glob_module_sources) file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h") file(GLOB lib_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h") - file(GLOB_RECURSE lib_srcs_apple "src/*.m*") + file(GLOB_RECURSE lib_srcs_apple "src/*.mm") if (APPLE) list(APPEND lib_srcs ${lib_srcs_apple}) endif() @@ -748,12 +748,8 @@ function(ocv_add_accuracy_tests) endif() get_native_precompiled_header(${the_target} test_precomp.hpp) + add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch}) - if(APPLE AND ${the_target} STREQUAL "opencv_test_viz") - add_executable(${the_target} MACOSX_BUNDLE ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch}) - else() - add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch}) - endif() target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS}) add_dependencies(opencv_tests ${the_target}) diff --git a/modules/viz/CMakeLists.txt b/modules/viz/CMakeLists.txt index 7ccd07921..d839491c1 100644 --- a/modules/viz/CMakeLists.txt +++ b/modules/viz/CMakeLists.txt @@ -9,3 +9,7 @@ ocv_define_module(viz opencv_core ${VTK_LIBRARIES}) if(APPLE AND BUILD_opencv_viz) target_link_libraries(opencv_viz "-framework Cocoa") endif() + +if(TARGET opencv_test_viz) + set_target_properties(opencv_test_viz PROPERTIES MACOSX_BUNDLE TRUE) +endif() From a5afcd9f115b82112cb2427f314c8af216655084 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Wed, 12 Mar 2014 19:58:53 +0400 Subject: [PATCH 17/25] improved performance of cv::ocl::minMax --- modules/ocl/src/arithm.cpp | 67 ++++++++++----------- modules/ocl/src/opencl/arithm_minMax.cl | 78 +++++-------------------- 2 files changed, 48 insertions(+), 97 deletions(-) diff --git a/modules/ocl/src/arithm.cpp b/modules/ocl/src/arithm.cpp index 0b316c5ea..d72904cce 100644 --- a/modules/ocl/src/arithm.cpp +++ b/modules/ocl/src/arithm.cpp @@ -473,20 +473,13 @@ void cv::ocl::meanStdDev(const oclMat &src, Scalar &mean, Scalar &stddev) ////////////////////////////////////////////////////////////////////////////// template -static void arithmetic_minMax_run(const oclMat &src, const oclMat & mask, cl_mem &dst, int groupnum, string kernelName) +static void arithmetic_minMax_run(const oclMat &src, const oclMat & mask, cl_mem &dst, int vlen, int groupnum) { - int all_cols = src.step / src.elemSize(); - int pre_cols = (src.offset % src.step) / src.elemSize(); - int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize() - 1) / src.elemSize() - 1; - int invalid_cols = pre_cols + sec_cols; - int cols = all_cols - invalid_cols , elemnum = cols * src.rows; - int offset = src.offset / src.elemSize(); - const char * const typeMap[] = { "uchar", "char", "ushort", "short", "int", "float", "double" }; - const char * const channelMap[] = { " ", " ", "2", "4", "4" }; + const char * const channelMap[] = { " ", " ", "2", "4", "4", "", "", "", "8" }; ostringstream stream; - stream << "-D T=" << typeMap[src.depth()] << channelMap[src.channels()]; + stream << "-D T=" << typeMap[src.depth()] << channelMap[vlen]; if (numeric_limits::is_integer) { stream << " -D MAX_VAL=" << (WT)numeric_limits::max(); @@ -494,38 +487,38 @@ static void arithmetic_minMax_run(const oclMat &src, const oclMat & mask, cl_mem } else stream << " -D DEPTH_" << src.depth(); + stream << " -D vlen=" << vlen; std::string buildOptions = stream.str(); + int vElemSize = src.elemSize1() * vlen, src_cols = src.cols / vlen; + int src_step = src.step / vElemSize, src_offset = src.offset / vElemSize; + int mask_step = mask.step / vlen, mask_offset = mask.offset / vlen; + int total = src.size().area() / vlen; + vector > args; args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data)); - args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&offset)); - args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum)); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src.rows )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_cols )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&total)); args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum)); + args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst)); - int minvalid_cols = 0, moffset = 0; if (!mask.empty()) { - int mall_cols = mask.step / mask.elemSize(); - int mpre_cols = (mask.offset % mask.step) / mask.elemSize(); - int msec_cols = mall_cols - (mask.offset % mask.step + mask.cols * mask.elemSize() - 1) / mask.elemSize() - 1; - minvalid_cols = mpre_cols + msec_cols; - moffset = mask.offset / mask.elemSize(); - args.push_back( make_pair( sizeof(cl_mem) , (void *)&mask.data )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&minvalid_cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&moffset )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&mask_step )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&mask_offset )); - kernelName += "_mask"; + buildOptions += " -D WITH_MASK"; } - size_t globalThreads[3] = {groupnum * 256, 1, 1}; - size_t localThreads[3] = {256, 1, 1}; + size_t globalThreads[3] = { groupnum * 256, 1, 1 }; + size_t localThreads[3] = { 256, 1, 1 }; // kernel use fixed grid size, replace lt on NULL is imposible without kernel changes - openCLExecuteKernel(src.clCxt, &arithm_minMax, kernelName, globalThreads, localThreads, + openCLExecuteKernel(src.clCxt, &arithm_minMax, "arithm_op_minMax", globalThreads, localThreads, args, -1, -1, buildOptions.c_str()); } @@ -535,25 +528,33 @@ void arithmetic_minMax(const oclMat &src, double *minVal, double *maxVal, const size_t groupnum = src.clCxt->getDeviceInfo().maxComputeUnits; CV_Assert(groupnum != 0); - int dbsize = groupnum * 2 * src.elemSize(); + int vlen = mask.empty() ? 8 : 1, vElemSize = vlen * src.elemSize1(); + while (src.offset % vElemSize != 0 || src.step % vElemSize != 0 || src.cols % vlen != 0) + { + vlen >>= 1; + vElemSize >>= 1; + } + + int dbsize = groupnum * 2 * vElemSize; oclMat buf; ensureSizeIsEnough(1, dbsize, CV_8UC1, buf); cl_mem buf_data = reinterpret_cast(buf.data); - arithmetic_minMax_run(src, mask, buf_data, groupnum, "arithm_op_minMax"); + arithmetic_minMax_run(src, mask, buf_data, vlen, groupnum); Mat matbuf = Mat(buf); T *p = matbuf.ptr(); + if (minVal != NULL) { *minVal = std::numeric_limits::max(); - for (int i = 0, end = src.oclchannels() * (int)groupnum; i < end; i++) + for (int i = 0, end = vlen * (int)groupnum; i < end; i++) *minVal = *minVal < p[i] ? *minVal : p[i]; } if (maxVal != NULL) { *maxVal = -std::numeric_limits::max(); - for (int i = src.oclchannels() * (int)groupnum, end = i << 1; i < end; i++) + for (int i = vlen * (int)groupnum, end = i << 1; i < end; i++) *maxVal = *maxVal > p[i] ? *maxVal : p[i]; } } @@ -564,7 +565,7 @@ void cv::ocl::minMax(const oclMat &src, double *minVal, double *maxVal, const oc { CV_Assert(src.channels() == 1); CV_Assert(src.size() == mask.size() || mask.empty()); - CV_Assert(src.step % src.elemSize() == 0); + CV_Assert(src.step % src.elemSize1() == 0); if (minVal == NULL && maxVal == NULL) return; diff --git a/modules/ocl/src/opencl/arithm_minMax.cl b/modules/ocl/src/opencl/arithm_minMax.cl index 01db7d064..b0cd1c8b6 100644 --- a/modules/ocl/src/opencl/arithm_minMax.cl +++ b/modules/ocl/src/opencl/arithm_minMax.cl @@ -63,81 +63,31 @@ /**************************************Array minMax**************************************/ -__kernel void arithm_op_minMax(__global const T * src, __global T * dst, - int cols, int invalid_cols, int offset, int elemnum, int groupnum) +__kernel void arithm_op_minMax(__global const T * src, int src_step, int src_offset, int src_rows, int src_cols, + int total, int groupnum, __global T * dst +#ifdef WITH_MASK + , __global const uchar * mask, int mask_step, int mask_offset +#endif +) { int lid = get_local_id(0); int gid = get_group_id(0); int id = get_global_id(0); - int idx = offset + id + (id / cols) * invalid_cols; - __local T localmem_max[128], localmem_min[128]; T minval = (T)(MAX_VAL), maxval = (T)(MIN_VAL), temp; + int y, x; - for (int grainSize = groupnum << 8; id < elemnum; id += grainSize) + for (int grainSize = groupnum << 8; id < total; id += grainSize) { - idx = offset + id + (id / cols) * invalid_cols; - temp = src[idx]; - minval = min(minval, temp); - maxval = max(maxval, temp); - } + y = id / src_cols; + x = id % src_cols; - if (lid > 127) - { - localmem_min[lid - 128] = minval; - localmem_max[lid - 128] = maxval; - } - barrier(CLK_LOCAL_MEM_FENCE); - - if (lid < 128) - { - localmem_min[lid] = min(minval, localmem_min[lid]); - localmem_max[lid] = max(maxval, localmem_max[lid]); - } - barrier(CLK_LOCAL_MEM_FENCE); - - for (int lsize = 64; lsize > 0; lsize >>= 1) - { - if (lid < lsize) +#ifdef WITH_MASK + if (mask[mad24(y, mask_step, x + mask_offset)]) +#endif { - int lid2 = lsize + lid; - localmem_min[lid] = min(localmem_min[lid], localmem_min[lid2]); - localmem_max[lid] = max(localmem_max[lid], localmem_max[lid2]); - } - barrier(CLK_LOCAL_MEM_FENCE); - } - - if (lid == 0) - { - dst[gid] = localmem_min[0]; - dst[gid + groupnum] = localmem_max[0]; - } -} - -__kernel void arithm_op_minMax_mask(__global const T * src, __global T * dst, - int cols, int invalid_cols, int offset, - int elemnum, int groupnum, - const __global uchar * mask, int minvalid_cols, int moffset) -{ - int lid = get_local_id(0); - int gid = get_group_id(0); - int id = get_global_id(0); - - int idx = offset + id + (id / cols) * invalid_cols; - int midx = moffset + id + (id / cols) * minvalid_cols; - - __local T localmem_max[128], localmem_min[128]; - T minval = (T)(MAX_VAL), maxval = (T)(MIN_VAL), temp; - - for (int grainSize = groupnum << 8; id < elemnum; id += grainSize) - { - idx = offset + id + (id / cols) * invalid_cols; - midx = moffset + id + (id / cols) * minvalid_cols; - - if (mask[midx]) - { - temp = src[idx]; + temp = src[mad24(y, src_step, x + src_offset)]; minval = min(minval, temp); maxval = max(maxval, temp); } From 8e79de35a800560f70631b614265ef12d5f95c29 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Thu, 13 Mar 2014 14:57:13 +0400 Subject: [PATCH 18/25] changes for GFTT --- modules/ocl/src/gftt.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/modules/ocl/src/gftt.cpp b/modules/ocl/src/gftt.cpp index 4f24d1358..b30c0b502 100644 --- a/modules/ocl/src/gftt.cpp +++ b/modules/ocl/src/gftt.cpp @@ -146,34 +146,33 @@ static void minMaxEig_caller(const oclMat &src, oclMat &dst, oclMat & tozero) CV_Assert(groupnum != 0); int dbsize = groupnum * 2 * src.elemSize(); - ensureSizeIsEnough(1, dbsize, CV_8UC1, dst); cl_mem dst_data = reinterpret_cast(dst.data); - int all_cols = src.step / src.elemSize(); - int pre_cols = (src.offset % src.step) / src.elemSize(); - int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize() - 1) / src.elemSize() - 1; - int invalid_cols = pre_cols + sec_cols; - int cols = all_cols - invalid_cols , elemnum = cols * src.rows; - int offset = src.offset / src.elemSize(); + int vElemSize = src.elemSize1(); + int src_step = src.step / vElemSize, src_offset = src.offset / vElemSize; + int total = src.size().area(); - {// first parallel pass + { + // first parallel pass vector > args; args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data)); - args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst_data )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&offset)); - args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum)); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset)); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step)); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src.rows )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src.cols )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&total)); args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum)); + args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst_data )); size_t globalThreads[3] = {groupnum * 256, 1, 1}; size_t localThreads[3] = {256, 1, 1}; openCLExecuteKernel(src.clCxt, &arithm_minMax, "arithm_op_minMax", globalThreads, localThreads, - args, -1, -1, "-D T=float -D DEPTH_5"); + args, -1, -1, "-D T=float -D DEPTH_5 -D vlen=1"); } - {// run final "serial" kernel to find accumulate results from threads and reset corner counter + { + // run final "serial" kernel to find accumulate results from threads and reset corner counter vector > args; args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst_data )); args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum )); From 3ebfe60008d9a0ea74cac18d1c30bcd8be8d16a9 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Thu, 13 Mar 2014 15:35:53 +0400 Subject: [PATCH 19/25] improved performance of cv::ocl::countNonZero --- modules/ocl/src/arithm.cpp | 43 ++++++++++++------------ modules/ocl/src/opencl/arithm_nonzero.cl | 13 +++---- modules/ocl/test/test_arithm.cpp | 4 +-- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/modules/ocl/src/arithm.cpp b/modules/ocl/src/arithm.cpp index d72904cce..3a8524fa4 100644 --- a/modules/ocl/src/arithm.cpp +++ b/modules/ocl/src/arithm.cpp @@ -1263,38 +1263,35 @@ void cv::ocl::minMaxLoc(const oclMat &src, double *minVal, double *maxVal, ///////////////////////////// countNonZero /////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -static void arithmetic_countNonZero_run(const oclMat &src, cl_mem &dst, int groupnum, string kernelName) +static void arithmetic_countNonZero_run(const oclMat &src, cl_mem &dst, int groupnum, int vlen) { - int ochannels = src.oclchannels(); - int all_cols = src.step / src.elemSize(); - int pre_cols = (src.offset % src.step) / src.elemSize(); - int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize() - 1) / src.elemSize() - 1; - int invalid_cols = pre_cols + sec_cols; - int cols = all_cols - invalid_cols , elemnum = cols * src.rows;; - int offset = src.offset / src.elemSize(); + int vElemSize = vlen * src.elemSize1(); + int src_step = src.step / vElemSize, src_offset = src.offset / vElemSize; + int src_cols = src.cols / vlen, total = src.size().area() / vlen; const char * const typeMap[] = { "uchar", "char", "ushort", "short", "int", "float", "double" }; - const char * const channelMap[] = { " ", " ", "2", "4", "4" }; - string buildOptions = format("-D srcT=%s%s -D dstT=int%s", typeMap[src.depth()], channelMap[ochannels], - channelMap[ochannels]); + const char * const channelMap[] = { "", "", "2", "4", "4", "", "", "", "8" }; + string buildOptions = format("-D srcT=%s%s -D dstT=int%s -D convertToDstT=convert_int%s", + typeMap[src.depth()], channelMap[vlen], + channelMap[vlen], channelMap[vlen]); vector > args; - args.push_back( make_pair( sizeof(cl_int) , (void *)&cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&offset)); - args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum)); - args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum)); args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data)); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_cols )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&total )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum )); args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst )); size_t globalThreads[3] = { groupnum * 256, 1, 1 }; #ifdef ANDROID - openCLExecuteKernel(src.clCxt, &arithm_nonzero, kernelName, globalThreads, NULL, + openCLExecuteKernel(src.clCxt, &arithm_nonzero, "arithm_op_nonzero", globalThreads, NULL, args, -1, -1, buildOptions.c_str()); #else size_t localThreads[3] = { 256, 1, 1 }; - openCLExecuteKernel(src.clCxt, &arithm_nonzero, kernelName, globalThreads, localThreads, + openCLExecuteKernel(src.clCxt, &arithm_nonzero, "arithm_op_nonzero", globalThreads, localThreads, args, -1, -1, buildOptions.c_str()); #endif } @@ -1311,18 +1308,20 @@ int cv::ocl::countNonZero(const oclMat &src) return -1; } + int vlen = 8, vElemSize = src.elemSize1() * vlen; + while (src.offset % vElemSize != 0 || src.step % vElemSize != 0 || src.cols % vlen != 0) + vlen >>= 1, vElemSize >>= 1; + size_t groupnum = src.clCxt->getDeviceInfo().maxComputeUnits; CV_Assert(groupnum != 0); - int dbsize = groupnum; - - string kernelName = "arithm_op_nonzero"; + int dbsize = groupnum * vlen; AutoBuffer _buf(dbsize); int *p = (int*)_buf, nonzero = 0; memset(p, 0, dbsize * sizeof(int)); cl_mem dstBuffer = openCLCreateBuffer(clCxt, CL_MEM_WRITE_ONLY, dbsize * sizeof(int)); - arithmetic_countNonZero_run(src, dstBuffer, groupnum, kernelName); + arithmetic_countNonZero_run(src, dstBuffer, groupnum, vlen); openCLReadBuffer(clCxt, dstBuffer, (void *)p, dbsize * sizeof(int)); for (int i = 0; i < dbsize; i++) diff --git a/modules/ocl/src/opencl/arithm_nonzero.cl b/modules/ocl/src/opencl/arithm_nonzero.cl index 3180c26e8..6a21f27e0 100644 --- a/modules/ocl/src/opencl/arithm_nonzero.cl +++ b/modules/ocl/src/opencl/arithm_nonzero.cl @@ -52,23 +52,18 @@ /**************************************Count NonZero**************************************/ -__kernel void arithm_op_nonzero(int cols, int invalid_cols, int offset, int elemnum, int groupnum, - __global srcT *src, __global dstT *dst) +__kernel void arithm_op_nonzero(__global srcT * src, int src_step, int src_offset, int src_cols, + int total, int groupnum, __global dstT * dst) { int lid = get_local_id(0); int gid = get_group_id(0); int id = get_global_id(0); - int idx = offset + id + (id / cols) * invalid_cols; __local dstT localmem_nonzero[128]; dstT nonzero = (dstT)(0); - srcT zero = (srcT)(0), one = (srcT)(1); - for (int grain = groupnum << 8; id < elemnum; id += grain) - { - idx = offset + id + (id / cols) * invalid_cols; - nonzero += src[idx] == zero ? zero : one; - } + for (int grain = groupnum << 8; id < total; id += grain) + nonzero += convertToDstT(src[mad24(id / src_cols, src_step, id % src_cols + src_offset)] == (srcT)(0)) ? (dstT)(0) : (dstT)(1); if (lid > 127) localmem_nonzero[lid - 128] = nonzero; diff --git a/modules/ocl/test/test_arithm.cpp b/modules/ocl/test/test_arithm.cpp index 17260580d..29976b6e4 100644 --- a/modules/ocl/test/test_arithm.cpp +++ b/modules/ocl/test/test_arithm.cpp @@ -198,7 +198,7 @@ PARAM_TEST_CASE(ArithmTestBase, MatDepth, Channels, bool) Size roiSize = randomSize(1, MAX_VALUE); Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0); - randomSubMat(src1, src1_roi, roiSize, src1Border, type, 2, 11); + randomSubMat(src1, src1_roi, roiSize, src1Border, type, -11, 11); Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0); randomSubMat(src2, src2_roi, roiSize, src2Border, type, -1540, 1740); @@ -1163,7 +1163,7 @@ OCL_TEST_P(CountNonZero, MAT) int cpures = cv::countNonZero(src1_roi); int gpures = cv::ocl::countNonZero(gsrc1_roi); - EXPECT_DOUBLE_EQ((double)cpures, (double)gpures); + EXPECT_EQ(cpures, gpures); } } From adc15c2bbaecaee5e60345c7c10c4b6cac585219 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Thu, 13 Mar 2014 16:27:07 +0400 Subject: [PATCH 20/25] improved performance of cv::ocl::sum --- modules/ocl/src/arithm.cpp | 42 ++++++++++++++-------------- modules/ocl/src/gftt.cpp | 2 +- modules/ocl/src/opencl/arithm_sum.cl | 10 +++---- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/modules/ocl/src/arithm.cpp b/modules/ocl/src/arithm.cpp index 3a8524fa4..34c665203 100644 --- a/modules/ocl/src/arithm.cpp +++ b/modules/ocl/src/arithm.cpp @@ -313,32 +313,28 @@ void cv::ocl::compare(const oclMat &src1, const oclMat &src2, oclMat &dst , int enum { SUM = 0, ABS_SUM, SQR_SUM }; -static void arithmetic_sum_buffer_run(const oclMat &src, cl_mem &dst, int groupnum, int type, int ddepth) +static void arithmetic_sum_buffer_run(const oclMat &src, cl_mem &dst, int groupnum, int type, int ddepth, int vlen) { - int ochannels = src.oclchannels(); - int all_cols = src.step / src.elemSize(); - int pre_cols = (src.offset % src.step) / src.elemSize(); - int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize() - 1) / src.elemSize() - 1; - int invalid_cols = pre_cols + sec_cols; - int cols = all_cols - invalid_cols , elemnum = cols * src.rows;; - int offset = src.offset / src.elemSize(); + int vElemSize = vlen * src.elemSize(); + int src_offset = src.offset / vElemSize, src_step = src.step / vElemSize; + int src_cols = src.cols / vlen, total = src.size().area() / vlen; + + vlen *= src.oclchannels(); const char * const typeMap[] = { "uchar", "char", "ushort", "short", "int", "float", "double" }; const char * const funcMap[] = { "FUNC_SUM", "FUNC_ABS_SUM", "FUNC_SQR_SUM" }; - const char * const channelMap[] = { " ", " ", "2", "4", "4" }; + const char * const channelMap[] = { " ", " ", "2", "4", "4", "", "", "", "8" }; string buildOptions = format("-D srcT=%s%s -D dstT=%s%s -D convertToDstT=convert_%s%s -D %s", - typeMap[src.depth()], channelMap[ochannels], - typeMap[ddepth], channelMap[ochannels], - typeMap[ddepth], channelMap[ochannels], - funcMap[type]); + typeMap[src.depth()], channelMap[vlen], typeMap[ddepth], + channelMap[vlen], typeMap[ddepth], channelMap[vlen], funcMap[type]); vector > args; - args.push_back( make_pair( sizeof(cl_int) , (void *)&cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols )); - args.push_back( make_pair( sizeof(cl_int) , (void *)&offset)); - args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum)); - args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum)); args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data)); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_cols )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&total )); + args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum )); args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst )); size_t globalThreads[3] = { groupnum * 256, 1, 1 }; @@ -360,7 +356,11 @@ Scalar arithmetic_sum(const oclMat &src, int type, int ddepth) size_t groupnum = src.clCxt->getDeviceInfo().maxComputeUnits; CV_Assert(groupnum != 0); - int dbsize = groupnum * src.oclchannels(); + int vlen = 8 / src.channels(), vElemSize = vlen * src.elemSize1(); + while (src.offset % vElemSize != 0 || src.step % vElemSize != 0 || src.cols % vlen != 0) + vlen >>= 1, vElemSize >>= 1; + + int dbsize = groupnum * src.oclchannels() * vlen; Context *clCxt = src.clCxt; AutoBuffer _buf(dbsize); @@ -368,12 +368,12 @@ Scalar arithmetic_sum(const oclMat &src, int type, int ddepth) memset(p, 0, dbsize * sizeof(T)); cl_mem dstBuffer = openCLCreateBuffer(clCxt, CL_MEM_WRITE_ONLY, dbsize * sizeof(T)); - arithmetic_sum_buffer_run(src, dstBuffer, groupnum, type, ddepth); + arithmetic_sum_buffer_run(src, dstBuffer, groupnum, type, ddepth, vlen); openCLReadBuffer(clCxt, dstBuffer, (void *)p, dbsize * sizeof(T)); openCLFree(dstBuffer); Scalar s = Scalar::all(0.0); - for (int i = 0; i < dbsize;) + for (int i = 0; i < dbsize; ) for (int j = 0; j < src.oclchannels(); j++, i++) s.val[j] += p[i]; diff --git a/modules/ocl/src/gftt.cpp b/modules/ocl/src/gftt.cpp index b30c0b502..57ed12f00 100644 --- a/modules/ocl/src/gftt.cpp +++ b/modules/ocl/src/gftt.cpp @@ -158,8 +158,8 @@ static void minMaxEig_caller(const oclMat &src, oclMat &dst, oclMat & tozero) // first parallel pass vector > args; args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data)); - args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset)); args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step)); + args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset)); args.push_back( make_pair( sizeof(cl_int) , (void *)&src.rows )); args.push_back( make_pair( sizeof(cl_int) , (void *)&src.cols )); args.push_back( make_pair( sizeof(cl_int) , (void *)&total)); diff --git a/modules/ocl/src/opencl/arithm_sum.cl b/modules/ocl/src/opencl/arithm_sum.cl index 514cf2a7f..86015cfe9 100644 --- a/modules/ocl/src/opencl/arithm_sum.cl +++ b/modules/ocl/src/opencl/arithm_sum.cl @@ -63,21 +63,19 @@ /**************************************Array buffer SUM**************************************/ -__kernel void arithm_op_sum(int cols,int invalid_cols,int offset,int elemnum,int groupnum, - __global srcT *src, __global dstT *dst) +__kernel void arithm_op_sum(__global srcT * src, int src_step, int src_offset, int src_cols, + int total, int groupnum, __global dstT * dst) { int lid = get_local_id(0); int gid = get_group_id(0); int id = get_global_id(0); - int idx = offset + id + (id / cols) * invalid_cols; __local dstT localmem_sum[128]; dstT sum = (dstT)(0), temp; - for (int grainSize = groupnum << 8; id < elemnum; id += grainSize) + for (int grainSize = groupnum << 8; id < total; id += grainSize) { - idx = offset + id + (id / cols) * invalid_cols; - temp = convertToDstT(src[idx]); + temp = convertToDstT(src[mad24(id / src_cols, src_step, id % src_cols + src_offset)]); FUNC(temp, sum); } From 6f76e7b42dc52308c13f8d64331cbd3ca08aa750 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Thu, 13 Mar 2014 19:42:13 +0400 Subject: [PATCH 21/25] improved performance of bitwise ops --- modules/ocl/src/arithm.cpp | 155 ++++------- ...hm_bitwise_binary.cl => arithm_bitwise.cl} | 55 ++-- .../src/opencl/arithm_bitwise_binary_mask.cl | 88 ------ .../opencl/arithm_bitwise_binary_scalar.cl | 82 ------ .../arithm_bitwise_binary_scalar_mask.cl | 86 ------ modules/ocl/src/opencl/arithm_bitwise_not.cl | 253 ------------------ 6 files changed, 91 insertions(+), 628 deletions(-) rename modules/ocl/src/opencl/{arithm_bitwise_binary.cl => arithm_bitwise.cl} (67%) delete mode 100644 modules/ocl/src/opencl/arithm_bitwise_binary_mask.cl delete mode 100644 modules/ocl/src/opencl/arithm_bitwise_binary_scalar.cl delete mode 100644 modules/ocl/src/opencl/arithm_bitwise_binary_scalar_mask.cl delete mode 100644 modules/ocl/src/opencl/arithm_bitwise_not.cl diff --git a/modules/ocl/src/arithm.cpp b/modules/ocl/src/arithm.cpp index 34c665203..eabc055d0 100644 --- a/modules/ocl/src/arithm.cpp +++ b/modules/ocl/src/arithm.cpp @@ -1336,157 +1336,118 @@ int cv::ocl::countNonZero(const oclMat &src) ////////////////////////////////bitwise_op//////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -static void bitwise_unary_run(const oclMat &src1, oclMat &dst, string kernelName, const cv::ocl::ProgramEntry* source) +enum { AND = 0, OR, XOR, NOT }; + +static void bitwise_run(const oclMat & src1, const oclMat & src2, const Scalar & src3, const oclMat & mask, + oclMat & dst, int operationType) { - dst.create(src1.size(), src1.type()); - - int channels = dst.oclchannels(); - int depth = dst.depth(); - - int vector_lengths[4][7] = {{4, 4, 4, 4, 1, 1, 1}, - {4, 4, 4, 4, 1, 1, 1}, - {4, 4, 4, 4, 1, 1, 1}, - {4, 4, 4, 4, 1, 1, 1} - }; - - size_t vector_length = vector_lengths[channels - 1][depth]; - int offset_cols = (dst.offset / dst.elemSize1()) & (vector_length - 1); - int cols = divUp(dst.cols * channels + offset_cols, vector_length); - -#ifdef ANDROID - size_t localThreads[3] = { 64, 2, 1 }; -#else - size_t localThreads[3] = { 64, 4, 1 }; -#endif - size_t globalThreads[3] = { cols, dst.rows, 1 }; - - int dst_step1 = dst.cols * dst.elemSize(); - vector > args; - args.push_back( make_pair( sizeof(cl_mem), (void *)&src1.data )); - args.push_back( make_pair( sizeof(cl_int), (void *)&src1.step )); - args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset )); - args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data )); - args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step )); - args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset )); - args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows )); - args.push_back( make_pair( sizeof(cl_int), (void *)&cols )); - args.push_back( make_pair( sizeof(cl_int), (void *)&dst_step1 )); - - openCLExecuteKernel(src1.clCxt, source, kernelName, globalThreads, localThreads, args, -1, depth); -} - -enum { AND = 0, OR, XOR }; - -static void bitwise_binary_run(const oclMat &src1, const oclMat &src2, const Scalar& src3, const oclMat &mask, - oclMat &dst, int operationType) -{ - CV_Assert(operationType >= AND && operationType <= XOR); - CV_Assert(src2.empty() || (!src2.empty() && src1.type() == src2.type() && src1.size() == src2.size())); - CV_Assert(mask.empty() || (!mask.empty() && mask.type() == CV_8UC1 && mask.size() == src1.size())); + CV_Assert(operationType >= AND && operationType <= NOT); + CV_Assert(src2.empty() || (src1.type() == src2.type() && src1.size() == src2.size())); + CV_Assert(mask.empty() || (mask.type() == CV_8UC1 && mask.size() == src1.size())); dst.create(src1.size(), src1.type()); - oclMat m; + double scalar[4]; - const char operationMap[] = { '&', '|', '^' }; - std::string kernelName("arithm_bitwise_binary"); + bool haveScalar = src2.empty() && operationType != NOT, haveMask = !mask.empty(); + int ocn = dst.oclchannels(), depth = dst.depth(); + const char operationMap[] = { '&', '|', '^', '~' }; + const char * const typeMap[] = { "uchar", "uchar", "ushort", "ushort", "int", "int", "ulong" }; + const char * const channelMap[] = { "", "", "2", "4", "4", "", "", "", "8", "", "", "", "", "", "", "", "16" }; + const int preferredVectorWidth[] = { 4, 4, 2, 2, 1, 1, 1 }; + int kercn = haveMask || haveScalar ? ocn : preferredVectorWidth[depth]; - int vlen = std::min(8, src1.elemSize1() * src1.oclchannels()); - std::string vlenstr = vlen > 1 ? format("%d", vlen) : ""; - std::string buildOptions = format("-D Operation=%c -D vloadn=vload%s -D vstoren=vstore%s -D elemSize=%d -D vlen=%d" - " -D ucharv=uchar%s", - operationMap[operationType], vlenstr.c_str(), vlenstr.c_str(), - (int)src1.elemSize(), vlen, vlenstr.c_str()); - -#ifdef ANDROID - size_t localThreads[3] = { 16, 10, 1 }; -#else - size_t localThreads[3] = { 16, 16, 1 }; -#endif - size_t globalThreads[3] = { dst.cols, dst.rows, 1 }; - - vector > args; - args.push_back( make_pair( sizeof(cl_mem), (void *)&src1.data )); - args.push_back( make_pair( sizeof(cl_int), (void *)&src1.step )); - args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset )); - - if (src2.empty()) + if (!haveScalar && !haveMask) { - m.create(1, 1, dst.type()); - m.setTo(src3); - - args.push_back( make_pair( sizeof(cl_mem), (void *)&m.data )); - - kernelName += "_scalar"; + int velemsize = dst.elemSize1() * kercn; + while (src1.offset % velemsize != 0 || src1.step % velemsize != 0 || src1.cols * ocn % kercn != 0 || + src2.offset % velemsize != 0 || src2.step % velemsize != 0 || src2.cols * ocn % kercn != 0 || + dst.offset % velemsize != 0 || dst.step % velemsize != 0 || dst.cols * ocn % kercn != 0) + kercn >>= 1, velemsize >>= 1; } - else + + int cols = dst.cols * ocn / kercn; + + std::string buildOptions = format("-D Operation=%c -D T=%s%s", operationMap[operationType], + typeMap[depth], channelMap[kercn]); + + vector > args; + args.push_back( make_pair( sizeof(cl_mem), (void *)&src1.data )); + args.push_back( make_pair( sizeof(cl_int), (void *)&src1.step )); + args.push_back( make_pair( sizeof(cl_int), (void *)&src1.offset )); + + if (haveScalar) + { + int sctype = CV_MAKE_TYPE(dst.depth(), ocn); + cv::scalarToRawData(src3, scalar, sctype); + + args.push_back( make_pair( CV_ELEM_SIZE(sctype), (void *)scalar )); + + buildOptions += " -D HAVE_SCALAR"; + } + else if (operationType != NOT) { args.push_back( make_pair( sizeof(cl_mem), (void *)&src2.data )); args.push_back( make_pair( sizeof(cl_int), (void *)&src2.step )); args.push_back( make_pair( sizeof(cl_int), (void *)&src2.offset )); + + buildOptions += " -D OP_BINARY"; } - if (!mask.empty()) + if (haveMask) { args.push_back( make_pair( sizeof(cl_mem), (void *)&mask.data )); args.push_back( make_pair( sizeof(cl_int), (void *)&mask.step )); args.push_back( make_pair( sizeof(cl_int), (void *)&mask.offset )); - kernelName += "_mask"; + buildOptions += " -D HAVE_MASK"; } args.push_back( make_pair( sizeof(cl_mem), (void *)&dst.data )); args.push_back( make_pair( sizeof(cl_int), (void *)&dst.step )); args.push_back( make_pair( sizeof(cl_int), (void *)&dst.offset )); - args.push_back( make_pair( sizeof(cl_int), (void *)&src1.cols )); - args.push_back( make_pair( sizeof(cl_int), (void *)&src1.rows )); + args.push_back( make_pair( sizeof(cl_int), (void *)&dst.rows )); + args.push_back( make_pair( sizeof(cl_int), (void *)&cols )); - openCLExecuteKernel(src1.clCxt, mask.empty() ? (!src2.empty() ? &arithm_bitwise_binary : &arithm_bitwise_binary_scalar) : - (!src2.empty() ? &arithm_bitwise_binary_mask : &arithm_bitwise_binary_scalar_mask), - kernelName, globalThreads, localThreads, + size_t globalsize[3] = { dst.cols * ocn / kercn, dst.rows, 1 }; + globalsize[0] = divUp(globalsize[0], 256) * 256; + openCLExecuteKernel(src1.clCxt, &arithm_bitwise, "arithm_bitwise", globalsize, NULL, args, -1, -1, buildOptions.c_str()); } void cv::ocl::bitwise_not(const oclMat &src, oclMat &dst) { - if (!src.clCxt->supportsFeature(FEATURE_CL_DOUBLE) && src.depth() == CV_64F) - { - CV_Error(CV_OpenCLDoubleNotSupported, "Selected device doesn't support double"); - return; - } - - dst.create(src.size(), src.type()); - bitwise_unary_run(src, dst, "arithm_bitwise_not", &arithm_bitwise_not); + bitwise_run(src, oclMat(), Scalar(), oclMat(), dst, NOT); } void cv::ocl::bitwise_or(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask) { - bitwise_binary_run(src1, src2, Scalar(), mask, dst, OR); + bitwise_run(src1, src2, Scalar(), mask, dst, OR); } void cv::ocl::bitwise_or(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask) { - bitwise_binary_run(src1, oclMat(), src2, mask, dst, OR); + bitwise_run(src1, oclMat(), src2, mask, dst, OR); } void cv::ocl::bitwise_and(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask) { - bitwise_binary_run(src1, src2, Scalar(), mask, dst, AND); + bitwise_run(src1, src2, Scalar(), mask, dst, AND); } void cv::ocl::bitwise_and(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask) { - bitwise_binary_run(src1, oclMat(), src2, mask, dst, AND); + bitwise_run(src1, oclMat(), src2, mask, dst, AND); } void cv::ocl::bitwise_xor(const oclMat &src1, const oclMat &src2, oclMat &dst, const oclMat &mask) { - bitwise_binary_run(src1, src2, Scalar(), mask, dst, XOR); + bitwise_run(src1, src2, Scalar(), mask, dst, XOR); } void cv::ocl::bitwise_xor(const oclMat &src1, const Scalar &src2, oclMat &dst, const oclMat &mask) { - bitwise_binary_run(src1, oclMat(), src2, mask, dst, XOR); + bitwise_run(src1, oclMat(), src2, mask, dst, XOR); } oclMat cv::ocl::operator ~ (const oclMat &src) diff --git a/modules/ocl/src/opencl/arithm_bitwise_binary.cl b/modules/ocl/src/opencl/arithm_bitwise.cl similarity index 67% rename from modules/ocl/src/opencl/arithm_bitwise_binary.cl rename to modules/ocl/src/opencl/arithm_bitwise.cl index 56cd745d2..899d41970 100644 --- a/modules/ocl/src/opencl/arithm_bitwise_binary.cl +++ b/modules/ocl/src/opencl/arithm_bitwise.cl @@ -48,35 +48,46 @@ /////////////////////////////////////////// bitwise_binary ////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// -__kernel void arithm_bitwise_binary(__global uchar * src1, int src1_step, int src1_offset, - __global uchar * src2, int src2_step, int src2_offset, - __global uchar * dst, int dst_step, int dst_offset, - int cols, int rows) +__kernel void arithm_bitwise(__global uchar * src1ptr, int src1_step, int src1_offset, +#ifdef OP_BINARY + __global uchar * src2ptr, int src2_step, int src2_offset, +#elif defined HAVE_SCALAR + T scalar, +#endif +#ifdef HAVE_MASK + __global uchar * mask, int mask_step, int mask_offset, +#endif + __global uchar * dstptr, int dst_step, int dst_offset, int dst_rows, int dst_cols) { int x = get_global_id(0); int y = get_global_id(1); - if (x < cols && y < rows) + if (x < dst_cols && y < dst_rows) { -#if elemSize > 1 - x *= elemSize; +#ifdef HAVE_MASK + mask += mad24(y, mask_step, x + mask_offset); + if (mask[0]) #endif - int src1_index = mad24(y, src1_step, x + src1_offset); - int src2_index = mad24(y, src2_step, x + src2_offset); - int dst_index = mad24(y, dst_step, x + dst_offset); - -#if elemSize > 1 - #pragma unroll - for (int i = 0; i < elemSize; i += vlen) { - ucharv t0 = vloadn(0, src1 + src1_index + i); - ucharv t1 = vloadn(0, src2 + src2_index + i); - ucharv t2 = t0 Operation t1; - - vstoren(t2, 0, dst + dst_index + i); - } -#else - dst[dst_index] = src1[src1_index] Operation src2[src2_index]; + int src1_index = mad24(y, src1_step, mad24(x, (int)sizeof(T), src1_offset)); +#ifdef OP_BINARY + int src2_index = mad24(y, src2_step, mad24(x, (int)sizeof(T), src2_offset)); #endif + int dst_index = mad24(y, dst_step, mad24(x, (int)sizeof(T), dst_offset)); + + __global const T * src1 = (__global const T *)(src1ptr + src1_index); +#ifdef OP_BINARY + __global const T * src2 = (__global const T *)(src2ptr + src2_index); +#endif + __global T * dst = (__global T *)(dstptr + dst_index); + +#ifdef OP_BINARY + dst[0] = src1[0] Operation src2[0]; +#elif defined HAVE_SCALAR + dst[0] = src1[0] Operation scalar; +#else + dst[0] = Operation src1[0]; +#endif + } } } diff --git a/modules/ocl/src/opencl/arithm_bitwise_binary_mask.cl b/modules/ocl/src/opencl/arithm_bitwise_binary_mask.cl deleted file mode 100644 index 328ccd91a..000000000 --- a/modules/ocl/src/opencl/arithm_bitwise_binary_mask.cl +++ /dev/null @@ -1,88 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved. -// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// @Authors -// Jiang Liyuan, jlyuan001.good@163.com -// Peng Xiao, pengxiao@outlook.com -// -// 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*/ - -////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////bitwise_binary//////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////// - -__kernel void arithm_bitwise_binary_mask(__global uchar * src1, int src1_step, int src1_offset, - __global uchar * src2, int src2_step, int src2_offset, - __global uchar * mask, int mask_step, int mask_offset, - __global uchar * dst, int dst_step, int dst_offset, - int cols1, int rows) -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols1 && y < rows) - { - int mask_index = mad24(y, mask_step, mask_offset + x); - - if (mask[mask_index]) - { -#if elemSize > 1 - x *= elemSize; -#endif - int src1_index = mad24(y, src1_step, x + src1_offset); - int src2_index = mad24(y, src2_step, x + src2_offset); - int dst_index = mad24(y, dst_step, x + dst_offset); - -#if elemSize > 1 - #pragma unroll - for (int i = 0; i < elemSize; i += vlen) - { - ucharv t0 = vloadn(0, src1 + src1_index + i); - ucharv t1 = vloadn(0, src2 + src2_index + i); - ucharv t2 = t0 Operation t1; - - vstoren(t2, 0, dst + dst_index + i); - } -#else - dst[dst_index] = src1[src1_index] Operation src2[src2_index]; -#endif - } - } -} diff --git a/modules/ocl/src/opencl/arithm_bitwise_binary_scalar.cl b/modules/ocl/src/opencl/arithm_bitwise_binary_scalar.cl deleted file mode 100644 index 434bd5eca..000000000 --- a/modules/ocl/src/opencl/arithm_bitwise_binary_scalar.cl +++ /dev/null @@ -1,82 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////// -// -// 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) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved. -// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// @Authors -// Jiang Liyuan, jlyuan001.good@163.com -// Peng Xiao, pengxiao@outlook.com -// -// 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. -// -// - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////bitwise_binary///////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////// - -__kernel void arithm_bitwise_binary_scalar( - __global uchar *src1, int src1_step, int src1_offset, - __global uchar *src2, - __global uchar *dst, int dst_step, int dst_offset, - int cols, int rows) -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { -#if elemSize > 1 - x *= elemSize; -#endif - int src1_index = mad24(y, src1_step, src1_offset + x); - int dst_index = mad24(y, dst_step, dst_offset + x); - -#if elemSize > 1 - #pragma unroll - for (int i = 0; i < elemSize; i += vlen) - { - ucharv t0 = vloadn(0, src1 + src1_index + i); - ucharv t1 = vloadn(0, src2 + i); - ucharv t2 = t0 Operation t1; - - vstoren(t2, 0, dst + dst_index + i); - } -#else - dst[dst_index] = src1[src1_index] Operation src2[0]; -#endif - } -} diff --git a/modules/ocl/src/opencl/arithm_bitwise_binary_scalar_mask.cl b/modules/ocl/src/opencl/arithm_bitwise_binary_scalar_mask.cl deleted file mode 100644 index 756f20165..000000000 --- a/modules/ocl/src/opencl/arithm_bitwise_binary_scalar_mask.cl +++ /dev/null @@ -1,86 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved. -// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// @Authors -// Jiang Liyuan, jlyuan001.good@163.com -// -// 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*/ - -////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////bitwise_binary//////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////// - -__kernel void arithm_bitwise_binary_scalar_mask(__global uchar *src1, int src1_step, int src1_offset, - __global uchar *src2, - __global uchar *mask, int mask_step, int mask_offset, - __global uchar *dst, int dst_step, int dst_offset, - int cols, int rows) -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { - int mask_index = mad24(y, mask_step, x + mask_offset); - - if (mask[mask_index]) - { -#if elemSize > 1 - x *= elemSize; -#endif - int src1_index = mad24(y, src1_step, x + src1_offset); - int dst_index = mad24(y, dst_step, x + dst_offset); - -#if elemSize > 1 - #pragma unroll - for (int i = 0; i < elemSize; i += vlen) - { - ucharv t0 = vloadn(0, src1 + src1_index + i); - ucharv t1 = vloadn(0, src2 + i); - ucharv t2 = t0 Operation t1; - - vstoren(t2, 0, dst + dst_index + i); - } -#else - dst[dst_index] = src1[src1_index] Operation src2[0]; -#endif - } - } -} diff --git a/modules/ocl/src/opencl/arithm_bitwise_not.cl b/modules/ocl/src/opencl/arithm_bitwise_not.cl deleted file mode 100644 index b6f76d606..000000000 --- a/modules/ocl/src/opencl/arithm_bitwise_not.cl +++ /dev/null @@ -1,253 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved. -// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// @Authors -// Jiang Liyuan, jlyuan001.good@163.com -// -// 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*/ - -#ifdef DOUBLE_SUPPORT -#ifdef cl_amd_fp64 -#pragma OPENCL EXTENSION cl_amd_fp64:enable -#elif defined (cl_khr_fp64) -#pragma OPENCL EXTENSION cl_khr_fp64:enable -#endif -#endif - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////BITWISE_NOT//////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////// - -__kernel void arithm_bitwise_not_D0 (__global uchar *src1, int src1_step, int src1_offset, - __global uchar *dst, int dst_step, int dst_offset, - int rows, int cols, int dst_step1) -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { - x = x << 2; - int src1_index = mad24(y, src1_step, x + src1_offset); - - int dst_end = mad24(y, dst_step, dst_offset + dst_step1); - int dst_index = mad24(y, dst_step, dst_offset + x); - - uchar4 src1_data = vload4(0, src1 + src1_index); - uchar4 dst_data = vload4(0, dst + dst_index); - uchar4 tmp_data = ~src1_data; - - dst_data.x = dst_index + 0 < dst_end ? tmp_data.x : dst_data.x; - dst_data.y = dst_index + 1 < dst_end ? tmp_data.y : dst_data.y; - dst_data.z = dst_index + 2 < dst_end ? tmp_data.z : dst_data.z; - dst_data.w = dst_index + 3 < dst_end ? tmp_data.w : dst_data.w; - - vstore4(dst_data, 0, dst + dst_index); - } -} - - -__kernel void arithm_bitwise_not_D1 (__global char *src1, int src1_step, int src1_offset, - __global char *dst, int dst_step, int dst_offset, - int rows, int cols, int dst_step1) -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { - x = x << 2; - int src1_index = mad24(y, src1_step, x + src1_offset); - - int dst_end = mad24(y, dst_step, dst_offset + dst_step1); - int dst_index = mad24(y, dst_step, dst_offset + x); - - char4 src1_data = vload4(0, src1 + src1_index); - char4 dst_data = vload4(0, dst + dst_index); - char4 tmp_data = ~src1_data; - - dst_data.x = dst_index + 0 < dst_end ? tmp_data.x : dst_data.x; - dst_data.y = dst_index + 1 < dst_end ? tmp_data.y : dst_data.y; - dst_data.z = dst_index + 2 < dst_end ? tmp_data.z : dst_data.z; - dst_data.w = dst_index + 3 < dst_end ? tmp_data.w : dst_data.w; - - vstore4(dst_data, 0, dst + dst_index); - } -} - - -__kernel void arithm_bitwise_not_D2 (__global ushort *src1, int src1_step, int src1_offset, - __global ushort *dst, int dst_step, int dst_offset, - int rows, int cols, int dst_step1) - -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { - x = x << 2; - -#ifdef dst_align -#undef dst_align -#endif -#define dst_align ((dst_offset >> 1) & 3) - int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); - - int dst_start = mad24(y, dst_step, dst_offset); - int dst_end = mad24(y, dst_step, dst_offset + dst_step1); - int dst_index = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8); - - ushort4 src1_data = vload4(0, (__global ushort *)((__global char *)src1 + src1_index)); - - ushort4 dst_data = *((__global ushort4 *)((__global char *)dst + dst_index)); - ushort4 tmp_data = ~ src1_data; - - dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x; - dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y; - dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z; - dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w; - - *((__global ushort4 *)((__global char *)dst + dst_index)) = dst_data; - } -} - - - -__kernel void arithm_bitwise_not_D3 (__global short *src1, int src1_step, int src1_offset, - __global short *dst, int dst_step, int dst_offset, - int rows, int cols, int dst_step1) - -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { - x = x << 2; - -#ifdef dst_align -#undef dst_align -#endif -#define dst_align ((dst_offset >> 1) & 3) - int src1_index = mad24(y, src1_step, (x << 1) + src1_offset - (dst_align << 1)); - - int dst_start = mad24(y, dst_step, dst_offset); - int dst_end = mad24(y, dst_step, dst_offset + dst_step1); - int dst_index = mad24(y, dst_step, dst_offset + (x << 1) & (int)0xfffffff8); - - short4 src1_data = vload4(0, (__global short *)((__global char *)src1 + src1_index)); - - short4 dst_data = *((__global short4 *)((__global char *)dst + dst_index)); - short4 tmp_data = ~ src1_data; - - dst_data.x = ((dst_index + 0 >= dst_start) && (dst_index + 0 < dst_end)) ? tmp_data.x : dst_data.x; - dst_data.y = ((dst_index + 2 >= dst_start) && (dst_index + 2 < dst_end)) ? tmp_data.y : dst_data.y; - dst_data.z = ((dst_index + 4 >= dst_start) && (dst_index + 4 < dst_end)) ? tmp_data.z : dst_data.z; - dst_data.w = ((dst_index + 6 >= dst_start) && (dst_index + 6 < dst_end)) ? tmp_data.w : dst_data.w; - - *((__global short4 *)((__global char *)dst + dst_index)) = dst_data; - } -} - - - -__kernel void arithm_bitwise_not_D4 (__global int *src1, int src1_step, int src1_offset, - __global int *dst, int dst_step, int dst_offset, - int rows, int cols, int dst_step1) -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { - int src1_index = mad24(y, src1_step, (x << 2) + src1_offset); - int dst_index = mad24(y, dst_step, (x << 2) + dst_offset); - - int data1 = *((__global int *)((__global char *)src1 + src1_index)); - int tmp = ~ data1; - - *((__global int *)((__global char *)dst + dst_index)) = tmp; - } -} - -__kernel void arithm_bitwise_not_D5 (__global char *src, int src_step, int src_offset, - __global char *dst, int dst_step, int dst_offset, - int rows, int cols, int dst_step1) -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { - int src_index = mad24(y, src_step, (x << 2) + src_offset); - int dst_index = mad24(y, dst_step, (x << 2) + dst_offset); - - char4 data; - - data = *((__global char4 *)((__global char *)src + src_index)); - data = ~ data; - - *((__global char4 *)((__global char *)dst + dst_index)) = data; - } -} - -#if defined (DOUBLE_SUPPORT) -__kernel void arithm_bitwise_not_D6 (__global char *src, int src_step, int src_offset, - __global char *dst, int dst_step, int dst_offset, - int rows, int cols, int dst_step1) -{ - int x = get_global_id(0); - int y = get_global_id(1); - - if (x < cols && y < rows) - { - int src_index = mad24(y, src_step, (x << 3) + src_offset); - int dst_index = mad24(y, dst_step, (x << 3) + dst_offset); - - char8 data; - - data = *((__global char8 *)((__global char *)src + src_index)); - data = ~ data; - - *((__global char8 *)((__global char *)dst + dst_index)) = data; - } -} -#endif From 357a856cf68b6bb63f05f66ba9d7556f292913a8 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Thu, 13 Mar 2014 22:35:08 +0400 Subject: [PATCH 22/25] nonfree perf tests --- modules/nonfree/perf/perf_main.cpp | 2 +- modules/nonfree/perf/perf_surf_ocl.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/nonfree/perf/perf_main.cpp b/modules/nonfree/perf/perf_main.cpp index 03f9b7185..2cd609d41 100644 --- a/modules/nonfree/perf/perf_main.cpp +++ b/modules/nonfree/perf/perf_main.cpp @@ -5,7 +5,7 @@ static const char * impls[] = { #ifdef HAVE_CUDA "cuda", #endif -#ifdef HAVE_OPENCL +#ifdef HAVE_OPENCV_OCL "ocl", #endif "plain" diff --git a/modules/nonfree/perf/perf_surf_ocl.cpp b/modules/nonfree/perf/perf_surf_ocl.cpp index 4528b7926..8413ed072 100644 --- a/modules/nonfree/perf/perf_surf_ocl.cpp +++ b/modules/nonfree/perf/perf_surf_ocl.cpp @@ -59,7 +59,7 @@ typedef perf::TestBaseWithParam OCL_SURF; #define OCL_TEST_CYCLE() for( ; startTimer(), next(); cv::ocl::finish(), stopTimer()) -PERF_TEST_P(OCL_SURF, with_data_transfer, testing::Values(SURF_IMAGES)) +PERF_TEST_P(OCL_SURF, DISABLED_with_data_transfer, testing::Values(SURF_IMAGES)) { string filename = getDataPath(GetParam()); Mat src = imread(filename, IMREAD_GRAYSCALE); @@ -94,7 +94,7 @@ PERF_TEST_P(OCL_SURF, with_data_transfer, testing::Values(SURF_IMAGES)) SANITY_CHECK_NOTHING(); } -PERF_TEST_P(OCL_SURF, without_data_transfer, testing::Values(SURF_IMAGES)) +PERF_TEST_P(OCL_SURF, DISABLED_without_data_transfer, testing::Values(SURF_IMAGES)) { string filename = getDataPath(GetParam()); Mat src = imread(filename, IMREAD_GRAYSCALE); From 61c347fb76ce3789e85fb41c526d007f11661870 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Thu, 13 Mar 2014 22:56:46 +0400 Subject: [PATCH 23/25] typos --- modules/ocl/src/arithm.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ocl/src/arithm.cpp b/modules/ocl/src/arithm.cpp index eabc055d0..e7638ecc4 100644 --- a/modules/ocl/src/arithm.cpp +++ b/modules/ocl/src/arithm.cpp @@ -517,7 +517,7 @@ static void arithmetic_minMax_run(const oclMat &src, const oclMat & mask, cl_mem size_t globalThreads[3] = { groupnum * 256, 1, 1 }; size_t localThreads[3] = { 256, 1, 1 }; - // kernel use fixed grid size, replace lt on NULL is imposible without kernel changes + // kernel use fixed grid size, replace lt on NULL is impossible without kernel changes openCLExecuteKernel(src.clCxt, &arithm_minMax, "arithm_op_minMax", globalThreads, localThreads, args, -1, -1, buildOptions.c_str()); } @@ -1140,7 +1140,7 @@ static void arithmetic_minMaxLoc_run(const oclMat &src, cl_mem &dst, int vlen , sprintf(build_options, "-D DEPTH_%d -D REPEAT_S%d -D REPEAT_E%d", src.depth(), repeat_s, repeat_e); size_t gt[3] = {groupnum * 256, 1, 1}, lt[3] = {256, 1, 1}; - // kernel use fixed grid size, replace lt on NULL is imposible without kernel changes + // kernel use fixed grid size, replace lt on NULL is impossible without kernel changes openCLExecuteKernel(src.clCxt, &arithm_minMaxLoc, "arithm_op_minMaxLoc", gt, lt, args, -1, -1, build_options); } @@ -1170,7 +1170,7 @@ static void arithmetic_minMaxLoc_mask_run(const oclMat &src, const oclMat &mask, args.push_back( make_pair( sizeof(cl_mem) , (void *)&mask.data )); args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst )); - // kernel use fixed grid size, replace lt on NULL is imposible without kernel changes + // kernel use fixed grid size, replace lt on NULL is impossible without kernel changes openCLExecuteKernel(src.clCxt, &arithm_minMaxLoc_mask, "arithm_op_minMaxLoc_mask", gt, lt, args, -1, -1, build_options); } } From 80708008a411f8beb50e300128b82a8d35921c40 Mon Sep 17 00:00:00 2001 From: berak Date: Sun, 16 Mar 2014 14:04:05 +0100 Subject: [PATCH 24/25] missing () on Mat::type() --- modules/core/doc/basic_structures.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/core/doc/basic_structures.rst b/modules/core/doc/basic_structures.rst index 6f9c10e1d..3edfa3b06 100644 --- a/modules/core/doc/basic_structures.rst +++ b/modules/core/doc/basic_structures.rst @@ -1350,7 +1350,7 @@ Copies the matrix to another one. The method copies the matrix data to another matrix. Before copying the data, the method invokes :: - m.create(this->size(), this->type); + m.create(this->size(), this->type()); so that the destination matrix is reallocated if needed. While ``m.copyTo(m);`` works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices. @@ -1445,7 +1445,7 @@ Transposes a matrix. The method performs matrix transposition by means of matrix expressions. It does not perform the actual transposition but returns a temporary matrix transposition object that can be further used as a part of more complex matrix expressions or can be assigned to a matrix: :: - Mat A1 = A + Mat::eye(A.size(), A.type)*lambda; + Mat A1 = A + Mat::eye(A.size(), A.type())*lambda; Mat C = A1.t()*A1; // compute (A + lambda*I)^t * (A + lamda*I) From 24d8cbf940d47b6cea39634a6c3a2a051b33cd74 Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Sun, 16 Mar 2014 20:07:05 +0400 Subject: [PATCH 25/25] Viz::setViewerPose() - changed up-vector to down (common for Computer Vision & Odometry) --- modules/viz/src/vizimpl.cpp | 6 +++--- modules/viz/test/test_tutorial3.cpp | 22 +++++++++------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/modules/viz/src/vizimpl.cpp b/modules/viz/src/vizimpl.cpp index 2401e76b5..ab621ad16 100644 --- a/modules/viz/src/vizimpl.cpp +++ b/modules/viz/src/vizimpl.cpp @@ -427,12 +427,12 @@ void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3d &pose) // Rotate the view vector cv::Matx33d rotation = pose.rotation(); - cv::Vec3d y_axis(0.0, 1.0, 0.0); + cv::Vec3d y_axis(0.0, -1.0, 0.0); // In Computer Vision Camera Y-axis is oriented down cv::Vec3d up_vec(rotation * y_axis); // Compute the new focal point cv::Vec3d z_axis(0.0, 0.0, 1.0); - cv::Vec3d focal_vec = pos_vec + rotation * z_axis; + cv::Vec3d focal_vec = pose * z_axis; camera.SetPosition(pos_vec.val); camera.SetFocalPoint(focal_vec.val); @@ -450,7 +450,7 @@ cv::Affine3d cv::viz::Viz3d::VizImpl::getViewerPose() Vec3d view_up(camera.GetViewUp()); Vec3d focal(camera.GetFocalPoint()); - Vec3d y_axis = normalized(view_up); + Vec3d y_axis = normalized(-view_up); // In Computer Vision Camera Y-axis is oriented down Vec3d z_axis = normalized(focal - pos); Vec3d x_axis = normalized(y_axis.cross(z_axis)); diff --git a/modules/viz/test/test_tutorial3.cpp b/modules/viz/test/test_tutorial3.cpp index 590e29ebf..b20e8d7a1 100644 --- a/modules/viz/test/test_tutorial3.cpp +++ b/modules/viz/test/test_tutorial3.cpp @@ -15,50 +15,46 @@ void tutorial3(bool camera_pov) myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); /// Let's assume camera has the following properties - Point3d cam_pos(3.0, 3.0, 3.0), cam_focal_point(3.0, 3.0, 2.0), cam_y_dir(-1.0, 0.0, 0.0); + Point3d cam_origin(3.0, 3.0, 3.0), cam_focal_point(3.0, 3.0, 2.0), cam_y_dir(-1.0, 0.0, 0.0); /// We can get the pose of the cam using makeCameraPose - Affine3d cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + Affine3d camera_pose = viz::makeCameraPose(cam_origin, cam_focal_point, cam_y_dir); /// We can get the transformation matrix from camera coordinate system to global using /// - makeTransformToGlobal. We need the axes of the camera - Affine3d transform = viz::makeTransformToGlobal(Vec3d(0.0, -1.0, 0.0), Vec3d(-1.0, 0.0, 0.0), Vec3d(0.0, 0.0, -1.0), cam_pos); + Affine3d transform = viz::makeTransformToGlobal(Vec3d(0.0, -1.0, 0.0), Vec3d(-1.0, 0.0, 0.0), Vec3d(0.0, 0.0, -1.0), cam_origin); /// Create a cloud widget. Mat dragon_cloud = viz::readCloud(get_dragon_ply_file_path()); viz::WCloud cloud_widget(dragon_cloud, viz::Color::green()); /// Pose of the widget in camera frame - Affine3d cloud_pose = Affine3d().translate(Vec3d(0.0, 0.0, 3.0)); + Affine3d cloud_pose = Affine3d().rotate(Vec3d(0.0, CV_PI/2, 0.0)).rotate(Vec3d(0.0, 0.0, CV_PI)).translate(Vec3d(0.0, 0.0, 3.0)); /// Pose of the widget in global frame Affine3d cloud_pose_global = transform * cloud_pose; /// Visualize camera frame + myWindow.showWidget("CPW_FRUSTUM", viz::WCameraPosition(Vec2f(0.889484f, 0.523599f)), camera_pose); if (!camera_pov) - { - viz::WCameraPosition cpw(0.5); // Coordinate axes - viz::WCameraPosition cpw_frustum(Vec2f(0.889484f, 0.523599f)); // Camera frustum - myWindow.showWidget("CPW", cpw, cam_pose); - myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); - } + myWindow.showWidget("CPW", viz::WCameraPosition(0.5), camera_pose); /// Visualize widget myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); /// Set the viewer pose to that of camera if (camera_pov) - myWindow.setViewerPose(cam_pose); + myWindow.setViewerPose(camera_pose); /// Start event loop. myWindow.spin(); } -TEST(Viz, DISABLED_tutorial3_global_view) +TEST(Viz, tutorial3_global_view) { tutorial3(false); } -TEST(Viz, DISABLED_tutorial3_camera_view) +TEST(Viz, tutorial3_camera_view) { tutorial3(true); }