diff --git a/.gitignore b/.gitignore index c390e7f9..016afb65 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .idea/ build/ debug/ -3rdparty/svmlight/ *~ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..de9d9399 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "3rdparty/pugixml"] + path = 3rdparty/pugixml + url = https://github.com/zeux/pugixml.git +[submodule "3rdparty/SiftGPU"] + path = 3rdparty/SiftGPU + url = https://github.com/pitzer/SiftGPU.git +[submodule "3rdparty/svmlight"] + path = 3rdparty/svmlight + url = https://github.com/giacomodabisias/svmlightlib.git diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index ef76da1c..8e740eb2 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,9 +1,9 @@ -#add mandatory 3rd party builds -add_subdirectory(pugixml-1.6) +#add mandatory 3rdparty libraries +add_subdirectory(pugixml_build) if(WITH_SVMLIGHT) - add_subdirectory(svmlight) -endif(WITH_SVMLIGHT) + add_subdirectory(svmlight) +endif() if(WITH_GPU) add_subdirectory(SiftGPU) diff --git a/3rdparty/SiftGPU b/3rdparty/SiftGPU new file mode 160000 index 00000000..b46bd5b8 --- /dev/null +++ b/3rdparty/SiftGPU @@ -0,0 +1 @@ +Subproject commit b46bd5b8cc5cfdc1dc163444b72c705569800b6d diff --git a/3rdparty/SiftGPU/CMakeLists.txt b/3rdparty/SiftGPU/CMakeLists.txt deleted file mode 100644 index 10bab6ff..00000000 --- a/3rdparty/SiftGPU/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -PROJECT(OD_SIFTGPU C CXX) - -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-write-strings -Wno-unused-result -Wno-deprecated -fPIC") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -Wno-unused-result -Wno-deprecated -fPIC") - -ADD_SUBDIRECTORY(src) - diff --git a/3rdparty/SiftGPU/History.txt b/3rdparty/SiftGPU/History.txt deleted file mode 100644 index 1f8e9154..00000000 --- a/3rdparty/SiftGPU/History.txt +++ /dev/null @@ -1,190 +0,0 @@ -0.5.400 - Fixes some platform issues to make SiftGPU work with Intel integrated GPUs. - Tested on window 7 and Ubuntu. - Note that Linux+Intel card works only on Mesa 9 for now. - Replaced the deprecated ostrstream by ostringstream - Fixed a few memory leaks (delete[]/delete mistakes); -0.5.382 - Fixed a bug with CUDA-based SiftMatchGPU (can match up to only 4096) - * The maximu texture dimension is not updated from hardware since V370 -0.5.381 - Really fixed the bug in CUDA-implementation of Guided SIFT matching... - -0.5.380 - Fixed a bug in CUDA-implementation of Guided SIFT matching. (Thanks to Oliver Whyte) - Added auto-downsampling to try fit the GPU memory cap. - Fixed minor GLSL code issue on Intel Integrated Cards.. not fully functional on Intel - Fixed bug with a rarely used parameter -tc for limiting feature counts - Updated Devil 64 bit lib to let it search for Devil64.dll (to keep both in the same folder) - Fixed an issue on the new nVidia driver with one GLSL shader. - Fixed a glReadPixels issue on ATI when the feature count is too big. - Modified the descriptor code to make it work correctly for ATI - Finally made GPU selection for Windows working (e.g. -display \\.\DISPLAY4) - MSVC Only: Converted the visual studio solution to v2010 -0.5.370 - Automatic switch from OpenGL to CUDA when OpenGL is not supported (Useful for X) - Dropped indirect data transfer path CPU->GL->CUDA - (CUDA part not requiring OpenGL at all, but restrictive on input type) - New parameter -mind (mininum working dimension) for performance tweak - (By default it is 16; Gaussian octaves smaller than this will be skipped) - (Small dimensions are ineffecient for GPU because many processes are on idle) - Added a function to compute SIFT for any rectangle (not only square!) - (Email me if you are interested in using it) - - Dropped all CG implementation to simplify maintance - Added a partial OpenCL implementation (half speed of CUDA/GLSL) - Added macro SIFTGPU_NO_DEVIL to allow droping DevIL depencency - Fixed minor bug in makefile - Removed reference to MAX_PATH in SiftGPU.h. It is dangerrous..since they can be redefined. - -0.5.360 - Added demo MultiThreadSIFT to demonstrate using Multi-GPU with Multi-Threading. - Improved CUDA performance on frequent image size changes - Skipped unacessary gradient/dog computation when using keypoint list on a same image - Added x64 projects to VisualStudio solution - Provided three different ways to limit the number of feautres -tc1 -tc2 -tc3 - (to keep either the highest levels or the lowest levels) - Fixed a bug with -tc introduced in V360Beta (2/26/10) - Fixed a bug in CUDA-implementation when the first several octaves are skipped (2/28/10) - Let RunSIFT return 0 when errors are found in CUDA (previously ignored) - Added option -display to select GPU according to Display - Modified option -cuda [device_index] to select GPU device. - Added Wrapper ServerSiftGPU to allow run multiple SiftGPU on multiple GPUs - Added option -tc to set a soft limit for the number of returned features. - Changed OpenGL context creation. The core library no longer requires GLUT. - Removed calles to std in file ProgramCU.cu to avoid possible compiling errors. - Reorganized the file structure of the code package. - Fixed some linux makefile issue and linux compilation issue. - Fixed linux name mangling problem for dynamic library loading. -0.5.345 - New Linux makefile. CG, CUDA and sse parameters can now be changed easily in makefile. - CG-based SiftGPU is now disabled by default to reduce dependencies. - Made more parameters changable after initizlization (check manual for details) - Changed the way of handling out-of-boundary user-specified keypoints. - Changed the timing function from clock to gettimeofday for Linux (Thanks to Pilet) - Fixed a bug in saving binary format(Thanks to Dekker) - Fixed linux makefile for CUDA-SIFTGPU (Thanks to Planna) - Fixed a conversion bug for 64-bit system introduced in V340 (Thanks to Plana and Wang) -0.5.340 - Added (-glsl -pack -m -s) to default setting. (You can change back to CG by -cg) - Updated libraries (CG 2.1, GLEW 1.5, DEVIL 1.77) - Used SSE to speed up descriptor normalization - Improved speed of the OpenGL-based SiftMatchGPU. (1.5x) - Added GLSL and CUDA implementation of SiftMatchGPU - Added the packed glsl implementation. It might be slightly faster than cg. - Added a CUDA-based SiftGPU implementation(use -cuda to turn it on) - Cleaned up the GLSL code to follow the GLSL standard more strictly. - Tested many of the GLSL shaders in GPU ShaderAnalyzer 1.5. - Added option -fastmath to specify -fastmath to cg compiler(yet no big difference). - Increased the threshold to fix the bug in guided matching when F is NULL - Fixed a bug in orientation for -m2p (missing a ";" in shader code) - Changed interface to handle all OpenGL pixel data (Previous only float and unsigned char). - Kept only the fastest verion of descriptor generation code, and dropped others. -0.5.320 - Fixed a bug (Wrong texture size may be assigned when image size changes) - Fixed a bug (Descriptor storage size may be not updated when image size changes) -0.5.319 - Fixed a bug (Setkeypoint before specifying image was not working in previous versoins) -0.5.318 - Changed interface to process keypoints WITHOUT known orientations - Added interface to specifiy float image data - Overloaded new operator of SiftGPU and SiftMatchGPU to fix a possible heap corruption on deallocation -0.5.317 - Fixed a bug in processing user-specified keypoints - Updated the .def file for the released package -0.5.316 - Fixed a bug of insufficient buffer allocation in very rare cases. (Thanks to Zheng) - Added guided SIFT putative matching using homography or/and fundamental matrix - Added function to change the feature number limitation for sift matching -0.5.315 - Added a cg-based sift matching implementation (Thanks to Zach)(see SimpleSIFT.cpp for example). - Added optional output of the extremum type (maximum or minimum) of feature - Added function to compute descriptors for user-specified keypoints - Included xcode project and makefile(Thanks to Perfanov and Wittenhagen) -0.5.313 - Finished the GLSL implementation of SIFT (use -glsl to turn it on). - Fixed a bug of crashing after many iterations on newer graphic card like GTX 280. (Thanks to Zheng) -0.5.312 - Fixed a bug introduced in V311(One texture size not updated for image size chaning with -pack) - Fixed a bug introduced in V311(feature readback function is empty for -pack). (Thanks to Palomo) -0.5.311 - Fixed a bug in descriptor computation (it may cause error in descriptors of 10% of features) - Implemented a packed SIFT implementation (use -pack to use it. 3x pyramid construction speed) - Used GPU/CPU mixed list generation (2X compared with old method) - Used only CPU for multi-orientation list generation (much faster than GPU) - Changed parameter to avoid using dyamic array indexing by default. - Implemented a new descriptor computation method(30% faster than the old one - Evaluated the speed on GTX 280. (obtained 1.5x the speed of 8800 GTX) - Dropped many unreferenced functions and also some old shaders. - Changed some definition for better compiliation on Mac (Thanks to Wittenhagen) - Changed SaveSIFT function to keep a little bit less fractional digits - Combined the horizontal gradient and vertical gradient visualization to one. -0.5.302 - Updated cg, glew and glut libraries - Added speed evaluation code - Added some debug code to write out floating point tiff images - Refactorized code a little bit, now it is having much less warnings -0.5.293 - Changed gaussian weighting factor in orientation computation, now closer to Lowe's - Minor bug fix on texture reallocation for too many features - Added new feature to automatically down-sample images that are larger than user-defined size. -0.5.288 - Added comparision with Lowe's SIFT on box.pgm(check /doc/evaluation for results) - Fixed two bugs related to feature scale - Fixed a bug related to up-sampling - Added a missing dog threshold test after subpixel localization. - Added new parameter for fixing the feature orientations - Added export function to check how SiftGPU is supported by current OpenGL context - Changed some default parameter ( now it downloades result, and use verbose level 2 by default) -0.5.280 - Added an example of dyanmic loading of siftgpu library - Fixed a serious bug of GetFeatureVector (orientation and scale are misordered previously) - Fixed a bug in def file - Fixed a bug in calling RunSIFT with pixel data. - Fixed some GLSL shader bugs -0.5.276 - Removed file "gs_types.h" and put the export definition in "siftgpu.h" - Added high resolution timing for windows by using funciton timeGetTime - Fixed some problems on arbfp1. Now it can run a limited demo again. - Added parameter for changing the maximum allowed feature number of a level -0.5.267 - Corrected a neglected stricmp to _stricmp for linux compiliation - Fixed a bug in function ResizePyramid which happens when image size changes in some way - Added key input function to change verbose level for GUI mode - -0.5.265 - Added display of fps information in console for sequential processing - Added an optional step that converts RGB to Luminance before uploading to GPU - Added a parameter "-p WxH" to specify the size for initializing the pyramids -0.5.261 - Added a new feature for using existing memories for processing smaller images - Added new functions to let user control the allocation pyramid momory - Fixed a bug with sub-pixel localization - -0.5.256 - Added linux makefile - Added a new feature for allocating seperate processing memories for multiple images. -0.5.250 - New keypoint detection code capable of sub-pixel/sub-scale localization - Changed code for easy Linux porting. Thank Martin Schneider for his help on this - Changed some default values of the parameters. - Improved SIFT visualization. -0.5.236 - Fixed an important bug in orientation computation - Successfully tested on many image matching experiments - Changed the command line -m to default 2 orientations -0.5.232 - Fixed a sift output bug - Fixed a NaN bug in descriptor generation - Fixed a bug that some images are flipped -0.5.224 - Fixed a memory leak bug on FBO - Added one more demo for processing 640*480 image sequence - Smalled change to interface, so that image data can be specified like OpenGL textures -0.5.220 - Added more examples to manual. - Added more comments about the siftgpu interface - Added one more input interface - Fixed bug of crash on image size change -0.5.208 - First release \ No newline at end of file diff --git a/3rdparty/SiftGPU/OpenGL_and_CUDA.txt b/3rdparty/SiftGPU/OpenGL_and_CUDA.txt deleted file mode 100644 index 6f6307ea..00000000 --- a/3rdparty/SiftGPU/OpenGL_and_CUDA.txt +++ /dev/null @@ -1,79 +0,0 @@ -PART 1, OPENGL, - -Pay special attention if you have your own OpenGL code. -The OpenGL-based implmentations of SiftGPU need valid OpenGL context to run properly. - -1. If you use the same OpenGL context for SiftGPU and your own your visualization - Make sure the OpenGL states are restored before calling SiftGPU. SiftGPU changes several - OpenGL internal states, including texture binding to GL_TEXTURE_RECTANGLE_ARB and current - ViewPort. You might need to restore them for your own OpenGL part. To avoid this problem, - you can create a seperate GL context, and activate different context for different part. - - Note that GL_TEXTURE_RECTANGLE_ARB is always enabled in SiftGPU. When you have problem - displaying textures, you can try first glDisable(GL_TEXTURE_RECTANGLE_ARB) before painting, - but don't forget to call glEnable(GL_TEXTURE_RECTANGLE_ARB) after. (Thanks to Pilet) - -2. How to create/setup an OpenGL context for SiftGPU - - If you choose to let SiftGPU to manage OpenGL context, you can simply do that by - SiftGPU::CreateContextGL and SiftMatchGPU::CreateContextGL. When you mix your own OpenGL - code with SiftGPU, you need to re-call CreateContextGL before calling SiftGPU functions, - which will implicitly activate the internal OpenGL context. - - - If you choose to create openGL contexts yourself when mixing SiftGPU with other openGL - code, don't call SiftGPU::CreateContextGL or SiftMatchGPU::CreateContextGL; Instead you - should first activate your OpenGL context (WglMakeCurrent in win32), and set GL_FILL - for polygon mode, then call SiftGPU::VerifyContextGL or SiftMatchGPU::VerifyContextGL - for initialization. You should also setup in the same way before calling SiftGPU functions. - - -PART 2, CUDA ---------------------------------------------------------------------------------- -1. How to enable CUDA - -The CUDA implementation in the package is not compiled by default. - -To enable it for visual stuio 2010, use msvc/SiftGPU_CUDA_Enabled.sln -To enable it for other OS, you need to change siftgpu_enable_cuda to 1 in the makefile - - ---------------------------------------------------------------------------------- -2. Change CUDA build parameters. -For windows, you need to change the settings in the custom build command line of -ProgramCU.cu. For example, add -use_fast_match for using fast match. - -For Other OS, you need to change the makefile. The top part of the makefile is -the configuration section, which includes: - siftgpu_enable_cuda = 0 (Set 1 to enable CUDA-based SiftGPU) - CUDA_INSTALL_PATH = /usr/local/cuda (Where to find CUDA) - siftgpu_cuda_options = -arch sm_10 (Additional CUDA Compiling options) - - ------------------------------------------------------------------------------------- -3. CUDA runtime parameters for SiftGPU::ParseParam -First, you need to specify "-cuda" to use CUDA-based SiftGPU. More parameters can -be chagned at runtime in CUDA-based SiftGPU than in OpenGL-based version. Check out -the manual for details. - -NEW. You can choose GPU for CUDA computation by using "-cuda [device_index=0]" - -One parameter for CUDA is "-di", which controls whether dynamic indexing is used -in descriptor generations. It is turned off by default. My experiments on 8800 -GTX show that unrolled loop of 8 if-assigns are faster than dynamic indexing, but -it might be different on other GPUs. - - --------------------------------------------------------------------------------------- -4. Speed of CUDA-based SiftGPU -If the size of the first octave (multiply the original size by 2 if upsample is used) -is less than or around 1024x768, CUDA version will be faster than OpenGL versions, -otherwise the OpenGL versions are still faster. - -************************************************************************************** -This is observed on nVidia 8800 GTX, it might be different on other GPUs. Recent -experiments on GTX280 show that CUDA version is not as fast as OpenGL version. - -Note: the thread block settings are currently tuned on GPU nVidia GTX 8800, - which may not be optimized for other GPUs. -************************************************************************************** diff --git a/3rdparty/SiftGPU/README.txt b/3rdparty/SiftGPU/README.txt deleted file mode 100644 index f84381e5..00000000 --- a/3rdparty/SiftGPU/README.txt +++ /dev/null @@ -1,58 +0,0 @@ -A GPU implementation of David Lowe's Scale Invariant Feature Transform - -Changchang wu - -http://cs.unc.edu/~ccwu - -University of North Carolina at Chapel Hill - - - - -1. SIFT - - SIFTGPU is an implementation of SIFT for GPU. SiftGPU uses GPU to process pixels and features - parallely in Gaussian pyramid construction, DoG keypoint detection and descriptor generation - for SIFT. Compact feature list is efficiently build through a GPU/CPU mixed reduction. - - SIFTGPU is inspired by Andrea Vedaldi's sift++ and Sudipta N Sinha et al's GPU-SIFT. Many - parameters of sift++ ( for example, number of octaves,number of DOG levels, edge threshold, - etc) are available in SiftGPU. - - - SIFTGPU also includes a GPU exhaustive/guided sift matcher SiftMatchGPU. It basically multiplies - the descriptor matrix on GPU and find closest feature matches on GPU. GLSL/CUDA/CG implementations - are all provided. - - NEW: The latest SIFTGPU also enables you to use Multi-GPUs and GPUS on different computers. - Check doc/manual.pdf for more information. You can modify some marcros definition in - SimpleSIFT.cpp and speed.cpp to enable the testing of the new functions. - - -2. Requirements - - The default implemntation uses GLSL, and it requires a GPU that has large memory and supports - dynamic branching. For nVidia graphic cards, you can optionally use CG(require fp40) or - CUDA implementation. You can try different implementations and to find out the fastest one - for different image sizes and parameters. - - The GLSL version may not work on ATI now. They did compile sucessfully with ATI Catalyst 8.9, - but not any more with 9.x versions. - - SiftGPU uses DevIl Image library, GLEW and GLUT. You'll need to make sure your system has - all the dependening libraries. SiftGPU should be able to run on any operation system that supports - the above libraries - - For windows system visual studio solution are provided as msvc/SiftGPU.dsw, msvc/SiftGPU.sln and - msvc/SiftGPU_CUDA_Enabled.sln. Linux/Mac makefile is in folder Linux of the package. - - -3. Helps - - Use -help to get parameter information. Check /doc/manual.pdf for samples and explanations. - In the vc workspace, there is a project called SimpleSIF that gives an example of simple - SiftGPU usage. There are more examples of different ways of using SiftGPU in manual.pdf - - - Check /doc/manual.pdf for help on the viewer. - diff --git a/3rdparty/SiftGPU/bin/DevIL.dll b/3rdparty/SiftGPU/bin/DevIL.dll deleted file mode 100644 index 7cc8553d..00000000 Binary files a/3rdparty/SiftGPU/bin/DevIL.dll and /dev/null differ diff --git a/3rdparty/SiftGPU/bin/DevIL64.dll b/3rdparty/SiftGPU/bin/DevIL64.dll deleted file mode 100644 index 082f6965..00000000 Binary files a/3rdparty/SiftGPU/bin/DevIL64.dll and /dev/null differ diff --git a/3rdparty/SiftGPU/bin/SiftGPU.dll b/3rdparty/SiftGPU/bin/SiftGPU.dll deleted file mode 100644 index 2f2fdf64..00000000 Binary files a/3rdparty/SiftGPU/bin/SiftGPU.dll and /dev/null differ diff --git a/3rdparty/SiftGPU/bin/SiftGPU64.dll b/3rdparty/SiftGPU/bin/SiftGPU64.dll deleted file mode 100644 index 06a4cc60..00000000 Binary files a/3rdparty/SiftGPU/bin/SiftGPU64.dll and /dev/null differ diff --git a/3rdparty/SiftGPU/bin/SimpleSIFT.exe b/3rdparty/SiftGPU/bin/SimpleSIFT.exe deleted file mode 100644 index 2607c8f0..00000000 Binary files a/3rdparty/SiftGPU/bin/SimpleSIFT.exe and /dev/null differ diff --git a/3rdparty/SiftGPU/bin/Speed.exe b/3rdparty/SiftGPU/bin/Speed.exe deleted file mode 100644 index 8c72462f..00000000 Binary files a/3rdparty/SiftGPU/bin/Speed.exe and /dev/null differ diff --git a/3rdparty/SiftGPU/bin/TestWin.exe b/3rdparty/SiftGPU/bin/TestWin.exe deleted file mode 100644 index 6b3774c9..00000000 Binary files a/3rdparty/SiftGPU/bin/TestWin.exe and /dev/null differ diff --git a/3rdparty/SiftGPU/bin/glew32.dll b/3rdparty/SiftGPU/bin/glew32.dll deleted file mode 100644 index 8857ba67..00000000 Binary files a/3rdparty/SiftGPU/bin/glew32.dll and /dev/null differ diff --git a/3rdparty/SiftGPU/bin/glew64.dll b/3rdparty/SiftGPU/bin/glew64.dll deleted file mode 100644 index e1dda868..00000000 Binary files a/3rdparty/SiftGPU/bin/glew64.dll and /dev/null differ diff --git a/3rdparty/SiftGPU/license.txt b/3rdparty/SiftGPU/license.txt deleted file mode 100644 index c4c35d9b..00000000 --- a/3rdparty/SiftGPU/license.txt +++ /dev/null @@ -1,17 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/3rdparty/SiftGPU/makefile b/3rdparty/SiftGPU/makefile deleted file mode 100644 index 2059b927..00000000 --- a/3rdparty/SiftGPU/makefile +++ /dev/null @@ -1,207 +0,0 @@ -################################################################# -# SiftGPU congiruation: CUDA, SSE, TIMING -################################################################# -#enable siftgpu server -siftgpu_enable_server = 0 -#enable OpenCL-based SiftGPU? not finished yet; testing purpose -siftgpu_enable_opencl = 0 -#------------------------------------------------------------------------------------------------ -# enable CUDA-based SiftGPU? -simple_find_cuda = $(shell locate libcudart.so) -ifneq ($(simple_find_cuda), ) - siftgpu_enable_cuda = 0 -else - siftgpu_enable_cuda = 0 -endif - -CUDA_INSTALL_PATH = /usr/local/cuda -#change additional settings, like SM version here if it is not 1.0 (eg. -arch sm_13 for GTX280) -#siftgpu_cuda_options = -Xopencc -OPT:unroll_size=200000 -#siftgpu_cuda_options = -arch sm_10 -#-------------------------------------------------------------------------------------------------- -# enable SSE optimization for GL-based implementations -siftgpu_enable_sse = 1 -siftgpu_sse_options = -march=core2 -mfpmath=sse -#-------------------------------------------------------------------------------------------------- -# openGL context creation. 1 for glut, 0 for xlib -siftgpu_prefer_glut = 1 -#whether remove dependency on DevIL (1 to remove, the output libsiftgpu.so still works for VisualSFM) -siftgpu_disable_devil = 0 -#------------------------------------------------------------------------------------------------ -#whether SimpleSIFT uses runtime loading of libsiftgpu.so or static linking of libsiftgpu.a -simplesift_runtime_load = 1 - -################################################################# - - -# cleanup trailing whitespaces for a few settings -siftgpu_enable_cuda := $(strip $(siftgpu_enable_cuda)) -siftgpu_disable_devil := $(strip $(siftgpu_disable_devil)) -siftgpu_enable_server := $(strip $(siftgpu_enable_server)) -siftgpu_enable_opencl := $(strip $(siftgpu_enable_opencl)) -siftgpu_prefer_glut := $(strip $(siftgpu_prefer_glut)) -simplesift_runtime_load := $(strip $(simplesift_runtime_load)) - -# detect OS -OSUPPER = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:]) -OSLOWER = $(shell uname -s 2>/dev/null | tr [:upper:] [:lower:]) -DARWIN = $(strip $(findstring DARWIN, $(OSUPPER))) - - -SHELL = /bin/sh -INC_DIR = include -BIN_DIR = bin -SRC_SIFTGPU = src/SiftGPU -SRC_DRIVER = src/TestWin -SRC_SERVER = src/ServerSiftGPU -CC = g++ -CFLAGS = -I$(INC_DIR) -fPIC -L/usr/lib -L./bin -L./lib -Wall -Wno-deprecated -pthread - -#simple hack to repalce the native flat on OSX because gcc version is low -ifneq ($(DARWIN),) - siftgpu_sse_options = -march=core2 -mfpmath=sse -endif - -ifneq ($(siftgpu_enable_sse), 0) - CFLAGS += $(siftgpu_sse_options) -endif - -ifneq ($(siftgpu_prefer_glut), 0) - CFLAGS += -DWINDOW_PREFER_GLUT -endif - -ifneq ($(siftgpu_enable_opencl), 0) - CFLAGS += -DCL_SIFTGPU_ENABLED -endif - -ODIR_SIFTGPU = build - - -# external header files -_HEADER_EXTERNAL = GL/glew.h GL/glut.h IL/il.h -# siftgpu header files -_HEADER_SIFTGPU = FrameBufferObject.h GlobalUtil.h GLTexImage.h ProgramGPU.h ShaderMan.h ProgramGLSL.h SiftGPU.h SiftPyramid.h SiftMatch.h PyramidGL.h LiteWindow.h -# siftgpu library header files for drivers -_HEADER_SIFTGPU_LIB = SiftGPU.h - -ifneq ($(DARWIN),) -#librarys for SiftGPU -LIBS_SIFTGPU = -lGLEW -framework GLUT -framework OpenGL -CFLAGS += -L/Users/prb2pal/Development/Resources/lib -else -#librarys for SiftGPU -LIBS_SIFTGPU = -lGLEW -lglut -lGL -lX11 -endif - -ifneq ($(siftgpu_disable_devil), 0) - CFLAGS += -DSIFTGPU_NO_DEVIL -else - LIBS_SIFTGPU += -lIL -endif - -#Obj files for SiftGPU -_OBJ_SIFTGPU = FrameBufferObject.o GlobalUtil.o GLTexImage.o ProgramGLSL.o ProgramGPU.o ShaderMan.o SiftGPU.o SiftPyramid.o PyramidGL.o SiftMatch.o - -#add cuda options -ifneq ($(siftgpu_enable_cuda), 0) - ifdef CUDA_BIN_PATH - NVCC = $(CUDA_BIN_PATH)/nvcc - else - NVCC = $(CUDA_INSTALL_PATH)/bin/nvcc - endif - - ifndef CUDA_INC_PATH - CUDA_INC_PATH = $(CUDA_INSTALL_PATH)/include - endif - - ifndef CUDA_LIB_PATH - CUDA_LIB_PATH = $(CUDA_INSTALL_PATH)/lib64 -L$(CUDA_INSTALL_PATH)/lib - endif - - CFLAGS += -DCUDA_SIFTGPU_ENABLED -I$(CUDA_INC_PATH) -L$(CUDA_LIB_PATH) - LIBS_SIFTGPU += -lcudart - _OBJ_SIFTGPU += CuTexImage.o PyramidCU.o SiftMatchCU.o - _HEADER_SIFTGPU += CuTexImage.h ProgramCU.h PyramidCU.h -endif - -ifneq ($(siftgpu_enable_opencl), 0) - CFLAGS += -lOpenCL -endif - -all: makepath siftgpu server driver - - -#the dependencies of SiftGPU library -DEPS_SIFTGPU = $(patsubst %, $(SRC_SIFTGPU)/%, $(_HEADER_SIFTGPU)) - - -#rules for the rest of the object files -$(ODIR_SIFTGPU)/%.o: $(SRC_SIFTGPU)/%.cpp $(DEPS_SIFTGPU) - $(CC) -o $@ $< $(CFLAGS) -c - - -ifneq ($(siftgpu_enable_cuda), 0) -NVCC_FLAGS = -I$(INC_DIR) -I$(CUDA_INC_PATH) -DCUDA_SIFTGPU_ENABLED -O2 -Xcompiler -fPIC -ifdef siftgpu_cuda_options - NVCC_FLAGS += $(siftgpu_cuda_options) -endif -#build rule for CUDA -$(ODIR_SIFTGPU)/ProgramCU.o: $(SRC_SIFTGPU)/ProgramCU.cu $(DEPS_SIFTGPU) - $(NVCC) $(NVCC_FLAGS) -o $@ $< -c -_OBJ_SIFTGPU += ProgramCU.o -endif - - -ifneq ($(siftgpu_enable_server), 0) -$(ODIR_SIFTGPU)/ServerSiftGPU.o: $(SRC_SERVER)/ServerSiftGPU.cpp $(DEPS_SIFTGPU) - $(CC) -o $@ $< $(CFLAGS) -DSERVER_SIFTGPU_ENABLED -c -_OBJ_SIFTGPU += ServerSiftGPU.o -endif - -OBJ_SIFTGPU = $(patsubst %,$(ODIR_SIFTGPU)/%,$(_OBJ_SIFTGPU)) -LIBS_DRIVER = $(BIN_DIR)/libsiftgpu.a $(LIBS_SIFTGPU) -SRC_TESTWIN = $(SRC_DRIVER)/TestWinGlut.cpp $(SRC_DRIVER)/BasicTestWin.cpp -DEP_TESTWIN = $(SRC_DRIVER)/TestWinGlut.h $(SRC_DRIVER)/BasicTestwin.h $(SRC_DRIVER)/GLTransform.h - - - -ifneq ($(simplesift_runtime_load), 0) -LIBS_SIMPLESIFT = -ldl -DSIFTGPU_DLL_RUNTIME -else -LIBS_SIMPLESIFT = $(LIBS_DRIVER) -DSIFTGPU_STATIC -endif - -siftgpu: makepath $(OBJ_SIFTGPU) - ar rcs $(BIN_DIR)/libsiftgpu.a $(OBJ_SIFTGPU) - $(CC) -o $(BIN_DIR)/libsiftgpu.so $(OBJ_SIFTGPU) $(LIBS_SIFTGPU) $(CFLAGS) -shared -fPIC - -driver: makepath - $(CC) -o $(BIN_DIR)/TestWinGlut $(SRC_TESTWIN) $(LIBS_DRIVER) $(CFLAGS) - $(CC) -o $(BIN_DIR)/SimpleSIFT $(SRC_DRIVER)/SimpleSIFT.cpp $(LIBS_SIMPLESIFT) $(CFLAGS) - $(CC) -o $(BIN_DIR)/speed $(SRC_DRIVER)/speed.cpp $(LIBS_DRIVER) $(CFLAGS) - $(CC) -o $(BIN_DIR)/MultiThreadSIFT $(SRC_DRIVER)/MultiThreadSIFT.cpp $(LIBS_DRIVER) $(CFLAGS) -pthread - -ifneq ($(siftgpu_enable_server), 0) -server: makepath - $(CC) -o $(BIN_DIR)/server_siftgpu $(SRC_SERVER)/server.cpp $(LIBS_DRIVER) $(CFLAGS) -else -server: - -endif - -makepath: - mkdir -p $(ODIR_SIFTGPU) - mkdir -p $(BIN_DIR) - sed -i -e 's/\\/\//g' demos/*.bat - -clean: - rm -f $(ODIR_SIFTGPU)/*.o - rm -f $(BIN_DIR)/libsiftgpu.a - rm -f $(BIN_DIR)/libsiftgpu.so - rm -f $(BIN_DIR)/TestWinGlut - rm -f $(BIN_DIR)/SimpleSIFT - rm -f $(BIN_DIR)/speed - rm -f $(BIN_DIR)/server_siftgpu - rm -f $(BIN_DIR)/MultiThreadSIFT - rm -f ProgramCU.linkinfo - diff --git a/3rdparty/SiftGPU/msvc/ServerSiftGPU/SiftGPU_Server.dsp b/3rdparty/SiftGPU/msvc/ServerSiftGPU/SiftGPU_Server.dsp deleted file mode 100644 index 46978894..00000000 --- a/3rdparty/SiftGPU/msvc/ServerSiftGPU/SiftGPU_Server.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="SiftGPU_Server" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=SiftGPU_Server - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "SiftGPU_Server.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "SiftGPU_Server.mak" CFG="SiftGPU_Server - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "SiftGPU_Server - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "SiftGPU_Server - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "SiftGPU_Server - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "SiftGPU_Server___Win32_Release" -# PROP BASE Intermediate_Dir "SiftGPU_Server___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../Include/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib ws2_32.lib siftgpu.lib opengl32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/server_siftgpu.exe" /libpath:"../../lib" - -!ELSEIF "$(CFG)" == "SiftGPU_Server - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "SiftGPU_Server___Win32_Debug" -# PROP BASE Intermediate_Dir "SiftGPU_Server___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../Include/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib ws2_32.lib siftgpu_d.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/server_siftgpu.exe" /pdbtype:sept /libpath:"../../lib" - -!ENDIF - -# Begin Target - -# Name "SiftGPU_Server - Win32 Release" -# Name "SiftGPU_Server - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\ServerSiftGPU\server.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/3rdparty/SiftGPU/msvc/ServerSiftGPU/SiftGPU_Server.vcxproj b/3rdparty/SiftGPU/msvc/ServerSiftGPU/SiftGPU_Server.vcxproj deleted file mode 100644 index 5ab88619..00000000 --- a/3rdparty/SiftGPU/msvc/ServerSiftGPU/SiftGPU_Server.vcxproj +++ /dev/null @@ -1,204 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {65C987E1-F62C-4461-9E2C-BE1E8A770C51} - SiftGPU_Server - Win32Proj - - - - Application - MultiByte - true - - - Application - MultiByte - - - Application - MultiByte - true - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\ - $(Configuration)\ - true - ..\..\bin\ - $(Configuration)_$(Platform)\ - true - ..\..\bin\ - $(Configuration)\ - false - ..\..\bin\ - $(Configuration)_$(Platform)\ - false - server_siftgpu - server_siftgpu - server_siftgpu - server_siftgpu - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - $(IntDir) - Level3 - EditAndContinue - - - siftgpu_d.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - ../../lib;%(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - false - - - - - X64 - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - $(IntDir) - Level3 - ProgramDatabase - - - siftgpu_d.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - ../../lib;%(AdditionalLibraryDirectories) - true - Console - MachineX64 - - - false - - - - - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - $(IntDir) - Level3 - ProgramDatabase - - - siftgpu.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - ../../lib;%(AdditionalLibraryDirectories) - true - Console - true - true - MachineX86 - - - false - - - - - X64 - - - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - $(IntDir) - Level3 - ProgramDatabase - - - siftgpu.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - ../../lib;%(AdditionalLibraryDirectories) - true - Console - true - true - MachineX64 - - - false - - - - - - - - {594562d3-609a-47bc-b7e2-789c4e794cc3} - false - - - {9252e247-4fe2-4929-bd5d-c2fa16efd656} - false - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/msvc/SiftGPU.dsw b/3rdparty/SiftGPU/msvc/SiftGPU.dsw deleted file mode 100644 index 8af0f428..00000000 --- a/3rdparty/SiftGPU/msvc/SiftGPU.dsw +++ /dev/null @@ -1,119 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "SiftGPU"=.\SiftGPU\SiftGPU.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "SiftGPU_Server"=.\ServerSiftGPU\SiftGPU_Server.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name SiftGPU - End Project Dependency -}}} - -############################################################################### - -Project: "SimpleSIFT"=.\TestWin\SimpleSIFT.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name SiftGPU - End Project Dependency -}}} - -############################################################################### - -Project: "Speed"=.\TestWin\Speed.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name SiftGPU - End Project Dependency -}}} - -############################################################################### - -Project: "TestBase"=.\TestWin\TestBase.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name SiftGPU - End Project Dependency -}}} - -############################################################################### - -Project: "TestWin"=.\TestWin\TestWin.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name TestBase - End Project Dependency -}}} - -############################################################################### - -Project: "TestWinGlut"=.\TestWin\TestWinGlut.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name TestBase - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/3rdparty/SiftGPU/msvc/SiftGPU.sln b/3rdparty/SiftGPU/msvc/SiftGPU.sln deleted file mode 100644 index e4f56a40..00000000 --- a/3rdparty/SiftGPU/msvc/SiftGPU.sln +++ /dev/null @@ -1,86 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SiftGPU", "SiftGPU\SiftGPU.vcxproj", "{594562D3-609A-47BC-B7E2-789C4E794CC3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestBase", "TestWin\TestBase.vcxproj", "{57496D03-A005-4650-B041-8E70DDA4A591}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestWin", "TestWin\TestWin.vcxproj", "{E1C4EAB3-1677-46F7-92BC-1A1F309B2027}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestWinGlut", "TestWin\TestWinGlut.vcxproj", "{B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleSIFT", "TestWin\SimpleSIFT.vcxproj", "{D864A317-5A65-47B1-AA82-C04F99C4280F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Speed", "TestWin\Speed.vcxproj", "{7FF72B39-F50E-4ED5-9A50-DCD60EF03604}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SiftGPU_Server", "ServerSiftGPU\SiftGPU_Server.vcxproj", "{65C987E1-F62C-4461-9E2C-BE1E8A770C51}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {594562D3-609A-47BC-B7E2-789C4E794CC3}.Debug|Win32.ActiveCfg = Debug|Win32 - {594562D3-609A-47BC-B7E2-789C4E794CC3}.Debug|Win32.Build.0 = Debug|Win32 - {594562D3-609A-47BC-B7E2-789C4E794CC3}.Debug|x64.ActiveCfg = Debug|x64 - {594562D3-609A-47BC-B7E2-789C4E794CC3}.Debug|x64.Build.0 = Debug|x64 - {594562D3-609A-47BC-B7E2-789C4E794CC3}.Release|Win32.ActiveCfg = Release|Win32 - {594562D3-609A-47BC-B7E2-789C4E794CC3}.Release|Win32.Build.0 = Release|Win32 - {594562D3-609A-47BC-B7E2-789C4E794CC3}.Release|x64.ActiveCfg = Release|x64 - {594562D3-609A-47BC-B7E2-789C4E794CC3}.Release|x64.Build.0 = Release|x64 - {57496D03-A005-4650-B041-8E70DDA4A591}.Debug|Win32.ActiveCfg = Debug|Win32 - {57496D03-A005-4650-B041-8E70DDA4A591}.Debug|Win32.Build.0 = Debug|Win32 - {57496D03-A005-4650-B041-8E70DDA4A591}.Debug|x64.ActiveCfg = Debug|x64 - {57496D03-A005-4650-B041-8E70DDA4A591}.Debug|x64.Build.0 = Debug|x64 - {57496D03-A005-4650-B041-8E70DDA4A591}.Release|Win32.ActiveCfg = Release|Win32 - {57496D03-A005-4650-B041-8E70DDA4A591}.Release|Win32.Build.0 = Release|Win32 - {57496D03-A005-4650-B041-8E70DDA4A591}.Release|x64.ActiveCfg = Release|x64 - {57496D03-A005-4650-B041-8E70DDA4A591}.Release|x64.Build.0 = Release|x64 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Debug|Win32.Build.0 = Debug|Win32 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Debug|x64.ActiveCfg = Debug|x64 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Debug|x64.Build.0 = Debug|x64 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Release|Win32.ActiveCfg = Release|Win32 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Release|Win32.Build.0 = Release|Win32 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Release|x64.ActiveCfg = Release|x64 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Release|x64.Build.0 = Release|x64 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Debug|Win32.ActiveCfg = Debug|Win32 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Debug|Win32.Build.0 = Debug|Win32 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Debug|x64.ActiveCfg = Debug|x64 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Debug|x64.Build.0 = Debug|x64 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Release|Win32.ActiveCfg = Release|Win32 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Release|Win32.Build.0 = Release|Win32 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Release|x64.ActiveCfg = Release|x64 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Release|x64.Build.0 = Release|x64 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Debug|Win32.ActiveCfg = Debug|Win32 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Debug|Win32.Build.0 = Debug|Win32 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Debug|x64.ActiveCfg = Debug|x64 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Debug|x64.Build.0 = Debug|x64 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Release|Win32.ActiveCfg = Release|Win32 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Release|Win32.Build.0 = Release|Win32 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Release|x64.ActiveCfg = Release|x64 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Release|x64.Build.0 = Release|x64 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Debug|Win32.ActiveCfg = Debug|Win32 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Debug|Win32.Build.0 = Debug|Win32 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Debug|x64.ActiveCfg = Debug|x64 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Debug|x64.Build.0 = Debug|x64 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Release|Win32.ActiveCfg = Release|Win32 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Release|Win32.Build.0 = Release|Win32 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Release|x64.ActiveCfg = Release|x64 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Release|x64.Build.0 = Release|x64 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Debug|Win32.ActiveCfg = Debug|Win32 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Debug|Win32.Build.0 = Debug|Win32 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Debug|x64.ActiveCfg = Debug|x64 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Debug|x64.Build.0 = Debug|x64 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Release|Win32.ActiveCfg = Release|Win32 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Release|Win32.Build.0 = Release|Win32 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Release|x64.ActiveCfg = Release|x64 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.def b/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.def deleted file mode 100644 index 5512ab90..00000000 --- a/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.def +++ /dev/null @@ -1,6 +0,0 @@ -EXPORTS - CreateNewSiftGPU @1 - CreateNewSiftMatchGPU @2 - CreateLiteWindow @3 - CreateComboSiftGPU @4 - CreateRemoteSiftGPU @5 diff --git a/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.dsp b/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.dsp deleted file mode 100644 index 1bfcd0a4..00000000 --- a/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.dsp +++ /dev/null @@ -1,204 +0,0 @@ -# Microsoft Developer Studio Project File - Name="SiftGPU" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=SiftGPU - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "SiftGPU.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "SiftGPU.mak" CFG="SiftGPU - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "SiftGPU - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "SiftGPU - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "SiftGPU - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SIFTGPU_EXPORTS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../Include/" /D "NDEBUG" /D "SIFTGPU_EXPORTS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SIFTGPU_DLL" /D "DLL_EXPORT" /D "SERVER_SIFTGPU_ENABLED" /FD /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib opengl32.lib glu32.lib winmm.lib glew32.lib glew32s.lib /nologo /dll /machine:I386 /def:".\SiftGPU.def" /out:"../../bin/SIFTGPU.dll" /implib:"../../lib/SIFTGPU.lib" /libpath:"../../lib/" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "SiftGPU - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SIFTGPU_EXPORTS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../Include/" /D "_DEBUG" /D "DLL_EXPORT" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SIFTGPU_DLL" /D "SERVER_SIFTGPU_ENABLED" /FD /GZ /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib opengl32.lib glu32.lib winmm.lib glew32.lib glew32s.lib /nologo /dll /debug /machine:I386 /def:".\SiftGPU.def" /out:"../../bin/SIFTGPU_d.dll" /implib:"../../lib/SIFTGPU_d.lib" /pdbtype:sept /libpath:"../../lib/" -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "SiftGPU - Win32 Release" -# Name "SiftGPU - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\SiftGPU\FrameBufferObject.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\GlobalUtil.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\GLTexImage.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\ProgramGLSL.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\ProgramGPU.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\PyramidGL.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\ServerSiftGPU\ServerSiftGPU.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\ShaderMan.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\SiftGPU.cpp -# End Source File -# Begin Source File - -SOURCE=.\SiftGPU.def -# PROP Exclude_From_Build 1 -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\SiftMatch.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\SIFTPyramid.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\src\SiftGPU\FrameBufferObject.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\GlobalUtil.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\GLTexImage.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\LiteWindow.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\ProgramGLSL.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\programGPU.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\PyramidGL.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\ServerSiftGPU\ServerSiftGPU.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\ShaderMan.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\SiftGPU.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\SiftMatch.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SiftGPU\SIFTPyramid.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.vcxproj b/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.vcxproj deleted file mode 100644 index 6d3542d5..00000000 --- a/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU.vcxproj +++ /dev/null @@ -1,375 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {594562D3-609A-47BC-B7E2-789C4E794CC3} - SiftGPU - - - - DynamicLibrary - false - MultiByte - - - DynamicLibrary - false - MultiByte - - - DynamicLibrary - false - MultiByte - - - DynamicLibrary - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\ - $(Configuration)\ - false - ..\..\bin\ - $(Configuration)\ - true - ..\..\bin\ - $(Configuration)_$(Platform)\ - false - ..\..\bin\ - $(Configuration)_$(Platform)\ - true - $(ProjectName)_d - $(ProjectName)_d - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/SiftGPU.tlb - - - - - MaxSpeed - OnlyExplicitInline - false - Speed - ../../Include/;%(AdditionalIncludeDirectories) - NDEBUG;SIFTGPU_EXPORTS;WIN32;_WINDOWS;_USRDLL;SIFTGPU_DLL;DLL_EXPORT;_CRT_SECURE_NO_DEPRECATE;SERVER_SIFTGPU_ENABLED;%(PreprocessorDefinitions) - false - true - MultiThreaded - true - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;winmm.lib;glew32.lib;glew32s.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - SiftGPU.def - $(IntDir)/SIFTGPU.pdb - ../../lib/SIFTGPU.lib - MachineX86 - - - true - .\Release/SiftGPU.bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/SiftGPU.tlb - - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - _DEBUG;DLL_EXPORT;WIN32;_WINDOWS;_USRDLL;SIFTGPU_DLL;_CRT_SECURE_NO_DEPRECATE;SERVER_SIFTGPU_ENABLED;%(PreprocessorDefinitions) - false - true - EnableFastChecks - MultiThreadedDebug - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;winmm.lib;glew32.lib;glew32s.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - SiftGPU.def - true - $(IntDir)/SIFTGPU.pdb - ../../lib/SIFTGPU_d.lib - MachineX86 - - - true - .\Debug/SiftGPU.bsc - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - X64 - .\Release/SiftGPU.tlb - - - - - MaxSpeed - OnlyExplicitInline - false - Speed - ../../Include/;%(AdditionalIncludeDirectories) - NDEBUG;SIFTGPU_EXPORTS;WIN32;_WINDOWS;_USRDLL;SIFTGPU_DLL;DLL_EXPORT;_CRT_SECURE_NO_DEPRECATE;SERVER_SIFTGPU_ENABLED;%(PreprocessorDefinitions) - false - true - MultiThreaded - true - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;winmm.lib;glew64.lib;glew64s.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - SiftGPU.def - $(IntDir)/SIFTGPU.pdb - ../../lib/SIFTGPU.lib - MachineX64 - - - true - .\Release/SiftGPU.bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - X64 - .\Debug/SiftGPU.tlb - - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - _DEBUG;DLL_EXPORT;WIN32;_WINDOWS;_USRDLL;SIFTGPU_DLL;_CRT_SECURE_NO_DEPRECATE;SERVER_SIFTGPU_ENABLED;%(PreprocessorDefinitions) - false - true - EnableFastChecks - MultiThreadedDebug - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;winmm.lib;glew64.lib;glew64s.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - SiftGPU.def - true - $(IntDir)/SIFTGPU.pdb - ../../lib/SIFTGPU_d.lib - MachineX64 - - - true - .\Debug/SiftGPU.bsc - - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU_CUDA_Enabled.vcxproj b/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU_CUDA_Enabled.vcxproj deleted file mode 100644 index c9b216a4..00000000 --- a/3rdparty/SiftGPU/msvc/SiftGPU/SiftGPU_CUDA_Enabled.vcxproj +++ /dev/null @@ -1,390 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9252E247-4FE2-4929-BD5D-C2FA16EFD656} - SiftGPU_CUDA_Enabled - - - - DynamicLibrary - false - MultiByte - - - DynamicLibrary - false - MultiByte - - - DynamicLibrary - false - MultiByte - - - DynamicLibrary - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\ - .\Release_CUDA\ - false - ..\..\bin\ - .\Debug_CUDA\ - true - ..\..\bin\ - $(Configuration)_CUDA_$(Platform)\ - false - ..\..\bin\ - $(Configuration)_CUDA_$(Platform)\ - true - SiftGPU_d - SiftGPU_d - SiftGPU - SiftGPU - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/SiftGPU.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../Include/;%(AdditionalIncludeDirectories) - NDEBUG;SIFTGPU_EXPORTS;WIN32;_WINDOWS;_USRDLL;SIFTGPU_DLL;DLL_EXPORT;_CRT_SECURE_NO_DEPRECATE;CUDA_SIFTGPU_ENABLED;SERVER_SIFTGPU_ENABLED;%(PreprocessorDefinitions) - false - true - MultiThreaded - true - $(IntDir)/SIFTGPU.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;winmm.lib;cuda.lib;cudart.lib;glew32.lib;glew32s.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;$(CUDA_LIB_PATH)/../Win32;%(AdditionalLibraryDirectories) - SiftGPU.def - $(IntDir)/SIFTGPU.pdb - ../../lib/SIFTGPU.lib - MachineX86 - - - true - .\Release/SiftGPU.bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/SiftGPU.tlb - - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - _DEBUG;DLL_EXPORT;WIN32;_WINDOWS;_USRDLL;SIFTGPU_DLL;_CRT_SECURE_NO_DEPRECATE;CUDA_SIFTGPU_ENABLED;SERVER_SIFTGPU_ENABLED;%(PreprocessorDefinitions) - false - true - EnableFastChecks - MultiThreadedDebug - $(IntDir)/SIFTGPU.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;winmm.lib;cuda.lib;cudart.lib;glew32.lib;glew32s.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;$(CUDA_LIB_PATH)/../Win32;%(AdditionalLibraryDirectories) - SiftGPU.def - true - $(IntDir)/SIFTGPU.pdb - ../../lib/SIFTGPU_d.lib - MachineX86 - - - true - .\Debug/SiftGPU.bsc - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - X64 - .\Release/SiftGPU.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../Include/;%(AdditionalIncludeDirectories) - NDEBUG;SIFTGPU_EXPORTS;WIN32;_WINDOWS;_USRDLL;SIFTGPU_DLL;DLL_EXPORT;_CRT_SECURE_NO_DEPRECATE;CUDA_SIFTGPU_ENABLED;SERVER_SIFTGPU_ENABLED;%(PreprocessorDefinitions) - false - true - MultiThreaded - true - $(IntDir)/SIFTGPU.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;winmm.lib;cuda.lib;cudart.lib;glew64.lib;glew64s.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;$(CUDA_LIB_PATH)/../x64;%(AdditionalLibraryDirectories) - SiftGPU.def - $(IntDir)/SIFTGPU.pdb - ../../lib/SIFTGPU.lib - MachineX64 - - - true - .\Release/SiftGPU.bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - X64 - .\Debug/SiftGPU.tlb - - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - _DEBUG;DLL_EXPORT;WIN32;_WINDOWS;_USRDLL;SIFTGPU_DLL;_CRT_SECURE_NO_DEPRECATE;CUDA_SIFTGPU_ENABLED;SERVER_SIFTGPU_ENABLED;%(PreprocessorDefinitions) - false - true - EnableFastChecks - MultiThreadedDebug - $(IntDir)/SIFTGPU.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;winmm.lib;cuda.lib;cudart.lib;glew64.lib;glew64s.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;$(CUDA_LIB_PATH)/../x64;%(AdditionalLibraryDirectories) - SiftGPU.def - true - $(IntDir)/SIFTGPU.pdb - ../../lib/SIFTGPU_d.lib - MachineX64 - - - true - .\Debug/SiftGPU.bsc - - - - - $(CUDA_INC_PATH)\;%(AdditionalIncludeDirectories) - $(CUDA_INC_PATH)\;%(AdditionalIncludeDirectories) - $(CUDA_INC_PATH)\;%(AdditionalIncludeDirectories) - $(CUDA_INC_PATH)\;%(AdditionalIncludeDirectories) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - $(CUDA_INC_PATH)\;%(AdditionalIncludeDirectories) - $(CUDA_INC_PATH)\;%(AdditionalIncludeDirectories) - $(CUDA_INC_PATH)\;%(AdditionalIncludeDirectories) - $(CUDA_INC_PATH)\;%(AdditionalIncludeDirectories) - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - Document - "$(CUDA_BIN_PATH)\nvcc.exe" -ccbin "$(VCInstallDir)\bin" -c -DWIN32 -D_CONSOLE -D_MBCS -DCUDA_SIFTGPU_ENABLED -Xcompiler /EHsc,/W3,/nologo,/O2,/Zi,/MTd -m 64 -I "$(CUDA_INC_PATH)" -I./ -I../../Include -o $(IntDir)\$(InputName).obj %(FullPath) - $(IntDir)\$(InputName).obj - "$(CUDA_BIN_PATH)\nvcc.exe" -ccbin "$(VCInstallDir)\bin" -c -DWIN32 -D_CONSOLE -D_MBCS -DCUDA_SIFTGPU_ENABLED -Xcompiler /EHsc,/W3,/nologo,/O2,/MT -m 64 -I "$(CUDA_INC_PATH)" -I./ -I../../Include -o $(IntDir)\$(InputName).obj %(FullPath) - $(IntDir)\$(InputName).obj - "$(CUDA_BIN_PATH)\nvcc.exe" -ccbin "$(VCInstallDir)\bin" -c -DWIN32 -D_CONSOLE -D_MBCS -DCUDA_SIFTGPU_ENABLED -Xcompiler /EHsc,/W3,/nologo,/O2,/Zi,/MT -m 32 -I "$(CUDA_INC_PATH)" -I./ -I../../Include -o $(IntDir)\$(InputName).obj %(FullPath) - $(IntDir)\$(InputName).obj - "$(CUDA_BIN_PATH)\nvcc.exe" -ccbin "$(VCInstallDir)\bin" -c -DWIN32 -D_CONSOLE -D_MBCS -DCUDA_SIFTGPU_ENABLED -Xcompiler /EHsc,/W3,/nologo,/O2,/Zi,/MTd -m 32 -I "$(CUDA_INC_PATH)" -I./ -I../../Include -o $(IntDir)\$(InputName).obj %(FullPath) - $(IntDir)\$(InputName).obj - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/msvc/SiftGPU_CUDA_Enabled.sln b/3rdparty/SiftGPU/msvc/SiftGPU_CUDA_Enabled.sln deleted file mode 100644 index febda092..00000000 --- a/3rdparty/SiftGPU/msvc/SiftGPU_CUDA_Enabled.sln +++ /dev/null @@ -1,105 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestBase", "TestWin\TestBase.vcxproj", "{57496D03-A005-4650-B041-8E70DDA4A591}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestWin", "TestWin\TestWin.vcxproj", "{E1C4EAB3-1677-46F7-92BC-1A1F309B2027}" - ProjectSection(ProjectDependencies) = postProject - {9252E247-4FE2-4929-BD5D-C2FA16EFD656} = {9252E247-4FE2-4929-BD5D-C2FA16EFD656} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestWinGlut", "TestWin\TestWinGlut.vcxproj", "{B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}" - ProjectSection(ProjectDependencies) = postProject - {9252E247-4FE2-4929-BD5D-C2FA16EFD656} = {9252E247-4FE2-4929-BD5D-C2FA16EFD656} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleSIFT", "TestWin\SimpleSIFT.vcxproj", "{D864A317-5A65-47B1-AA82-C04F99C4280F}" - ProjectSection(ProjectDependencies) = postProject - {9252E247-4FE2-4929-BD5D-C2FA16EFD656} = {9252E247-4FE2-4929-BD5D-C2FA16EFD656} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Speed", "TestWin\Speed.vcxproj", "{7FF72B39-F50E-4ED5-9A50-DCD60EF03604}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SiftGPU_CUDA_Enabled", "SiftGPU\SiftGPU_CUDA_Enabled.vcxproj", "{9252E247-4FE2-4929-BD5D-C2FA16EFD656}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SiftGPU_Server", "ServerSiftGPU\SiftGPU_Server.vcxproj", "{65C987E1-F62C-4461-9E2C-BE1E8A770C51}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MultiThreadSIFT", "TestWin\MultiThreadSIFT.vcxproj", "{8F087E0E-0B77-4CF7-BCD7-F899DB361128}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {57496D03-A005-4650-B041-8E70DDA4A591}.Debug|Win32.ActiveCfg = Debug|Win32 - {57496D03-A005-4650-B041-8E70DDA4A591}.Debug|Win32.Build.0 = Debug|Win32 - {57496D03-A005-4650-B041-8E70DDA4A591}.Debug|x64.ActiveCfg = Debug|x64 - {57496D03-A005-4650-B041-8E70DDA4A591}.Debug|x64.Build.0 = Debug|x64 - {57496D03-A005-4650-B041-8E70DDA4A591}.Release|Win32.ActiveCfg = Release|Win32 - {57496D03-A005-4650-B041-8E70DDA4A591}.Release|Win32.Build.0 = Release|Win32 - {57496D03-A005-4650-B041-8E70DDA4A591}.Release|x64.ActiveCfg = Release|x64 - {57496D03-A005-4650-B041-8E70DDA4A591}.Release|x64.Build.0 = Release|x64 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Debug|Win32.ActiveCfg = Debug|Win32 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Debug|Win32.Build.0 = Debug|Win32 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Debug|x64.ActiveCfg = Debug|x64 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Debug|x64.Build.0 = Debug|x64 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Release|Win32.ActiveCfg = Release|Win32 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Release|Win32.Build.0 = Release|Win32 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Release|x64.ActiveCfg = Release|x64 - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027}.Release|x64.Build.0 = Release|x64 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Debug|Win32.ActiveCfg = Debug|Win32 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Debug|Win32.Build.0 = Debug|Win32 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Debug|x64.ActiveCfg = Debug|x64 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Debug|x64.Build.0 = Debug|x64 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Release|Win32.ActiveCfg = Release|Win32 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Release|Win32.Build.0 = Release|Win32 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Release|x64.ActiveCfg = Release|x64 - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395}.Release|x64.Build.0 = Release|x64 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Debug|Win32.ActiveCfg = Debug|Win32 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Debug|Win32.Build.0 = Debug|Win32 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Debug|x64.ActiveCfg = Debug|x64 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Debug|x64.Build.0 = Debug|x64 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Release|Win32.ActiveCfg = Release|Win32 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Release|Win32.Build.0 = Release|Win32 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Release|x64.ActiveCfg = Release|x64 - {D864A317-5A65-47B1-AA82-C04F99C4280F}.Release|x64.Build.0 = Release|x64 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Debug|Win32.ActiveCfg = Debug|Win32 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Debug|Win32.Build.0 = Debug|Win32 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Debug|x64.ActiveCfg = Debug|x64 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Debug|x64.Build.0 = Debug|x64 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Release|Win32.ActiveCfg = Release|Win32 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Release|Win32.Build.0 = Release|Win32 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Release|x64.ActiveCfg = Release|x64 - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604}.Release|x64.Build.0 = Release|x64 - {9252E247-4FE2-4929-BD5D-C2FA16EFD656}.Debug|Win32.ActiveCfg = Debug|Win32 - {9252E247-4FE2-4929-BD5D-C2FA16EFD656}.Debug|Win32.Build.0 = Debug|Win32 - {9252E247-4FE2-4929-BD5D-C2FA16EFD656}.Debug|x64.ActiveCfg = Debug|x64 - {9252E247-4FE2-4929-BD5D-C2FA16EFD656}.Debug|x64.Build.0 = Debug|x64 - {9252E247-4FE2-4929-BD5D-C2FA16EFD656}.Release|Win32.ActiveCfg = Release|Win32 - {9252E247-4FE2-4929-BD5D-C2FA16EFD656}.Release|Win32.Build.0 = Release|Win32 - {9252E247-4FE2-4929-BD5D-C2FA16EFD656}.Release|x64.ActiveCfg = Release|x64 - {9252E247-4FE2-4929-BD5D-C2FA16EFD656}.Release|x64.Build.0 = Release|x64 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Debug|Win32.ActiveCfg = Debug|Win32 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Debug|Win32.Build.0 = Debug|Win32 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Debug|x64.ActiveCfg = Debug|x64 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Debug|x64.Build.0 = Debug|x64 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Release|Win32.ActiveCfg = Release|Win32 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Release|Win32.Build.0 = Release|Win32 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Release|x64.ActiveCfg = Release|x64 - {65C987E1-F62C-4461-9E2C-BE1E8A770C51}.Release|x64.Build.0 = Release|x64 - {8F087E0E-0B77-4CF7-BCD7-F899DB361128}.Debug|Win32.ActiveCfg = Debug|Win32 - {8F087E0E-0B77-4CF7-BCD7-F899DB361128}.Debug|Win32.Build.0 = Debug|Win32 - {8F087E0E-0B77-4CF7-BCD7-F899DB361128}.Debug|x64.ActiveCfg = Debug|x64 - {8F087E0E-0B77-4CF7-BCD7-F899DB361128}.Debug|x64.Build.0 = Debug|x64 - {8F087E0E-0B77-4CF7-BCD7-F899DB361128}.Release|Win32.ActiveCfg = Release|Win32 - {8F087E0E-0B77-4CF7-BCD7-F899DB361128}.Release|Win32.Build.0 = Release|Win32 - {8F087E0E-0B77-4CF7-BCD7-F899DB361128}.Release|x64.ActiveCfg = Release|x64 - {8F087E0E-0B77-4CF7-BCD7-F899DB361128}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/3rdparty/SiftGPU/msvc/TestWin/MultiThreadSIFT.dsp b/3rdparty/SiftGPU/msvc/TestWin/MultiThreadSIFT.dsp deleted file mode 100644 index 0070f726..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/MultiThreadSIFT.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="MultiThreadSIFT" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=MultiThreadSIFT - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "MultiThreadSIFT.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "MultiThreadSIFT.mak" CFG="MultiThreadSIFT - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "MultiThreadSIFT - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "MultiThreadSIFT - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "MultiThreadSIFT - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/MultiThreadSIFT.exe" - -!ELSEIF "$(CFG)" == "MultiThreadSIFT - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/MultiThreadSIFT_d.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "MultiThreadSIFT - Win32 Release" -# Name "MultiThreadSIFT - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\TestWin\MultiThreadSIFT.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/3rdparty/SiftGPU/msvc/TestWin/MultiThreadSIFT.vcxproj b/3rdparty/SiftGPU/msvc/TestWin/MultiThreadSIFT.vcxproj deleted file mode 100644 index fe0c1b20..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/MultiThreadSIFT.vcxproj +++ /dev/null @@ -1,259 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {8F087E0E-0B77-4CF7-BCD7-F899DB361128} - - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - true - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - false - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - true - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - false - $(ProjectName)_d - $(ProjectName)_d - - - - .\Debug/MultiThreadSIFT.tlb - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - .\Debug/MultiThreadSIFT.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - true - .\Debug/MultiThreadSIFT_d.pdb - Console - MachineX86 - - - true - .\Debug/MultiThreadSIFT.bsc - - - false - - - - - .\Release/MultiThreadSIFT.tlb - - - - - MaxSpeed - OnlyExplicitInline - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - .\Release/MultiThreadSIFT.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - .\Release/MultiThreadSIFT.pdb - Console - MachineX86 - - - true - .\Release/MultiThreadSIFT.bsc - - - false - - - - - X64 - .\Debug/MultiThreadSIFT.tlb - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - .\Debug/MultiThreadSIFT.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - true - .\Debug/MultiThreadSIFT_d.pdb - Console - MachineX64 - - - true - .\Debug/MultiThreadSIFT.bsc - - - false - - - - - X64 - .\Release/MultiThreadSIFT.tlb - - - - - MaxSpeed - OnlyExplicitInline - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - .\Release/MultiThreadSIFT.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - .\Release/MultiThreadSIFT.pdb - Console - MachineX64 - - - true - .\Release/MultiThreadSIFT.bsc - - - false - - - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - - {9252e247-4fe2-4929-bd5d-c2fa16efd656} - false - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/msvc/TestWin/SimpleSIFT.dsp b/3rdparty/SiftGPU/msvc/TestWin/SimpleSIFT.dsp deleted file mode 100644 index 512e9ff3..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/SimpleSIFT.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="SimpleSIFT" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=SimpleSIFT - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "SimpleSIFT.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "SimpleSIFT.mak" CFG="SimpleSIFT - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "SimpleSIFT - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "SimpleSIFT - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "SimpleSIFT - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/SimpleSIFT.exe" - -!ELSEIF "$(CFG)" == "SimpleSIFT - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/SimpleSIFT_d.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "SimpleSIFT - Win32 Release" -# Name "SimpleSIFT - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\TestWin\SimpleSIFT.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/3rdparty/SiftGPU/msvc/TestWin/SimpleSIFT.vcxproj b/3rdparty/SiftGPU/msvc/TestWin/SimpleSIFT.vcxproj deleted file mode 100644 index 5648fa6f..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/SimpleSIFT.vcxproj +++ /dev/null @@ -1,259 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {D864A317-5A65-47B1-AA82-C04F99C4280F} - - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - true - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - true - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - false - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - false - $(ProjectName)_d - $(ProjectName)_d - - - - .\Debug/SimpleSIFT.tlb - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/SimpleSIFT.pch - .\Debug/ - .\Debug/ - .\Debug/ - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - true - .\Debug/SimpleSIFT_d.pdb - Console - MachineX86 - - - true - .\Debug/SimpleSIFT.bsc - - - false - - - - - X64 - .\Debug/SimpleSIFT.tlb - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/SimpleSIFT.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - true - .\Debug/SimpleSIFT_d.pdb - Console - MachineX64 - - - true - .\Debug/SimpleSIFT.bsc - - - false - - - - - .\Release/SimpleSIFT.tlb - - - - - MaxSpeed - OnlyExplicitInline - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/SimpleSIFT.pch - .\Release/ - .\Release/ - .\Release/ - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - .\Release/SimpleSIFT.pdb - Console - MachineX86 - - - true - .\Release/SimpleSIFT.bsc - - - false - - - - - X64 - .\Release/SimpleSIFT.tlb - - - - - MaxSpeed - OnlyExplicitInline - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/SimpleSIFT.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - .\Release/SimpleSIFT.pdb - Console - MachineX64 - - - true - .\Release/SimpleSIFT.bsc - - - false - - - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - - {594562d3-609a-47bc-b7e2-789c4e794cc3} - false - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/msvc/TestWin/Speed.dsp b/3rdparty/SiftGPU/msvc/TestWin/Speed.dsp deleted file mode 100644 index 001d7f41..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/Speed.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Speed" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=Speed - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Speed.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Speed.mak" CFG="Speed - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Speed - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Speed - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Speed - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib siftgpu.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/speed.exe" /libpath:"../../lib" - -!ELSEIF "$(CFG)" == "Speed - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib siftgpu_d.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/speed_d.exe" /pdbtype:sept /libpath:"../../lib" - -!ENDIF - -# Begin Target - -# Name "Speed - Win32 Release" -# Name "Speed - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\TestWin\speed.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/3rdparty/SiftGPU/msvc/TestWin/Speed.vcxproj b/3rdparty/SiftGPU/msvc/TestWin/Speed.vcxproj deleted file mode 100644 index 725c3709..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/Speed.vcxproj +++ /dev/null @@ -1,272 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {7FF72B39-F50E-4ED5-9A50-DCD60EF03604} - Speed - - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - false - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - false - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - true - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - true - $(ProjectName)_d - $(ProjectName)_d - - - - .\Release/Speed.tlb - - - - - MaxSpeed - OnlyExplicitInline - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/Speed.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - siftgpu.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib;%(AdditionalLibraryDirectories) - .\Release/speed.pdb - Console - MachineX86 - - - true - .\Release/Speed.bsc - - - false - - - - - X64 - .\Release/Speed.tlb - - - - - MaxSpeed - OnlyExplicitInline - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/Speed.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - siftgpu.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib;%(AdditionalLibraryDirectories) - .\Release/speed.pdb - Console - MachineX64 - - - true - .\Release/Speed.bsc - - - false - - - - - .\Debug/Speed.tlb - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/Speed.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - siftgpu_d.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib;%(AdditionalLibraryDirectories) - true - .\Debug/speed_d.pdb - Console - MachineX86 - - - true - .\Debug/Speed.bsc - - - false - - - - - X64 - .\Debug/Speed.tlb - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/Speed.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - siftgpu_d.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib;%(AdditionalLibraryDirectories) - true - .\Debug/speed_d.pdb - Console - MachineX64 - - - true - .\Debug/Speed.bsc - - - false - - - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - - {594562d3-609a-47bc-b7e2-789c4e794cc3} - false - - - {9252e247-4fe2-4929-bd5d-c2fa16efd656} - false - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/msvc/TestWin/TestBase.dsp b/3rdparty/SiftGPU/msvc/TestWin/TestBase.dsp deleted file mode 100644 index 80d004e0..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/TestBase.dsp +++ /dev/null @@ -1,104 +0,0 @@ -# Microsoft Developer Studio Project File - Name="TestBase" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=TestBase - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "TestBase.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "TestBase.mak" CFG="TestBase - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "TestBase - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "TestBase - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "TestBase - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../../Include/" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\..\lib\TestBase.lib" - -!ELSEIF "$(CFG)" == "TestBase - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../Include/" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\..\lib\TestBase_d.lib" - -!ENDIF - -# Begin Target - -# Name "TestBase - Win32 Release" -# Name "TestBase - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\TestWin\BasicTestWin.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\src\TestWin\BasicTestWin.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\TestWin\GLTransform.h -# End Source File -# End Group -# End Target -# End Project diff --git a/3rdparty/SiftGPU/msvc/TestWin/TestBase.vcxproj b/3rdparty/SiftGPU/msvc/TestWin/TestBase.vcxproj deleted file mode 100644 index d8ca6db5..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/TestBase.vcxproj +++ /dev/null @@ -1,230 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {57496D03-A005-4650-B041-8E70DDA4A591} - - - - StaticLibrary - false - MultiByte - - - StaticLibrary - false - MultiByte - - - StaticLibrary - false - MultiByte - - - StaticLibrary - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\lib\ - $(ProjectName)_$(Configuration)\ - ..\..\lib\ - $(ProjectName)_$(Configuration)_$(Platform)\ - ..\..\lib\ - $(ProjectName)_$(Configuration)\ - ..\..\lib\ - $(ProjectName)_$(Configuration)_$(Platform)\ - $(ProjectName)_d - $(ProjectName)_$(Platform)_d - $(ProjectName)_$(Platform) - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/TestBase.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - - - true - .\Debug/TestBase.bsc - - - - - X64 - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/TestBase.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - - - true - .\Debug/TestBase.bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/TestBase.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - - - true - .\Release/TestBase.bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/TestBase.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(TargetName)$(TargetExt) - true - - - true - .\Release/TestBase.bsc - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - - {594562d3-609a-47bc-b7e2-789c4e794cc3} - false - - - {9252e247-4fe2-4929-bd5d-c2fa16efd656} - false - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/msvc/TestWin/TestWin.dsp b/3rdparty/SiftGPU/msvc/TestWin/TestWin.dsp deleted file mode 100644 index 0aa9998f..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/TestWin.dsp +++ /dev/null @@ -1,115 +0,0 @@ -# Microsoft Developer Studio Project File - Name="TestWin" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=TestWin - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "TestWin.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "TestWin.mak" CFG="TestWin - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "TestWin - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "TestWin - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "TestWin - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../../Include/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib opengl32.lib siftgpu.lib testbase.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/TestWin.exe" /libpath:"../../lib/" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "TestWin - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../Include/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib opengl32.lib siftgpu_d.lib testbase_d.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/TestWin_d.exe" /pdbtype:sept /libpath:"../../lib/" -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "TestWin - Win32 Release" -# Name "TestWin - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\TestWin\GLTestWnd.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\src\TestWin\GLTestWnd.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/3rdparty/SiftGPU/msvc/TestWin/TestWin.vcxproj b/3rdparty/SiftGPU/msvc/TestWin/TestWin.vcxproj deleted file mode 100644 index c901972d..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/TestWin.vcxproj +++ /dev/null @@ -1,292 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {E1C4EAB3-1677-46F7-92BC-1A1F309B2027} - - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - false - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - false - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - true - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - true - $(ProjectName)_d - $(ProjectName)_d - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/TestWin.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/TestWin.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;testbase.lib;siftgpu.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - .\Release/TestWin.pdb - Console - MachineX86 - - - true - .\Release/TestWin.bsc - - - false - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - X64 - .\Release/TestWin.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/TestWin.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;testbase_x64.lib;siftgpu.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - .\Release/TestWin.pdb - Console - MachineX64 - - - true - .\Release/TestWin.bsc - - - false - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/TestWin.tlb - - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/TestWin.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;testbase_d.lib;siftgpu_d.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - true - .\Debug/TestWin_d.pdb - Console - MachineX86 - - - true - .\Debug/TestWin.bsc - - - false - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - X64 - .\Debug/TestWin.tlb - - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/TestWin.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - opengl32.lib;glu32.lib;testbase_x64_d.lib;siftgpu_d.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - true - .\Debug/TestWin_d.pdb - Console - MachineX64 - - - true - .\Debug/TestWin.bsc - - - false - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - {57496d03-a005-4650-b041-8e70dda4a591} - false - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/msvc/TestWin/TestWinGlut.dsp b/3rdparty/SiftGPU/msvc/TestWin/TestWinGlut.dsp deleted file mode 100644 index 0d069123..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/TestWinGlut.dsp +++ /dev/null @@ -1,106 +0,0 @@ -# Microsoft Developer Studio Project File - Name="TestWinGlut" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=TestWinGlut - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "TestWinGlut.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "TestWinGlut.mak" CFG="TestWinGlut - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "TestWinGlut - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "TestWinGlut - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "TestWinGlut - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../../Include/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib siftgpu.lib testbase.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/TestWinGlut.exe" /libpath:"../../lib/" - -!ELSEIF "$(CFG)" == "TestWinGlut - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../Include/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib siftgpu_d.lib testbase_d.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/TestWinGlut_d.exe" /pdbtype:sept /libpath:"../../lib/" - -!ENDIF - -# Begin Target - -# Name "TestWinGlut - Win32 Release" -# Name "TestWinGlut - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\TestWin\TestWinGlut.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\src\TestWin\TestWinGlut.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/3rdparty/SiftGPU/msvc/TestWin/TestWinGlut.vcxproj b/3rdparty/SiftGPU/msvc/TestWin/TestWinGlut.vcxproj deleted file mode 100644 index 937f2cc0..00000000 --- a/3rdparty/SiftGPU/msvc/TestWin/TestWinGlut.vcxproj +++ /dev/null @@ -1,280 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {B33F9B4E-BF99-442B-BDC5-3DAA4BCCA395} - - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - true - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - true - ..\..\bin\ - $(ProjectName)_$(Configuration)\ - false - ..\..\bin\ - $(ProjectName)_$(Configuration)_$(Platform)\ - false - $(ProjectName)_d - $(ProjectName)_d - - - - .\Debug/TestWinGlut.tlb - - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/TestWinGlut.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - siftgpu_d.lib;testbase_d.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - true - .\Debug/TestWinGlut_d.pdb - Console - MachineX86 - - - true - .\Debug/TestWinGlut.bsc - - - false - - - - - X64 - .\Debug/TestWinGlut.tlb - - - - - Disabled - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - .\Debug/TestWinGlut.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - siftgpu_d.lib;testbase_x64_d.lib;glut64.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - glut32.lib;%(IgnoreSpecificDefaultLibraries) - true - .\Debug/TestWinGlut_d.pdb - Console - MachineX64 - - - true - .\Debug/TestWinGlut.bsc - - - false - - - - - .\Release/TestWinGlut.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/TestWinGlut.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - siftgpu.lib;testbase.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - .\Release/TestWinGlut.pdb - Console - MachineX86 - - - true - .\Release/TestWinGlut.bsc - - - false - - - - - X64 - .\Release/TestWinGlut.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../Include/;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\Release/TestWinGlut.pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - siftgpu.lib;testbase_x64.lib;glut64.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - ../../lib/;%(AdditionalLibraryDirectories) - glut32.lib;%(IgnoreSpecificDefaultLibraries) - .\Release/TestWinGlut.pdb - Console - MachineX64 - - - true - .\Release/TestWinGlut.bsc - - - false - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - {57496d03-a005-4650-b041-8e70dda4a591} - false - - - - - - \ No newline at end of file diff --git a/3rdparty/SiftGPU/speed_and_accuracy.txt b/3rdparty/SiftGPU/speed_and_accuracy.txt deleted file mode 100644 index ca68166c..00000000 --- a/3rdparty/SiftGPU/speed_and_accuracy.txt +++ /dev/null @@ -1,87 +0,0 @@ ------------------------------------------------------------------------- -SPEED ------------------------------------------------------------------------- -1. The first several rounds of SiftGPU might be slow, don't worry. If it -is always slow, the reason might be either the graphic card is old or the -graphic memory is small. - -2. Texture reallocation happens when a new image does not fit in the already -allocated storage. To get less reallocations, you can pre-allocate storage -to fit the largest image size, or just use images with the same size. - -3. Loading some compressed images (.e.g jpg) may take a lot of time on -decompressing. Using binary pgm files or directly specifying data in memory -can achive better performance. Writing ASCII SIFT files is also slow. - -4. The packd version saves GPU memory but also run faster than the unpacked, -which is default now. - -5. SiftGPU might be faster with older grpahic card drivers than with newer ones. - -6. The descriptor normalization in the OpenGL-based implementation is running -on CPU. New versions are now using SSE, which improves the speed for this part -a lot. - -7. The orientation computation in unpacked implementation is occasionally slow -under single orientation mode (-m 1) or packed orientation mode (-m2p). By -default, siftgpu uses 2 orientations (-m 2), which should be fine. This issue -is still unresolved. - -8. The thread block settings in the CUDA-based SiftGPU are currently tuned -for my GPU nVidia GTX 8800, which may not be optimized for other GPUs. - ----------------------------------------------------------------------------- -ACCURACY ----------------------------------------------------------------------------- -1. The latest version of SiftGPU now has comparable accuracy with CPU -implementatins. Evaluation on box.pgm of Lowe's package now gives around 600 -matches, which is close to SIFT++. - -2. In orientation computation, SiftGPU uses a factor 2.0 * sigma as the sample -window size, which is smaller than the typical value 3.0. Changing it from 2.0 -to 3.0 reduces the speed of this step by %40, but gives only a very small -improvements in matching. You can change it by specifying parameter "-w 3". - -3. In keypoint localization, SiftGPU refines the location only once by default, -and SiftGPU does not move the level of keypoints in the refinement. - -4. The feature locations are having a (0.5,0.5) offset compared with CPU -implementations by default. (0, 0) in texture is at the top-left coorner -(instead of center) of the top-left pixel. You can use the center as (0, 0) -by specifying "-loweo" - -5. By default, SiftGPU does not do Upsampling(-fo -1), To match it with Lowe's -implementation you need to use "-fo -1 -loweo". - -6. SiftGPU may get slightly different results on different GPUs due to different -floating point precision. SiftGPU is tested on limited types of graphic cards/OS, -working on your graphic card is not guaranteed. - -IF it returns different number of features at different run on the same card, -then something is going wrong, and probably some special tricks need to be used. -Please email me if that happens. - -7. When getting wrong matches, please look at the saved SIFT file to make sure -there are no weired descriptors( for example, all of the numbers of a descriptor -are 45, or any number in a descriptor is larger than 255) - ------------------------------------------------------------------------------- -KWOWN ISSUES. ------------------------------------------------------------------------------- -1. SiftGPU may have problem with dual monitor. -2. Slow on 7950. Changing GlobalParam::_iTexFormat to GL_RGBA16F_ARB can make - it work. Unknown reason. -3. Experiments on 8600 show problems. It works fine for the first image, but - gets wrong keypoints after. - - - - - - - - - - - - diff --git a/3rdparty/SiftGPU/src/CMakeLists.txt b/3rdparty/SiftGPU/src/CMakeLists.txt deleted file mode 100644 index d72205fe..00000000 --- a/3rdparty/SiftGPU/src/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -ADD_SUBDIRECTORY(SiftGPU) diff --git a/3rdparty/SiftGPU/src/ServerSiftGPU/ServerSiftGPU.cpp b/3rdparty/SiftGPU/src/ServerSiftGPU/ServerSiftGPU.cpp deleted file mode 100644 index 894aa75f..00000000 --- a/3rdparty/SiftGPU/src/ServerSiftGPU/ServerSiftGPU.cpp +++ /dev/null @@ -1,902 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ServerSiftGPU.cpp -// Author: Changchang Wu -// Description : implementation for the ServerSiftGPU class. -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#include -#include - -using std::cout; -using std::vector; - - -#if defined(SERVER_SIFTGPU_ENABLED) - -#include "GL/glew.h" - -#ifdef _WIN32 - #include - #include - #define socklen_t int - #pragma comment(lib, "ws2_32.lib") -#else - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - //conversion from Win32 - typedef int SOCKET; - #define INVALID_SOCKET -1 - #define closesocket close -#endif - -#include "../SiftGPU/SiftGPU.h" -#include "ServerSiftGPU.h" - - - - - - -class SocketUtil -{ -public: - static int readline(SOCKET s, char *buf, int nread) - { - char c; - int num,n=0; - for(n=1; n 0 && count_read_sum < count); - return count_read_sum == count; - } - static int init() - { - -#ifdef _WIN32 - WSADATA WsaData; - if(WSAStartup(0x0202, &WsaData)) - { - std::cout << "server: can't startup socket\n"; - return 0; - }else - { - return 1; - } -#else - return 1; -#endif - - } -}; - - -ServerSiftGPU::ServerSiftGPU(int port, char* remote_server) -{ - _port = port; - _socketfd = INVALID_SOCKET; - _connected = 0; - strcpy(_server_name, remote_server? remote_server : "\0"); -} - -int ServerSiftGPU::InitSocket() -{ - return SocketUtil::init(); -} - - -int ServerSiftGPU::StartServerProcess(int argc, char** argv) -{ - vector args(argc + 4); char ports[16]; - - args[0] = "server_siftgpu"; - args[1] = "-server"; - sprintf(ports, "%d", _port); - args[2] = ports; - /////////////////////////////////////////////// - for(int i = 0; i < argc; ++i) args[i + 3] = argv[i]; - args[argc + 3] = 0; - /////////////////////////////////////////////////////// - //make a new process -#ifdef _WIN32 - int result = (int) _spawnv(_P_NOWAIT, "server_siftgpu.exe", &args[0]); - if(result == -1) std::cerr<< "spawn returns -1 with error = " << errno << "\n"; - return result != -1; -#else - #ifdef __APPLE__ - #define LIBPATH_NAME "DYLD_LIBRARY_PATH" - #else - #define LIBPATH_NAME "LD_LIBRARY_PATH" - #endif - int result; pid_t pid; - char* oldpath = getenv(LIBPATH_NAME); - if(oldpath == NULL) - { - result = posix_spawn(&pid, "server_siftgpu", NULL, NULL, &args[0], NULL); - }else - { - char newpath[1024]= LIBPATH_NAME "="; - strcat(newpath, oldpath); - char* envp [] = {newpath, 0}; - result = posix_spawn(&pid, "server_siftgpu", NULL, NULL, &args[0], envp); - } - if(result) std::cerr << "failed to use poxis_spawn to create the server.\n"; - return result == 0; -#endif -} - -int ServerSiftGPU::ConnectServer(const char* server_name, int port) -{ - struct hostent* hh; - - if((hh = gethostbyname(server_name)) == NULL)return 0; - - //////////////////////////////////////// - struct sockaddr_in servaddr; - memset(&servaddr, 0, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_port = htons(port); - servaddr.sin_addr.s_addr=((struct in_addr*)(hh->h_addr))->s_addr; - - ((SOCKET&)_socketfd) = socket(AF_INET, SOCK_STREAM, 0); - if(_socketfd==INVALID_SOCKET) return 0; - - //if can not connect to server, start again - if(connect(_socketfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) - { - closesocket(_socketfd); - _socketfd = INVALID_SOCKET; - return 0; - }else - { - std::cout<<"Connected to server " << server_name << "\n"; - return 1; - } -} - -void ServerSiftGPU::Disconnect() -{ - SocketUtil::writeint(_socketfd, _server_name[0]? COMMAND_DISCONNECT : COMMAND_EXIT); - closesocket(_socketfd); - _socketfd = INVALID_SOCKET; - _connected = 0; -} - -ServerSiftGPU::~ServerSiftGPU() -{ - if(_connected) Disconnect(); -} - - -inline void ServerSiftGPU::ServerLoop(int port, int argc, char** argv) -{ - SOCKET sockfd, newsockfd; - struct sockaddr_in serv_addr, cli_addr; - socklen_t addr_len = sizeof(sockaddr_in); - ////////////////////////////////////////////////// - memset((char*)&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(port); - serv_addr.sin_addr.s_addr = INADDR_ANY; - ///////////////////////////////////////////// - - if(ServerSiftGPU::InitSocket() == 0) - { - return; - } - ////////////////////////////////////////////////////////////// - sockfd=socket(AF_INET,SOCK_STREAM,0); - if(sockfd==INVALID_SOCKET) - { - std::cout << "server: can't open stream socket\n"; - return; - }else if(bind(sockfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr))) - { - std::cout << "server: can't bind to port " << port <<"\n"; - return; - }else if(listen(sockfd, 1)) - { - std::cout << "server: failed to listen\n"; - return; - }else - { - std::cout << "server: listent to port "<< port << "\n"; - } - - newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &addr_len); - if(newsockfd == INVALID_SOCKET) - { - std::cout << "error: accept failed\n"; - closesocket(sockfd); - return; - } - //////////////////////////////////////////////////////////////// - char buf[1024]; - int command, result; - int sift_feature_count = 0;; - vector keys; - vector descriptors; - vector databuf; - - ///////////////////////////////////////////////////////////////// - SiftGPU siftgpu; - SiftMatchGPU matcher; - - if(argc > 0) siftgpu.ParseParam(argc, argv); - - ///////////////////// - siftgpu.SetVerbose(0); - ///////////////////////////////////////////////////////////////// - - do - { - while(SocketUtil::readint(newsockfd, &command) && command != COMMAND_DISCONNECT) - { - switch(command) - { - case COMMAND_INITIALIZE: - { - result = (siftgpu.CreateContextGL() == SiftGPU::SIFTGPU_FULL_SUPPORTED); - SocketUtil::writeint(newsockfd, result); - if(result) break; - } - case COMMAND_EXIT: - closesocket(newsockfd); - closesocket(sockfd); - return; - case COMMAND_ALLOCATE_PYRAMID: - { - int size[2]; - SocketUtil::readint(newsockfd, size, 2); - if(size[0] > 0 && size[1] > 0) siftgpu.AllocatePyramid(size[0], size[1]); - break; - } - case COMMAND_GET_KEY_VECTOR: - { - int size = sift_feature_count * sizeof(SiftGPU::SiftKeypoint); - SocketUtil::writedata(newsockfd, &keys[0], size); - break; - } - case COMMAND_GET_DES_VECTOR: - { - int size = sift_feature_count * sizeof(float) * 128; - SocketUtil::writedata(newsockfd, &descriptors[0], size); - break; - } - case COMMAND_RUNSIFT: - { - result = siftgpu.RunSIFT(); - if((sift_feature_count = siftgpu.GetFeatureNum()) > 0) - { - keys.resize(sift_feature_count); - descriptors.resize(sift_feature_count * 128); - siftgpu.GetFeatureVector(&keys[0], &descriptors[0]); - std::cout << "RunSIFT: [-] [" << sift_feature_count << "]\n"; - } - SocketUtil::writeint(newsockfd, result); - break; - } - case COMMAND_RUNSIFT_FILE: - { - SocketUtil::readline(newsockfd, buf, 1024); - - result = siftgpu.RunSIFT(buf); - if((sift_feature_count = siftgpu.GetFeatureNum()) > 0) - { - keys.resize(sift_feature_count); - descriptors.resize(sift_feature_count * 128); - siftgpu.GetFeatureVector(&keys[0], &descriptors[0]); - } - std::cout << "RunSIFT: "<< buf <<" " << sift_feature_count << "\n" ; - SocketUtil::writeint(newsockfd, result); - break; - } - case COMMAND_SET_KEYPOINT: - { - int keys_have_orientation; - SocketUtil::readint(newsockfd, &sift_feature_count); - SocketUtil::readint(newsockfd, &keys_have_orientation); - if(sift_feature_count > 0) - { - keys.resize(sift_feature_count); - descriptors.resize(sift_feature_count * 128); - SocketUtil::readdata(newsockfd, &keys[0], int(keys.size() * sizeof(SiftGPU::SiftKeypoint))); - siftgpu.SetKeypointList(sift_feature_count, &keys[0], keys_have_orientation); - } - break; - } - case COMMAND_RUNSIFT_KEY: - { - int keys_have_orientation; - SocketUtil::readint(newsockfd, &sift_feature_count); - SocketUtil::readint(newsockfd, &keys_have_orientation); - if(sift_feature_count > 0) - { - std::cout << "RunSIFT: "<< sift_feature_count << " KEYPOINTS\n" ; - int key_data_size = sift_feature_count * sizeof(SiftGPU::SiftKeypoint); - keys.resize(sift_feature_count); - descriptors.resize(sift_feature_count * 128); - SocketUtil::readdata(newsockfd, &keys[0], key_data_size); - result = siftgpu.RunSIFT(sift_feature_count, &keys[0], keys_have_orientation); - siftgpu.GetFeatureVector(NULL, &descriptors[0]); - }else - { - result = 0; - } - SocketUtil::writeint(newsockfd, result); - break; - } - case COMMAND_RUNSIFT_DATA: - { - int data_des[4], size = 0; - SocketUtil::readint(newsockfd, data_des, 4); - SocketUtil::readint(newsockfd, &size, 1); - std::cout << "RunSIFT: [" << data_des[0] << "x" << data_des[1] << "]"; - - databuf.resize(size); - void* data_ptr = &databuf[0]; - SocketUtil::readdata(newsockfd, data_ptr, size); - - - result = siftgpu.RunSIFT(data_des[0], data_des[1], data_ptr, data_des[2], data_des[3]); - if((sift_feature_count = siftgpu.GetFeatureNum()) > 0) - { - keys.resize(sift_feature_count); - descriptors.resize(sift_feature_count * 128); - siftgpu.GetFeatureVector(&keys[0], &descriptors[0]); - } - std::cout << "[" << sift_feature_count << "]\n"; - SocketUtil::writeint(newsockfd, result); - break; - } - case COMMAND_SAVE_SIFT: - { - SocketUtil::readline(newsockfd, buf, 1024); - siftgpu.SaveSIFT(buf); - break; - } - case COMMAND_SET_MAX_DIMENSION: - { - int maxd; - if(SocketUtil::readint(newsockfd, &maxd) && maxd > 0) siftgpu.SetMaxDimension(maxd); - break; - } - case COMMAND_SET_TIGHTPYRAMID: - { - int tight; - if(SocketUtil::readint(newsockfd, &tight)) siftgpu.SetTightPyramid(tight); - break; - } - case COMMAND_GET_FEATURE_COUNT: - { - SocketUtil::writeint(newsockfd, sift_feature_count); - break; - } - case COMMAND_PARSE_PARAM: - { - SocketUtil::readline(newsockfd, buf, 1024); - std::cout << "ParseParam [" << buf << "]\n"; - vector params; - char* p = buf; - while(*p) - { - while(*p == ' ' || *p == '\t')*p++ = 0; - params.push_back(p); - while(*p && *p != ' ' && *p != '\t') p++; - } - siftgpu.ParseParam(params.size(), ¶ms[0]); - break; - } - case COMMAND_MATCH_INITIALIZE: - { - result = matcher.CreateContextGL(); - SocketUtil::writeint(newsockfd, result); - break; - } - case COMMAND_MATCH_SET_LANGUAGE: - { - int language; - if(SocketUtil::readint(newsockfd, &language)) matcher.SetLanguage(language); - break; - } - case COMMAND_MATCH_SET_DES_FLOAT: - { - int command[3] = {0, 0, 0}; - if(SocketUtil::readdata(newsockfd, command, sizeof(command))) - { - databuf.resize(sizeof(float) * 128 * command[1]); - if(SocketUtil::readdata(newsockfd, &databuf[0], databuf.size())) - { - matcher.SetDescriptors(command[0], command[1], (float*) (&databuf[0]), command[2]); - } - } - break; - } - case COMMAND_MATCH_SET_DES_BYTE: - { - int command[3] = {0, 0, 0}; - if(SocketUtil::readdata(newsockfd, command, sizeof(command))) - { - databuf.resize(sizeof(unsigned char) * 128 * command[1]); - if(SocketUtil::readdata(newsockfd, &databuf[0], databuf.size())) - { - matcher.SetDescriptors(command[0], command[1], (unsigned char*) (&databuf[0]), command[2]); - } - } - break; - } - case COMMAND_MATCH_GET_MATCH: - { - int command[2]; float fcommand[2]; - result = 0; - if( SocketUtil::readdata(newsockfd, command, sizeof(command)) && - SocketUtil::readdata(newsockfd, fcommand, sizeof(fcommand))) - { - int max_match = command[0], mbm = command[1]; - float distmax = fcommand[0], ratiomax = fcommand[1]; - databuf.resize(max_match * 2 * sizeof(int)); - result = matcher.GetSiftMatch(max_match, ( int(*)[2]) (&databuf[0]), distmax, ratiomax, mbm); - - } - SocketUtil::writeint(newsockfd, result); - if(result > 0) SocketUtil::writedata(newsockfd, &databuf[0], sizeof(int) * 2 * result); - std::cout << "SiftMatch: " << result << "\n"; - break; - } - case COMMAND_MATCH_SET_MAXSIFT: - { - int max_sift; - if(SocketUtil::readint(newsockfd, &max_sift)) matcher.SetMaxSift(max_sift); - break; - } - break; - default: - std::cout << "unrecognized command: " << command << "\n"; - break; - } - } - - //client disconneted - closesocket(newsockfd); - //wait for the next client. - std::cout << "wait for new client..."; - newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &addr_len); - if(newsockfd == INVALID_SOCKET) - { - std::cout << "error: accept failed"; - closesocket(sockfd); - return; - }else - { - std::cout << "connected\n\n"; - } - }while(1); -} - -void ServerSiftGPU::SetParamSiftGPU(int argc, char** argv) -{ - if(!_connected || argc <= 0) return; - - char buf[1025], *p = buf, cret = '\n'; - for(int i = 0; i < argc; ++i) - { - if(argv[i]) - { - strcpy(p, argv[i]); - p += strlen(argv[i]); - } - *p++= ((i +1 < argc)? ' ' : '\0'); - } - SocketUtil::writeint(_socketfd, COMMAND_PARSE_PARAM); - SocketUtil::writedata(_socketfd, buf, (p - buf)); - SocketUtil::writedata(_socketfd, &cret, 1); - -} - -int ServerSiftGPU:: InitializeConnection(int argc, char** argv) -{ - char server_name[1024]; - if(!InitSocket()) return 0 ; - if(_server_name[0] == 0) - { - if(StartServerProcess(argc, argv) == 0) - { - std::cout<<"Unable to start local siftgpu server\n"; - return 0 ; - } - strcpy(server_name, "127.0.0.1"); - }else - { - strcpy(server_name, _server_name); - } - - /////////////////////////////////////////////// - if(ConnectServer(server_name, _port) == 0) - { - //wait for one second -#ifdef _WIN32 - Sleep(1000); -#else - sleep(1); -#endif - if(ConnectServer(server_name, _port) == 0) - { - std::cout<<"Unable to connect siftgpu sever\n"; - return 0 ; - } - } - return 1; -} - -void ServerSiftGPU::ParseParam(int argc, char **argv) -{ - if(_connected == 1) - { - SetParamSiftGPU(argc, argv); - }else - { - _connected = InitializeConnection(argc, argv); - if(_server_name[0] && argc > 0) SetParamSiftGPU(argc, argv); - } -} - -int ServerSiftGPU::VerifyContextGL() -{ - //////////////////////////////////////////////////// - if(!_connected) return 0; - - int result = 0; - - if(SocketUtil::writeint(_socketfd, COMMAND_INITIALIZE) && - SocketUtil::readint(_socketfd, &result) && result) - { - return SiftGPU::SIFTGPU_FULL_SUPPORTED; - }else - { - std::cout<<"SifGPU failed to initialize\n"; - Disconnect(); - return 0; - } -} - -int ServerSiftGPU::GetFeatureNum() -{ - if(!_connected) return 0; - int result = 0; - SocketUtil::writeint(_socketfd, COMMAND_GET_FEATURE_COUNT); - SocketUtil::readint(_socketfd, &result); - return result; -} - -int ServerSiftGPU::AllocatePyramid(int width, int height) -{ - if(!_connected) return 0; - int command[3] = {COMMAND_ALLOCATE_PYRAMID, width, height}; - return SocketUtil::writedata(_socketfd, command, sizeof(int) * 3); -} - -//////////////////////////////////////////////////////////// -void ServerSiftGPU::SaveSIFT(const char * szFileName) -{ - if(!_connected) return; - - char cret = '\n'; - SocketUtil::writeint(_socketfd, COMMAND_SAVE_SIFT); - SocketUtil::writedata(_socketfd, szFileName, (int)strlen(szFileName)); - SocketUtil::writedata(_socketfd, &cret, 1); - -} - -void ServerSiftGPU::GetFeatureVector(SiftGPU::SiftKeypoint * keys, float * descriptors) -{ - if(!_connected) return; - - int num = GetFeatureNum(), result = 1; - if(keys && num > 0) - { - result&= SocketUtil::writeint(_socketfd, COMMAND_GET_KEY_VECTOR); - result &= SocketUtil::readdata(_socketfd, keys, num * sizeof(SiftGPU::SiftKeypoint)); - } - if(descriptors && num > 0) - { - result&= SocketUtil::writeint(_socketfd, COMMAND_GET_DES_VECTOR); - result&= SocketUtil::readdata(_socketfd, descriptors, num * 128 * sizeof(float)); - } -} - -void ServerSiftGPU::SetKeypointList(int num, const SiftGPU::SiftKeypoint * keys, int keys_have_orientation) -{ - if(!_connected) return; - - SocketUtil::writeint(_socketfd, COMMAND_SET_KEYPOINT); - SocketUtil::writeint(_socketfd, num); - SocketUtil::writeint(_socketfd, keys_have_orientation); - SocketUtil::writedata(_socketfd, keys, sizeof(SiftGPU::SiftKeypoint) * num); - -} - -void ServerSiftGPU::SetTightPyramid(int tight) -{ - if(!_connected) return ; - SocketUtil::writeint(_socketfd, COMMAND_SET_TIGHTPYRAMID); - SocketUtil::writeint(_socketfd, tight); - -} - -void ServerSiftGPU::SetMaxDimension(int sz) -{ - if(!_connected) return ; - SocketUtil::writeint(_socketfd, COMMAND_SET_MAX_DIMENSION); - SocketUtil::writeint(_socketfd, sz); - -} - -int ServerSiftGPU::GetPixelSizeGL(unsigned int gl_format, unsigned int gl_type) -{ - int num_channel_byte = 0; - int num_channels = 0; - switch(gl_type) - { - case GL_BITMAP: - case GL_UNSIGNED_BYTE: - case GL_BYTE: - num_channel_byte = 1; - break; - case GL_UNSIGNED_SHORT: - case GL_SHORT: - num_channel_byte = 2; - break; - case GL_UNSIGNED_INT: - case GL_INT: - case GL_FLOAT: - num_channel_byte = 4; - break; - default: - num_channel_byte = 0; - break; - } - - switch(gl_format) - { - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - num_channels = 1; - break; - case GL_RGB: - case GL_BGR_EXT: - num_channels = 3; - break; - case GL_RGBA: - case GL_BGRA_EXT: -#ifdef GL_ARGB_I3D - case GL_ARGB_I3D: -#endif - num_channels = 4; - break; - case GL_LUMINANCE_ALPHA: -#ifdef GL_422_EXT - case GL_422_EXT: - case GL_422_REV_EXT: - case GL_422_AVERAGE_EXT: - case GL_422_REV_AVERAGE_EXT: -#endif - num_channels = 2; - default: - num_channels = 0; - break; - } - return num_channels * num_channel_byte; -} - -int ServerSiftGPU::RunSIFT(int width, int height, const void * data, unsigned int gl_format, unsigned int gl_type) -{ - if(width <=0 || height <= 0 || data == NULL || !_connected) return 0; - int num_bytes = GetPixelSizeGL(gl_format , gl_type) * width * height; - if(num_bytes == 0) return 0; - SocketUtil::writeint(_socketfd, COMMAND_RUNSIFT_DATA); - unsigned int data_des[5] = {width, height, gl_format, gl_type, num_bytes}; - SocketUtil::writedata(_socketfd, data_des, 5 * sizeof(unsigned int)); - SocketUtil::writedata(_socketfd, data, num_bytes); - int result = 0; - return SocketUtil::readint(_socketfd, &result) && result; -} - -int ServerSiftGPU::RunSIFT(int num, const SiftGPU::SiftKeypoint * keys, int keys_have_orientation) -{ - if(num <= 0 || keys == NULL) return 0; - if(!_connected) return 0; - SocketUtil::writeint(_socketfd, COMMAND_RUNSIFT_KEY); - SocketUtil::writeint(_socketfd, num); - SocketUtil::writeint(_socketfd, keys_have_orientation); - SocketUtil::writedata(_socketfd, keys, sizeof(SiftGPU::SiftKeypoint) * num); - int result = 0; - return SocketUtil::readint(_socketfd, &result) && result; -} - -int ServerSiftGPU::RunSIFT() -{ - if(!_connected) return 0; - int result = 0; - SocketUtil::writeint(_socketfd, COMMAND_RUNSIFT); - return SocketUtil::readint(_socketfd, &result) && result; -} - -int ServerSiftGPU::RunSIFT(const char *imgpath) -{ - if(!_connected) return 0; - int result = 0; char cret = '\n'; - SocketUtil::writeint(_socketfd, COMMAND_RUNSIFT_FILE); - SocketUtil::writedata(_socketfd, imgpath, (int)strlen(imgpath)); - SocketUtil::writedata(_socketfd, &cret, 1); - return SocketUtil::readint(_socketfd, &result) && result; -} - - -//////////////////////////////////////////////// -int ServerSiftGPU::_VerifyContextGL() -{ - if(!_connected) return 0; - int result; - if( SocketUtil::writeint(_socketfd, COMMAND_MATCH_INITIALIZE) && - SocketUtil::readint(_socketfd, &result) && result) - { - return 1; - }else - { - Disconnect(); - return 0; - } -} - -void ServerSiftGPU::SetLanguage(int gpu_language) -{ - if(!_connected) return ; - SocketUtil::writeint(_socketfd, COMMAND_MATCH_SET_LANGUAGE); - SocketUtil::writeint(_socketfd, gpu_language); -} - -void ServerSiftGPU::SetDeviceParam(int argc, char**argv) -{ - ServerSiftGPU::ParseParam(argc, argv); -} - - -void ServerSiftGPU::SetMaxSift(int max_sift) -{ - if(!_connected) return; - SocketUtil::writeint(_socketfd, COMMAND_MATCH_SET_MAXSIFT); - SocketUtil::writeint(_socketfd, max_sift); -} - -void ServerSiftGPU::SetDescriptors(int index, int num, const float* descriptors, int id) -{ - if(!_connected) return ; - int command[4] = {COMMAND_MATCH_SET_DES_FLOAT, index, num, id}; - SocketUtil::writedata(_socketfd, command, sizeof(command)); - SocketUtil::writedata(_socketfd, descriptors, sizeof(float) * 128 * num); -} - - -void ServerSiftGPU::SetDescriptors(int index, int num, const unsigned char * descriptors, int id) -{ - if(!_connected) return ; - int command[4] = {COMMAND_MATCH_SET_DES_BYTE, index, num, id}; - SocketUtil::writedata(_socketfd, command, sizeof(command)); - SocketUtil::writedata(_socketfd, descriptors, sizeof(unsigned char) * 128 * num); -} - -int ServerSiftGPU::GetSiftMatch(int max_match, int match_buffer[][2], - float distmax, float ratiomax, int mutual_best_match) -{ - if(!_connected) return 0; - int command[3] = {COMMAND_MATCH_GET_MATCH, max_match, mutual_best_match}; - float fcommand[2] = {distmax, ratiomax}; - SocketUtil::writedata(_socketfd, command, sizeof(command)); - SocketUtil::writedata(_socketfd, fcommand, sizeof(fcommand)); - int nm; SocketUtil::readint(_socketfd, &nm); - if(nm > 0) SocketUtil::readint(_socketfd, match_buffer[0], 2 * nm); - return nm; -} - -void RunServerLoop(int port, int argc, char** argv) -{ - ServerSiftGPU::ServerLoop(port, argc, argv); -} - - -ComboSiftGPU* CreateRemoteSiftGPU(int port, char* remote_server) -{ - return new ServerSiftGPU(port, remote_server); -} - - -#else - -#include "../SiftGPU/LiteWindow.h" -#include "../SiftGPU/SiftGPU.h" - -ComboSiftGPU* CreateRemoteSiftGPU(int port, char* remote_server) -{ - std::cout << "ServerSiftGPU need marcro SERVER_SIFTGPU_EANBLED.\n" - << "Use local SiftGPU/SiftMatchGPU instead. \n"; - return new ComboSiftGPU; -} - -void RunServerLoop(int port, int argc, char** argv) -{ - std::cout << "ServerSiftGPU need marcro SERVER_SIFTGPU_EANBLED.\n" - } - -#endif - diff --git a/3rdparty/SiftGPU/src/ServerSiftGPU/ServerSiftGPU.h b/3rdparty/SiftGPU/src/ServerSiftGPU/ServerSiftGPU.h deleted file mode 100644 index b0a28b22..00000000 --- a/3rdparty/SiftGPU/src/ServerSiftGPU/ServerSiftGPU.h +++ /dev/null @@ -1,159 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ServerSiftGPu.h -// Author: Changchang Wu -// Description : interface for the ServerSiftGPU class. -// It starts a SiftGPU server in a new process -// or connects to an existing server. -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#ifndef GPU_SIFT_SERVER_H -#define GPU_SIFT_SERVER_H - - -class ComboSiftGPU; -class LiteWindow; - -///////////////////////////////////////////////////////////////////////////// -//ServerSiftGPU::ServerSiftGPU(int port, char* remote_server) -//Run SiftGPU/SiftMatchGPU computation on a remote computer/process -//if( remote_server == NULL) -// a local server is created in a different process and connects to it -// multiple-GPU can be used by creating multiple instances -// GPU selection done through ParseParam function -//otherwise, -// Assumes the existenc of a remote server and connects to it -// GPU selection is done on the server-end when create the server by running -// server_siftgpu -server port [siftgpu_param] -///////////////////////////////////////////////////////////////////////////// - - -class ServerSiftGPU: public ComboSiftGPU -{ - enum - { - COMMAND_NONE= 0, - COMMAND_EXIT= 1, - COMMAND_DISCONNECT, - /////////////////////////////// - COMMAND_INITIALIZE, - COMMAND_ALLOCATE_PYRAMID, - COMMAND_RUNSIFT, - COMMAND_RUNSIFT_FILE, - COMMAND_RUNSIFT_KEY, - COMMAND_RUNSIFT_DATA, - COMMAND_SAVE_SIFT, - COMMAND_SET_MAX_DIMENSION, - COMMAND_SET_KEYPOINT, - COMMAND_GET_FEATURE_COUNT, - COMMAND_SET_TIGHTPYRAMID, - COMMAND_GET_KEY_VECTOR, - COMMAND_GET_DES_VECTOR, - COMMAND_PARSE_PARAM, - - ///////////////////////////////// - COMMAND_MATCH_INITIALIZE, - COMMAND_MATCH_SET_LANGUAGE, - COMMAND_MATCH_SET_DES_FLOAT, - COMMAND_MATCH_SET_DES_BYTE, - COMMAND_MATCH_SET_MAXSIFT, - COMMAND_MATCH_GET_MATCH, - /////////////////////////////// - DEFAULT_PORT = 7777 - }; -private: -#ifdef _WIN64 - unsigned __int64 _socketfd; -#else - int _socketfd; -#endif - int _port; - int _connected; - char _server_name[1024]; -private: - void SetParamSiftGPU(int argc, char** argv); - int InitializeConnection(int argc, char** argv); - int StartServerProcess(int argc, char** argv); - int ConnectServer(const char* server_name, int port); - void Disconnect(); - static int InitSocket(); - static int GetPixelSizeGL(unsigned int gl_format, unsigned int gl_type); - static void ServerLoop(int port, int argc, char** argv); -public: - //two options : multi-threading or multi-processing - SIFTGPU_EXPORT ServerSiftGPU(int port = DEFAULT_PORT, char* remote_server = NULL); - virtual ~ServerSiftGPU(); - //////////////////////////////////////// - virtual void ParseParam(int argc, char **argv); - virtual int VerifyContextGL(); - //////////////////////////////////////////////////////////////////////// - //available SiftGPU functions are the following: - virtual int RunSIFT(const char * imgpath); - virtual int RunSIFT(); - //note the difference with class SiftGPU for the function below, - //you have to provide the number of bytes of the data. - virtual int RunSIFT(int width, int height, const void * data, unsigned int gl_format, unsigned int gl_type); - virtual int RunSIFT(int num, const SiftGPU::SiftKeypoint * keys, int keys_have_orientation = 1); - virtual int AllocatePyramid(int width, int height); - ///////////////////////////////////////////////////////////////////// - virtual int GetFeatureNum(); - virtual void SetTightPyramid(int tight = 1); - virtual void SetMaxDimension(int sz); - virtual void GetFeatureVector(SiftGPU::SiftKeypoint * keys, float * descriptors); - virtual void SetKeypointList(int num, const SiftGPU::SiftKeypoint * keys, int keys_have_orientation = 1); - ///////////////////////////////////////////////////////////////////////////// - //the following functions do not block in multi-process mode - //for example, SaveSIFT will return before the file is written - virtual void SaveSIFT(const char * szFileName); - - //simplified functions - int GetImageCount(){return 1;} - int CreateContextGL(){return VerifyContextGL();} - int IsFullSupported(){return VerifyContextGL() == SiftGPU::SIFTGPU_FULL_SUPPORTED;} - int RunSIFT(int index) {return RunSIFT();} - -//////////////////////// -public: - virtual int _CreateContextGL() {return _VerifyContextGL();} - virtual int _VerifyContextGL(); - virtual void SetLanguage(int gpu_language); - virtual void SetDeviceParam(int argc, char**argv); - virtual void SetMaxSift(int max_sift); - virtual void SetDescriptors(int index, int num, const float* descriptors, int id = -1); - virtual void SetDescriptors(int index, int num, const unsigned char * descriptors, int id = -1); - virtual int GetSiftMatch(int max_match, int match_buffer[][2], //buffeture indices - float distmax, float ratiomax, int mutual_best_match); // -public: - ////////////////////////////////////////////////////// - //Some SiftGPU functions are not supported - void SetImageList(int nimage, const char** filelist) {} - void SetVerbose(){} - - ///Guided matching is not supported here, not hard to implement yourself - virtual void SetFeautreLocation(int index, const float* locations, int gap) {return ;} - virtual int GetGuidedSiftMatch(int max_match, int match_buffer[][2], float H[3][3],float F[3][3], - float distmax, float ratiomax, float hdistmax, float fdistmax, int mutual_best_match) {return 0; } - - friend void RunServerLoop(int port, int argc, char** argv); - -}; - - - -#endif - - diff --git a/3rdparty/SiftGPU/src/ServerSiftGPU/server.cpp b/3rdparty/SiftGPU/src/ServerSiftGPU/server.cpp deleted file mode 100644 index c0f0e240..00000000 --- a/3rdparty/SiftGPU/src/ServerSiftGPU/server.cpp +++ /dev/null @@ -1,119 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: server.cpp -// Author: Changchang Wu -// Description : driver of a SiftGPU Server. -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// -#include -#include -#include -using std::cout; - -#include "../SiftGPU/SiftGPU.h" - -//if you included ServerSiftGPU.h here. -//CreateRemoteSiftGPU can be replaced by new ServerSiftGPU(); - -int main(int argc, char** argv) -{ - - if(argc >= 2 && strcmp(argv[1], "-server") == 0) - { - //run siftgpu server - std::cout << "Starting server process...\n"; - int port = 7777; - if(argc >= 3) sscanf(argv[2], "%d", &port); - ////////////////////////////////////// - RunServerLoop(port, argc - 3, argv + 3); - }else if(argc >=2 && strcmp(argv[1], "-test") == 0) - { - //start server on same computer and connect... - //note we are using a SiftGPU pointer.. - SiftGPU* siftgpu = CreateRemoteSiftGPU(); - siftgpu->ParseParam(argc - 2, argv + 2); - if(siftgpu->VerifyContextGL()) - { - //files on the matchines where the server runs - siftgpu->RunSIFT("../data/800-1.jpg"); - siftgpu->RunSIFT("../data/800-2.jpg"); - } - delete siftgpu; //this will terminate the server - }else if(argc >=4 && strcmp(argv[1], "-test_remote") == 0) - { - ////test client that connects to remote server... - char server_name[1024]; int port = 7777; - strcpy(server_name, argv[2]); - sscanf(argv[3], "%d", &port); - SiftGPU* siftgpu = CreateRemoteSiftGPU(port, server_name);//new ServerSiftGPU(port, server_name); - siftgpu->ParseParam(argc - 4, argv + 4); - if(siftgpu->VerifyContextGL()) - { - //files on the matchines where the server runs - siftgpu->RunSIFT("../data/800-1.jpg"); - siftgpu->RunSIFT("../data/800-2.jpg"); - } - delete siftgpu; - }else if(argc >=2 && strcmp(argv[1], "-test2") == 0) - { - //test using two siftgpu servers...usage: - //server_siftgpu -test2 [server1_params] [-server2 [server2_params]] - - //////////////////////////////////////////// - //they need to use different ports. - SiftGPU* siftgpu1 = CreateRemoteSiftGPU(7777);//new ServerSiftGPU(7777); - SiftGPU* siftgpu2 = CreateRemoteSiftGPU(8888);//new ServerSiftGPU(8888); - - //split the parameters for the two servers - int argc1 = 0, argc2 = 0; - char** argv1 = argv + 2, **argv2 = 0; - while(argc1 + 2 < argc && strcmp(argv[argc1 + 2], "-server2")) - { - argc1++; - } - if(argc1 + 3 < argc && strcmp(argv[argc1 + 2], "-server2") == 0) - { - argv2 = argv + argc1 + 3; - argc2 = argc - argc1 - 3; - } - - //initialize the two servers with their siftgpu parameters - siftgpu1->ParseParam(argc1, argv1); - siftgpu2->ParseParam(argc2, argv2); - if(siftgpu1->VerifyContextGL() && siftgpu2->VerifyContextGL()) - { - siftgpu1->RunSIFT("../data/800-1.jpg"); - siftgpu2->RunSIFT("../data/800-1.jpg"); - siftgpu1->RunSIFT("../data/800-2.jpg"); - siftgpu2->RunSIFT("../data/800-2.jpg"); - } - delete siftgpu1; - delete siftgpu2; - }else - { - std::cout - <<"try -test [siftgpu_param] to create a local server and a client\n" - <<"try -test2 [siftgpu_param1] [-server2 [siftgpu_param2]]\n" - <<" to create two servers and two clients\n" - <<"try -test_remote remote_sever_name remote_server_port\n" - <<" to create a client and connect to remote server\n" - <<"use -server port [siftgpu_param] to start a server\n" - <<"Note [siftgpu_param] allows you to select GPU from multi-GPUs\n" - <<"\n"; - } - return 1; -} - diff --git a/3rdparty/SiftGPU/src/SiftGPU/CLTexImage.cpp b/3rdparty/SiftGPU/src/SiftGPU/CLTexImage.cpp deleted file mode 100644 index a796721f..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/CLTexImage.cpp +++ /dev/null @@ -1,229 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: CLTexImage.cpp -// Author: Changchang Wu -// Description : implementation of the CLTexImage class. -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if defined(CL_SIFTGPU_ENABLED) - -#include "GL/glew.h" -#include -#include -#include -#include -#include -using namespace std; - - -#include -#include "CLTexImage.h" -#include "ProgramCL.h" -#include "GlobalUtil.h" - - -CLTexImage::CLTexImage() -{ - _context = NULL; - _queue = NULL; - _clData = NULL; - _numChannel = _bufferLen = _fromGL = 0; - _imgWidth = _imgHeight = _texWidth = _texHeight = 0; -} - -CLTexImage::CLTexImage(cl_context context, cl_command_queue queue) -{ - _context = context; - _queue = queue; - _clData = NULL; - _numChannel = _bufferLen = _fromGL = 0; - _imgWidth = _imgHeight = _texWidth = _texHeight = 0; -} - -void CLTexImage::SetContext(cl_context context, cl_command_queue queue) -{ - _context = context; - _queue = queue; -} - - -CLTexImage::~CLTexImage() -{ - ReleaseTexture(); -} - -void CLTexImage::ReleaseTexture() -{ - if(_fromGL) clEnqueueReleaseGLObjects(_queue, 1, &_clData, 0, NULL, NULL); - if(_clData) clReleaseMemObject(_clData); -} - -void CLTexImage::SetImageSize(int width, int height) -{ - _imgWidth = width; - _imgHeight = height; -} - -void CLTexImage::InitBufferTex(int width, int height, int nchannel) -{ - if(width == 0 || height == 0 || nchannel <= 0 || _fromGL) return; - - _imgWidth = width; _imgHeight = height; - _texWidth = _texHeight = _fromGL = 0; - _numChannel = min(nchannel, 4); - - int size = width * height * _numChannel * sizeof(float); - if (size <= _bufferLen) return; - - //allocate the buffer data - cl_int status; - if(_clData) status = clReleaseMemObject(_clData); - - _clData = clCreateBuffer(_context, CL_MEM_READ_WRITE, - _bufferLen = size, NULL, &status); - - ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitBufferTex"); - -} - -void CLTexImage::InitTexture(int width, int height, int nchannel) -{ - if(width == 0 || height == 0 || nchannel <= 0 || _fromGL) return; - if(_clData && width == _texWidth && height == _texHeight && _numChannel == nchannel) return; - if(_clData) clReleaseMemObject(_clData); - - _texWidth = _imgWidth = width; - _texHeight = _imgHeight = height; - _numChannel = nchannel; - _bufferLen = _fromGL = 0; - - cl_int status; cl_image_format format; - - if(nchannel == 1) format.image_channel_order = CL_R; - else if(nchannel == 2) format.image_channel_order = CL_RG; - else if(nchannel == 3) format.image_channel_order = CL_RGB; - else format.image_channel_order = CL_RGBA; - - format.image_channel_data_type = CL_FLOAT; - _clData = clCreateImage2D(_context, CL_MEM_READ_WRITE, & format, - _texWidth, _texHeight, 0, 0, &status); - ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTexture"); -} - -void CLTexImage::InitPackedTex(int width, int height, int packed) -{ - if(packed) InitTexture((width + 1) >> 1, (height + 1) >> 1, 4); - else InitTexture(width, height, 1); -} - -void CLTexImage::SetPackedSize(int width, int height, int packed) -{ - if(packed) SetImageSize((width + 1) >> 1, (height + 1) >> 1); - else SetImageSize(width, height); -} - -void CLTexImage::InitTextureGL(GLuint tex, int width, int height, int nchannel) -{ - if(tex == 0) return; - if(_clData) clReleaseMemObject(_clData); - - ////create the memory object - cl_int status; - _clData = clCreateFromGLTexture2D(_context, CL_MEM_WRITE_ONLY, - GlobalUtil::_texTarget, 0 , tex, &status); - ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTextureGL->clCreateFromGLTexture2D"); - if(status != CL_SUCCESS) return; - - _texWidth = _imgWidth = width; - _texHeight = _imgHeight = height; - _numChannel = nchannel; - _bufferLen = 0; _fromGL = 1; - - ////acquire object - status = clEnqueueAcquireGLObjects(_queue, 1, &_clData, 0, NULL, NULL); - ProgramBagCL::CheckErrorCL(status, "CLTexImage::InitTextureGL->clEnqueueAcquireGLObjects"); - -} - -void CLTexImage::CopyFromHost(const void * buf) -{ - if(_clData == NULL) return; - cl_int status; - if(_bufferLen) - { - status = clEnqueueWriteBuffer(_queue, _clData, false, 0, - _imgWidth * _imgHeight * _numChannel * sizeof(float), buf, 0, NULL, NULL); - }else - { - size_t origin[3] = {0, 0, 0}, region[3] = {_imgWidth, _imgHeight, 1}; - size_t row_pitch = _imgWidth * _numChannel * sizeof(float); - status = clEnqueueWriteImage(_queue, _clData, false, origin, - region, row_pitch, 0, buf, 0, 0, 0); - } - ProgramBagCL::CheckErrorCL(status, "CLTexImage::CopyFromHost"); -} - -int CLTexImage::GetImageDataSize() -{ - return _imgWidth * _imgHeight * _numChannel * sizeof(float); -} - -int CLTexImage::CopyToPBO(GLuint pbo) -{ - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); - - int esize = GetImageDataSize(), bsize; - glGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - if(bsize < esize) - { - glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, esize, NULL, GL_STATIC_DRAW_ARB); - glGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - } - if(bsize >= esize) - { - // map the buffer object into client's memory - void* ptr = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); - CopyToHost(ptr); - clFinish(_queue); - glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); - } - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); - GlobalUtil::CheckErrorsGL("CLTexImage::CopyToPBO"); - return esize >= bsize; -} - -void CLTexImage::CopyToHost(void * buf) -{ - if(_clData == NULL) return; - cl_int status; - if(_bufferLen) - { - status = clEnqueueReadBuffer(_queue, _clData, true, 0, - _imgWidth * _imgHeight * _numChannel * sizeof(float), buf, 0, NULL, NULL); - }else - { - size_t origin[3] = {0, 0, 0}, region[3] = {_imgWidth, _imgHeight, 1}; - size_t row_pitch = _imgWidth * _numChannel * sizeof(float); - status = clEnqueueReadImage(_queue, _clData, true, origin, - region, row_pitch, 0, buf, 0, 0, 0); - } - - ProgramBagCL::CheckErrorCL(status, "CLTexImage::CopyToHost"); -} - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/CLTexImage.h b/3rdparty/SiftGPU/src/SiftGPU/CLTexImage.h deleted file mode 100644 index 2897cbc8..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/CLTexImage.h +++ /dev/null @@ -1,83 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: CLTexImage.h -// Author: Changchang Wu -// Description : interface for the CLTexImage class. -// class for storing data in CUDA. -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// -#if defined(CL_SIFTGPU_ENABLED) - -#ifndef CL_TEX_IMAGE_H -#define CL_TEX_IMAGE_H - -class GLTexImage; - -class CLTexImage -{ -protected: - cl_context _context; - cl_command_queue _queue; - cl_mem _clData; - int _numChannel; - int _imgWidth; - int _imgHeight; - int _texWidth; - int _texHeight; - int _bufferLen; - int _fromGL; -private: - void ReleaseTexture(); -public: - void SetImageSize(int width, int height); - void SetPackedSize(int width, int height, int packed); - void InitBufferTex(int width, int height, int nchannel); - void InitTexture(int width, int height, int nchannel); - void InitPackedTex(int width, int height, int packed); - void InitTextureGL(GLuint tex, int width, int height, int nchannel); - void CopyToHost(void* buf); - void CopyFromHost(const void* buf); -public: - int CopyToPBO(GLuint pbo); - int GetImageDataSize(); -public: - inline operator cl_mem(){return _clData; } - inline int GetImgWidth(){return _imgWidth;} - inline int GetImgHeight(){return _imgHeight;} - inline int GetTexWidth(){return _texWidth;} - inline int GetTexHeight(){return _texHeight;} - inline int GetDataSize(){return _bufferLen;} - inline bool IsImage2D() {return _bufferLen == 0;} - inline int GetImgPixelCount(){return _imgWidth*_imgHeight;} - inline int GetTexPixelCount(){return _texWidth*_texHeight;} -public: - CLTexImage(); - CLTexImage(cl_context context, cl_command_queue queue); - void SetContext(cl_context context, cl_command_queue queue); - virtual ~CLTexImage(); - friend class ProgramCL; - friend class PyramidCL; - friend class ProgramBagCL; - friend class ProgramBagCLN; -}; - -////////////////////////////////////////////////// -//transfer OpenGL Texture to PBO, then to CUDA vector -//#endif -#endif // !defined(CU_TEX_IMAGE_H) -#endif - - diff --git a/3rdparty/SiftGPU/src/SiftGPU/CMakeLists.txt b/3rdparty/SiftGPU/src/SiftGPU/CMakeLists.txt deleted file mode 100644 index e280fe72..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -find_package(OpenGL REQUIRED) -find_package(GLUT REQUIRED) -find_package(GLEW) - -OPTION(SIFTGPU_ENABLE_SERVER FALSE) -SET(SIFTGPU_ENABLE_OPENCL FALSE) -SET(SIFTGPU_ENABLE_CUDA TRUE) -SET(SIFTGPU_ENABLE_SSE TRUE) -SET(SIFTGPU_SSE_OPTIONS -march=core2 -mfpmath=sse) -SET(SIFTGPU_PREFER_GLUT TRUE) -SET(SIFTGPU_DISABLE_DEVIL TRUE) - -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -Wno-deprecated" ) - -IF(SIFTGPU_ENABLE_SSE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=core2 -mfpmath=sse" ) -ENDIF(SIFTGPU_ENABLE_SSE) - -IF(SIFTGPU_PREFER_GLUT) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINDOW_PREFER_GLUT" ) -ENDIF(SIFTGPU_PREFER_GLUT) - -IF(SIFTGPU_ENABLE_OPENCL) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCL_SIFTGPU_ENABLED" ) -ENDIF(SIFTGPU_ENABLE_OPENCL) - -IF(APPLE) - SET(LIBS_SIFTGPU ) -ELSE(APPLE) - SET(LIBS_SIFTGPU glut GL X11 ) -ENDIF(APPLE) - -IF(SIFTGPU_DISABLE_DEVIL) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSIFTGPU_NO_DEVIL" ) -ELSE(SIFTGPU_DISABLE_DEVIL) - SET(LIBS_SIFTGPU ${LIBS_SIFTGPU} IL ) -ENDIF(SIFTGPU_DISABLE_DEVIL) - -if (GLEW_FOUND) - include_directories( ${GLEW_INCLUDE_DIRS} ) - SET (GLEW_LIBRARIES GLEW) -endif (GLEW_FOUND) - -ADD_LIBRARY(siftgpu STATIC FrameBufferObject.cpp GlobalUtil.cpp GLTexImage.cpp ProgramGLSL.cpp - ProgramGPU.cpp ShaderMan.cpp SiftGPU.cpp SiftPyramid.cpp PyramidGL.cpp SiftMatch.cpp) - -TARGET_LINK_LIBRARIES(siftgpu ${LIBS_SIFTGPU} ${GLEW_LIBRARIES} ${GLUT_LIBRARIES} ${OPENGL_LIBRARIES} ) - -INSTALL(FILES SiftGPU.h DESTINATION include) -INSTALL(TARGETS siftgpu DESTINATION lib ) diff --git a/3rdparty/SiftGPU/src/SiftGPU/CuTexImage.cpp b/3rdparty/SiftGPU/src/SiftGPU/CuTexImage.cpp deleted file mode 100644 index c8feeb74..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/CuTexImage.cpp +++ /dev/null @@ -1,259 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: CuTexImage.cpp -// Author: Changchang Wu -// Description : implementation of the CuTexImage class. -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if defined(CUDA_SIFTGPU_ENABLED) - -#include "GL/glew.h" -#include -#include -#include -#include -#include -using namespace std; - - -#include -#include -#include - -#include "GlobalUtil.h" -#include "GLTexImage.h" -#include "CuTexImage.h" -#include "ProgramCU.h" - -#if CUDA_VERSION <= 2010 && defined(SIFTGPU_ENABLE_LINEAR_TEX2D) -#error "Require CUDA 2.2 or higher" -#endif - - -CuTexImage::CuTexImage() -{ - _cuData = NULL; - _cuData2D = NULL; - _fromPBO = 0; - _numChannel = _numBytes = 0; - _imgWidth = _imgHeight = _texWidth = _texHeight = 0; -} - -CuTexImage::CuTexImage(int width, int height, int nchannel, GLuint pbo) -{ - _cuData = NULL; - - //check size of pbo - GLint bsize, esize = width * height * nchannel * sizeof(float); - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - if(bsize < esize) - { - glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize, NULL, GL_STATIC_DRAW_ARB); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); - if(bsize >=esize) - { - - cudaGLRegisterBufferObject(pbo); - cudaGLMapBufferObject(&_cuData, pbo); - ProgramCU::CheckErrorCUDA("cudaGLMapBufferObject"); - _fromPBO = pbo; - }else - { - _cuData = NULL; - _fromPBO = 0; - } - if(_cuData) - { - _numBytes = bsize; - _imgWidth = width; - _imgHeight = height; - _numChannel = nchannel; - }else - { - _numBytes = 0; - _imgWidth = 0; - _imgHeight = 0; - _numChannel = 0; - } - - _texWidth = _texHeight =0; - - _cuData2D = NULL; -} - -CuTexImage::~CuTexImage() -{ - - - if(_fromPBO) - { - cudaGLUnmapBufferObject(_fromPBO); - cudaGLUnregisterBufferObject(_fromPBO); - }else if(_cuData) - { - cudaFree(_cuData); - } - if(_cuData2D) cudaFreeArray(_cuData2D); -} - -void CuTexImage::SetImageSize(int width, int height) -{ - _imgWidth = width; - _imgHeight = height; -} - -void CuTexImage::InitTexture(int width, int height, int nchannel) -{ - int size; - _imgWidth = width; - _imgHeight = height; - _numChannel = min(max(nchannel, 1), 4); - - size = width * height * _numChannel * sizeof(float); - - if(size <= _numBytes) return; - - if(_cuData) cudaFree(_cuData); - - //allocate the array data - cudaMalloc(&_cuData, _numBytes = size); - -#ifdef _DEBUG - ProgramCU::CheckErrorCUDA("CuTexImage::InitTexture"); -#endif -} - -void CuTexImage::CopyFromHost(const void * buf) -{ - if(_cuData == NULL) return; - cudaMemcpy( _cuData, buf, _imgWidth * _imgHeight * _numChannel * sizeof(float), cudaMemcpyHostToDevice); -} - -void CuTexImage::CopyToHost(void * buf) -{ - if(_cuData == NULL) return; - cudaMemcpy(buf, _cuData, _imgWidth * _imgHeight * _numChannel * sizeof(float), cudaMemcpyDeviceToHost); -} - -void CuTexImage::CopyToHost(void * buf, int stream) -{ - if(_cuData == NULL) return; - cudaMemcpyAsync(buf, _cuData, _imgWidth * _imgHeight * _numChannel * sizeof(float), cudaMemcpyDeviceToHost, (cudaStream_t)stream); -} - -void CuTexImage::InitTexture2D() -{ -#if !defined(SIFTGPU_ENABLE_LINEAR_TEX2D) - if(_cuData2D && (_texWidth < _imgWidth || _texHeight < _imgHeight)) - { - cudaFreeArray(_cuData2D); - _cuData2D = NULL; - } - - if(_cuData2D == NULL) - { - _texWidth = max(_texWidth, _imgWidth); - _texHeight = max(_texHeight, _imgHeight); - cudaChannelFormatDesc desc; - desc.f = cudaChannelFormatKindFloat; - desc.x = sizeof(float) * 8; - desc.y = _numChannel >=2 ? sizeof(float) * 8 : 0; - desc.z = _numChannel >=3 ? sizeof(float) * 8 : 0; - desc.w = _numChannel >=4 ? sizeof(float) * 8 : 0; - cudaMallocArray(&_cuData2D, &desc, _texWidth, _texHeight); - ProgramCU::CheckErrorCUDA("cudaMallocArray"); - } -#endif -} - -void CuTexImage::CopyToTexture2D() -{ -#if !defined(SIFTGPU_ENABLE_LINEAR_TEX2D) - InitTexture2D(); - - if(_cuData2D) - { - cudaMemcpy2DToArray(_cuData2D, 0, 0, _cuData, _imgWidth* _numChannel* sizeof(float) , - _imgWidth * _numChannel*sizeof(float), _imgHeight, cudaMemcpyDeviceToDevice); - ProgramCU::CheckErrorCUDA("cudaMemcpy2DToArray"); - } -#endif - -} - -int CuTexImage::DebugCopyToTexture2D() -{ - -/* CuTexImage tex; - float data1[2][3] = {{1, 2, 5}, {3, 4, 5}}, data2[2][5]; - tex.InitTexture(3, 2, 1); - cudaMemcpy(tex._cuData, data1[0], 6 * sizeof(float), cudaMemcpyHostToDevice); - cudaMemcpy(data1, tex._cuData, 4 * sizeof(float) , cudaMemcpyDeviceToHost); - tex._texWidth =5; tex._texHeight = 2; - tex.CopyToTexture2D(); - cudaMemcpyFromArray(data2[0], tex._cuData2D, 0, 0, 10 * sizeof(float), cudaMemcpyDeviceToHost);*/ - - return 1; -} - - - -void CuTexImage::CopyFromPBO(int width, int height, GLuint pbo) -{ - void* pbuf =NULL; - GLint esize = width * height * sizeof(float); - cudaGLRegisterBufferObject(pbo); - cudaGLMapBufferObject(&pbuf, pbo); - - cudaMemcpy(_cuData, pbuf, esize, cudaMemcpyDeviceToDevice); - - cudaGLUnmapBufferObject(pbo); - cudaGLUnregisterBufferObject(pbo); -} - -int CuTexImage::CopyToPBO(GLuint pbo) -{ - void* pbuf =NULL; - GLint bsize, esize = _imgWidth * _imgHeight * sizeof(float) * _numChannel; - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - if(bsize < esize) - { - glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize*3/2, NULL, GL_STATIC_DRAW_ARB); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); - - if(bsize >= esize) - { - cudaGLRegisterBufferObject(pbo); - cudaGLMapBufferObject(&pbuf, pbo); - cudaMemcpy(pbuf, _cuData, esize, cudaMemcpyDeviceToDevice); - cudaGLUnmapBufferObject(pbo); - cudaGLUnregisterBufferObject(pbo); - return 1; - }else - { - return 0; - } -} - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/CuTexImage.h b/3rdparty/SiftGPU/src/SiftGPU/CuTexImage.h deleted file mode 100644 index 6785c8d7..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/CuTexImage.h +++ /dev/null @@ -1,76 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: CuTexImage.h -// Author: Changchang Wu -// Description : interface for the CuTexImage class. -// class for storing data in CUDA. -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#ifndef CU_TEX_IMAGE_H -#define CU_TEX_IMAGE_H - -class GLTexImage; -struct cudaArray; -struct textureReference; - -//using texture2D from linear memory - -#define SIFTGPU_ENABLE_LINEAR_TEX2D - -class CuTexImage -{ -protected: - void* _cuData; - cudaArray* _cuData2D; - int _numChannel; - int _numBytes; - int _imgWidth; - int _imgHeight; - int _texWidth; - int _texHeight; - GLuint _fromPBO; -public: - virtual void SetImageSize(int width, int height); - virtual void InitTexture(int width, int height, int nchannel = 1); - void InitTexture2D(); - inline void BindTexture(textureReference& texRef); - inline void BindTexture2D(textureReference& texRef); - void CopyToTexture2D(); - void CopyToHost(void* buf); - void CopyToHost(void* buf, int stream); - void CopyFromHost(const void* buf); - int CopyToPBO(GLuint pbo); - void CopyFromPBO(int width, int height, GLuint pbo); - static int DebugCopyToTexture2D(); -public: - inline int GetImgWidth(){return _imgWidth;} - inline int GetImgHeight(){return _imgHeight;} - inline int GetDataSize(){return _numBytes;} -public: - CuTexImage(); - CuTexImage(int width, int height, int nchannel, GLuint pbo); - virtual ~CuTexImage(); - friend class ProgramCU; - friend class PyramidCU; -}; - -////////////////////////////////////////////////// -//transfer OpenGL Texture to PBO, then to CUDA vector -//#endif -#endif // !defined(CU_TEX_IMAGE_H) - diff --git a/3rdparty/SiftGPU/src/SiftGPU/FrameBufferObject.cpp b/3rdparty/SiftGPU/src/SiftGPU/FrameBufferObject.cpp deleted file mode 100644 index b586d9b0..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/FrameBufferObject.cpp +++ /dev/null @@ -1,105 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: FrameBufferObject.cpp -// Author: Changchang Wu -// Description : Implementation of FrameBufferObject Class -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include "GL/glew.h" -#include -#include "GlobalUtil.h" -#include "FrameBufferObject.h" - -//whether use only one FBO globally -int FrameBufferObject::UseSingleFBO=1; -GLuint FrameBufferObject::GlobalFBO=0; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -FrameBufferObject::FrameBufferObject(int autobind) -{ - if(UseSingleFBO && GlobalFBO) - { - _fboID = GlobalFBO; - }else - { - glGenFramebuffersEXT(1, &_fboID); - if(UseSingleFBO )GlobalFBO = _fboID; - } - if(autobind ) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fboID); -} - -FrameBufferObject::~FrameBufferObject() -{ - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - if(!UseSingleFBO ) - { - glDeleteFramebuffersEXT (1,&_fboID); - } -} - -void FrameBufferObject::DeleteGlobalFBO() -{ - if(UseSingleFBO) - { - glDeleteFramebuffersEXT (1,&GlobalFBO); - GlobalFBO = 0; - } -} - -void FrameBufferObject::AttachDepthTexture(GLenum textureTarget, GLuint texID) -{ - - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, textureTarget, texID, 0); -} - -void FrameBufferObject::AttachTexture(GLenum textureTarget, GLenum attachment, GLuint texId) -{ - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachment, textureTarget, texId, 0); -} - -void FrameBufferObject::BindFBO() -{ - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fboID); -} - -void FrameBufferObject::UnbindFBO() -{ - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -} - -void FrameBufferObject::UnattachTex(GLenum attachment) -{ - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, 0, 0 ); -} - -void FrameBufferObject::AttachRenderBuffer(GLenum attachment, GLuint buffID) -{ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, buffID); - -} - -void FrameBufferObject:: UnattachRenderBuffer(GLenum attachment) -{ - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, 0); -} - diff --git a/3rdparty/SiftGPU/src/SiftGPU/FrameBufferObject.h b/3rdparty/SiftGPU/src/SiftGPU/FrameBufferObject.h deleted file mode 100644 index e4cc5263..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/FrameBufferObject.h +++ /dev/null @@ -1,49 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: FrameBufferObject.h -// Author: Changchang Wu -// Description : interface for the FrameBufferObject class. -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#if !defined(_FRAME_BUFFER_OBJECT_H) -#define _FRAME_BUFFER_OBJECT_H - -class FrameBufferObject -{ - static GLuint GlobalFBO; //not thread-safe - GLuint _fboID; -public: - static int UseSingleFBO; -public: - static void DeleteGlobalFBO(); - static void UnattachTex(GLenum attachment); - static void UnbindFBO(); - static void AttachDepthTexture(GLenum textureTarget, GLuint texID); - static void AttachTexture( GLenum textureTarget, GLenum attachment, GLuint texID); - static void AttachRenderBuffer(GLenum attachment, GLuint buffID ); - static void UnattachRenderBuffer(GLenum attachment); -public: - void BindFBO(); - FrameBufferObject(int autobind = 1); - ~FrameBufferObject(); - -}; - -#endif diff --git a/3rdparty/SiftGPU/src/SiftGPU/GLTexImage.cpp b/3rdparty/SiftGPU/src/SiftGPU/GLTexImage.cpp deleted file mode 100644 index a6a28098..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/GLTexImage.cpp +++ /dev/null @@ -1,1264 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: GLTexImage.cpp -// Author: Changchang Wu -// Description : implementation of the GLTexImage class. -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include "GL/glew.h" -#include -#include -#include -#include -#include -#include -#include -using namespace std; - - - -#include "GlobalUtil.h" - -#include "GLTexImage.h" -#include "FrameBufferObject.h" -#include "ShaderMan.h" - - -//#define SIFTGPU_NO_DEVIL - -#ifndef SIFTGPU_NO_DEVIL - #include "IL/il.h" - #if defined(_WIN64) - #pragma comment(lib, "../../lib/DevIL64.lib") - #elif defined(_WIN32) - #pragma comment(lib, "../../lib/DevIL.lib") - #endif -#else - #include -#endif -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - - -GLTexImage::GLTexImage() -{ - _imgWidth = _imgHeight = 0; - _texWidth = _texHeight = 0; - _drawWidth = _drawHeight = 0; - _texID = 0; - -} - -GLTexImage::~GLTexImage() -{ - if(_texID) glDeleteTextures(1, &_texID); -} - -int GLTexImage::CheckTexture() -{ - if(_texID) - { - GLint tw, th; - BindTex(); - glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_WIDTH , &tw); - glGetTexLevelParameteriv(_texTarget, 0, GL_TEXTURE_HEIGHT , &th); - UnbindTex(); - return tw == _texWidth && th == _texHeight; - }else - { - return _texWidth == 0 && _texHeight ==0; - - } -} -//set a dimension that is smaller than the actuall size -//for drawQuad -void GLTexImage::SetImageSize( int width, int height) -{ - _drawWidth = _imgWidth = width; - _drawHeight = _imgHeight = height; -} - -void GLTexImage::InitTexture( int width, int height, int clamp_to_edge) -{ - - if(_texID && width == _texWidth && height == _texHeight ) return; - if(_texID==0) glGenTextures(1, &_texID); - - _texWidth = _imgWidth = _drawWidth = width; - _texHeight = _imgHeight = _drawHeight = height; - - BindTex(); - - if(clamp_to_edge) - { - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - }else - { - //out of bound tex read returns 0?? - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - } - glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glTexImage2D(_texTarget, 0, _iTexFormat, - _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL); - CheckErrorsGL("glTexImage2D"); - - - UnbindTex(); - -} - - -void GLTexImage::InitTexture( int width, int height, int clamp_to_edge, GLuint format) -{ - - if(_texID && width == _texWidth && height == _texHeight ) return; - if(_texID==0) glGenTextures(1, &_texID); - - _texWidth = _imgWidth = _drawWidth = width; - _texHeight = _imgHeight = _drawHeight = height; - - BindTex(); - - if(clamp_to_edge) - { - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - }else - { - //out of bound tex read returns 0?? - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - } - glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glTexImage2D(_texTarget, 0, format, _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL); - - UnbindTex(); - -} -void GLTexImage::BindTex() -{ - glBindTexture(_texTarget, _texID); -} - -void GLTexImage::UnbindTex() -{ - glBindTexture(_texTarget, 0); -} - - -void GLTexImage::DrawQuad() -{ - glBegin (GL_QUADS); - glTexCoord2i ( 0 , 0 ); glVertex2i ( 0 , 0 ); - glTexCoord2i ( 0 , _drawHeight ); glVertex2i ( 0 , _drawHeight ); - glTexCoord2i ( _drawWidth , _drawHeight ); glVertex2i ( _drawWidth , _drawHeight ); - glTexCoord2i ( _drawWidth , 0 ); glVertex2i ( _drawWidth , 0 ); - glEnd (); - glFlush(); -} - -void GLTexImage::FillMargin(int marginx, int marginy) -{ - // - marginx = min(marginx, _texWidth - _imgWidth); - marginy = min(marginy, _texHeight - _imgHeight); - if(marginx >0 || marginy > 0) - { - GlobalUtil::FitViewPort(_imgWidth + marginx, _imgHeight + marginy); - AttachToFBO(0); - BindTex(); - ShaderMan::UseShaderMarginCopy(_imgWidth, _imgHeight); - DrawMargin(_imgWidth + marginx, _imgHeight + marginy); - } -} - -void GLTexImage::ZeroHistoMargin() -{ - ZeroHistoMargin(_imgWidth, _imgHeight); -} - -void GLTexImage::ZeroHistoMargin(int width, int height) -{ - int marginx = width & 0x01; - int marginy = height & 0x01; - if(marginx >0 || marginy > 0) - { - int right = width + marginx; - int bottom = height + marginy; - GlobalUtil::FitViewPort(right, bottom); - AttachToFBO(0); - ShaderMan::UseShaderZeroPass(); - glBegin(GL_QUADS); - if(right > width && _texWidth > width) - { - glTexCoord2i ( width , 0 ); glVertex2i ( width , 0 ); - glTexCoord2i ( width , bottom ); glVertex2i ( width , bottom ); - glTexCoord2i ( right , bottom ); glVertex2i ( right , bottom ); - glTexCoord2i ( right , 0 ); glVertex2i ( right , 0 ); - } - if(bottom>height && _texHeight > height) - { - glTexCoord2i ( 0 , height ); glVertex2i ( 0 , height ); - glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom ); - glTexCoord2i ( width , bottom ); glVertex2i ( width , bottom ); - glTexCoord2i ( width , height ); glVertex2i ( width , height ); - } - glEnd(); - glFlush(); - } - -} - -void GLTexImage::DrawMargin(int right, int bottom) -{ - glBegin(GL_QUADS); - if(right > _drawWidth) - { - glTexCoord2i ( _drawWidth , 0 ); glVertex2i ( _drawWidth , 0 ); - glTexCoord2i ( _drawWidth , bottom ); glVertex2i ( _drawWidth , bottom ); - glTexCoord2i ( right , bottom ); glVertex2i ( right , bottom ); - glTexCoord2i ( right , 0 ); glVertex2i ( right , 0 ); - } - if(bottom>_drawHeight) - { - glTexCoord2i ( 0 , _drawHeight ); glVertex2i ( 0 , _drawHeight ); - glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom ); - glTexCoord2i ( _drawWidth , bottom ); glVertex2i ( _drawWidth , bottom ); - glTexCoord2i ( _drawWidth , _drawHeight ); glVertex2i ( _drawWidth , _drawHeight ); - } - glEnd(); - glFlush(); - - -} - - -void GLTexImage::DrawQuadMT4() -{ - int w = _drawWidth, h = _drawHeight; - glBegin (GL_QUADS); - glMultiTexCoord2i( GL_TEXTURE0, 0 , 0 ); - glMultiTexCoord2i( GL_TEXTURE1, -1 , 0 ); - glMultiTexCoord2i( GL_TEXTURE2, 1 , 0 ); - glMultiTexCoord2i( GL_TEXTURE3, 0 , -1 ); - glMultiTexCoord2i( GL_TEXTURE4, 0 , 1 ); - glVertex2i ( 0 , 0 ); - - glMultiTexCoord2i( GL_TEXTURE0, 0 , h ); - glMultiTexCoord2i( GL_TEXTURE1, -1 , h ); - glMultiTexCoord2i( GL_TEXTURE2, 1 , h ); - glMultiTexCoord2i( GL_TEXTURE3, 0 , h -1 ); - glMultiTexCoord2i( GL_TEXTURE4, 0 , h +1 ); - glVertex2i ( 0 , h ); - - - glMultiTexCoord2i( GL_TEXTURE0, w , h ); - glMultiTexCoord2i( GL_TEXTURE1, w-1 , h ); - glMultiTexCoord2i( GL_TEXTURE2, w+1 , h ); - glMultiTexCoord2i( GL_TEXTURE3, w , h-1 ); - glMultiTexCoord2i( GL_TEXTURE4, w , h+1 ); - glVertex2i ( w , h ); - - glMultiTexCoord2i( GL_TEXTURE0, w , 0 ); - glMultiTexCoord2i( GL_TEXTURE1, w-1 , 0 ); - glMultiTexCoord2i( GL_TEXTURE2, w+1 , 0 ); - glMultiTexCoord2i( GL_TEXTURE3, w , -1 ); - glMultiTexCoord2i( GL_TEXTURE4, w , 1 ); - glVertex2i ( w , 0 ); - glEnd (); - glFlush(); -} - - -void GLTexImage::DrawQuadMT8() -{ - int w = _drawWidth; - int h = _drawHeight; - glBegin (GL_QUADS); - glMultiTexCoord2i( GL_TEXTURE0, 0 , 0 ); - glMultiTexCoord2i( GL_TEXTURE1, -1 , 0 ); - glMultiTexCoord2i( GL_TEXTURE2, 1 , 0 ); - glMultiTexCoord2i( GL_TEXTURE3, 0 , -1 ); - glMultiTexCoord2i( GL_TEXTURE4, 0 , 1 ); - glMultiTexCoord2i( GL_TEXTURE5, -1 , -1 ); - glMultiTexCoord2i( GL_TEXTURE6, -1 , 1 ); - glMultiTexCoord2i( GL_TEXTURE7, 1 , -1 ); - glVertex2i ( 0 , 0 ); - - glMultiTexCoord2i( GL_TEXTURE0, 0 , h ); - glMultiTexCoord2i( GL_TEXTURE1, -1 , h ); - glMultiTexCoord2i( GL_TEXTURE2, 1 , h ); - glMultiTexCoord2i( GL_TEXTURE3, 0 , h -1 ); - glMultiTexCoord2i( GL_TEXTURE4, 0 , h +1 ); - glMultiTexCoord2i( GL_TEXTURE5, -1 , h -1 ); - glMultiTexCoord2i( GL_TEXTURE6, -1 , h +1 ); - glMultiTexCoord2i( GL_TEXTURE7, 1 , h -1 ); - glVertex2i ( 0 , h ); - - - glMultiTexCoord2i( GL_TEXTURE0, w , h ); - glMultiTexCoord2i( GL_TEXTURE1, w-1 , h ); - glMultiTexCoord2i( GL_TEXTURE2, w+1 , h ); - glMultiTexCoord2i( GL_TEXTURE3, w , h -1 ); - glMultiTexCoord2i( GL_TEXTURE4, w , h +1 ); - glMultiTexCoord2i( GL_TEXTURE5, w-1 , h -1 ); - glMultiTexCoord2i( GL_TEXTURE6, w-1 , h +1 ); - glMultiTexCoord2i( GL_TEXTURE7, w+1 , h -1 ); - glVertex2i ( w , h ); - - glMultiTexCoord2i( GL_TEXTURE0, w , 0 ); - glMultiTexCoord2i( GL_TEXTURE1, w-1 , 0 ); - glMultiTexCoord2i( GL_TEXTURE2, w+1 , 0 ); - glMultiTexCoord2i( GL_TEXTURE3, w , -1 ); - glMultiTexCoord2i( GL_TEXTURE4, w , 1 ); - glMultiTexCoord2i( GL_TEXTURE5, w-1 , -1 ); - glMultiTexCoord2i( GL_TEXTURE6, w-1 , 1 ); - glMultiTexCoord2i( GL_TEXTURE7, w+1 , -1 ); - glVertex2i ( w , 0 ); - glEnd (); - glFlush(); -} - - - - -void GLTexImage::DrawImage() -{ - DrawQuad(); -} - - - -void GLTexImage::FitTexViewPort() -{ - GlobalUtil::FitViewPort(_drawWidth, _drawHeight); -} - -void GLTexImage::FitRealTexViewPort() -{ - GlobalUtil::FitViewPort(_texWidth, _texHeight); -} - -void GLTexImage::AttachToFBO(int i) -{ - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, _texID, 0 ); -} - -void GLTexImage::DetachFBO(int i) -{ - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, i+GL_COLOR_ATTACHMENT0_EXT, _texTarget, 0, 0 ); -} - - -void GLTexImage::DrawQuad(float x1, float x2, float y1, float y2) -{ - - glBegin (GL_QUADS); - glTexCoord2f ( x1 , y1 ); glVertex2f ( x1 , y1 ); - glTexCoord2f ( x1 , y2 ); glVertex2f ( x1 , y2 ); - glTexCoord2f ( x2 , y2 ); glVertex2f ( x2 , y2 ); - glTexCoord2f ( x2 , y1 ); glVertex2f ( x2 , y1 ); - glEnd (); - glFlush(); -} - -void GLTexImage::TexConvertRGB() -{ - //change 3/22/09 - FrameBufferObject fbo; - //GlobalUtil::FitViewPort(1, 1); - FitTexViewPort(); - - AttachToFBO(0); - ShaderMan::UseShaderRGB2Gray(); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - DrawQuad(); - ShaderMan::UnloadProgram(); - DetachFBO(0); -} - -void GLTexImage::DrawQuadDS(int scale) -{ - DrawScaledQuad(float(scale)); -} - -void GLTexImage::DrawQuadUS(int scale) -{ - DrawScaledQuad(1.0f/scale); -} - -void GLTexImage::DrawScaledQuad(float texscale) -{ - - ////the texture coordinate for 0.5 is to + 0.5*texscale - float to = 0.5f -0.5f * texscale; - float tx = _imgWidth*texscale +to; - float ty = _imgHeight*texscale +to; - glBegin (GL_QUADS); - glTexCoord2f ( to , to ); glVertex2i ( 0 , 0 ); - glTexCoord2f ( to , ty ); glVertex2i ( 0 , _imgHeight ); - glTexCoord2f ( tx , ty ); glVertex2i ( _imgWidth , _imgHeight ); - glTexCoord2f ( tx , to ); glVertex2i ( _imgWidth , 0 ); - glEnd (); - glFlush(); -} - - -void GLTexImage::DrawQuadReduction(int w , int h) -{ - float to = -0.5f; - float tx = w*2 +to; - float ty = h*2 +to; - glBegin (GL_QUADS); - glMultiTexCoord2f ( GL_TEXTURE0, to , to ); - glMultiTexCoord2f ( GL_TEXTURE1, to +1, to ); - glMultiTexCoord2f ( GL_TEXTURE2, to , to+1 ); - glMultiTexCoord2f ( GL_TEXTURE3, to +1, to+1 ); - glVertex2i ( 0 , 0 ); - - glMultiTexCoord2f ( GL_TEXTURE0, to , ty ); - glMultiTexCoord2f ( GL_TEXTURE1, to +1, ty ); - glMultiTexCoord2f ( GL_TEXTURE2, to , ty +1 ); - glMultiTexCoord2f ( GL_TEXTURE3, to +1, ty +1 ); - glVertex2i ( 0 , h ); - - glMultiTexCoord2f ( GL_TEXTURE0, tx , ty ); - glMultiTexCoord2f ( GL_TEXTURE1, tx +1, ty ); - glMultiTexCoord2f ( GL_TEXTURE2, tx , ty +1); - glMultiTexCoord2f ( GL_TEXTURE3, tx +1, ty +1); - - glVertex2i ( w , h ); - - glMultiTexCoord2f ( GL_TEXTURE0, tx , to ); - glMultiTexCoord2f ( GL_TEXTURE1, tx +1, to ); - glMultiTexCoord2f ( GL_TEXTURE2, tx , to +1 ); - glMultiTexCoord2f ( GL_TEXTURE3, tx +1, to +1 ); - glVertex2i ( w , 0 ); - glEnd (); - - glFlush(); -} - - -void GLTexImage::DrawQuadReduction() -{ - float to = -0.5f; - float tx = _drawWidth*2 +to; - float ty = _drawHeight*2 +to; - glBegin (GL_QUADS); - glMultiTexCoord2f ( GL_TEXTURE0, to , to ); - glMultiTexCoord2f ( GL_TEXTURE1, to +1, to ); - glMultiTexCoord2f ( GL_TEXTURE2, to , to+1 ); - glMultiTexCoord2f ( GL_TEXTURE3, to +1, to+1 ); - glVertex2i ( 0 , 0 ); - - glMultiTexCoord2f ( GL_TEXTURE0, to , ty ); - glMultiTexCoord2f ( GL_TEXTURE1, to +1, ty ); - glMultiTexCoord2f ( GL_TEXTURE2, to , ty +1 ); - glMultiTexCoord2f ( GL_TEXTURE3, to +1, ty +1 ); - glVertex2i ( 0 , _drawHeight ); - - glMultiTexCoord2f ( GL_TEXTURE0, tx , ty ); - glMultiTexCoord2f ( GL_TEXTURE1, tx +1, ty ); - glMultiTexCoord2f ( GL_TEXTURE2, tx , ty +1); - glMultiTexCoord2f ( GL_TEXTURE3, tx +1, ty +1); - - glVertex2i ( _drawWidth , _drawHeight ); - - glMultiTexCoord2f ( GL_TEXTURE0, tx , to ); - glMultiTexCoord2f ( GL_TEXTURE1, tx +1, to ); - glMultiTexCoord2f ( GL_TEXTURE2, tx , to +1 ); - glMultiTexCoord2f ( GL_TEXTURE3, tx +1, to +1 ); - glVertex2i ( _drawWidth , 0 ); - glEnd (); - - glFlush(); -} - -void GLTexPacked::TexConvertRGB() -{ - //update the actual size of daw area - _drawWidth = (1 + _imgWidth) >> 1; - _drawHeight = (1 + _imgHeight) >> 1; - /// - FrameBufferObject fbo; - GLuint oldTexID = _texID; - glGenTextures(1, &_texID); - glBindTexture(_texTarget, _texID); - glTexImage2D(_texTarget, 0, _iTexFormat, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - //input - glBindTexture(_texTarget, oldTexID); - //output - AttachToFBO(0); - //program - ShaderMan::UseShaderRGB2Gray(); - //draw buffer - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - //run - DrawQuadDS(2); - ShaderMan::UnloadProgram(); - - glDeleteTextures(1, &oldTexID); - DetachFBO(0); -} - - -void GLTexPacked::SetImageSize( int width, int height) -{ - _imgWidth = width; _drawWidth = (width + 1) >> 1; - _imgHeight = height; _drawHeight = (height + 1) >> 1; -} - -void GLTexPacked::InitTexture( int width, int height, int clamp_to_edge) -{ - - if(_texID && width == _imgWidth && height == _imgHeight ) return; - if(_texID==0) glGenTextures(1, &_texID); - - _imgWidth = width; - _imgHeight = height; - if(GlobalUtil::_PreciseBorder) - { - _texWidth = (width + 2) >> 1; - _texHeight = (height + 2) >> 1; - }else - { - _texWidth = (width + 1) >> 1; - _texHeight = (height + 1) >> 1; - } - _drawWidth = (width + 1) >> 1; - _drawHeight = (height + 1) >> 1; - - BindTex(); - - if(clamp_to_edge) - { - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - }else - { - //out of bound tex read returns 0?? - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - } - glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glTexImage2D(_texTarget, 0, _iTexFormat, - _texWidth, _texHeight, 0, GL_RGBA, GL_FLOAT, NULL); - - UnbindTex(); - -} - - -void GLTexPacked::DrawImage() -{ - float x1 =0, y1 = 0; //border.. - float x2 = _imgWidth*0.5f +x1; - float y2 = _imgHeight*0.5f + y1; - glBegin (GL_QUADS); - glTexCoord2f ( x1 , y1 ); glVertex2i ( 0 , 0 ); - glTexCoord2f ( x1 , y2 ); glVertex2i ( 0 , _imgHeight ); - glTexCoord2f ( x2 , y2 ); glVertex2i ( _imgWidth , _imgHeight ); - glTexCoord2f ( x2 , y1 ); glVertex2i ( _imgWidth , 0 ); - glEnd (); - glFlush(); -} - -void GLTexPacked::DrawQuadUS(int scale) -{ - int tw =_drawWidth, th = _drawHeight; - float texscale = 1.0f / scale; - float x1 = 0.5f - 0.5f*scale, y1 = x1; - float x2 = tw * texscale + x1; - float y2 = th * texscale + y1; - float step = texscale *0.5f; - glBegin (GL_QUADS); - glMultiTexCoord2f( GL_TEXTURE0, x1 , y1 ); - glMultiTexCoord2f( GL_TEXTURE1, x1+step , y1 ); - glMultiTexCoord2f( GL_TEXTURE2, x1 , y1 +step); - glMultiTexCoord2f( GL_TEXTURE3, x1+step , y1 +step); - glVertex2i ( 0 , 0 ); - - glMultiTexCoord2f( GL_TEXTURE0, x1 , y2 ); - glMultiTexCoord2f( GL_TEXTURE1, x1+step , y2 ); - glMultiTexCoord2f( GL_TEXTURE2, x1 , y2 +step); - glMultiTexCoord2f( GL_TEXTURE3, x1+step , y2 +step); - glVertex2i ( 0 , th ); - - glMultiTexCoord2f( GL_TEXTURE0, x2 , y2 ); - glMultiTexCoord2f( GL_TEXTURE1, x2+step , y2 ); - glMultiTexCoord2f( GL_TEXTURE2, x2 , y2 +step); - glMultiTexCoord2f( GL_TEXTURE3, x2+step , y2 +step); - glVertex2i ( tw , th ); - - glMultiTexCoord2f( GL_TEXTURE0, x2 , y1 ); - glMultiTexCoord2f( GL_TEXTURE1, x2+step , y1 ); - glMultiTexCoord2f( GL_TEXTURE2, x2 , y1 +step); - glMultiTexCoord2f( GL_TEXTURE3, x2+step , y1 +step); - glVertex2i ( tw , 0 ); - glEnd (); -} - -void GLTexPacked::DrawQuadDS(int scale) -{ - int tw = _drawWidth; - int th = _drawHeight; - float x1 = 0.5f - 0.5f*scale; - float x2 = tw * scale + x1; - float y1 = 0.5f - 0.5f * scale; - float y2 = th * scale + y1; - int step = scale / 2; - - glBegin (GL_QUADS); - glMultiTexCoord2f( GL_TEXTURE0, x1 , y1 ); - glMultiTexCoord2f( GL_TEXTURE1, x1+step , y1 ); - glMultiTexCoord2f( GL_TEXTURE2, x1 , y1 +step); - glMultiTexCoord2f( GL_TEXTURE3, x1+step , y1 +step); - glVertex2i ( 0 , 0 ); - - glMultiTexCoord2f( GL_TEXTURE0, x1 , y2 ); - glMultiTexCoord2f( GL_TEXTURE1, x1+step , y2 ); - glMultiTexCoord2f( GL_TEXTURE2, x1 , y2 +step); - glMultiTexCoord2f( GL_TEXTURE3, x1+step , y2 +step); - glVertex2i ( 0 , th ); - - glMultiTexCoord2f( GL_TEXTURE0, x2 , y2 ); - glMultiTexCoord2f( GL_TEXTURE1, x2+step , y2 ); - glMultiTexCoord2f( GL_TEXTURE2, x2 , y2 +step); - glMultiTexCoord2f( GL_TEXTURE3, x2+step , y2 +step); - glVertex2i ( tw , th ); - - glMultiTexCoord2f( GL_TEXTURE0, x2 , y1 ); - glMultiTexCoord2f( GL_TEXTURE1, x2+step , y1 ); - glMultiTexCoord2f( GL_TEXTURE2, x2 , y1 +step); - glMultiTexCoord2f( GL_TEXTURE3, x2+step , y1 +step); - glVertex2i ( tw , 0 ); - glEnd (); -} - -void GLTexPacked::ZeroHistoMargin() -{ - int marginx = (((_imgWidth + 3) /4)*4) - _imgWidth; - int marginy = (((-_imgHeight + 3)/4)*4) - _imgHeight; - if(marginx >0 || marginy > 0) - { - int tw = (_imgWidth + marginx ) >> 1; - int th = (_imgHeight + marginy ) >> 1; - tw = min(_texWidth, tw ); - th = min(_texHeight, th); - GlobalUtil::FitViewPort(tw, th); - AttachToFBO(0); - BindTex(); - ShaderMan::UseShaderZeroPass(); - DrawMargin(tw, th, 1, 1); - } -} - - -void GLTexPacked::FillMargin(int marginx, int marginy) -{ - // - marginx = min(marginx, _texWidth * 2 - _imgWidth); - marginy = min(marginy, _texHeight * 2 - _imgHeight); - if(marginx >0 || marginy > 0) - { - int tw = (_imgWidth + marginx + 1) >> 1; - int th = (_imgHeight + marginy + 1) >> 1; - GlobalUtil::FitViewPort(tw, th); - BindTex(); - AttachToFBO(0); - ShaderMan::UseShaderMarginCopy(_imgWidth , _imgHeight); - DrawMargin(tw, th, marginx, marginy); - } -} -void GLTexPacked::DrawMargin(int right, int bottom, int mx, int my) -{ - int tw = (_imgWidth >>1); - int th = (_imgHeight >>1); - glBegin(GL_QUADS); - if(right>tw && mx) - { - glTexCoord2i ( tw , 0 ); glVertex2i ( tw , 0 ); - glTexCoord2i ( tw , bottom ); glVertex2i ( tw , bottom ); - glTexCoord2i ( right, bottom ); glVertex2i ( right, bottom ); - glTexCoord2i ( right, 0 ); glVertex2i ( right, 0 ); - } - if(bottom>th && my) - { - glTexCoord2i ( 0 , th ); glVertex2i ( 0 , th ); - glTexCoord2i ( 0 , bottom ); glVertex2i ( 0 , bottom ); - glTexCoord2i ( tw , bottom ); glVertex2i ( tw , bottom ); - glTexCoord2i ( tw , th ); glVertex2i ( tw , th ); - } - glEnd(); - glFlush(); - -} - - -void GLTexImage::UnbindMultiTex(int n) -{ - for(int i = n-1; i>=0; i--) - { - glActiveTexture(GL_TEXTURE0+i); - glBindTexture(_texTarget, 0); - } -} - -template int - -#if !defined(_MSC_VER) || _MSC_VER > 1200 -GLTexInput:: -#endif - -DownSamplePixelDataI(unsigned int gl_format, int width, int height, int ds, - const Uint * pin, Uint * pout) -{ - int step, linestep; - int i, j; - int ws = width/ds; - int hs = height/ds; - const Uint * line = pin, * p; - Uint *po = pout; - switch(gl_format) - { - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - step = ds * (gl_format == GL_LUMINANCE? 1: 2); - linestep = width * step; - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - *po++ = *p; - } - } - break; - case GL_RGB: - case GL_RGBA: - step = ds * (gl_format == GL_RGB? 3: 4); - linestep = width * step; - - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - //*po++ = int(p[0]*0.299 + p[1] * 0.587 + p[2]* 0.114 + 0.5); - *po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]+ 32768)>>16); - } - } - break; - case GL_BGR: - case GL_BGRA: - step = ds * (gl_format == GL_BGR? 3: 4); - linestep = width * step; - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - *po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]+ 32768)>>16); - } - } - break; - default: - return 0; - } - - return 1; - -} - - -template int - -#if !defined(_MSC_VER) || _MSC_VER > 1200 -GLTexInput:: -#endif - -DownSamplePixelDataI2F(unsigned int gl_format, int width, int height, int ds, - const Uint * pin, float * pout, int skip) -{ - int step, linestep; - int i, j; - int ws = width/ds - skip; - int hs = height/ds; - const Uint * line = pin, * p; - float *po = pout; - const float factor = (sizeof(Uint) == 1? 255.0f : 65535.0f); - switch(gl_format) - { - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - step = ds * (gl_format == GL_LUMINANCE? 1: 2); - linestep = width * step; - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - *po++ = (*p) / factor; - } - } - break; - case GL_RGB: - case GL_RGBA: - step = ds * (gl_format == GL_RGB? 3: 4); - linestep = width * step; - - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - //*po++ = int(p[0]*0.299 + p[1] * 0.587 + p[2]* 0.114 + 0.5); - *po++ = ((19595*p[0] + 38470*p[1] + 7471*p[2]) / (65535.0f * factor)); - } - } - break; - case GL_BGR: - case GL_BGRA: - step = ds * (gl_format == GL_BGR? 3: 4); - linestep = width * step; - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - *po++ = ((7471*p[0] + 38470*p[1] + 19595*p[2]) / (65535.0f * factor)); - } - } - break; - default: - return 0; - } - return 1; -} - -int GLTexInput::DownSamplePixelDataF(unsigned int gl_format, int width, int height, int ds, const float * pin, float * pout, int skip) -{ - int step, linestep; - int i, j; - int ws = width/ds - skip; - int hs = height/ds; - const float * line = pin, * p; - float *po = pout; - switch(gl_format) - { - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - step = ds * (gl_format == GL_LUMINANCE? 1: 2); - linestep = width * step; - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - *po++ = *p; - } - } - break; - case GL_RGB: - case GL_RGBA: - step = ds * (gl_format == GL_RGB? 3: 4); - linestep = width * step; - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - *po++ = (0.299f*p[0] + 0.587f*p[1] + 0.114f*p[2]); - } - } - break; - case GL_BGR: - case GL_BGRA: - step = ds * (gl_format == GL_BGR? 3: 4); - linestep = width * step; - for(i = 0 ; i < hs; i++, line+=linestep) - { - for(j = 0, p = line; j < ws; j++, p+=step) - { - *po++ = (0.114f*p[0] + 0.587f*p[1] + 0.299f * p[2]); - } - } - break; - default: - return 0; - } - - return 1; - -} - -int GLTexInput::SetImageData( int width, int height, const void * data, - unsigned int gl_format, unsigned int gl_type ) -{ - int simple_format = IsSimpleGlFormat(gl_format, gl_type);//no cpu code to handle other formats - int ws, hs, done = 1; - - if(_converted_data) {delete [] _converted_data; _converted_data = NULL; } - - _rgb_converted = 1; - _data_modified = 0; - - if( simple_format - && ( width > _texMaxDim || height > _texMaxDim || GlobalUtil::_PreProcessOnCPU) - && GlobalUtil::_octave_min_default >0 ) - { - _down_sampled = GlobalUtil::_octave_min_default; - ws = width >> GlobalUtil::_octave_min_default; - hs = height >> GlobalUtil::_octave_min_default; - }else - { - _down_sampled = 0; - ws = width; - hs = height; - } - - if ( ws > _texMaxDim || hs > _texMaxDim) - { - if(simple_format) - { - if(GlobalUtil::_verbose) std::cout<<"Automatic down-sampling is used\n"; - do - { - _down_sampled ++; - ws >>= 1; - hs >>= 1; - }while(ws > _texMaxDim || hs > _texMaxDim); - }else - { - std::cerr<<"Input images is too big to fit into a texture\n"; - return 0; - } - } - - _texWidth = _imgWidth = _drawWidth = ws; - _texHeight = _imgHeight = _drawHeight = hs; - - if(GlobalUtil::_verbose) - { - std::cout<<"Image size :\t"<0) std::cout<<"Down sample to \t"< 0 || gl_format != GL_LUMINANCE || gl_type != GL_FLOAT) - { - _converted_data = new float [_imgWidth * _imgHeight]; - if(gl_type == GL_UNSIGNED_BYTE) - DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled, - ((const unsigned char*) data), _converted_data, skip); - else if(gl_type == GL_UNSIGNED_SHORT) - DownSamplePixelDataI2F(gl_format, width, height, 1<<_down_sampled, - ((const unsigned short*) data), _converted_data, skip); - else - DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, _converted_data, skip); - _rgb_converted = 2; //indidates a new data copy - _pixel_data = _converted_data; - }else - { - //Luminance data that doesn't need to down sample - _rgb_converted = 1; - _pixel_data = data; - if(skip > 0) - { - for(int i = 1; i < _imgHeight; ++i) - { - float * dst = ((float*)data) + i * tWidth, * src = ((float*)data) + i * _imgWidth; - for(int j = 0; j < tWidth; ++j) *dst++ = * src++; - } - } - } - _texWidth = _imgWidth = _drawWidth = tWidth; - _data_modified = 1; - }else - { - if(_texID ==0) glGenTextures(1, &_texID); - glBindTexture(_texTarget, _texID); - CheckErrorsGL("glBindTexture"); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glPixelStorei(GL_UNPACK_ALIGNMENT , 1); - - if(simple_format && ( _down_sampled> 0 || (gl_format != GL_LUMINANCE && GlobalUtil::_PreProcessOnCPU) )) - { - - if(gl_type == GL_UNSIGNED_BYTE) - { - unsigned char * newdata = new unsigned char [_imgWidth * _imgHeight]; - DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned char*) data), newdata); - glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed - _imgWidth, _imgHeight, 0, - GL_LUMINANCE, GL_UNSIGNED_BYTE, newdata); - delete[] newdata; - }else if(gl_type == GL_UNSIGNED_SHORT) - { - unsigned short * newdata = new unsigned short [_imgWidth * _imgHeight]; - DownSamplePixelDataI(gl_format, width, height, 1<<_down_sampled, ((const unsigned short*) data), newdata); - - glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed - _imgWidth, _imgHeight, 0, - GL_LUMINANCE, GL_UNSIGNED_SHORT, newdata); - delete[] newdata; - }else if(gl_type == GL_FLOAT) - { - float * newdata = new float [_imgWidth * _imgHeight]; - DownSamplePixelDataF(gl_format, width, height, 1<<_down_sampled, (float*)data, newdata); - glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed - _imgWidth, _imgHeight, 0, - GL_LUMINANCE, GL_FLOAT, newdata); - delete[] newdata; - }else - { - //impossible - done = 0; - _rgb_converted = 0; - } - GlobalUtil::FitViewPort(1, 1); //this used to be necessary - }else - { - //ds must be 0 here if not simpleformat - if(gl_format == GL_LUMINANCE || gl_format == GL_LUMINANCE_ALPHA) - { - //use one channel internal format if data is intensity image - glTexImage2D(_texTarget, 0, GL_LUMINANCE32F_ARB, - _imgWidth, _imgHeight, 0, gl_format, gl_type, data); - GlobalUtil::FitViewPort(1, 1); //this used to be necessary - } - else - { - //convert RGB 2 GRAY if needed - glTexImage2D(_texTarget, 0, _iTexFormat, _imgWidth, _imgHeight, 0, gl_format, gl_type, data); - if(ShaderMan::HaveShaderMan()) - TexConvertRGB(); - else - _rgb_converted = 0; //In CUDA mode, the conversion will be done by CUDA kernel - } - } - UnbindTex(); - } - return done; -} - - -GLTexInput::~GLTexInput() -{ - if(_converted_data) delete [] _converted_data; -} - - -int GLTexInput::LoadImageFile(char *imagepath, int &w, int &h ) -{ -#ifndef SIFTGPU_NO_DEVIL - static int devil_loaded = 0; - unsigned int imID; - int done = 1; - - if(devil_loaded == 0) - { - ilInit(); - ilOriginFunc(IL_ORIGIN_UPPER_LEFT); - ilEnable(IL_ORIGIN_SET); - devil_loaded = 1; - } - - /// - ilGenImages(1, &imID); - ilBindImage(imID); - - if(ilLoadImage(imagepath)) - { - w = ilGetInteger(IL_IMAGE_WIDTH); - h = ilGetInteger(IL_IMAGE_HEIGHT); - int ilformat = ilGetInteger(IL_IMAGE_FORMAT); - - if(SetImageData(w, h, ilGetData(), ilformat, GL_UNSIGNED_BYTE)==0) - { - done =0; - }else if(GlobalUtil::_verbose) - { - std::cout<<"Image loaded :\t"< 255 || width < 0 || height < 0) - { - fclose(file); - std::cerr << "ERROR: fileformat not supported\n"; - return 0; - }else - { - w = width; - h = height; - } - unsigned char * data = new unsigned char[width * height]; - unsigned char * pixels = data; - if (strcmp(buf, "P5")==0 ) - { - fscanf(file, "%c",buf);//skip one byte - fread(pixels, 1, width*height, file); - }else if (strcmp(buf, "P2")==0 ) - { - for (int i = 0 ; i< height; i++) - { - for ( int j = 0; j < width; j++) - { - fscanf(file, "%d", &g); - *pixels++ = (unsigned char) g; - } - } - }else if (strcmp(buf, "P6")==0 ) - { - fscanf(file, "%c", buf);//skip one byte - int j, num = height*width; - unsigned char buf[3]; - for ( j =0 ; j< num; j++) - { - fread(buf,1,3, file); - *pixels++=int(0.10454f* buf[2]+0.60581f* buf[1]+0.28965f* buf[0]); - } - }else if (strcmp(buf, "P3")==0 ) - { - int r, g, b; - int i , num =height*width; - for ( i = 0 ; i< num; i++) - { - fscanf(file, "%d %d %d", &r, &g, &b); - *pixels++ = int(0.10454f* b+0.60581f* g+0.28965f* r); - } - - }else - { - std::cerr << "ERROR: fileformat not supported\n"; - done = 0; - } - if(done) SetImageData(width, height, data, GL_LUMINANCE, GL_UNSIGNED_BYTE); - fclose(file); - delete data; - if(GlobalUtil::_verbose && done) std::cout<< "Image loaded :\t" << imagepath << "\n"; - return 1; -#endif -} - -int GLTexImage::CopyToPBO(GLuint pbo, int width, int height, GLenum format) -{ - ///////// - if(format != GL_RGBA && format != GL_LUMINANCE) return 0; - - FrameBufferObject fbo; - GLint bsize, esize = width * height * sizeof(float) * (format == GL_RGBA ? 4 : 1); - AttachToFBO(0); - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - if(bsize < esize) - { - glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize, NULL, GL_STATIC_DRAW_ARB); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - } - if(bsize >= esize) - { - glReadPixels(0, 0, width, height, format, GL_FLOAT, 0); - } - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); - DetachFBO(0); - - return bsize >= esize; -} - -void GLTexImage::SaveToASCII(const char* path) -{ - vector buf(GetImgWidth() * GetImgHeight() * 4); - FrameBufferObject fbo; - AttachToFBO(0); - glReadPixels(0, 0, GetImgWidth(), GetImgHeight(), GL_RGBA, GL_FLOAT, &buf[0]); - ofstream out(path); - - for(int i = 0, idx = 0; i < GetImgHeight(); ++i) - { - for(int j = 0; j < GetImgWidth(); ++j, idx += 4) - { - out << i << " " << j << " " << buf[idx] << " " << buf[idx + 1] << " " - << buf[idx + 2] << " " << buf[idx + 3] << "\n"; - } - } -} - - -void GLTexInput::VerifyTexture() -{ - //for CUDA or OpenCL the texture is not generated by default - if(!_data_modified) return; - if(_pixel_data== NULL) return; - InitTexture(_imgWidth, _imgHeight); - BindTex(); - glTexImage2D( _texTarget, 0, GL_LUMINANCE32F_ARB, //internal format changed - _imgWidth, _imgHeight, 0, - GL_LUMINANCE, GL_FLOAT, _pixel_data); - UnbindTex(); - _data_modified = 0; -} - -void GLTexImage::CopyFromPBO(GLuint pbo, int width, int height, GLenum format) -{ - InitTexture(max(width, _texWidth), max(height, _texHeight)); - SetImageSize(width, height); - if(width > 0 && height > 0) - { - BindTex(); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, width, height, format, GL_FLOAT, 0); - GlobalUtil::CheckErrorsGL("GLTexImage::CopyFromPBO->glTexSubImage2D"); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); - UnbindTex(); - } -} - diff --git a/3rdparty/SiftGPU/src/SiftGPU/GLTexImage.h b/3rdparty/SiftGPU/src/SiftGPU/GLTexImage.h deleted file mode 100644 index 0862e7a9..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/GLTexImage.h +++ /dev/null @@ -1,158 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: GLTexImage.h -// Author: Changchang Wu -// Description : interface for the GLTexImage class. -// GLTexImage: naive texture class. -// sevral different quad drawing functions are provied -// GLTexPacked: packed version (four value packed as four channels of a pixel) -// GLTexInput: GLTexImage + some input information -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#ifndef GL_TEX_IMAGE_H -#define GL_TEX_IMAGE_H - -class GlobalUtil; -class GLTexImage :public GlobalUtil -{ -protected: - GLuint _texID; - int _imgWidth; - int _imgHeight; - int _texWidth; - int _texHeight; - int _drawWidth; - int _drawHeight; -public: - static void DetachFBO(int i); - static void UnbindTex(); - static void UnbindMultiTex(int n); - static void DrawQuad(float x1, float x2, float y1, float y2); - -public: - virtual void DrawQuadUS(int scale); - virtual void DrawQuadDS(int scale); - virtual void DrawImage(); - virtual void TexConvertRGB(); - virtual void ZeroHistoMargin(); - virtual void SetImageSize(int width, int height); - virtual void InitTexture(int width, int height, int clamp_to_edge =1 ); - void InitTexture(int width, int height, int clamp_to_edge, GLuint format); - virtual void FillMargin(int marginx, int marginy); -public: - void DrawScaledQuad(float scale); - int CopyToPBO(GLuint pbo, int width, int height, GLenum format = GL_RGBA); - void CopyFromPBO(GLuint pbo, int width, int height, GLenum format = GL_RGBA); - void FitRealTexViewPort(); - void DrawQuadMT8(); - void DrawQuadMT4(); - void DrawQuadReduction(); - void DrawQuadReduction(int w, int h); - void DrawMargin(int right, int bottom); - void DrawQuad(); - void FitTexViewPort(); - void ZeroHistoMargin(int hw, int hh); - int CheckTexture(); - void SaveToASCII(const char* path); -public: - void AttachToFBO(int i ); - void BindTex(); - operator GLuint (){return _texID;} - GLuint GetTexID(){return _texID;} - int GetImgPixelCount(){return _imgWidth*_imgHeight;} - int GetTexPixelCount(){return _texWidth*_texHeight;} - int GetImgWidth(){return _imgWidth;} - int GetImgHeight(){return _imgHeight;} - int GetTexWidth(){return _texWidth;} - int GetTexHeight(){return _texHeight;} - int GetDrawWidth(){return _drawWidth;} - int GetDrawHeight(){return _drawHeight;} - //int IsTexTight(){return _texWidth == _drawWidth && _texHeight == _drawHeight;} - int IsTexPacked(){return _drawWidth != _imgWidth;} - GLTexImage(); - virtual ~GLTexImage(); - friend class SiftGPU; -}; - -//class for handle data input, to support all openGL-supported data format, -//data are first uploaded to an openGL texture then converted, and optionally -//when the datatype is simple, we downsample/convert on cpu -class GLTexInput:public GLTexImage -{ -public: - int _down_sampled; - int _rgb_converted; - int _data_modified; - - ////////////////////////// - float * _converted_data; - const void* _pixel_data; -public: - static int IsSimpleGlFormat(unsigned int gl_format, unsigned int gl_type) - { - //the formats there is a cpu code to conver rgb and downsample - return (gl_format ==GL_LUMINANCE ||gl_format == GL_LUMINANCE_ALPHA|| - gl_format == GL_RGB|| gl_format == GL_RGBA|| - gl_format == GL_BGR || gl_format == GL_BGRA) && - (gl_type == GL_UNSIGNED_BYTE || gl_type == GL_FLOAT || gl_type == GL_UNSIGNED_SHORT); - } -//in vc6, template member function doesn't work -#if !defined(_MSC_VER) || _MSC_VER > 1200 - template - static int DownSamplePixelDataI(unsigned int gl_format, int width, int height, - int ds, const Uint * pin, Uint * pout); - template - static int DownSamplePixelDataI2F(unsigned int gl_format, int width, int height, - int ds, const Uint * pin, float * pout, int skip = 0); -#endif - static int DownSamplePixelDataF(unsigned int gl_format, int width, int height, - int ds, const float * pin, float * pout, int skip = 0); - static int TruncateWidthCU(int w) {return w & 0xfffffffc; } -public: - GLTexInput() : _down_sampled(0), _rgb_converted(0), _data_modified(0), - _converted_data(0), _pixel_data(0){} - int SetImageData(int width, int height, const void * data, - unsigned int gl_format, unsigned int gl_type); - int LoadImageFile(char * imagepath, int & w, int &h); - void VerifyTexture(); - virtual ~GLTexInput(); -}; - -//GLTexPacked doesn't have any data -//so that we can use the GLTexImage* pointer to index a GLTexPacked Vector - -class GLTexPacked:public GLTexImage -{ -public: - virtual void DrawImage(); - virtual void DrawQuadUS(int scale); - virtual void DrawQuadDS(int scale); - virtual void FillMargin(int marginx, int marginy); - virtual void InitTexture(int width, int height, int clamp_to_edge =1); - virtual void TexConvertRGB(); - virtual void SetImageSize(int width, int height); - virtual void ZeroHistoMargin(); - //virtual void GetHistWH(int& w, int& h){return w = (3 + sz)>>1;} -public: - void DrawMargin(int right, int bottom, int mx, int my); - GLTexPacked():GLTexImage(){} -}; - - -#endif // !defined(GL_TEX_IMAGE_H) - diff --git a/3rdparty/SiftGPU/src/SiftGPU/GlobalUtil.cpp b/3rdparty/SiftGPU/src/SiftGPU/GlobalUtil.cpp deleted file mode 100644 index e068e18d..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/GlobalUtil.cpp +++ /dev/null @@ -1,519 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: GlobalUtil.cpp -// Author: Changchang Wu -// Description : Global Utility class for SiftGPU -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// -#include -#include -using std::cout; - -#include "GL/glew.h" -#include "GlobalUtil.h" - -//for windows, the default timing uses timeGetTime, you can define TIMING_BY_CLOCK to use clock() -//for other os, the timing uses gettimeofday - - -#if defined(_WIN32) - #if defined(TIMING_BY_CLOCK) - #include - #else - #define WIN32_LEAN_AND_MEAN - #include - #include - #endif -#else - #include - #include -#endif - -#include "LiteWindow.h" - -// -int GlobalParam:: _verbose = 1; -int GlobalParam:: _timingS = 1; //print out information of each step -int GlobalParam:: _timingO = 0; //print out information of each octave -int GlobalParam:: _timingL = 0; //print out information of each level -GLuint GlobalParam:: _texTarget = GL_TEXTURE_RECTANGLE_ARB; //only this one is supported -GLuint GlobalParam:: _iTexFormat =GL_RGBA32F_ARB; //or GL_RGBA16F_ARB -int GlobalParam:: _debug = 0; //enable debug code? -int GlobalParam:: _usePackedTex = 1;//packed implementation -int GlobalParam:: _UseCUDA = 0; -int GlobalParam:: _UseOpenCL = 0; -int GlobalParam:: _MaxFilterWidth = -1; //maximum filter width, use when GPU is not good enough -float GlobalParam:: _FilterWidthFactor = 4.0f; //the filter size will be _FilterWidthFactor*sigma*2+1 -float GlobalParam:: _DescriptorWindowFactor = 3.0f; //descriptor sampling window factor -int GlobalParam:: _SubpixelLocalization = 1; //sub-pixel and sub-scale localization -int GlobalParam:: _MaxOrientation = 2; //whether we find multiple orientations for each feature -int GlobalParam:: _OrientationPack2 = 0; //use one float to store two orientations -float GlobalParam:: _MaxFeaturePercent = 0.005f;//at most 0.005 of all pixels -int GlobalParam:: _MaxLevelFeatureNum = 4096; //maximum number of features of a level -int GlobalParam:: _FeatureTexBlock = 4; //feature texture storagte alignment -int GlobalParam:: _NarrowFeatureTex = 0; - -//if _ForceTightPyramid is not 0, pyramid will be reallocated to fit the size of input images. -//otherwise, pyramid can be reused for smaller input images. -int GlobalParam:: _ForceTightPyramid = 0; - -//use gpu or cpu to generate feature list ...gpu is a little bit faster -int GlobalParam:: _ListGenGPU = 1; -int GlobalParam:: _ListGenSkipGPU = 6; //how many levels are skipped on gpu -int GlobalParam:: _PreProcessOnCPU = 1; //convert rgb 2 intensity on gpu, down sample on GPU - -//hardware parameter, automatically retrieved -int GlobalParam:: _texMaxDim = 3200; //Maximum working size for SiftGPU, 3200 for packed -int GlobalParam:: _texMaxDimGL = 4096; //GPU texture limit -int GlobalParam:: _texMinDim = 16; // -int GlobalParam:: _MemCapGPU = 0; -int GlobalParam:: _FitMemoryCap = 0; -int GlobalParam:: _IsNvidia = 0; //GPU vendor -int GlobalParam:: _KeepShaderLoop = 0; - -//you can't change the following 2 values -//all other versions of code are now dropped -int GlobalParam:: _DescriptorPPR = 8; -int GlobalParam:: _DescriptorPPT = 16; - -//whether orientation/descriptor is supported by hardware -int GlobalParam:: _SupportNVFloat = 0; -int GlobalParam:: _SupportTextureRG = 0; -int GlobalParam:: _UseDynamicIndexing = 0; -int GlobalParam:: _FullSupported = 1; - -//when SiftGPUEX is not used, display VBO generation is skipped -int GlobalParam:: _UseSiftGPUEX = 0; -int GlobalParam:: _InitPyramidWidth=0; -int GlobalParam:: _InitPyramidHeight=0; -int GlobalParam:: _octave_min_default=0; -int GlobalParam:: _octave_num_default=-1; - - -////////////////////////////////////////////////////////////////// -int GlobalParam:: _GoodOpenGL = -1; //indicates OpenGl initialization status -int GlobalParam:: _FixedOrientation = 0; //upright -int GlobalParam:: _LoweOrigin = 0; //(0, 0) to be at the top-left corner. -int GlobalParam:: _NormalizedSIFT = 1; //normalize descriptor -int GlobalParam:: _BinarySIFT = 0; //saving binary format -int GlobalParam:: _ExitAfterSIFT = 0; //exif after saving result -int GlobalParam:: _KeepExtremumSign = 0; // if 1, scales of dog-minimum will be multiplied by -1 -/// -int GlobalParam:: _KeyPointListForceLevel0 = 0; -int GlobalParam:: _DarknessAdaption = 0; -int GlobalParam:: _ProcessOBO = 0; -int GlobalParam:: _TruncateMethod = 0; -int GlobalParam:: _PreciseBorder = 1; - -// parameter changing for better matching with Lowe's SIFT -float GlobalParam:: _OrientationWindowFactor = 2.0f; // 1.0(-v292), 2(v293-), -float GlobalParam:: _OrientationGaussianFactor = 1.5f; // 4.5(-v292), 1.5(v293-) -float GlobalParam:: _MulitiOrientationThreshold = 0.8f; -/// -int GlobalParam:: _FeatureCountThreshold = -1; - -/////////////////////////////////////////////// -int GlobalParam:: _WindowInitX = -1; -int GlobalParam:: _WindowInitY = -1; -int GlobalParam:: _DeviceIndex = 0; -const char * GlobalParam:: _WindowDisplay = NULL; - - - -///////////////// -//// -ClockTimer GlobalUtil:: _globalTimer; - - -#ifdef _DEBUG -void GlobalUtil::CheckErrorsGL(const char* location) -{ - GLuint errnum; - const char *errstr; - while (errnum = glGetError()) - { - errstr = (const char *)(gluErrorString(errnum)); - if(errstr) { - std::cerr << errstr; - } - else { - std::cerr << "Error " << errnum; - } - - if(location) std::cerr << " at " << location; - std::cerr << "\n"; - } - return; -} - -#endif - -void GlobalUtil::CleanupOpenGL() -{ - glActiveTexture(GL_TEXTURE0); -} - -void GlobalUtil::SetDeviceParam(int argc, char** argv) -{ - if(GlobalParam::_GoodOpenGL!= -1) return; - - #define CHAR1_TO_INT(x) ((x >= 'A' && x <= 'Z') ? x + 32 : x) - #define CHAR2_TO_INT(str, i) (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR1_TO_INT(str[i+1]) << 8) : 0) - #define CHAR3_TO_INT(str, i) (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR2_TO_INT(str, i + 1) << 8) : 0) - #define STRING_TO_INT(str) (CHAR1_TO_INT(str[0]) + (CHAR3_TO_INT(str, 1) << 8)) - - char* arg, * opt; - for(int i = 0; i< argc; i++) - { - arg = argv[i]; - if(arg == NULL || arg[0] != '-')continue; - opt = arg+1; - - //////////////////////////////// - switch( STRING_TO_INT(opt)) - { - case 'w' + ('i' << 8) + ('n' << 16) + ('p' << 24): - if(_GoodOpenGL != 2 && i + 1 < argc) - { - int x =0, y=0; - if(sscanf(argv[++i], "%dx%d", &x, &y) == 2) - { - GlobalParam::_WindowInitX = x; - GlobalParam::_WindowInitY = y; - } - } - break; - case 'd' + ('i' << 8) + ('s' << 16) + ('p' << 24): - if(_GoodOpenGL != 2 && i + 1 < argc) - { - GlobalParam::_WindowDisplay = argv[++i]; - } - break; - case 'c' + ('u' << 8) + ('d' << 16) + ('a' << 24): - if(i + 1 < argc) - { - int device = 0; - scanf(argv[++i], "%d", &device) ; - GlobalParam::_DeviceIndex = device; - } - break; - default: - break; - } - } -} - -void GlobalUtil::SetTextureParameter() -{ - - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -} - -//if image need to be up sampled ..use this one - -void GlobalUtil::SetTextureParameterUS() -{ - - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -} - - -void GlobalUtil::FitViewPort(int width, int height) -{ - GLint port[4]; - glGetIntegerv(GL_VIEWPORT, port); - if(port[2] !=width || port[3] !=height) - { - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, 0, height, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - } -} - - -bool GlobalUtil::CheckFramebufferStatus() { - GLenum status; - status=(GLenum)glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - switch(status) { - case GL_FRAMEBUFFER_COMPLETE_EXT: - return true; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - std::cerr<<("Framebuffer incomplete,incomplete attachment\n"); - return false; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - std::cerr<<("Unsupported framebuffer format\n"); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: - std::cerr<<("Framebuffer incomplete,missing attachment\n"); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: - std::cerr<<("Framebuffer incomplete,attached images must have same dimensions\n"); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: - std::cerr<<("Framebuffer incomplete,attached images must have same format\n"); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: - std::cerr<<("Framebuffer incomplete,missing draw buffer\n"); - return false; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: - std::cerr<<("Framebuffer incomplete,missing read buffer\n"); - return false; - } - return false; -} - - -int ClockTimer::ClockMS() -{ -#if defined(_WIN32) - #if defined(TIMING_BY_CLOCK) - return clock() * 1000 / CLOCKS_PER_SEC; - #else - static int started = 0; - static int tstart; - if(started == 0) - { - tstart = timeGetTime(); - started = 1; - return 0; - }else - { - return timeGetTime() - tstart; - } - #endif -#else - static int started = 0; - static struct timeval tstart; - if(started == 0) - { - gettimeofday(&tstart, NULL); - started = 1; - return 0; - }else - { - struct timeval now; - gettimeofday(&now, NULL) ; - return (now.tv_usec - tstart.tv_usec + (now.tv_sec - tstart.tv_sec) * 1000000)/1000; - } -#endif -} - -double ClockTimer::CLOCK() -{ - return ClockMS() * 0.001; -} - -void ClockTimer::InitHighResolution() -{ -#if defined(_WIN32) - timeBeginPeriod(1); -#endif -} - -void ClockTimer::StartTimer(const char* event, int verb) -{ - strcpy(_current_event, event); - _time_start = ClockMS(); - if(verb && GlobalUtil::_verbose) - { - std::cout<<"\n["<<_current_event<<"]:\tbegin ...\n"; - } -} - -void ClockTimer::StopTimer(int verb) -{ - _time_stop = ClockMS(); - if(verb && GlobalUtil::_verbose) - { - std::cout<<"["<<_current_event<<"]:\t"< GlobalUtil::_texMaxDimGL) - { - GlobalUtil::_texMaxDim = GlobalUtil::_texMaxDimGL; - } - glEnable(GlobalUtil::_texTarget); - }else - { - std::cerr << "GL_ARB_texture_rectangle not supported!\n"; - GlobalUtil::_GoodOpenGL = 0; - } - - GlobalUtil::_SupportNVFloat = glewGetExtension("GL_NV_float_buffer"); - GlobalUtil::_SupportTextureRG = glewGetExtension("GL_ARB_texture_rg"); - - - glShadeModel(GL_FLAT); - glPolygonMode(GL_FRONT, GL_FILL); - - GlobalUtil::SetTextureParameter(); - - } -} - -void GlobalUtil::SelectDisplay() -{ -#ifdef WIN32 - if(_WindowDisplay == NULL) return; - - HDC hdc = CreateDC(_WindowDisplay, _WindowDisplay, NULL, NULL); - _WindowDisplay = NULL; - if(hdc == NULL) - { - std::cout << "ERROR: invalid dispaly specified\n"; - return; - } - - PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR),1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA,24,0, 0, 0, 0, 0, 0,0,0,0,0, 0, 0, 0,16,0,0, - PFD_MAIN_PLANE,0,0, 0, 0 - }; - ChoosePixelFormat(hdc, &pfd); -#endif -} - -int GlobalUtil::CreateWindowEZ(LiteWindow* window) -{ - if(window == NULL) return 0; - if(!window->IsValid())window->Create(_WindowInitX, _WindowInitY, _WindowDisplay); - if(window->IsValid()) - { - window->MakeCurrent(); - return 1; - } - else - { - std::cerr << "Unable to create OpenGL Context!\n"; - std::cerr << "For nVidia cards, you can try change to CUDA mode in this case\n"; - return 0; - } -} - -int GlobalUtil::CreateWindowEZ() -{ - static LiteWindow window; - return CreateWindowEZ(&window); -} - -int CreateLiteWindow(LiteWindow* window) -{ - return GlobalUtil::CreateWindowEZ(window); -} diff --git a/3rdparty/SiftGPU/src/SiftGPU/GlobalUtil.h b/3rdparty/SiftGPU/src/SiftGPU/GlobalUtil.h deleted file mode 100644 index 4a0f6e63..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/GlobalUtil.h +++ /dev/null @@ -1,157 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: GlobalUtil.h -// Author: Changchang Wu -// Description : -// GlobalParam: Global parameters -// ClockTimer: Timer -// GlobalUtil: Global Function wrapper -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#ifndef _GLOBAL_UTILITY_H -#define _GLOBAL_UTILITY_H - - -//wrapper for some shader function -//class ProgramGPU; -class LiteWindow; - -class GlobalParam -{ -public: - static GLuint _texTarget; - static GLuint _iTexFormat; - static int _texMaxDim; - static int _texMaxDimGL; - static int _texMinDim; - static int _MemCapGPU; - static int _FitMemoryCap; - static int _verbose; - static int _timingS; - static int _timingO; - static int _timingL; - static int _usePackedTex; - static int _IsNvidia; - static int _KeepShaderLoop; - static int _UseCUDA; - static int _UseOpenCL; - static int _UseDynamicIndexing; - static int _debug; - static int _MaxFilterWidth; - static float _FilterWidthFactor; - static float _OrientationWindowFactor; - static float _DescriptorWindowFactor; - static int _MaxOrientation; - static int _OrientationPack2; - static int _ListGenGPU; - static int _ListGenSkipGPU; - static int _SupportNVFloat; - static int _SupportTextureRG; - static int _FullSupported; - static float _MaxFeaturePercent; - static int _MaxLevelFeatureNum; - static int _DescriptorPPR; - static int _DescriptorPPT; //pixel per texture for one descriptor - static int _FeatureTexBlock; - static int _NarrowFeatureTex; //implemented but no performance improvement - static int _SubpixelLocalization; - static int _ProcessOBO; //not implemented yet - static int _TruncateMethod; - static int _PreciseBorder; //implemented - static int _UseSiftGPUEX; - static int _ForceTightPyramid; - static int _octave_min_default; - static int _octave_num_default; - static int _InitPyramidWidth; - static int _InitPyramidHeight; - static int _PreProcessOnCPU; - static int _GoodOpenGL; - static int _FixedOrientation; - static int _LoweOrigin; - static int _ExitAfterSIFT; - static int _NormalizedSIFT; - static int _BinarySIFT; - static int _KeepExtremumSign; - static int _FeatureCountThreshold; - static int _KeyPointListForceLevel0; - static int _DarknessAdaption; - - //for compatability with old version: - static float _OrientationExtraFactor; - static float _OrientationGaussianFactor; - static float _MulitiOrientationThreshold; - - //////////////////////////////////////// - static int _WindowInitX; - static int _WindowInitY; - static const char* _WindowDisplay; - static int _DeviceIndex; -}; - - -class ClockTimer -{ -private: - char _current_event[256]; - int _time_start; - int _time_stop; -public: - static int ClockMS(); - static double CLOCK(); - static void InitHighResolution(); - void StopTimer(int verb = 1); - void StartTimer(const char * event, int verb=0); - float GetElapsedTime(); -}; - -class GlobalUtil:public GlobalParam -{ - static ClockTimer _globalTimer; -public: - inline static double CLOCK() { return ClockTimer::CLOCK(); } - inline static void StopTimer() { _globalTimer.StopTimer(_timingS); } - inline static void StartTimer(const char * event) { _globalTimer.StartTimer(event, _timingO); } - inline static float GetElapsedTime() { return _globalTimer.GetElapsedTime(); } - - static void FitViewPort(int width, int height); - static void SetTextureParameter(); - static void SetTextureParameterUS(); -#ifdef _DEBUG - static void CheckErrorsGL(const char* location = NULL); -#else - static void inline CheckErrorsGL(const char* location = NULL){}; -#endif - static bool CheckFramebufferStatus(); - //initialize Opengl parameters - static void SelectDisplay(); - static void InitGLParam(int NotTargetGL = 0); - static void SetGLParam(); - static int CreateWindowEZ(); - static void CleanupOpenGL(); - static void SetDeviceParam(int argc, char** argv); - static int CreateWindowEZ(LiteWindow* window); -}; - - -#if defined(_MSC_VER) && _MSC_VER == 1200 -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/LiteWindow.h b/3rdparty/SiftGPU/src/SiftGPU/LiteWindow.h deleted file mode 100644 index 9c053ebd..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/LiteWindow.h +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef LITE_WINDOW_H -#define LITE_WINDOW_H - -//#define WINDOW_PREFER_GLUT - -#if defined(WINDOW_PREFER_GLUT) - -#ifdef __APPLE__ - #include "GLUT/glut.h" -#else - #include "GL/glut.h" -#endif -//for apple, use GLUT to create the window.. -class LiteWindow -{ - int glut_id; -public: - LiteWindow() { glut_id = 0; } - int IsValid() { return glut_id > 0; } - virtual ~LiteWindow() { if(glut_id > 0) glutDestroyWindow(glut_id); } - void MakeCurrent() { glutSetWindow(glut_id); } - void Create(int x = -1, int y = -1, const char* display = NULL) - { - static int _glut_init_called = 0; - if(glut_id != 0) return; - - //see if there is an existing window - if(_glut_init_called) glut_id = glutGetWindow(); - - //create one if no glut window exists - if(glut_id != 0) return; - - if(_glut_init_called == 0) - { - int argc = 1; - char * argv[4] = { "-iconic", 0 , 0, 0}; - if(display) - { - argc = 3; - argv[1] = "-display"; - argv[2] = (char*) display; - } - glutInit(&argc, argv); - glutInitDisplayMode (GLUT_RGBA ); - _glut_init_called = 1; - } - if(x != -1) glutInitWindowPosition(x, y); - if(display || x != -1) std::cout << "Using display [" - << (display? display : "\0" )<< "] at (" << x << "," << y << ")\n"; - glut_id = glutCreateWindow ("SIFT_GPU_GLUT"); - glutHideWindow(); - } -}; -#elif defined( _WIN32) - -#ifndef _INC_WINDOWS -#ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN -#endif -#include -#endif - -class LiteWindow -{ - HWND hWnd; - HGLRC hContext; - HDC hdc; -public: - LiteWindow() - { - hWnd = NULL; - hContext = NULL; - hdc = NULL; - } - virtual ~LiteWindow() - { - if(hContext)wglDeleteContext(hContext); - if(hdc)ReleaseDC(hWnd, hdc); - if(hWnd)DestroyWindow(hWnd); - } - int IsValid() - { - return hContext != NULL; - } - - //display is ignored under Win32 - void Create(int x = -1, int y = -1, const char* display = NULL) - { - if(hContext) return; - WNDCLASSEX wcex = { sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, - (WNDPROC)DefWindowProc, 0, 4, 0, 0, 0, 0, 0, - ("SIFT_GPU_LITE"), 0}; - RegisterClassEx(&wcex); - hWnd = CreateWindow("SIFT_GPU_LITE", "SIFT_GPU", 0, - CW_USEDEFAULT, CW_USEDEFAULT, - 100, 100, NULL, NULL, 0, 0); - - //move the window so that it can be on the second monitor - if(x !=-1) - { - MoveWindow(hWnd, x, y, 100, 100, 0); - std::cout << "CreateWindow at (" << x << "," << y<<")\n"; - } - - /////////////////////////////////////////////////// - PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL , - PFD_TYPE_RGBA,16,0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 - }; - hdc=GetDC(hWnd); - //////////////////////////////////// - int pixelformat = ChoosePixelFormat(hdc, &pfd); - DescribePixelFormat(hdc, pixelformat, sizeof(pfd), &pfd); - SetPixelFormat(hdc, pixelformat, &pfd); - hContext = wglCreateContext(hdc); - - } - void MakeCurrent() - { - wglMakeCurrent(hdc, hContext); - } -}; - -#else - -#include -#include -#include - -class LiteWindow -{ - Display* xDisplay; - XVisualInfo* xVisual; - Window xWin; - GLXContext xContext; - Colormap xColormap; -public: - LiteWindow() - { - xDisplay = NULL; - xVisual = NULL; - xWin = 0; - xColormap = 0; - xContext = NULL; - } - int IsValid () - { - return xContext != NULL && glXIsDirect(xDisplay, xContext); - } - virtual ~LiteWindow() - { - if(xWin) XDestroyWindow(xDisplay, xWin); - if(xContext) glXDestroyContext(xDisplay, xContext); - if(xColormap) XFreeColormap(xDisplay, xColormap); - if(xDisplay) XCloseDisplay(xDisplay); - } - void Create(int x = 0, int y = 0, const char * display = NULL) - { - if(xDisplay) return; - if(display) std::cout << "Using display ["<screen), - xVisual->visual, AllocNone); - - XSetWindowAttributes wa; - wa.event_mask = 0; - wa.border_pixel = 0; - wa.colormap = xColormap; - - xWin = XCreateWindow( xDisplay, RootWindow(xDisplay, xVisual->screen) , - x, y, 100, 100, 0, xVisual->depth, - InputOutput, xVisual->visual, - CWBorderPixel |CWColormap | CWEventMask, &wa); - - xContext = glXCreateContext(xDisplay, xVisual, 0, GL_TRUE); - } - void MakeCurrent() - { - if(xContext) glXMakeCurrent(xDisplay, xWin, xContext); - } -}; - -#endif - - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramCG.cpp b/3rdparty/SiftGPU/src/SiftGPU/ProgramCG.cpp deleted file mode 100644 index 09c3f915..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramCG.cpp +++ /dev/null @@ -1,2765 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// File: ProgramCG.cpp -// Author: Changchang Wu -// Description : implementation of cg related class. -// class ProgramCG A simple wrapper of Cg programs -// class ShaderBagCG cg shaders for SIFT -// class FilterCGGL cg gaussian filters for SIFT -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if defined(CG_SIFTGPU_ENABLED) - -#include "GL/glew.h" - -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "GlobalUtil.h" -#include "ProgramCG.h" -#include "GLTexImage.h" -#include "ShaderMan.h" -#include "FrameBufferObject.h" - - - -#if defined(_WIN32) - #pragma comment (lib, "../../lib/cg.lib") - #pragma comment (lib, "../../lib/cggl.lib") -#endif - -CGcontext ProgramCG::_Context =0; -CGprofile ProgramCG::_FProfile; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -ProgramCG::ProgramCG() -{ - _programID = NULL; -} - -ProgramCG::~ProgramCG() -{ - if(_programID) cgDestroyProgram(_programID); -} - -ProgramCG::ProgramCG(const char *code, const char** cg_compile_args, CGprofile profile) -{ - _valid = 0; - _profile = profile; - GLint epos; - const char* ati_args[] = {"-po", "ATI_draw_buffers",0}; - const char* fp40_args[] = {"-ifcvt", "none","-unroll", "all", GlobalUtil::_UseFastMath? "-fastmath" : 0, 0}; - if(cg_compile_args == NULL) cg_compile_args = GlobalUtil::_IsNvidia? (GlobalUtil::_SupportFP40? fp40_args:NULL) : ati_args; - _programID = ::cgCreateProgram(_Context, CG_SOURCE, code, profile, NULL, cg_compile_args); - if(_programID) - { - cgGLLoadProgram(_programID ); - //_texParamID = cgGetNamedParameter(_programID, "tex"); - - glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &epos); - if(epos >=0) - { - std::cout<=0) - { - std::cout< 0.9)? size : -size);\n" - " dxy.y = type < 0.2 ? 0 : ((type < 0.3 || type > 0.7 )? -size :size); \n" - " sincos(cc.b, s, c);\n" - " FragColor.x = cc.x + c*dxy.x-s*dxy.y;\n" - " FragColor.y = cc.y + c*dxy.y+s*dxy.x;}\n" - "}\n\0"); - /*FragColor = float4(tpos, 0.0, 1.0);}\n\0");*/ - - _param_genvbo_size = cgGetNamedParameter(*program, "sizes"); - - - s_display_gaussian = new ProgramCG( - "void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n" - "float r = texRECT(tex, TexCoord0.xy).r;\n" - "FragColor = float4(r, r, r, 1.0);}"); - - - s_display_dog = new ProgramCG( - "void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n" - "float g = (0.5+20.0*texRECT(tex, TexCoord0.xy).g);\n" - "FragColor = float4(g, g, g, 1.0);}" ); - - - s_display_grad = new ProgramCG( - "void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n" - "float4 cc = texRECT(tex, TexCoord0.xy); FragColor = float4(5.0 * cc.bbb, 1.0); }"); - - - s_display_keys= new ProgramCG( - "void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n" - "float4 cc = texRECT(tex, TexCoord0.xy);\n" - "if(cc.r ==1.0) FragColor = float4(1.0, 0, 0,1.0); \n" - "else {if (cc.r ==0.5) FragColor = float4(0.0,1.0,0.0,1.0); else discard;}}"); - -} - -void ShaderBagCG::SetMarginCopyParam(int xmax, int ymax) -{ - float truncate[2] = {xmax - 0.5f , ymax - 0.5f}; - cgGLSetParameter2fv(_param_margin_copy_truncate, truncate); -} - - -int ShaderBagCG::LoadKeypointShaderMR(float threshold, float edge_threshold) -{ - char buffer[10240]; - float threshold0 = threshold * 0.8f; - float threshold1 = threshold; - float threshold2 = (edge_threshold+1)*(edge_threshold+1)/edge_threshold; - int max_refine = max(2, GlobalUtil::_SubpixelLocalization); - ostrstream out(buffer, 10240); - - out << "#define THRESHOLD0 " << threshold0 << "\n" - "#define THRESHOLD1 " << threshold1 << "\n" - "#define THRESHOLD2 " << threshold2 << "\n" - "#define MAX_REFINE " << max_refine << "\n"; - out<< - "void main (\n" - "float4 TexCC : TEXCOORD0, float4 TexLC : TEXCOORD1,\n" - "float4 TexRC : TEXCOORD2, float4 TexCD : TEXCOORD3, \n" - "float4 TexCU : TEXCOORD4, float4 TexLD : TEXCOORD5, \n" - "float4 TexLU : TEXCOORD6, float4 TexRD : TEXCOORD7,\n" - "out float4 FragData0 : COLOR0, out float4 FragData1 : COLOR1, \n" - "uniform samplerRECT tex, uniform samplerRECT texU, uniform samplerRECT texD)\n" - "{\n" - " float4 v1, v2, gg;\n" - " float2 TexRU = float2(TexRC.x, TexCU.y); \n" - " float4 cc = texRECT(tex, TexCC.xy);\n" - " v1.x = texRECT(tex, TexLC.xy).g;\n" - " gg.x = texRECT(tex, TexLC.xy).r;\n" - " v1.y = texRECT(tex, TexRC.xy).g;\n" - " gg.y = texRECT(tex, TexRC.xy).r;\n" - " v1.z = texRECT(tex, TexCD.xy).g;\n" - " gg.z = texRECT(tex, TexCD.xy).r;\n" - " v1.w = texRECT(tex, TexCU.xy).g;\n" - " gg.w = texRECT(tex, TexCU.xy).r;\n" - " v2.x = texRECT(tex, TexLD.xy).g;\n" - " v2.y = texRECT(tex, TexLU.xy).g;\n" - " v2.z = texRECT(tex, TexRD.xy).g;\n" - " v2.w = texRECT(tex, TexRU.xy).g;\n" - " float2 dxdy = 0.5*(gg.yw - gg.xz); \n" - " float grad = length(dxdy);\n" - " float theta = grad==0? 0: atan2(dxdy.y, dxdy.x);\n" - " FragData0 = float4(cc.rg, grad, theta);\n" - << - " float dog = 0.0; \n" - " FragData1 = float4(0, 0, 0, 0); \n" - " float2 v3; float4 v4, v5, v6;\n" - << - " if( cc.g > THRESHOLD0 && all(cc.gggg > max(v1, v2)))\n" - " {\n" - " v3.x = texRECT(texU, TexCC.xy).g;\n" - " v4.x = texRECT(texU, TexLC.xy).g;\n" - " v4.y = texRECT(texU, TexRC.xy).g;\n" - " v4.z = texRECT(texU, TexCD.xy).g;\n" - " v4.w = texRECT(texU, TexCU.xy).g;\n" - " v6.x = texRECT(texU, TexLD.xy).g;\n" - " v6.y = texRECT(texU, TexLU.xy).g;\n" - " v6.z = texRECT(texU, TexRD.xy).g;\n" - " v6.w = texRECT(texU, TexRU.xy).g;\n" - " if(cc.g < v3.x || any(cc.gggg v3.x || any(cc.gggg>v4.xyzw || cc.gggg>v6.xyzw))return; \n" - " v3.y = texRECT(texD, TexCC.xy).g;\n" - " v5.x = texRECT(texD, TexLC.xy).g;\n" - " v5.y = texRECT(texD, TexRC.xy).g;\n" - " v5.z = texRECT(texD, TexCD.xy).g;\n" - " v5.w = texRECT(texD, TexCU.xy).g;\n" - " v6.x = texRECT(texD, TexLD.xy).g;\n" - " v6.y = texRECT(texD, TexLU.xy).g;\n" - " v6.z = texRECT(texD, TexRD.xy).g;\n" - " v6.w = texRECT(texD, TexRU.xy).g;\n" - " if(cc.g > v3.y || any(cc.gggg>v5.xyzw || cc.gggg>v6.xyzw))return; \n" - " dog = 0.5 ; \n" - " }\n" - " else\n" - " return;\n" - << - " int i = 0; \n" - " float2 offset = float2(0, 0);\n" - " float2 offsets = float2(0, 0);\n" - " float3 dxys; bool key_moved; \n" - " float fx, fy, fs; \n" - " float fxx, fyy, fxy; \n" - " float fxs, fys, fss; \n" - " do\n" - " {\n" - " dxys = float3(0, 0, 0);\n" - " offset = float2(0, 0);\n" - " float4 D2 = v1.xyzw - cc.gggg;\n" - " fxx = D2.x + D2.y;\n" - " fyy = D2.z + D2.w;\n" - " float2 D4 = v2.xw - v2.yz;\n" - " fxy = 0.25*(D4.x + D4.y);\n" - " float2 D5 = 0.5*(v1.yw-v1.xz); \n" - " fx = D5.x;\n" - " fy = D5.y ; \n" - " fs = 0.5*( v3.x - v3.y ); \n" - " fss = v3.x + v3.y - cc.g - cc.g;\n" - " fxs = 0.25 * ( v4.y + v5.x - v4.x - v5.y);\n" - " fys = 0.25 * ( v4.w + v5.z - v4.z - v5.w);\n" - " float4 A0, A1, A2 ; \n" - " A0 = float4(fxx, fxy, fxs, -fx); \n" - " A1 = float4(fxy, fyy, fys, -fy); \n" - " A2 = float4(fxs, fys, fss, -fs); \n" - " float3 x3 = abs(float3(fxx, fxy, fxs)); \n" - " float maxa = max(max(x3.x, x3.y), x3.z); \n" - " if(maxa > 1e-10 ) \n" - " {\n" - " if(x3.y ==maxa ) \n" - " { \n" - " float4 TEMP = A1; A1 = A0; A0 = TEMP; \n" - " }else if( x3.z == maxa ) \n" - " { \n" - " float4 TEMP = A2; A2 = A0; A0 = TEMP; \n" - " } \n" - " A0 /= A0.x; \n" - " A1 -= A1.x * A0; \n" - " A2 -= A2.x * A0; \n" - " float2 x2 = abs(float2(A1.y, A2.y)); \n" - " if( x2.y > x2.x ) \n" - " { \n" - " float3 TEMP = A2.yzw; \n" - " A2.yzw = A1.yzw; \n" - " A1.yzw = TEMP; \n" - " x2.x = x2.y; \n" - " } \n" - " if(x2.x > 1e-10) \n" - " {\n" - " A1.yzw /= A1.y; \n" - " A2.yzw -= A2.y * A1.yzw; \n" - " if(abs(A2.z) > 1e-10) \n" - " {\n" - // compute dx, dy, ds: - << - " dxys.z = A2.w /A2.z; \n" - " dxys.y = A1.w - dxys.z*A1.z; \n" - " dxys.x = A0.w - dxys.z*A0.z - dxys.y*A0.y; \n" - " }\n" - " }\n" - " }\n" - " offset.x = dxys.x > 0.6 ? 1 : 0 + dxys.x < -0.6 ? -1 : 0;\n" - " offset.y = dxys.y > 0.6 ? 1 : 0 + dxys.y < - 0.6? -1 : 0;\n" - " i++; key_moved = i < MAX_REFINE && any(abs(offset)>0) ; \n" - " if(key_moved)\n" - " {\n" - " offsets += offset; \n" - " cc = texRECT(tex, TexCC.xy + offsets);\n" - " v1.x = texRECT(tex , TexLC.xy + offsets).g;\n" - " v1.y = texRECT(tex , TexRC.xy + offsets).g;\n" - " v1.z = texRECT(tex , TexCD.xy + offsets).g;\n" - " v1.w = texRECT(tex , TexCU.xy + offsets).g;\n" - " v2.x = texRECT(tex , TexLD.xy + offsets).g;\n" - " v2.y = texRECT(tex , TexLU.xy + offsets).g;\n" - " v2.z = texRECT(tex , TexRD.xy + offsets).g;\n" - " v2.w = texRECT(tex , TexRU.xy + offsets).g;\n" - " v3.x = texRECT(texU, TexCC.xy + offsets).g;\n" - " v4.x = texRECT(texU, TexLC.xy + offsets).g;\n" - " v4.y = texRECT(texU, TexRC.xy + offsets).g;\n" - " v4.z = texRECT(texU, TexCD.xy + offsets).g;\n" - " v4.w = texRECT(texU, TexCU.xy + offsets).g;\n" - " v3.y = texRECT(texD, TexCC.xy + offsets).g;\n" - " v5.x = texRECT(texD, TexLC.xy + offsets).g;\n" - " v5.y = texRECT(texD, TexRC.xy + offsets).g;\n" - " v5.z = texRECT(texD, TexCD.xy + offsets).g;\n" - " v5.w = texRECT(texD, TexCU.xy + offsets).g;\n" - " }\n" - " }while(key_moved);\n" - << - " bool test1 = (abs(cc.g + 0.5*dot(float3(fx, fy, fs), dxys ))> THRESHOLD1) ;\n" - " float test2_v1= fxx*fyy - fxy *fxy; \n" - " float test2_v2 = (fxx+fyy); \n" - " test2_v2 = test2_v2*test2_v2;\n" - " bool test2 = test2_v1>0 && test2_v2 < THRESHOLD2 * test2_v1; \n " - //keep the point when the offset is less than 1 - << - " FragData1 = test1 && test2 && all( abs(dxys) < 1)? float4( dog, dxys.xy+offsets, dxys.z) : float4(0, 0, 0, 0); \n" - "}\n" - <<'\0'; - - ProgramCG * program; - s_keypoint = program = new ProgramCG(buffer); - //parameter - _param_dog_texu = cgGetNamedParameter(*program, "texU"); - _param_dog_texd = cgGetNamedParameter(*program, "texD"); - - return 1; - -} - -//keypoint detection shader -//1. compare with 26 neighbours -//2. sub-pixel sub-scale localization -//3. output: [dog, offset(x,y,s)] - -void ShaderBagCG:: LoadKeypointShader(float threshold, float edge_threshold) -{ - char buffer[10240]; - float threshold0 = threshold* (GlobalUtil::_SubpixelLocalization?0.8f:1.0f); - float threshold1 = threshold; - float threshold2 = (edge_threshold+1)*(edge_threshold+1)/edge_threshold; - ostrstream out(buffer, 10240); - out< THRESHOLD0 && all(cc.gggg > max(v1, v2))?1.0: 0.0;\n" - " dog = cc.g < -THRESHOLD0 && all(cc.gggg < min(v1, v2))?0.5: dog;\n"; - - pos = out.tellp(); - //do edge supression first.. - //vector v1 is < (-1, 0), (1, 0), (0,-1), (0, 1)> - //vector v2 is < (-1,-1), (-1,1), (1,-1), (1, 1)> - - out<< - " if(dog == 0.0) return;\n" - " float fxx, fyy, fxy; \n" - " float4 D2 = v1.xyzw - cc.gggg;\n" - " float2 D4 = v2.xw - v2.yz;\n" - " fxx = D2.x + D2.y;\n" - " fyy = D2.z + D2.w;\n" - " fxy = 0.25*(D4.x + D4.y);\n" - " float fxx_plus_fyy = fxx + fyy;\n" - " float score_up = fxx_plus_fyy*fxx_plus_fyy; \n" - " float score_down = (fxx*fyy - fxy*fxy);\n" - " if( score_down <= 0 || score_up > THRESHOLD2 * score_down)return;\n" - //... - << - " float2 D5 = 0.5*(v1.yw-v1.xz); \n" - " float fx = D5.x, fy = D5.y ; \n" - " float fs, fss , fxs, fys ; \n" - " float2 v3; float4 v4, v5, v6;\n" - //read 9 pixels of upper level - << - " v3.x = texRECT(texU, TexCC.xy).g;\n" - " v4.x = texRECT(texU, TexLC.xy).g;\n" - " v4.y = texRECT(texU, TexRC.xy).g;\n" - " v4.z = texRECT(texU, TexCD.xy).g;\n" - " v4.w = texRECT(texU, TexCU.xy).g;\n" - " v6.x = texRECT(texU, TexLD.xy).g;\n" - " v6.y = texRECT(texU, TexLU.xy).g;\n" - " v6.z = texRECT(texU, TexRD.xy).g;\n" - " v6.w = texRECT(texU, TexRU.xy).g;\n" - //compare with 9 pixels of upper level - //read and compare with 9 pixels of lower level - //the maximum case - << - " if(dog == 1.0)\n" - " {\n" - " bool4 test = cc.gggg < max(v4, v6); \n" - " if(cc.g < v3.x || any(test.xy||test.zw))return; \n" - " v3.y = texRECT(texD, TexCC.xy).g;\n" - " v5.x = texRECT(texD, TexLC.xy).g;\n" - " v5.y = texRECT(texD, TexRC.xy).g;\n" - " v5.z = texRECT(texD, TexCD.xy).g;\n" - " v5.w = texRECT(texD, TexCU.xy).g;\n" - " v6.x = texRECT(texD, TexLD.xy).g;\n" - " v6.y = texRECT(texD, TexLU.xy).g;\n" - " v6.z = texRECT(texD, TexRD.xy).g;\n" - " v6.w = texRECT(texD, TexRU.xy).g;\n" - " test = cc.ggggmin(v4, v6); \n" - " if(cc.g > v3.x || any(test.xy||test.zw))return; \n" - " v3.y = texRECT(texD, TexCC.xy).g;\n" - " v5.x = texRECT(texD, TexLC.xy).g;\n" - " v5.y = texRECT(texD, TexRC.xy).g;\n" - " v5.z = texRECT(texD, TexCD.xy).g;\n" - " v5.w = texRECT(texD, TexCU.xy).g;\n" - " v6.x = texRECT(texD, TexLD.xy).g;\n" - " v6.y = texRECT(texD, TexLU.xy).g;\n" - " v6.z = texRECT(texD, TexRD.xy).g;\n" - " v6.w = texRECT(texD, TexRU.xy).g;\n" - " test = cc.gggg>min(v5, v6); \n" - " if(cc.g > v3.y || any(test.xy||test.zw))return; \n" - " }\n"; - - if(GlobalUtil::_SubpixelLocalization) - - // sub-pixel localization FragData1 = float4(dog, 0, 0, 0); return; - out << - " fs = 0.5*( v3.x - v3.y ); //bug fix 9/12/2007 \n" - " fss = v3.x + v3.y - cc.g - cc.g;\n" - " fxs = 0.25 * ( v4.y + v5.x - v4.x - v5.y);\n" - " fys = 0.25 * ( v4.w + v5.z - v4.z - v5.w);\n" - - ///////////////////////////////////////////////////////////////// - // let dog difference be quatratic function of dx, dy, ds; - // df(dx, dy, ds) = fx * dx + fy*dy + fs * ds + - // + 0.5 * ( fxx * dx * dx + fyy * dy * dy + fss * ds * ds) - // + (fxy * dx * dy + fxs * dx * ds + fys * dy * ds) - // (fx, fy, fs, fxx, fyy, fss, fxy, fxs, fys are the derivatives) - - //the local extremum satisfies - // df/dx = 0, df/dy = 0, df/dz = 0 - - //that is - // |-fx| | fxx fxy fxs | |dx| - // |-fy| = | fxy fyy fys | * |dy| - // |-fs| | fxs fys fss | |ds| - // need to solve dx, dy, ds - - // Use Gauss elimination to solve the linear system - << - " float3 dxys = float3(0.0); \n" - " float4 A0, A1, A2 ; \n" - " A0 = float4(fxx, fxy, fxs, -fx); \n" - " A1 = float4(fxy, fyy, fys, -fy); \n" - " A2 = float4(fxs, fys, fss, -fs); \n" - " float3 x3 = abs(float3(fxx, fxy, fxs)); \n" - " float maxa = max(max(x3.x, x3.y), x3.z); \n" - " if(maxa >= 1e-10 ) { \n" - " if(x3.y ==maxa ) \n" - " { \n" - " float4 TEMP = A1; A1 = A0; A0 = TEMP; \n" - " }else if( x3.z == maxa ) \n" - " { \n" - " float4 TEMP = A2; A2 = A0; A0 = TEMP; \n" - " } \n" - " A0 /= A0.x; \n" - " A1 -= A1.x * A0; \n" - " A2 -= A2.x * A0; \n" - " float2 x2 = abs(float2(A1.y, A2.y)); \n" - " if( x2.y > x2.x ) \n" - " { \n" - " float3 TEMP = A2.yzw; \n" - " A2.yzw = A1.yzw; \n" - " A1.yzw = TEMP; \n" - " x2.x = x2.y; \n" - " } \n" - " if(x2.x >= 1e-10) { \n" - " A1.yzw /= A1.y; \n" - " A2.yzw -= A2.y * A1.yzw; \n" - " if(abs(A2.z) >= 1e-10) { \n" - // compute dx, dy, ds: - << - " dxys.z = A2.w /A2.z; \n" - " dxys.y = A1.w - dxys.z*A1.z; \n" - " dxys.x = A0.w - dxys.z*A0.z - dxys.y*A0.y; \n" - - //one more threshold which I forgot in versions prior to 286 - << - " bool bugfix_test = (abs(cc.g + 0.5*dot(float3(fx, fy, fs), dxys )) < THRESHOLD1) ;\n" - " if(bugfix_test || any(abs(dxys) >= 1.0)) dog = 0; \n" - " }}}\n" - //keep the point when the offset is less than 1 - << - " FragData1 = float4( dog, dxys); \n" - "}\n" <<'\0'; - - else out<< - " FragData1 = float4( dog, 0, 0, 0) ; \n" - "}\n" <<'\0'; - - ProgramCG * program; - s_keypoint = program = new ProgramCG(buffer); - if(!program->IsValidProgram()) - { - delete program; - out.seekp(pos); - out << - " FragData1 = float4( fabs(cc.g) > 2.0 * THRESHOLD0? dog : 0, 0, 0, 0) ; \n" - "}\n" <<'\0'; - s_keypoint = program = new ProgramCG(buffer); - GlobalUtil::_SubpixelLocalization = 0; - std::cerr<<"Detection simplified on this hardware"<= width) - { - out<<"0"; - }else if(offset[j]==0.0) - { - out<<"or"; - }else - { - out<<"texRECT(tex, TexCoord0.xy + float2(float("<= width) out<<"0"; - else out<= height) - { - out<<"0"; - }else if(offset[j]==0.0) - { - out<<"orb.y"; - }else - { - out<<"texRECT(tex, TexCoord0.xy + float2(0, float("<= height) out<<"0"; - else out<>1; - float * pf = kernel + halfwidth; - int nhpixel = (halfwidth+1)>>1; //how many neighbour pixels need to be looked up - int npixel = (nhpixel<<1)+1;// - char buffer[10240]; - float weight[3]; - ostrstream out(buffer, 10240); - out< halfwidth? 0 : pf[xwn]; - } - //if(weight[1]!=0.0) out<<"FragColor += "<>1; - float * pf = kernel + halfh; - int nhpixel = (halfh+1)>>1; //how many neighbour pixels need to be looked up - int npixel = (nhpixel<<1)+1;// - char buffer[10240]; - float weight[3]; - ostrstream out(buffer, 10240); - out< halfh? 0 : pf[ywn]; - } - //if(weight[1]!=0.0) out<<"FragColor += "<0.0);\n" - "}"); - - s_genlist_init_ex = program = new ProgramCG( - "void main (uniform float2 bbox, \n" - "uniform samplerRECT tex, \n" - "in float4 TexCoord0 : TEXCOORD0,\n" - "in float4 TexCoord1 : TEXCOORD1, \n" - "in float4 TexCoord2 : TEXCOORD2, \n" - "in float4 TexCoord3 : TEXCOORD3,\n" - "out float4 FragColor : COLOR0){\n" - "float4 helper = float4( \n" - "texRECT(tex, TexCoord0.xy).r, texRECT(tex, TexCoord1.xy).r,\n" - "texRECT(tex, TexCoord2.xy).r, texRECT(tex, TexCoord3.xy).r);\n" - "bool4 helper4 = bool4(TexCoord0.xy < bbox, TexCoord3.xy < bbox); \n" - "bool4 helper2 = helper4.xzxz && helper4.yyww; \n" - "FragColor = float4(helper2 && (helper>0.0 ));\n" - "}"); - _param_genlist_init_bbox = cgGetNamedParameter( *program, "bbox"); - - - //reduction ... - s_genlist_histo = new ProgramCG( - "void main (\n" - "uniform samplerRECT tex, in float2 TexCoord0 : TEXCOORD0,\n" - "in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, in float2 TexCoord3 : TEXCOORD3,\n" - "out float4 FragColor : COLOR0){\n" - "float4 helper; float4 helper2; \n" - "helper = texRECT(tex, TexCoord0); helper2.xy = helper.xy + helper.zw; \n" - "helper = texRECT(tex, TexCoord1); helper2.zw = helper.xy + helper.zw; \n" - "FragColor.rg = helper2.xz + helper2.yw;\n" - "helper = texRECT(tex, TexCoord2); helper2.xy = helper.xy + helper.zw; \n" - "helper = texRECT(tex, TexCoord3); helper2.zw = helper.xy + helper.zw; \n" - "FragColor.ba= helper2.xz+helper2.yw;\n" - "}"); - - - //read of the first part, which generates tex coordinates - - s_genlist_start= program = LoadGenListStepShader(1, 1); - _param_ftex_width= cgGetNamedParameter(*program, "width"); - _param_genlist_start_tex0 = cgGetNamedParameter(*program, "tex0"); - //stepping - s_genlist_step = program = LoadGenListStepShader(0, 1); - _param_genlist_step_tex= cgGetNamedParameter(*program, "tex"); - _param_genlist_step_tex0= cgGetNamedParameter(*program, "tex0"); - - -} - -ProgramCG* ShaderBagCG::LoadGenListStepShader(int start, int step) -{ - int i; - char buffer[10240]; - //char chanels[5] = "rgba"; - ostrstream out(buffer, 10240); - out<<"void main(out float4 FragColor : COLOR0, \n"; - - for(i = 0; i < step; i++) out<<"uniform samplerRECT tex"<0) - { - out<<"float2 cpos = float2(-0.5, 0.5);\t float2 opos;\n"; - for(i = 0; i < step; i++) - { -//#define SETP_CODE_2 - -#ifndef SETP_CODE_2 -/* out<<"cc = texRECT(tex"< float3(sum3[0], sum3[1], sum3[2]));\n"; - out<<"opos.y = -0.5 + cmp.y; opos.x = -0.5 + cmp.x + (cmp.z - cmp.y);\n"; - out<<"index -= dot(cmp, cc.rgb);\n"; - out<<"pos = (pos + pos + opos);\n";*/ - - out<<"cc = texRECT(tex"<=dim-1)) " - " //discard; \n" - " { FragData0 = FragData1 = float4(0.0); return; }\n" - " float anglef = texRECT(tex, coord).z;\n" - " if(anglef > M_PI) anglef -= TWO_PI;\n" - " float sigma = texRECT(tex, coord).w; \n" - " float spt = abs(sigma * WF); //default to be 3*sigma \n"; - - //rotation - out<< - " float4 cscs, rots; \n" - " sincos(anglef, cscs.y, cscs.x); \n" - " cscs.zw = - cscs.xy; \n" - " rots = cscs /spt; \n" - " cscs *= spt; \n"; - - //here cscs is actually (cos, sin, -cos, -sin) * (factor: 3)*sigma - //and rots is (cos, sin, -cos, -sin ) /(factor*sigma) - //devide the 4x4 sift grid into 16 1x1 block, and each corresponds to a shader thread - //To use linear interoplation, 1x1 is increased to 2x2, by adding 0.5 to each side - out<< - " float4 temp; float2 pt, offsetpt; \n" - " /*the fraction part of idx is .5*/ \n" - " offsetpt.x = 4.0 * frac(idx*0.25) - 2.0; \n" - " offsetpt.y = floor(idx*0.25) - 1.5; \n" - " temp = cscs.xwyx*offsetpt.xyxy; \n" - " pt = pos + temp.xz + temp.yw; \n"; - - //get a horizontal bounding box of the rotated rectangle - out<< - " float2 bwin = abs(cscs.xy); \n" - " float bsz = bwin.x + bwin.y; \n" - " float4 sz; float2 spos; \n" - " sz.xy = max(pt - bsz, float2(1,1));\n" - " sz.zw = min(pt + bsz, dim - 2); \n" - " sz = floor(sz)+0.5;"; //move sample point to pixel center - - //get voting for two box - out<<"\n" - " float4 DA, DB; \n" - " DA = DB = float4(0, 0, 0, 0); \n" - " for(spos.y = sz.y; spos.y <= sz.w; spos.y+=1.0) \n" - " { \n" - " for(spos.x = sz.x; spos.x <= sz.z; spos.x+=1.0) \n" - " { \n" - " float2 diff = spos - pt; \n" - " temp = rots.xywx * diff.xyxy; \n" - " float2 nxy = (temp.xz + temp.yw); \n" - " float2 nxyn = abs(nxy); \n" - " if(all(nxyn < float2(1.0)))\n" - " {\n" - " float4 cc = texRECT(gradTex, spos); \n" - " float mod = cc.b; float angle = cc.a; \n" - " float theta0 = (anglef - angle)*RPI; \n" - " float theta = theta0 < 0? theta0 + 8.0 : theta0; // fmod(theta0 + 8.0, 8.0); \n" - " diff = nxy + offsetpt.xy; \n" - " float ww = exp(-0.125*dot(diff, diff));\n" - " float2 weights = 1 - nxyn;\n" - " float weight = weights.x * weights.y *mod*ww; \n" - " float theta1 = floor(theta); \n" - " float weight2 = (theta - theta1) * weight; \n" - " float weight1 = weight - weight2;\n" - " DA += float4(theta1 == float4(0, 1, 2, 3))*weight1; \n" - " DA += float4(theta1 == float4(7, 0, 1, 2))*weight2; \n" - " DB += float4(theta1 == float4(4, 5, 6, 7))*weight1; \n" - " DB += float4(theta1 == float4(3, 4, 5, 6))*weight2; \n" - " }\n" - " }\n" - " }\n"; - - out<< - " FragData0 = DA; FragData1 = DB;\n" - "}\n"<<'\0'; - - ProgramCG * program; - s_descriptor_fp = program = new ProgramCG(buffer); - _param_descriptor_gtex = cgGetNamedParameter(*program, "gradTex"); - _param_descriptor_size = cgGetNamedParameter(*program, "size"); - _param_descriptor_dsize = cgGetNamedParameter(*program, "dsize"); - - -} - -//the shader that computes the descriptors -void ShaderBagCG::LoadDescriptorShader() -{ - GlobalUtil::_DescriptorPPT = 16; - LoadDescriptorShaderF2(); -} - -void ShaderBagCG::LoadOrientationShader() -{ - - char buffer[10240]; - ostrstream out(buffer,10240); - - - out<<"\n" - "#define GAUSSIAN_WF "<1 && GlobalUtil::_OrientationPack2 == 0) - out<<", out float4 OrientationData : COLOR1"; - - if(GlobalUtil::_SubpixelLocalization || GlobalUtil::_KeepExtremumSign) - { - //data for sub-pixel localization - out<<", uniform samplerRECT texS"; - } - - //use 9 float4 to store histogram of 36 directions - out<<") \n" - "{ \n" - " float4 bins[10]; \n" - " for (int i=0; i<9; i++) bins[i] = float4(0,0,0,0); \n" - " const float4 loc = texRECT(tex, TexCoord0); \n" - " const bool orientation_mode = (size.z != 0); \n" - " float2 pos = loc.xy; \n" - " float sigma = orientation_mode? abs(size.z) : loc.w; \n"; - if(GlobalUtil::_SubpixelLocalization || GlobalUtil::_KeepExtremumSign) - { - out<< - " if(orientation_mode) {\n" - " float4 keyx = texRECT(texS, pos);\n" - " sigma = sigma * pow(size.w, keyx.w); \n" - " pos.xy = pos.xy + keyx.yz; \n" - " #if " << GlobalUtil::_KeepExtremumSign << "\n" - " if(keyx.x<0.6) sigma = - sigma;\n" - " #endif\n" - " }\n"; - } - - out<< - " //bool fixed_orientation = (size.z < 0); \n" - " if(size.z < 0) {FeatureData = float4(pos, 0, sigma); return;}" - " const float gsigma = sigma * GAUSSIAN_WF; \n" - " const float2 win = abs(sigma.xx) * (SAMPLE_WF * GAUSSIAN_WF); \n" - " const float2 dim = size.xy; \n" - " const float dist_threshold = win.x*win.x+0.5; \n" - " const float factor = -0.5/(gsigma*gsigma); \n" - " float4 sz; float2 spos; \n" - " //if(any(pos.xy <= 1)) discard; \n" - " sz.xy = max( pos - win, float2(1,1)); \n" - " sz.zw = min( pos + win, dim-2); \n" - " sz = floor(sz)+0.5;"; - //loop to get the histogram - - out<<"\n" - " for(spos.y = sz.y; spos.y <= sz.w; spos.y+=1.0) \n" - " { \n" - " for(spos.x = sz.x; spos.x <= sz.z; spos.x+=1.0) \n" - " { \n" - " const float2 offset = spos - pos; \n" - " const float sq_dist = dot(offset,offset); \n" - " if( sq_dist < dist_threshold){ \n" - " const float4 cc = texRECT(gradTex, spos); \n" - " const float grad = cc.b; float theta = cc.a; \n" - " float idx = floor(degrees(theta)*0.1); \n" - " const float weight = grad*exp(sq_dist * factor); \n" - " if(idx < 0 ) idx += 36; \n" - " const float vidx = 4.0 * fract(idx * 0.25);//fmod(idx, 4); \n" - " const float4 inc = weight*float4(vidx == float4(0,1,2,3)); "; - - if(GlobalUtil::_UseDynamicIndexing && strcmp(cgGetProfileString(ProgramCG::_FProfile), "gp4fp")==0) -// if(ProgramCG::_FProfile == CG_PROFILE_GPU_FP) this enumerant is not defined in cg1.5 - { - //gp_fp supports dynamic indexing - out<<"\n" - " int iidx = int(floor(idx*0.25)); \n" - " bins[iidx]+=inc; \n" - " } \n" - " } \n" - " }"; - - }else - { - //nvfp40 still does not support dynamic array indexing - //unrolled binary search... - out<<"\n" - " if(idx < 16) \n" - " { \n" - " if(idx < 8) \n" - " { \n" - " if(idx < 4) { bins[0]+=inc;} \n" - " else { bins[1]+=inc;} \n" - " }else \n" - " { \n" - " if(idx < 12){ bins[2]+=inc;} \n" - " else { bins[3]+=inc;} \n" - " } \n" - " }else if(idx < 32) \n" - " { \n" - " if(idx < 24) \n" - " { \n" - " if(idx <20) { bins[4]+=inc;} \n" - " else { bins[5]+=inc;} \n" - " }else \n" - " { \n" - " if(idx < 28){ bins[6]+=inc;} \n" - " else { bins[7]+=inc;} \n" - " } \n" - " }else \n" - " { \n" - " bins[8]+=inc; \n" - " } \n" - " } \n" - " } \n" - " }"; - - } - - WriteOrientationCodeToStream(out); - - ProgramCG * program; - s_orientation = program = new ProgramCG(buffer); - _param_orientation_gtex = cgGetNamedParameter(*program, "gradTex"); - _param_orientation_size = cgGetNamedParameter(*program, "size"); - _param_orientation_stex = cgGetNamedParameter(*program, "texS"); -} - -void ShaderBagCG::WriteOrientationCodeToStream(std::ostream& out) -{ - //smooth histogram and find the largest -/* - smoothing kernel: (1 3 6 7 6 3 1 )/27 - the same as 3 pass of (1 1 1)/3 averaging - maybe better to use 4 pass on the vectors... -*/ - - - //the inner loop on different array numbers is always unrolled in fp40 - - //bug fixed here:) - out<<"\n" - " float3x3 mat1 = float3x3(1, 0, 0, 3, 1, 0, 6, 3, 1)/27.0;; //bug fix.. \n" - " float4x4 mat2 = float4x4( 7, 6, 3, 1, 6, 7, 6, 3, 3, 6, 7, 6, 1, 3, 6, 7)/27.0;;\n" - " for (int j=0; j<2; j++) \n" - " { \n" - " float4 prev = bins[8]; \n" - " bins[9] = bins[0]; \n" - " for (int i=0; i<9; i++) \n" - " { \n" - " float4 newb = mul ( bins[i], mat2); \n" - " newb.xyz += mul ( prev.yzw, mat1); \n" - " prev = bins[i]; \n" - " newb.wzy += mul ( bins[i+1].zyx, mat1); \n" - " bins[i] = newb; \n" - " } \n" - " }"; - - - //find the maximum voting - out<<"\n" - " float4 maxh; float2 maxh2; float4 maxh4 = bins[0]; \n" - " for (int i=1; i<9; i++) maxh4 = max(maxh4, bins[i]); \n" - " maxh2 = max(maxh4.xy, maxh4.zw); maxh = float4(max(maxh2.x, maxh2.y));"; - - char *testpeak_code; - char *savepeak_code; - - - - //save two/three/four orientations with the largest votings? - - // - if(GlobalUtil::_MaxOrientation>1) - { - out<<"\n" - " float4 Orientations = float4(0, 0, 0, 0); \n" - " float4 weights = float4(0,0,0,0); "; - - testpeak_code = "\n" - " {test = bins[i]>hh;"; - - //save the orientations in weight-decreasing order - if(GlobalUtil::_MaxOrientation ==2) - { - savepeak_code = "\n" - " if(weight <=weights.g){}\n" - " else if(weight >weights.r)\n" - " {weights.rg = float2(weight, weights.r); Orientations.rg = float2(th, Orientations.r);}\n" - " else {weights.g = weight; Orientations.g = th;}"; - - }else if(GlobalUtil::_MaxOrientation ==3) - { - savepeak_code = "\n" - " if(weight <=weights.b){}\n" - " else if(weight >weights.r)\n" - " {weights.rgb = float3(weight, weights.rg); Orientations.rgb = float3(th, Orientations.rg);}\n" - " else if(weight >weights.g)\n" - " {weights.gb = float2(weight, weights.g); Orientations.gb = float2(th, Orientations.g);}\n" - " else {weights.b = weight; Orientations.b = th;}"; - }else - { - savepeak_code = "\n" - " if(weight <=weights.a){}\n" - " else if(weight >weights.r)\n" - " {weights = float4(weight, weights.rgb); Orientations = float4(th, Orientations.rgb);}\n" - " else if(weight >weights.g)\n" - " {weights.gba = float3(weight, weights.gb); Orientations.gba = float3(th, Orientations.gb);}\n" - " else if(weight >weights.b)\n" - " {weights.ba = float2(weight, weights.b); Orientations.ba = float2(th, Orientations.b);}\n" - " else {weights.a = weight; Orientations.a = th;}"; - } - - }else - { - out<<"\n" - " float Orientations = 0; "; - testpeak_code ="\n" - " if(npeaks==0){ \n" - " test = (bins[i] >= maxh) ;"; - savepeak_code="\n" - " npeaks++; \n" - " Orientations = th.x;"; - - } - - //find the peaks - //the following loop will be unrolled - - out<<"\n" - " const float4 hh = maxh * ORIENTATION_THRESHOLD; bool4 test; \n" - " bins[9] = bins[0]; \n" - " float npeaks = 0, k = 0; \n" - " float prevb = bins[8].w; \n" - " for (int i = 0; i <9 ; i++) \n" - " {" - < prevb && bins[i].x > bins[i].y ) \n" - " { \n" - " float di = 0.5 * (bins[i].y-prevb) / (bins[i].x *2.0 -bins[i].y -prevb) ; \n" - " float th = (k+di+0.5); float weight = bins[i].x;" - < bins[i].xz) ) \n" - " { \n" - " float di = 0.5 * (bins[i].z-bins[i].x) / (bins[i].y * 2.0 - bins[i].z - bins[i].x) ; \n" - " float th = (k+di+1.5); float weight = bins[i].y; " - < bins[i].yw) ) \n" - " { \n" - " float di = 0.5 * (bins[i].w-bins[i].y) / (bins[i].z * 2.0-bins[i].w-bins[i].y) ; \n" - " float th = (k+di+2.5); float weight = bins[i].z; " - < bins[i].z && bins[i].w > bins[i+1].x ) \n" - " { \n" - " float di = 0.5 * (bins[i+1].x-bins[i].z) / (bins[i].w * 2.0- bins[i+1].x-bins[i].z) ; \n" - " float th = (k+di+3.5); float weight = bins[i].w; " - <1) - { - out<<"\n" - " if(orientation_mode){\n" - " npeaks = dot(float4(1,1," - <<(GlobalUtil::_MaxOrientation>2 ? 1 : 0)<<"," - <<(GlobalUtil::_MaxOrientation >3? 1 : 0)<<"), float4(weights>hh));\n" - " OrientationData = radians((Orientations )*10.0);\n" - " FeatureData = float4(pos, npeaks, sigma);\n" - " }else{\n" - " FeatureData = float4(pos, radians((Orientations.x)*10.0), sigma);\n" - " }\n"; - }else - { - out<<"\n" - " FeatureData = float4(pos, radians((Orientations.x)*10.0), sigma);"; - } - //end - out<<"\n" - "}\n"<<'\0'; - - -} - -void ShaderBagCG::SetSimpleOrientationInput(int oTex, float sigma, float sigma_step) -{ - cgGLSetTextureParameter(_param_orientation_gtex, oTex); - cgGLEnableTextureParameter(_param_orientation_gtex); - cgGLSetParameter1f(_param_orientation_size, sigma); -} - -void ShaderBagCG::SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int stex, float step) -{ - /// - cgGLSetTextureParameter(_param_orientation_gtex, gtex); - cgGLEnableTextureParameter(_param_orientation_gtex); - - if((GlobalUtil::_SubpixelLocalization || GlobalUtil::_KeepExtremumSign)&& stex) - { - //specify texutre for subpixel subscale localization - cgGLSetTextureParameter(_param_orientation_stex, stex); - cgGLEnableTextureParameter(_param_orientation_stex); - } - - float size[4]; - size[0] = (float)width; - size[1] = (float)height; - size[2] = sigma; - size[3] = step; - cgGLSetParameter4fv(_param_orientation_size, size); - -} - -void ShaderBagCG::SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma) -{ - /// - cgGLSetTextureParameter(_param_descriptor_gtex, gtex); - cgGLEnableTextureParameter(_param_descriptor_gtex); - - float dsize[4] ={dwidth, 1.0f/dwidth, fwidth, 1.0f/fwidth}; - cgGLSetParameter4fv(_param_descriptor_dsize, dsize); - float size[3]; - size[0] = width; - size[1] = height; - size[2] = GlobalUtil::_DescriptorWindowFactor; - cgGLSetParameter3fv(_param_descriptor_size, size); -} - - -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////PACKED VERSION?/////////////////////////////////// - -ShaderBagPKCG::ShaderBagPKCG() -{ - ProgramCG::InitContext(); -} - -void ShaderBagPKCG::UnloadProgram() -{ - - cgGLUnbindProgram(ProgramCG::_FProfile); - cgGLDisableProfile(ProgramCG::_FProfile); -} - -void ShaderBagPKCG::LoadFixedShaders() -{ - ProgramCG * program; - - /* - char *rgb2gray_packing_code = - "void main(uniform samplerRECT rgbTex, in float4 TexCoord0 : TEXCOORD0, \n" - " in float4 TexCoord1 : TEXCOORD1, in float4 TexCoord2 : TEXCOORD2, \n" - " in float4 TexCoord3 : TEXCOORD3, out float4 FragData : COLOR0){\n" - " const float3 weight = vec3(0.299, 0.587, 0.114);\n" - " FragData.r = dot(weight, texRECT(rgbTex,TexCoord0.st ).rgb);\n" - " FragData.g = dot(weight, texRECT(rgbTex,TexCoord1.st ).rgb);\n" - " FragData.b = dot(weight, texRECT(rgbTex,TexCoord2.st ).rgb);\n" - " FragData.a = dot(weight, texRECT(rgbTex,TexCoord3.st ).rgb);}";// - s_gray = new ProgramCG( rgb2gray_packing_code); - */ - - s_gray = new ProgramCG( - "void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n" - "float intensity = dot(float3(0.299, 0.587, 0.114), texRECT(tex,TexCoord0.xy ).rgb);\n" - "FragColor= float4(intensity, intensity, intensity, 1.0);}" ); - - - s_sampling = new ProgramCG( - "void main(uniform samplerRECT tex, in float4 TexCoord0 : TEXCOORD0, \n" - " in float4 TexCoord1 : TEXCOORD1, in float4 TexCoord2 : TEXCOORD2, \n" - " in float4 TexCoord3 : TEXCOORD3, out float4 FragData : COLOR0 ){\n" - " FragData= float4( texRECT(tex,TexCoord0.st ).r,texRECT(tex,TexCoord1.st ).r,\n" - " texRECT(tex,TexCoord2.st ).r,texRECT(tex,TexCoord3.st ).r);}" ); - - - s_margin_copy = program = new ProgramCG( - "void main(in float4 texCoord0: TEXCOORD0, out float4 FragColor: COLOR0, \n" - "uniform samplerRECT tex, uniform float4 truncate){\n" - "float4 cc = texRECT(tex, min(texCoord0.xy, truncate.xy)); \n" - "bool2 ob = texCoord0.xy < truncate.xy;\n" - "if(ob.y) { FragColor = (truncate.z ==0 ? cc.rrbb : cc.ggaa); } \n" - "else if(ob.x) {FragColor = (truncate.w <1.5 ? cc.rgrg : cc.baba);} \n" - "else { float4 weights = float4(float4(0, 1, 2, 3) == truncate.w);\n" - "float v = dot(weights, cc); FragColor = v.xxxx;}}"); - - _param_margin_copy_truncate = cgGetNamedParameter(*program, "truncate"); - - - s_zero_pass = new ProgramCG("void main(out float4 FragColor : COLOR0){FragColor = 0;}"); - - s_grad_pass = program = new ProgramCG( - "void main (\n" - "float4 TexCC : TEXCOORD0, float4 TexLC : TEXCOORD1,\n" - "float4 TexRC : TEXCOORD2, float4 TexCD : TEXCOORD3, float4 TexCU : TEXCOORD4,\n" - "out float4 FragData0 : COLOR0, out float4 FragData1 : COLOR1, \n" - "out float4 FragData2 : COLOR2, uniform samplerRECT tex, uniform samplerRECT texp)\n" - "{\n" - " float4 v1, v2, gg;\n" - " float4 cc = texRECT(tex, TexCC.xy);\n" - " float4 cp = texRECT(texp, TexCC.xy);\n" - " FragData0 = cc - cp; \n" - " float4 cl = texRECT(tex, TexLC.xy); float4 cr = texRECT(tex, TexRC.xy);\n" - " float4 cd = texRECT(tex, TexCD.xy); float4 cu = texRECT(tex, TexCU.xy);\n" - " float4 dx = (float4(cr.rb, cc.ga) - float4(cc.rb, cl.ga)).zxwy;\n" - " float4 dy = (float4(cu.rg, cc.ba) - float4(cc.rg, cd.ba)).zwxy;\n" - " FragData1 = 0.5 * sqrt(dx*dx + dy * dy);\n" - " FragData2 = FragData1 > 0? atan2(dy, dx) : float4(0);\n" - "}\n\0"); - - _param_grad_pass_texp = cgGetNamedParameter(*program, "texp"); - - - s_dog_pass = program = new ProgramCG( - "void main (float4 TexCC : TEXCOORD0, out float4 FragData0 : COLOR0, \n" - " uniform samplerRECT tex, uniform samplerRECT texp)\n" - "{\n" - " float4 cc = texRECT(tex, TexCC.xy);\n" - " float4 cp = texRECT(texp, TexCC.xy);\n" - " FragData0 = cc - cp; \n" - "}\n\0"); - - //// - if(GlobalUtil::_SupportFP40) - { - LoadOrientationShader(); - if(GlobalUtil::_DescriptorPPT) LoadDescriptorShader(); - }else - { - s_orientation = program = new ProgramCG( - "void main(out float4 FragColor : COLOR0, \n" - " uniform samplerRECT fTex, uniform samplerRECT oTex, \n" - " uniform float2 size, \n" - " in float2 tpos : TEXCOORD0){\n" - " float4 cc = texRECT(fTex, tpos);\n" - " float2 co = cc.xy * 0.5; \n" - " float4 oo = texRECT(oTex, co);\n" - " bool2 bo = frac(co) < 0.5; \n" - " float o = bo.y? (bo.x? oo.r : oo.g) : (bo.x? oo.b : oo.a); \n" - " FragColor = float4(cc.rg, o, size.x * pow(size.y, cc.a));}"); - _param_orientation_gtex= cgGetNamedParameter(*program, "oTex"); - _param_orientation_size= cgGetNamedParameter(*program, "size"); - - GlobalUtil::_FullSupported = 0; - GlobalUtil::_MaxOrientation = 0; - GlobalUtil::_DescriptorPPT = 0; - std::cerr<<"Orientation simplified on this hardware"< 0.9)? size : -size);\n" - " dxy.y = type < 0.2 ? 0 : ((type < 0.3 || type > 0.7 )? -size :size); \n" - " sincos(cc.b, s, c);\n" - " FragColor.x = cc.x + c*dxy.x-s*dxy.y;\n" - " FragColor.y = cc.y + c*dxy.y+s*dxy.x;}\n" - "}\n\0"); - /*FragColor = float4(tpos, 0.0, 1.0);}\n\0");*/ - - _param_genvbo_size = cgGetNamedParameter(*program, "sizes"); - - s_display_gaussian = new ProgramCG( - "void main(uniform samplerRECT tex, in float4 TexCoord0:TEXCOORD0, out float4 FragData: COLOR0 ){\n" - "float4 pc = texRECT(tex, TexCoord0.xy); bool2 ff = (frac(TexCoord0.xy) < 0.5);\n" - "float v = ff.y?(ff.x? pc.r : pc.g):(ff.x?pc.b:pc.a); FragData = float4(v.xxx, 1.0);}"); - - s_display_dog = new ProgramCG( - "void main(in float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n" - "float4 pc = texRECT(tex, TexCoord0.xy); bool2 ff = (frac(TexCoord0.xy) < 0.5);\n" - "float v = ff.y ?(ff.x ? pc.r : pc.g):(ff.x ? pc.b : pc.a);float g = (0.5+20.0*v);\n" - "FragColor = float4(g, g, g, 1.0);}" ); - - - s_display_grad = new ProgramCG( - "void main(in float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n" - "float4 pc = texRECT(tex, TexCoord0.xy); bool2 ff = (frac(TexCoord0.xy) < 0.5);\n" - "float v = ff.y ?(ff.x ? pc.r : pc.g):(ff.x ? pc.b : pc.a); FragColor = float4(5.0 *v.xxx, 1.0); }"); - - s_display_keys= new ProgramCG( - "void main(in float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n" - "float4 oc = texRECT(tex, TexCoord0.xy); \n" - "float4 cc = float4(abs(oc.r) == float4(1.0, 2.0, 3.0, 4.0));\n" - "bool2 ff = (frac(TexCoord0.xy) < 0.5);\n" - "float v = ff.y ?(ff.x ? cc.r : cc.g):(ff.x ? cc.b : cc.a);\n" - "if(oc.r == 0) discard;\n" - "else if(oc.r > 0) FragColor = float4(1.0, 0, 0,1.0); \n" - "else FragColor = float4(0.0,1.0,0.0,1.0); }" ); -} - -void ShaderBagPKCG::LoadGenListShader(int ndoglev, int nlev) -{ - - //the V2 algorithms are only slightly faster, but way more complicated - //LoadGenListShaderV2(ndoglev, nlev); return; - ProgramCG * program; - - s_genlist_init_tight = new ProgramCG( - "void main (uniform samplerRECT tex, in float4 TexCoord0 : TEXCOORD0,\n" - "in float4 TexCoord1 : TEXCOORD1, in float4 TexCoord2 : TEXCOORD2, \n" - "in float4 TexCoord3 : TEXCOORD3, out float4 FragColor : COLOR0)\n" - "{\n" - " float4 data = float4( texRECT(tex, TexCoord0.xy).r,\n" - " texRECT(tex, TexCoord1.xy).r,\n" - " texRECT(tex, TexCoord2.xy).r,\n" - " texRECT(tex, TexCoord3.xy).r);\n" - " FragColor = float4(data != 0);\n" - "}"); - - s_genlist_init_ex = program = new ProgramCG( - "void main (uniform float4 bbox, uniform samplerRECT tex, \n" - "in float4 TexCoord0 : TEXCOORD0, in float4 TexCoord1 : TEXCOORD1, \n" - "in float4 TexCoord2 : TEXCOORD2, in float4 TexCoord3 : TEXCOORD3,\n" - "out float4 FragColor : COLOR0)\n" - "{\n" - " bool4 helper1 = abs(texRECT(tex, TexCoord0.xy).r)== float4(1.0, 2.0, 3.0, 4.0); \n" - " bool4 helper2 = abs(texRECT(tex, TexCoord1.xy).r)== float4(1.0, 2.0, 3.0, 4.0);\n" - " bool4 helper3 = abs(texRECT(tex, TexCoord2.xy).r)== float4(1.0, 2.0, 3.0, 4.0);\n" - " bool4 helper4 = abs(texRECT(tex, TexCoord3.xy).r)== float4(1.0, 2.0, 3.0, 4.0);\n" - " bool4 bx1 = TexCoord0.xxyy < bbox; \n" - " bool4 bx4 = TexCoord3.xxyy < bbox; \n" - " bool4 bx2 = bool4(bx4.xy, bx1.zw); \n" - " bool4 bx3 = bool4(bx1.xy, bx4.zw);\n" - " helper1 = (bx1.xyxy && bx1.zzww && helper1);\n" - " helper2 = (bx2.xyxy && bx2.zzww && helper2);\n" - " helper3 = (bx3.xyxy && bx3.zzww && helper3);\n" - " helper4 = (bx4.xyxy && bx4.zzww && helper4);\n" - " FragColor.r = any(helper1.xy || helper1.zw); \n" - " FragColor.g = any(helper2.xy || helper2.zw); \n" - " FragColor.b = any(helper3.xy || helper3.zw); \n" - " FragColor.a = any(helper4.xy || helper4.zw); \n" - "}"); - _param_genlist_init_bbox = cgGetNamedParameter( *program, "bbox"); - - s_genlist_end = program = new ProgramCG( - GlobalUtil::_KeepExtremumSign == 0 ? - - "void main( uniform samplerRECT tex, uniform samplerRECT ktex,\n" - " in float4 tpos : TEXCOORD0, out float4 FragColor : COLOR0)\n" - "{\n" - " float4 tc = texRECT( tex, tpos.xy);\n" - " float2 pos = tc.rg; float index = tc.b;\n" - " float4 tk = texRECT( ktex, pos); \n" - " float4 keys = float4(abs(tk.x) == float4(1.0, 2.0, 3.0, 4.0)); \n" - " float2 opos; \n" - " opos.x = dot(keys, float4(-0.5, 0.5, -0.5, 0.5));\n" - " opos.y = dot(keys, float4(-0.5, -0.5, 0.5, 0.5));\n" - " FragColor = float4(opos + pos + pos + tk.yz, 1.0, tk.w);\n" - "}" : - - "void main( uniform samplerRECT tex, uniform samplerRECT ktex,\n" - " in float4 tpos : TEXCOORD0, out float4 FragColor : COLOR0)\n" - "{\n" - " float4 tc = texRECT( tex, tpos.xy);\n" - " float2 pos = tc.rg; float index = tc.b;\n" - " float4 tk = texRECT( ktex, pos); \n" - " float4 keys = float4(abs(tk.x) == float4(1.0, 2.0, 3.0, 4.0)); \n" - " float2 opos; \n" - " opos.x = dot(keys, float4(-0.5, 0.5, -0.5, 0.5));\n" - " opos.y = dot(keys, float4(-0.5, -0.5, 0.5, 0.5));\n" - " FragColor = float4(opos + pos + pos + tk.yz, sign(tk.x), tk.w);\n" - "}" - ); - _param_genlist_end_ktex = cgGetNamedParameter(*program, "ktex"); - - //reduction ... - s_genlist_histo = new ProgramCG( - "void main (uniform samplerRECT tex, in float2 TexCoord0 : TEXCOORD0,\n" - "in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" - "in float2 TexCoord3 : TEXCOORD3, out float4 FragColor : COLOR0)\n" - "{\n" - " float4 helper; float4 helper2; \n" - " helper = texRECT(tex, TexCoord0); helper2.xy = helper.xy + helper.zw; \n" - " helper = texRECT(tex, TexCoord1); helper2.zw = helper.xy + helper.zw; \n" - " FragColor.rg = helper2.xz + helper2.yw;\n" - " helper = texRECT(tex, TexCoord2); helper2.xy = helper.xy + helper.zw; \n" - " helper = texRECT(tex, TexCoord3); helper2.zw = helper.xy + helper.zw; \n" - " FragColor.ba= helper2.xz+helper2.yw;\n" - "}"); - - - //read of the first part, which generates tex coordinates - - s_genlist_start= program = ShaderBagCG::LoadGenListStepShader(1, 1); - _param_ftex_width= cgGetNamedParameter(*program, "width"); - _param_genlist_start_tex0 = cgGetNamedParameter(*program, "tex0"); - //stepping - s_genlist_step = program = ShaderBagCG::LoadGenListStepShader(0, 1); - _param_genlist_step_tex= cgGetNamedParameter(*program, "tex"); - _param_genlist_step_tex0= cgGetNamedParameter(*program, "tex0"); - - -} - - - -void ShaderBagPKCG::LoadGenListShaderV2(int ndoglev, int nlev) -{ - ProgramCG * program; - - s_genlist_init_tight = new ProgramCG( - "void main (uniform samplerRECT tex, in float4 TexCoord0 : TEXCOORD0,\n" - "in float4 TexCoord1 : TEXCOORD1, in float4 TexCoord2 : TEXCOORD2, \n" - "in float4 TexCoord3 : TEXCOORD3, out float4 FragColor : COLOR0)\n" - "{\n" - " float4 data1 = texRECT(tex, TexCoord0.xy);\n" - " float4 data2 = texRECT(tex, TexCoord1.xy);\n" - " float4 data3 = texRECT(tex, TexCoord2.xy);\n" - " float4 data4 = texRECT(tex, TexCoord3.xy);\n" - " bool4 helper1 = (abs(data1.r), float4(1.0, 2.0, 3.0, 4.0)); \n" - " bool4 helper2 = (abs(data2.r), float4(1.0, 2.0, 3.0, 4.0));\n" - " bool4 helper3 = (abs(data3.r), float4(1.0, 2.0, 3.0, 4.0));\n" - " bool4 helper4 = (abs(data4.r), float4(1.0, 2.0, 3.0, 4.0));\n" - " FragColor.r = any(helper1.xy || helper1.zw); \n" - " FragColor.g = any(helper2.xy || helper2.zw); \n" - " FragColor.b = any(helper3.xy || helper3.zw); \n" - " FragColor.a = any(helper4.xy || helper4.zw); \n" - " if(dot(FragColor, float4(1,1,1,1)) == 1) \n" - " {\n" - " //use a special method if there is only one in the 16, \n" - " float4 data, helper; float2 pos, opos; \n" - " if(FragColor.r){ \n" - " data = data1; helper = helper1; pos = TexCoord0.xy;\n" - " }else if(FragColor.g){\n" - " data = data2; helper = helper2; pos = TexCoord1.xy;\n" - " }else if(FragColor.b){\n" - " data = data3; helper = helper3; pos = TexCoord2.xy;\n" - " }else{\n" - " data = data4; helper = helper4; pos = TexCoord3.xy;\n" - " }\n" - " opos.x = dot(helper, float4(-0.5, 0.5, -0.5, 0.5));\n" - " opos.y = dot(helper, float4(-0.5, -0.5, 0.5, 0.5));\n" - " FragColor = float4( pos + pos + opos + data.yz, -1, data.w); \n" - " }\n" - "}"); - - s_genlist_init_ex = program = new ProgramCG( - "void main (uniform float4 bbox, uniform samplerRECT tex, \n" - "in float4 TexCoord0 : TEXCOORD0, in float4 TexCoord1 : TEXCOORD1, \n" - "in float4 TexCoord2 : TEXCOORD2, in float4 TexCoord3 : TEXCOORD3,\n" - "out float4 FragColor : COLOR0)\n" - "{\n" - " float4 data1 = texRECT(tex, TexCoord0.xy);\n" - " float4 data2 = texRECT(tex, TexCoord1.xy);\n" - " float4 data3 = texRECT(tex, TexCoord2.xy);\n" - " float4 data4 = texRECT(tex, TexCoord3.xy);\n" - " bool4 helper1 = (abs(data1.r), float4(1.0, 2.0, 3.0, 4.0)); \n" - " bool4 helper2 = (abs(data2.r), float4(1.0, 2.0, 3.0, 4.0));\n" - " bool4 helper3 = (abs(data3.r), float4(1.0, 2.0, 3.0, 4.0));\n" - " bool4 helper4 = (abs(data4.r), float4(1.0, 2.0, 3.0, 4.0));\n" - " bool4 bx1 = TexCoord0.xxyy < bbox; \n" - " bool4 bx4 = TexCoord3.xxyy < bbox; \n" - " bool4 bx2 = bool4(bx4.xy, bx1.zw); \n" - " bool4 bx3 = bool4(bx1.xy, bx4.zw);\n" - " helper1 = bx1.xyxy && bx1.zzww && helper1; \n" - " helper2 = bx2.xyxy && bx2.zzww && helper2; \n" - " helper3 = bx3.xyxy && bx3.zzww && helper3; \n" - " helper4 = bx4.xyxy && bx4.zzww && helper4; \n" - " FragColor.r = any(helper1.xy || helper1.zw); \n" - " FragColor.g = any(helper2.xy || helper2.zw); \n" - " FragColor.b = any(helper3.xy || helper3.zw); \n" - " FragColor.a = any(helper4.xy || helper4.zw); \n" - " if(dot(FragColor, float4(1,1,1,1)) == 1) \n" - " {\n" - " //use a special method if there is only one in the 16, \n" - " float4 data, helper; bool4 bhelper; float2 pos, opos; \n" - " if(FragColor.r){ \n" - " data = data1; bhelper = helper1; pos = TexCoord0.xy;\n" - " }else if(FragColor.g){\n" - " data = data2; bhelper = helper2; pos = TexCoord1.xy;\n" - " }else if(FragColor.b){\n" - " data = data3; bhelper = helper3; pos = TexCoord2.xy;\n" - " }else{\n" - " data = data4; bhelper = helper4; pos = TexCoord3.xy;\n" - " }\n" - " helper = float4(bhelper); \n" - " opos.x = dot(helper, float4(-0.5, 0.5, -0.5, 0.5));\n" - " opos.y = dot(helper, float4(-0.5, -0.5, 0.5, 0.5));\n" - " FragColor = float4(pos + pos + opos + data.yz, -1, data.w); \n" - " }\n" - "}"); - _param_genlist_init_bbox = cgGetNamedParameter( *program, "bbox"); - - s_genlist_end = program = new ProgramCG( - - "void main( uniform samplerRECT tex, uniform samplerRECT ktex,\n" - " in float4 tpos : TEXCOORD0, out float4 FragColor : COLOR0)\n" - "{\n" - " float4 tc = texRECT( tex, tpos.xy);\n" - " float2 pos = tc.rg; float index = tc.b;\n" - " if(index == -1)\n" - " {\n" - " FragColor = float4(tc.xy, 0, tc.w);\n" - " }else\n" - " {\n" - " float4 tk = texRECT( ktex, pos); \n" - " float4 keys = float4(abs(tk.r) == float4(1.0, 2.0, 3.0, 4.0)); \n" - " float2 opos; \n" - " opos.x = dot(keys, float4(-0.5, 0.5, -0.5, 0.5));\n" - " opos.y = dot(keys, float4(-0.5, -0.5, 0.5, 0.5));\n" - " FragColor = float4(opos + pos + pos + tk.yz, 0, tk.w);\n" - " }\n" - "}"); - _param_genlist_end_ktex = cgGetNamedParameter(*program, "ktex"); - - //reduction ... - s_genlist_histo = new ProgramCG( - "void main (uniform samplerRECT tex, in float2 TexCoord0 : TEXCOORD0,\n" - "in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" - "in float2 TexCoord3 : TEXCOORD3, out float4 FragColor : COLOR0)\n" - "{\n" - " float4 helper[4]; float4 helper2; \n" - " helper[0] = texRECT(tex, TexCoord0); helper2.xy = helper[0].xy + helper[0].zw; \n" - " helper[1] = texRECT(tex, TexCoord1); helper2.zw = helper[1].xy + helper[1].zw; \n" - " FragColor.rg = helper2.xz + helper2.yw;\n" - " helper[2] = texRECT(tex, TexCoord2); helper2.xy = helper[2].xy + helper[2].zw; \n" - " helper[3] = texRECT(tex, TexCoord3); helper2.zw = helper[3].xy + helper[3].zw; \n" - " FragColor.ba= helper2.xz+helper2.yw;\n" - " bool4 keyt = float4(helper[0].z, helper[1].z, helper[2].z, helper[3].z) == -1.0; \n" - " float keyc = dot(float4(keyt), float4(1,1,1,1)); \n" - " if(keyc == 1.0 && dot(FragColor, float4(1,1,1,1)) == -1.0) \n" - " {\n" - " if(keyt.x) FragColor = helper[0];\n" - " else if(keyt.y) FragColor = helper[1]; \n" - " else if(keyt.z) FragColor = helper[2]; \n" - " else FragColor = helper[3]; \n" - " }else\n" - " {\n" - " FragColor = keyt? float4(1,1,1,1) : FragColor;\n" - " }\n" - "}"); - - //read of the first part, which generates tex coordinates - - s_genlist_start= program = ShaderBagCG::LoadGenListStepShaderV2(1, 1); - _param_ftex_width= cgGetNamedParameter(*program, "width"); - _param_genlist_start_tex0 = cgGetNamedParameter(*program, "tex0"); - //stepping - s_genlist_step = program = ShaderBagCG::LoadGenListStepShaderV2(0, 1); - _param_genlist_step_tex= cgGetNamedParameter(*program, "tex"); - _param_genlist_step_tex0= cgGetNamedParameter(*program, "tex0"); - - -} - - - -ProgramCG* ShaderBagCG::LoadGenListStepShaderV2(int start, int step) -{ - int i; - char buffer[10240]; - //char chanels[5] = "rgba"; - ostrstream out(buffer, 10240); - out<<"void main(out float4 FragColor : COLOR0, \n"; - - for(i = 0; i < step; i++) out<<"uniform samplerRECT tex"<0) - { - out<<"float2 cpos = float2(-0.5, 0.5);\t float2 opos;\n"; - for(i = 0; i < step; i++) - { - - out<<"cc = texRECT(tex"< max(v1[i], v2[i]), test2 = cc[i] < min(v1[i], v2[i]);\n" - " key[i] = cc[i] > THRESHOLD0 && all(test1.xy&&test1.zw)?1.0: 0.0;\n" - " key[i] = cc[i] < -THRESHOLD0 && all(test2.xy&&test2.zw)? -1.0: key[i];\n" - " }\n" - " if(TexCC.x < 1.0) {key.rb = 0;}\n" - " if(TexCC.y < 1.0) {key.rg = 0;}\n" - " FragData0 = float4(0.0);\n" - " if(all(key == 0.0)) return; \n"; - - //do edge supression first.. - //vector v1 is < (-1, 0), (1, 0), (0,-1), (0, 1)> - //vector v2 is < (-1,-1), (-1,1), (1,-1), (1, 1)> - - out<< - " float fxx[4], fyy[4], fxy[4], fx[4], fy[4];\n" - " for(int i = 0; i < 4; i++) \n" - " {\n" - " if(key[i] != 0)\n" - " {\n" - " float4 D2 = v1[i].xyzw - cc[i];\n" - " float2 D4 = v2[i].xw - v2[i].yz;\n" - " float2 D5 = 0.5*(v1[i].yw-v1[i].xz); \n" - " fx[i] = D5.x;\n" - " fy[i] = D5.y ;\n" - " fxx[i] = D2.x + D2.y;\n" - " fyy[i] = D2.z + D2.w;\n" - " fxy[i] = 0.25*(D4.x + D4.y);\n" - " float fxx_plus_fyy = fxx[i] + fyy[i];\n" - " float score_up = fxx_plus_fyy*fxx_plus_fyy; \n" - " float score_down = (fxx[i]*fyy[i] - fxy[i]*fxy[i]);\n" - " if( score_down <= 0 || score_up > THRESHOLD2 * score_down)key[i] = 0;\n" - " }\n" - " }\n" - " if(all(key == 0.0)) return; \n\n"; - - //////////////////////////////////////////////// - //read 9 pixels of upper/lower level - out<< - " float4 v4[4], v5[4], v6[4];\n" - " ccc = texRECT(texU, TexCC.xy);\n" - " clc = texRECT(texU, TexLC.xy);\n" - " crc = texRECT(texU, TexRC.xy);\n" - " ccd = texRECT(texU, TexCD.xy);\n" - " ccu = texRECT(texU, TexCU.xy);\n" - " cld = texRECT(texU, TexLD.xy);\n" - " clu = texRECT(texU, TexLU.xy);\n" - " crd = texRECT(texU, TexRD.xy);\n" - " cru = texRECT(texU, TexRU.xy);\n" - " float4 cu = ccc;\n" - " v4[0] = float4(clc.g, ccc.g, ccd.b, ccc.b);\n" - " v4[1] = float4(ccc.r, crc.r, ccd.a, ccc.a);\n" - " v4[2] = float4(clc.a, ccc.a, ccc.r, ccu.r);\n" - " v4[3] = float4(ccc.b, crc.b, ccc.g, ccu.g);\n" - " v6[0] = float4(cld.a, clc.a, ccd.a, ccc.a);\n" - " v6[1] = float4(ccd.b, ccc.b, crd.b, crc.b);\n" - " v6[2] = float4(clc.g, clu.g, ccc.g, ccu.g);\n" - " v6[3] = float4(ccc.r, ccu.r, crc.r, cru.r);\n" - << - " for(int i = 0; i < 4; i++)\n" - " {\n" - " if(key[i] == 1.0)\n" - " {\n" - " bool4 test = cc[i]< max(v4[i], v6[i]); \n" - " if(cc[i] < cu[i] || any(test.xy||test.zw))key[i] = 0.0; \n" - " }else if(key[i] == -1.0)\n" - " {\n" - " bool4 test = cc[i]> min( v4[i], v6[i]); \n" - " if(cc[i] > cu[i] || any(test.xy||test.zw))key[i] = 0.0; \n" - " }\n" - " }\n" - " if(all(key == 0.0)) return; \n" - << - " ccc = texRECT(texD, TexCC.xy);\n" - " clc = texRECT(texD, TexLC.xy);\n" - " crc = texRECT(texD, TexRC.xy);\n" - " ccd = texRECT(texD, TexCD.xy);\n" - " ccu = texRECT(texD, TexCU.xy);\n" - " cld = texRECT(texD, TexLD.xy);\n" - " clu = texRECT(texD, TexLU.xy);\n" - " crd = texRECT(texD, TexRD.xy);\n" - " cru = texRECT(texD, TexRU.xy);\n" - " float4 cd = ccc;\n" - " v5[0] = float4(clc.g, ccc.g, ccd.b, ccc.b);\n" - " v5[1] = float4(ccc.r, crc.r, ccd.a, ccc.a);\n" - " v5[2] = float4(clc.a, ccc.a, ccc.r, ccu.r);\n" - " v5[3] = float4(ccc.b, crc.b, ccc.g, ccu.g);\n" - " v6[0] = float4(cld.a, clc.a, ccd.a, ccc.a);\n" - " v6[1] = float4(ccd.b, ccc.b, crd.b, crc.b);\n" - " v6[2] = float4(clc.g, clu.g, ccc.g, ccu.g);\n" - " v6[3] = float4(ccc.r, ccu.r, crc.r, cru.r);\n" - << - " for(int i = 0; i < 4; i++)\n" - " {\n" - " if(key[i] == 1.0)\n" - " {\n" - " bool4 test = cc[i]< max(v5[i], v6[i]);\n" - " if(cc[i] < cd[i] || any(test.xy||test.zw))key[i] = 0.0; \n" - " }else if(key[i] == -1.0)\n" - " {\n" - " bool4 test = cc[i]>min(v5[i],v6[i]);\n" - " if(cc[i] > cd[i] || any(test.xy||test.zw))key[i] = 0.0; \n" - " }\n" - " }\n" - " float keysum = dot(abs(key), float4(1, 1, 1, 1)) ;\n" - " //assume there is only one keypoint in the four. \n" - " if(keysum != 1.0) return; \n"; - - ////////////////////////////////////////////////////////////////////// - if(GlobalUtil::_SubpixelLocalization) - - out << - " float3 offset = float3(0, 0, 0); \n" - " /*The unrolled follwing loop is faster than a dynamic indexing version.*/\n" - " for(int idx = 1; idx < 4; idx++)\n" - " {\n" - " if(key[idx] != 0) \n" - " {\n" - " cu[0] = cu[idx]; cd[0] = cd[idx]; cc[0] = cc[idx]; \n" - " v4[0] = v4[idx]; v5[0] = v5[idx]; \n" - " fxy[0] = fxy[idx]; fxx[0] = fxx[idx]; fyy[0] = fyy[idx]; \n" - " fx[0] = fx[idx]; fy[0] = fy[idx]; \n" - " }\n" - " }\n" - << - - " float fs = 0.5*( cu[0] - cd[0] ); \n" - " float fss = cu[0] + cd[0] - cc[0] - cc[0];\n" - " float fxs = 0.25 * (v4[0].y + v5[0].x - v4[0].x - v5[0].y);\n" - " float fys = 0.25 * (v4[0].w + v5[0].z - v4[0].z - v5[0].w);\n" - " float4 A0, A1, A2 ; \n" - " A0 = float4(fxx[0], fxy[0], fxs, -fx[0]); \n" - " A1 = float4(fxy[0], fyy[0], fys, -fy[0]); \n" - " A2 = float4(fxs, fys, fss, -fs); \n" - " float3 x3 = abs(float3(fxx[0], fxy[0], fxs)); \n" - " float maxa = max(max(x3.x, x3.y), x3.z); \n" - " if(maxa >= 1e-10 ) \n" - " { \n" - " if(x3.y ==maxa ) \n" - " { \n" - " float4 TEMP = A1; A1 = A0; A0 = TEMP; \n" - " }else if( x3.z == maxa ) \n" - " { \n" - " float4 TEMP = A2; A2 = A0; A0 = TEMP; \n" - " } \n" - " A0 /= A0.x; \n" - " A1 -= A1.x * A0; \n" - " A2 -= A2.x * A0; \n" - " float2 x2 = abs(float2(A1.y, A2.y)); \n" - " if( x2.y > x2.x ) \n" - " { \n" - " float3 TEMP = A2.yzw; \n" - " A2.yzw = A1.yzw; \n" - " A1.yzw = TEMP; \n" - " x2.x = x2.y; \n" - " } \n" - " if(x2.x >= 1e-10) { \n" - " A1.yzw /= A1.y; \n" - " A2.yzw -= A2.y * A1.yzw; \n" - " if(abs(A2.z) >= 1e-10) {\n" - " offset.z = A2.w /A2.z; \n" - " offset.y = A1.w - offset.z*A1.z; \n" - " offset.x = A0.w - offset.z*A0.z - offset.y*A0.y; \n" - " bool test = (abs(cc[0] + 0.5*dot(float3(fx[0], fy[0], fs), offset ))>THRESHOLD1) ;\n" - " if(!test || any( abs(offset) >= 1.0)) return;\n" - " }\n" - " }\n" - " }\n" - <<"\n" - " float keyv = dot(key, float4(1.0, 2.0, 3.0, 4.0));\n" - " FragData0 = float4(keyv, offset);\n" - "}\n" <<'\0'; - - else out << "\n" - " float keyv = dot(key, float4(1.0, 2.0, 3.0, 4.0));\n" - " FragData0 = float4(keyv, 0, 0, 0);\n" - "}\n" <<'\0'; - - s_keypoint = program = new ProgramCG(buffer); - //parameter - _param_dog_texu = cgGetNamedParameter(*program, "texU"); - _param_dog_texd = cgGetNamedParameter(*program, "texD"); -} - -void ShaderBagPKCG::LoadOrientationShader() -{ - char buffer[10240]; - ostrstream out(buffer,10240); - - out<<"\n" - "#define GAUSSIAN_WF "<1 && GlobalUtil::_OrientationPack2 == 0) - out<<", out float4 OrientationData : COLOR1"; - - - //use 9 float4 to store histogram of 36 directions - out<<") \n" - "{ \n" - " float4 bins[10]; \n" - " for (int i=0; i<9; i++) bins[i] = float4(0,0,0,0); \n" - " float4 sift = texRECT(tex, TexCoord0); \n" - " float2 pos = sift.xy; \n" - " bool orientation_mode = (size.z != 0); \n" - " float sigma = orientation_mode? (abs(size.z) * pow(size.w, sift.w) * sift.z) : (sift.w); \n" - " //bool fixed_orientation = (size.z < 0); \n" - " if(size.z < 0) {FeatureData = float4(pos, 0, sigma); return;}" - " float gsigma = sigma * GAUSSIAN_WF; \n" - " float2 win = abs(sigma.xx) * (SAMPLE_WF * GAUSSIAN_WF); \n" - " float2 dim = size.xy; \n" - " float4 dist_threshold = float4(win.x*win.x+0.5); \n" - " float factor = -0.5/(gsigma*gsigma); \n" - " float4 sz; float2 spos; \n" - " //if(any(pos.xy <= 1)) discard; \n" - " sz.xy = max( pos - win, float2(2,2)); \n" - " sz.zw = min( pos + win, dim-3); \n" - " sz = floor(sz*0.5) + 0.5; "; - //loop to get the histogram - - out<<"\n" - " for(spos.y = sz.y; spos.y <= sz.w; spos.y+=1.0) \n" - " { \n" - " for(spos.x = sz.x; spos.x <= sz.z; spos.x+=1.0) \n" - " { \n" - " float2 offset = 2* spos - pos - 0.5; \n" - " float4 off = float4(offset, offset + 1); \n" - " float4 distsq = off.xzxz * off.xzxz + off.yyww * off.yyww; \n" - " bool4 inside = distsq < dist_threshold; \n" - " if(any(inside.xy||inside.zw)) \n" - " { \n" - " float4 gg = texRECT(gtex, spos); \n" - " float4 oo = texRECT(otex, spos); \n" - " float4 weight = gg * exp(distsq * factor); \n" - " float4 idxv = floor(degrees(oo)*0.1); \n" - " idxv = idxv<0? idxv + 36.0: idxv; \n" - " float4 vidx = 4.0* fract(idxv * 0.25);//fmod(idxv, 4.0);\n"; - - // - if(GlobalUtil::_UseDynamicIndexing && strcmp(cgGetProfileString(ProgramCG::_FProfile), "gp4fp")==0) - //if(ProgramCG::_FProfile == CG_PROFILE_GPU_FP) this enumerant is not defined in cg1.5 - { - //gp4fp supports dynamic indexing, but it might be slow on some GPUs - out<<"\n" - " for(int i = 0 ; i < 4; i++)\n" - " {\n" - " if(inside[i])\n" - " {\n" - " float idx = idxv[i]; \n" - " float4 inc = weight[i] * float4(vidx[i] == float4(0,1,2,3)); \n" - " int iidx = int(floor(idx*0.25)); \n" - " bins[iidx]+=inc; \n" - " } \n" - " } \n" - " } \n" - " } \n" - " }"; - - }else - { - //nvfp40 still does not support dynamic array indexing - //unrolled binary search - //it seems to be faster than the dyanmic indexing version on some GPUs - out<<"\n" - " for(int i = 0 ; i < 4; i++)\n" - " {\n" - " if(inside[i])\n" - " {\n" - " float idx = idxv[i]; \n" - " float4 inc = weight[i] * float4(vidx[i] == float4(0,1,2,3)); \n" - " if(idx < 16) \n" - " { \n" - " if(idx < 8) \n" - " { \n" - " if(idx < 4) { bins[0]+=inc;} \n" - " else { bins[1]+=inc;} \n" - " }else \n" - " { \n" - " if(idx < 12){ bins[2]+=inc;} \n" - " else { bins[3]+=inc;} \n" - " } \n" - " }else if(idx < 32) \n" - " { \n" - " if(idx < 24) \n" - " { \n" - " if(idx <20) { bins[4]+=inc;} \n" - " else { bins[5]+=inc;} \n" - " }else \n" - " { \n" - " if(idx < 28){ bins[6]+=inc;} \n" - " else { bins[7]+=inc;} \n" - " } \n" - " }else \n" - " { \n" - " bins[8]+=inc; \n" - " } \n" - " } \n" - " } \n" - " } \n" - " } \n" - " }"; - - } - - //reuse the code from the unpacked version.. - ShaderBagCG::WriteOrientationCodeToStream(out); - - - ProgramCG * program; - s_orientation = program = new ProgramCG(buffer); - _param_orientation_gtex = cgGetNamedParameter(*program, "gtex"); - _param_orientation_otex = cgGetNamedParameter(*program, "otex"); - _param_orientation_size = cgGetNamedParameter(*program, "size"); - - -} - -void ShaderBagPKCG::LoadDescriptorShader() -{ - GlobalUtil::_DescriptorPPT = 16; - LoadDescriptorShaderF2(); - -} - -void ShaderBagPKCG::LoadDescriptorShaderF2() -{ - //one shader outpout 128/8 = 16 , each fragout encodes 4 - //const double twopi = 2.0*3.14159265358979323846; - //const double rpi = 8.0/twopi; - char buffer[10240]; - ostrstream out(buffer, 10240); - - out<=dim-1)) " - " //discard; \n" - " { FragData0 = FragData1 = float4(0.0); return; }\n" - " float anglef = texRECT(tex, coord).z;\n" - " if(anglef > M_PI) anglef -= TWO_PI;\n" - " float sigma = texRECT(tex, coord).w; \n" - " float spt = abs(sigma * WF); //default to be 3*sigma \n"; - //rotation - out<< - " float4 cscs, rots; \n" - " sincos(anglef, cscs.y, cscs.x); \n" - " cscs.zw = - cscs.xy; \n" - " rots = cscs /spt; \n" - " cscs *= spt; \n"; - - //here cscs is actually (cos, sin, -cos, -sin) * (factor: 3)*sigma - //and rots is (cos, sin, -cos, -sin ) /(factor*sigma) - //devide the 4x4 sift grid into 16 1x1 block, and each corresponds to a shader thread - //To use linear interoplation, 1x1 is increased to 2x2, by adding 0.5 to each side - out<< - " float4 temp; float2 pt, offsetpt; \n" - " /*the fraction part of idx is .5*/ \n" - " offsetpt.x = 4.0 * fract(idx * 0.25) - 2.0; \n" - " offsetpt.y = floor(idx*0.25) - 1.5; \n" - " temp = cscs.xwyx*offsetpt.xyxy; \n" - " pt = pos + temp.xz + temp.yw; \n"; - - //get a horizontal bounding box of the rotated rectangle - out<< - " float2 bwin = abs(cscs.xy); \n" - " float bsz = bwin.x + bwin.y; \n" - " float4 sz; float2 spos; \n" - " sz.xy = max(pt - bsz, float2(2,2));\n" - " sz.zw = min(pt + bsz, dim - 3); \n" - " sz = floor(sz * 0.5) + 0.5;"; //move sample point to pixel center - //get voting for two box - - out<<"\n" - " float4 DA, DB; \n" - " DA = DB = float4(0, 0, 0, 0); \n" - " float4 nox = float4(0, rots.xy, rots.x + rots.y); \n" - " float4 noy = float4(0, rots.wx, rots.w + rots.x); \n" - " for(spos.y = sz.y; spos.y <= sz.w; spos.y+=1.0) \n" - " { \n" - " for(spos.x = sz.x; spos.x <= sz.z; spos.x+=1.0) \n" - " { \n" - " float2 tpt = spos * 2.0 - pt - 0.5; \n" - " float4 temp = rots.xywx * tpt.xyxy; \n" - " float2 temp2 = temp.xz + temp.yw; \n" - " float4 nx = temp2.x + nox; \n" - " float4 ny = temp2.y + noy; \n" - " float4 nxn = abs(nx), nyn = abs(ny); \n" - " bool4 inside = (max(nxn, nyn) < 1.0); \n" - " if(any(inside.xy || inside.zw))\n" - " {\n" - " float4 gg = texRECT(gtex, spos);\n" - " float4 oo = texRECT(otex, spos);\n" - " float4 theta0 = (anglef - oo)*RPI;\n" - " float4 theta = theta0 < 0? theta0 + 8.0 : theta0;//8.0 * frac(1.0 + 0.125 * theta0);// \n" - " float4 theta1 = floor(theta); \n" - " float4 diffx = nx + offsetpt.x, diffy = ny + offsetpt.y; \n" - " float4 ww = exp(-0.125 * (diffx * diffx + diffy * diffy )); \n" - " float4 weight = (1 - nxn) * (1 - nyn) * gg * ww; \n" - " float4 weight2 = (theta - theta1) * weight; \n" - " float4 weight1 = weight - weight2; \n" - " for(int i = 0;i < 4; i++)\n" - " {\n" - " if(inside[i])\n" - " {\n" - " DA += float4(theta1[i] == float4(0, 1, 2, 3))*weight1[i]; \n" - " DA += float4(theta1[i] == float4(7, 0, 1, 2))*weight2[i]; \n" - " DB += float4(theta1[i] == float4(4, 5, 6, 7))*weight1[i]; \n" - " DB += float4(theta1[i] == float4(3, 4, 5, 6))*weight2[i]; \n" - " }\n" - " }\n" - " }\n" - " }\n" - " }\n"; - out<< - " FragData0 = DA; FragData1 = DB;\n" - "}\n"<<'\0'; - ProgramCG * program; - - s_descriptor_fp = program = new ProgramCG(buffer); - _param_descriptor_gtex = cgGetNamedParameter(*program, "gtex"); - _param_descriptor_otex = cgGetNamedParameter(*program, "otex"); - _param_descriptor_size = cgGetNamedParameter(*program, "size"); - _param_descriptor_dsize = cgGetNamedParameter(*program, "dsize"); - -} - -void ShaderBagPKCG::SetMarginCopyParam(int xmax, int ymax) -{ - float truncate[4]; - truncate[0] = (xmax - 0.5f) * 0.5f; //((xmax + 1) >> 1) - 0.5f; - truncate[1] = (ymax - 0.5f) * 0.5f; //((ymax + 1) >> 1) - 0.5f; - truncate[2] = (xmax %2 == 1)? 0.0f: 1.0f; - truncate[3] = truncate[2] + (((ymax % 2) == 1)? 0.0f : 2.0f); - cgGLSetParameter4fv(_param_margin_copy_truncate, truncate); -} - -void ShaderBagPKCG::SetGradPassParam(int texP) -{ - cgGLSetTextureParameter(_param_grad_pass_texp, texP); - cgGLEnableTextureParameter(_param_grad_pass_texp); -} - -void ShaderBagPKCG::SetGenListEndParam(int ktex) -{ - cgGLSetTextureParameter(_param_genlist_end_ktex, ktex); - cgGLEnableTextureParameter(_param_genlist_end_ktex); -} - -void ShaderBagPKCG::SetDogTexParam(int texU, int texD) -{ - cgGLSetTextureParameter(_param_dog_texu, texU); - cgGLEnableTextureParameter(_param_dog_texu); - cgGLSetTextureParameter(_param_dog_texd, texD); - cgGLEnableTextureParameter(_param_dog_texd); -} - -void ShaderBagPKCG::SetGenListInitParam(int w, int h) -{ - float bbox[4] = {(w -1.0f) * 0.5f +0.25f, (w-1.0f) * 0.5f - 0.25f, (h - 1.0f) * 0.5f + 0.25f, (h-1.0f) * 0.5f - 0.25f}; - cgGLSetParameter4fv(_param_genlist_init_bbox, bbox); -} - - -void ShaderBagPKCG::SetGenListStartParam(float width, int tex0) -{ - cgGLSetParameter1f(_param_ftex_width, width); - - if(_param_genlist_start_tex0) - { - cgGLSetTextureParameter(_param_genlist_start_tex0, tex0); - cgGLEnableTextureParameter(_param_genlist_start_tex0); - } -} - - - -void ShaderBagPKCG::SetGenListStepParam(int tex, int tex0) -{ - cgGLSetTextureParameter(_param_genlist_step_tex, tex); - cgGLEnableTextureParameter(_param_genlist_step_tex); - cgGLSetTextureParameter(_param_genlist_step_tex0, tex0); - cgGLEnableTextureParameter(_param_genlist_step_tex0); -} - -void ShaderBagPKCG::SetGenVBOParam(float width, float fwidth, float size) -{ - float sizes[4] = {size*3.0f, fwidth, width, 1.0f/width}; - cgGLSetParameter4fv(_param_genvbo_size, sizes); -} - -void ShaderBagPKCG::SetSimpleOrientationInput(int oTex, float sigma, float sigma_step) -{ - cgGLSetTextureParameter(_param_orientation_gtex, oTex); - cgGLEnableTextureParameter(_param_orientation_gtex); - cgGLSetParameter2f(_param_orientation_size, sigma, sigma_step); -} - - -void ShaderBagPKCG::SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int otex, float step) -{ - /// - cgGLSetTextureParameter(_param_orientation_gtex, gtex); - cgGLEnableTextureParameter(_param_orientation_gtex); - cgGLSetTextureParameter(_param_orientation_otex, otex); - cgGLEnableTextureParameter(_param_orientation_otex); - - float size[4]; - size[0] = (float)width; - size[1] = (float)height; - size[2] = sigma; - size[3] = step; - cgGLSetParameter4fv(_param_orientation_size, size); - -} - -void ShaderBagPKCG::SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma) -{ - /// - - cgGLSetTextureParameter(_param_descriptor_gtex, gtex); - cgGLEnableTextureParameter(_param_descriptor_gtex); - cgGLSetTextureParameter(_param_descriptor_otex, otex); - cgGLEnableTextureParameter(_param_descriptor_otex); - - - float dsize[4] ={dwidth, 1.0f/dwidth, fwidth, 1.0f/fwidth}; - cgGLSetParameter4fv(_param_descriptor_dsize, dsize); - float size[3]; - size[0] = width; - size[1] = height; - size[2] = GlobalUtil::_DescriptorWindowFactor; - cgGLSetParameter3fv(_param_descriptor_size, size); - - -} - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramCG.h b/3rdparty/SiftGPU/src/SiftGPU/ProgramCG.h deleted file mode 100644 index 6ce072cd..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramCG.h +++ /dev/null @@ -1,161 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ProgramCG.h -// Author: Changchang Wu -// Description : interface for the ProgramCG classes. -// ProgramCG: Cg programs -// ShaderBagCG: All Cg shaders for Sift in a bag -// FilterGLCG: Cg Gaussian Filters -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#if defined(CG_SIFTGPU_ENABLED) - -#ifndef _PROGRAM_CG_H -#define _PROGRAM_CG_H - -#include "ProgramGPU.h" -class FragmentProgram; -#include "Cg/cgGL.h" - -class ProgramCG:public ProgramGPU -{ - CGprogram _programID; - CGprofile _profile; - int _valid; -public: - static CGcontext _Context; - static CGprofile _FProfile; -public: - operator CGprogram (){return _programID;} - CGprogram GetProgramID(){return _programID;} - int UseProgram(); - int IsValidProgram(){return _programID && _valid;} - static void ErrorCallback(); - static void InitContext(); - static void DestroyContext(); - ProgramCG(const char * code, const char** cg_compile_args= NULL, CGprofile profile = ProgramCG::_FProfile); - ProgramCG(); - virtual ~ProgramCG(); - -}; - -class ShaderBagCG:public ShaderBag -{ - CGparameter _param_dog_texu; - CGparameter _param_dog_texd; - CGparameter _param_genlist_start_tex0; - CGparameter _param_ftex_width; - CGparameter _param_genlist_step_tex; - CGparameter _param_genlist_step_tex0; - CGparameter _param_genvbo_size; - CGparameter _param_orientation_gtex; - CGparameter _param_orientation_stex; - CGparameter _param_orientation_size; - CGparameter _param_descriptor_gtex; - CGparameter _param_descriptor_size; - CGparameter _param_descriptor_dsize; - CGparameter _param_margin_copy_truncate; - CGparameter _param_genlist_init_bbox; -public: - virtual void LoadDescriptorShader(); - void LoadDescriptorShaderF2(); - static void WriteOrientationCodeToStream(ostream& out); - virtual void SetGenListInitParam(int w, int h); - virtual void SetMarginCopyParam(int xmax, int ymax); - virtual void SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int stex = 0, float step = 1.0f); - virtual void SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma); - virtual void SetSimpleOrientationInput(int oTex, float sigma, float sigma_step); - void LoadOrientationShader(); - virtual void SetGenListStartParam(float width, int tex0); - static ProgramCG* LoadGenListStepShader(int start, int step); - static ProgramCG* LoadGenListStepShaderV2(int start, int step); - void LoadGenListShader(int ndoglev, int nlev); - virtual void UnloadProgram(); - virtual void SetDogTexParam(int texU, int texD); - virtual void SetGenListStepParam(int tex, int tex0); - virtual void SetGenVBOParam( float width, float fwidth, float size); - virtual void LoadFixedShaders(); - virtual void LoadDisplayShaders(); - virtual void LoadKeypointShader(float threshold, float edgeThreshold); - virtual int LoadKeypointShaderMR(float threshold, float edgeThreshold); - ShaderBagCG(); - virtual ~ShaderBagCG(){} -}; - - -class FilterGLCG : public FilterProgram -{ -private: - ProgramGPU* CreateFilterH(float kernel[], float offset[], int width); - ProgramGPU* CreateFilterV(float kernel[], float offset[], int height); - //packed version - ProgramGPU* CreateFilterHPK(float kernel[], float offset[], int width); - ProgramGPU* CreateFilterVPK(float kernel[], float offset[], int height); -}; - -class ShaderBagPKCG:public ShaderBag -{ -private: - CGparameter _param_dog_texu; - CGparameter _param_dog_texd; - CGparameter _param_margin_copy_truncate; - CGparameter _param_grad_pass_texp; - CGparameter _param_genlist_init_bbox; - CGparameter _param_genlist_start_tex0; - CGparameter _param_ftex_width; - CGparameter _param_genlist_step_tex; - CGparameter _param_genlist_step_tex0; - CGparameter _param_genlist_end_ktex; - CGparameter _param_genvbo_size; - CGparameter _param_orientation_gtex; - CGparameter _param_orientation_otex; - CGparameter _param_orientation_size; - CGparameter _param_descriptor_gtex; - CGparameter _param_descriptor_otex; - CGparameter _param_descriptor_size; - CGparameter _param_descriptor_dsize; - -public: - ShaderBagPKCG(); - virtual ~ShaderBagPKCG(){} - virtual void LoadDescriptorShader(); - virtual void LoadDescriptorShaderF2(); - virtual void LoadOrientationShader(); - virtual void LoadGenListShader(int ndoglev, int nlev); - virtual void LoadGenListShaderV2(int ndoglev, int nlev); - virtual void UnloadProgram() ; - virtual void LoadKeypointShader(float threshold, float edgeTrheshold); - virtual void LoadFixedShaders(); - virtual void LoadDisplayShaders(); - virtual void SetGradPassParam(int texP); - virtual void SetGenListEndParam(int ktex); -public: - //parameters - virtual void SetGenListStartParam(float width, int tex0); - virtual void SetGenListInitParam(int w, int h); - virtual void SetMarginCopyParam(int xmax, int ymax); - virtual void SetDogTexParam(int texU, int texD); - virtual void SetGenListStepParam(int tex, int tex0); - virtual void SetGenVBOParam( float width, float fwidth, float size); - virtual void SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma); - virtual void SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int stex, float step); - virtual void SetSimpleOrientationInput(int oTex, float sigma, float sigma_step); -}; -#endif -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramCL.cpp b/3rdparty/SiftGPU/src/SiftGPU/ProgramCL.cpp deleted file mode 100644 index 3b13ff12..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramCL.cpp +++ /dev/null @@ -1,1592 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// File: ProgramCL.cpp -// Author: Changchang Wu -// Description : implementation of CL related class. -// class ProgramCL A simple wrapper of Cg programs -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if defined(CL_SIFTGPU_ENABLED) - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "GlobalUtil.h" -#include "CLTexImage.h" -#include "ProgramCL.h" -#include "SiftGPU.h" - - -#if defined(_WIN32) - #pragma comment (lib, "OpenCL.lib") -#endif - -#ifndef _INC_WINDOWS -#ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN -#endif -#include -#endif - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -ProgramCL::ProgramCL() -{ - _program = NULL; - _kernel = NULL; - _valid = 0; -} - -ProgramCL::~ProgramCL() -{ - if(_kernel) clReleaseKernel(_kernel); - if(_program) clReleaseProgram(_program); -} - -ProgramCL::ProgramCL(const char* name, const char * code, cl_context context, cl_device_id device) : _valid(1) -{ - const char * src[1] = {code}; cl_int status; - - _program = clCreateProgramWithSource(context, 1, src, NULL, &status); - if(status != CL_SUCCESS) _valid = 0; - - status = clBuildProgram(_program, 0, NULL, - GlobalUtil::_debug ? - "-cl-fast-relaxed-math -cl-single-precision-constant -cl-nv-verbose" : - "-cl-fast-relaxed-math -cl-single-precision-constant", NULL, NULL); - - if(status != CL_SUCCESS) {PrintBuildLog(device, 1); _valid = 0;} - else if(GlobalUtil::_debug) PrintBuildLog(device, 0); - - _kernel = clCreateKernel(_program, name, &status); - if(status != CL_SUCCESS) _valid = 0; -} - -void ProgramCL::PrintBuildLog(cl_device_id device, int all) -{ - char buffer[10240] = "\0"; - cl_int status = clGetProgramBuildInfo( - _program, device, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, NULL); - if(all ) - { - std::cerr << buffer << endl; - }else - { - const char * pos = strstr(buffer, "ptxas"); - if(pos) std::cerr << pos << endl; - } -} - -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////PACKED VERSION?/////////////////////////////////// - -ProgramBagCL::ProgramBagCL() -{ - //////////////////////////////////// - _context = NULL; _queue = NULL; - s_gray = s_sampling = NULL; - s_packup = s_zero_pass = NULL; - s_gray_pack = s_unpack = NULL; - s_sampling_u = NULL; - s_dog_pass = NULL; - s_grad_pass = NULL; - s_grad_pass2 = NULL; - s_unpack_dog = NULL; - s_unpack_grd = NULL; - s_unpack_key = NULL; - s_keypoint = NULL; - f_gaussian_skip0 = NULL; - f_gaussian_skip1 = NULL; - f_gaussian_step = 0; - - //////////////////////////////// - GlobalUtil::StartTimer("Initialize OpenCL"); - if(!InitializeContext()) return; - GlobalUtil::StopTimer(); - -} - - - -ProgramBagCL::~ProgramBagCL() -{ - if(s_gray) delete s_gray; - if(s_sampling) delete s_sampling; - if(s_zero_pass) delete s_zero_pass; - if(s_packup) delete s_packup; - if(s_unpack) delete s_unpack; - if(s_gray_pack) delete s_gray_pack; - if(s_sampling_u) delete s_sampling_u; - if(s_dog_pass) delete s_dog_pass; - if(s_grad_pass) delete s_grad_pass; - if(s_grad_pass2) delete s_grad_pass2; - if(s_unpack_dog) delete s_unpack_dog; - if(s_unpack_grd) delete s_unpack_grd; - if(s_unpack_key) delete s_unpack_key; - if(s_keypoint) delete s_keypoint; - - if(f_gaussian_skip1) delete f_gaussian_skip1; - - for(unsigned int i = 0; i < f_gaussian_skip0_v.size(); i++) - { - if(f_gaussian_skip0_v[i]) delete f_gaussian_skip0_v[i]; - } - if(f_gaussian_step && _gaussian_step_num > 0) - { - for(int i = 0; i< _gaussian_step_num; i++) - { - delete f_gaussian_step[i]; - } - delete[] f_gaussian_step; - } - - ////////////////////////////////////// - if(_context) clReleaseContext(_context); - if(_queue) clReleaseCommandQueue(_queue); -} - -bool ProgramBagCL::InitializeContext() -{ - cl_uint num_platform, num_device; - cl_int status; - // Get OpenCL platform count - status = clGetPlatformIDs (0, NULL, &num_platform); - if (status != CL_SUCCESS || num_platform == 0) return false; - - cl_platform_id platforms[16]; - if(num_platform > 16 ) num_platform = 16; - status = clGetPlatformIDs (num_platform, platforms, NULL); - _platform = platforms[0]; - - /////////////////////////////// - status = clGetDeviceIDs(_platform, CL_DEVICE_TYPE_GPU, 0, NULL, &num_device); - if(status != CL_SUCCESS || num_device == 0) return false; - - // Create the device list - cl_device_id* devices = new cl_device_id [num_device]; - status = clGetDeviceIDs(_platform, CL_DEVICE_TYPE_GPU, num_device, devices, NULL); - _device = (status == CL_SUCCESS? devices[0] : 0); delete[] devices; - if(status != CL_SUCCESS) return false; - - - if(GlobalUtil::_verbose) - { - cl_device_mem_cache_type is_gcache; - clGetDeviceInfo(_device, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, sizeof(is_gcache), &is_gcache, NULL); - if(is_gcache == CL_NONE) std::cout << "No cache for global memory\n"; - //else if(is_gcache == CL_READ_ONLY_CACHE) std::cout << "Read only cache for global memory\n"; - //else std::cout << "Read/Write cache for global memory\n"; - } - - //context; - if(GlobalUtil::_UseSiftGPUEX) - { - cl_context_properties prop[] = { - CL_CONTEXT_PLATFORM, (cl_context_properties)_platform, - CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), - CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), 0 }; - _context = clCreateContext(prop, 1, &_device, NULL, NULL, &status); - if(status != CL_SUCCESS) return false; - }else - { - _context = clCreateContext(0, 1, &_device, NULL, NULL, &status); - if(status != CL_SUCCESS) return false; - } - - //command queue - _queue = clCreateCommandQueue(_context, _device, 0, &status); - return status == CL_SUCCESS; -} - -void ProgramBagCL::InitProgramBag(SiftParam¶m) -{ - GlobalUtil::StartTimer("Load Programs"); - LoadFixedShaders(); - LoadDynamicShaders(param); - if(GlobalUtil::_UseSiftGPUEX) LoadDisplayShaders(); - GlobalUtil::StopTimer(); -} - - -void ProgramBagCL::UnloadProgram() -{ - -} - -void ProgramBagCL::FinishCL() -{ - clFinish(_queue); -} - -void ProgramBagCL::LoadFixedShaders() -{ - - - s_gray = new ProgramCL( "gray", - "__kernel void gray(__read_only image2d_t input, __write_only image2d_t output) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int2 coord = (int2)(get_global_id(0), get_global_id(1));\n" - "float4 weight = (float4)(0.299, 0.587, 0.114, 0.0);\n" - "float intensity = dot(weight, read_imagef(input,sampler, coord ));\n" - "float4 result= (float4)(intensity, intensity, intensity, 1.0);\n" - "write_imagef(output, coord, result); }", _context, _device ); - - - s_sampling = new ProgramCL("sampling", - "__kernel void sampling(__read_only image2d_t input, __write_only image2d_t output,\n" - " int width, int height) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if( x >= width || y >= height) return;\n" - "int xa = x + x, ya = y + y; \n" - "int xb = xa + 1, yb = ya + 1; \n" - "float v1 = read_imagef(input, sampler, (int2) (xa, ya)).x; \n" - "float v2 = read_imagef(input, sampler, (int2) (xb, ya)).x; \n" - "float v3 = read_imagef(input, sampler, (int2) (xa, yb)).x; \n" - "float v4 = read_imagef(input, sampler, (int2) (xb, yb)).x; \n" - "float4 result = (float4) (v1, v2, v3, v4);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); - - s_sampling_k = new ProgramCL("sampling_k", - "__kernel void sampling_k(__read_only image2d_t input, __write_only image2d_t output, " - " int width, int height,\n" - " int step, int halfstep) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if( x >= width || y >= height) return;\n" - "int xa = x * step, ya = y *step; \n" - "int xb = xa + halfstep, yb = ya + halfstep; \n" - "float v1 = read_imagef(input, sampler, (int2) (xa, ya)).x; \n" - "float v2 = read_imagef(input, sampler, (int2) (xb, ya)).x; \n" - "float v3 = read_imagef(input, sampler, (int2) (xa, yb)).x; \n" - "float v4 = read_imagef(input, sampler, (int2) (xb, yb)).x; \n" - "float4 result = (float4) (v1, v2, v3, v4);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); - - - s_sampling_u = new ProgramCL("sampling_u", - "__kernel void sampling_u(__read_only image2d_t input, \n" - " __write_only image2d_t output,\n" - " int width, int height,\n" - " float step, float halfstep) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if( x >= width || y >= height) return;\n" - "float xa = x * step, ya = y *step; \n" - "float xb = xa + halfstep, yb = ya + halfstep; \n" - "float v1 = read_imagef(input, sampler, (float2) (xa, ya)).x; \n" - "float v2 = read_imagef(input, sampler, (float2) (xb, ya)).x; \n" - "float v3 = read_imagef(input, sampler, (float2) (xa, yb)).x; \n" - "float v4 = read_imagef(input, sampler, (float2) (xb, yb)).x; \n" - "float4 result = (float4) (v1, v2, v3, v4);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); - - - s_zero_pass = new ProgramCL("zero_pass", - "__kernel void zero_pass(__write_only image2d_t output){\n" - "int2 coord = (int2)(get_global_id(0), get_global_id(1));\n" - "write_imagef(output, coord, (float4)(0.0));}", _context, _device); - - s_packup = new ProgramCL("packup", - "__kernel void packup(__global float* input, __write_only image2d_t output,\n" - " int twidth, int theight, int width){\n" - "int2 coord = (int2)(get_global_id(0), get_global_id(1));\n" - "if(coord.x >= twidth || coord.y >= theight) return;\n" - "int index0 = (coord.y + coord.y) * width; \n" - "int index1 = index0 + coord.x;\n" - "int x2 = min(width -1, coord.x); \n" - "float v1 = input[index1 + coord.x], v2 = input[index1 + x2]; \n" - "int index2 = index1 + width; \n" - "float v3 = input[index2 + coord.x], v4 = input[index2 + x2]; \n " - "write_imagef(output, coord, (float4) (v1, v2, v3, v4));}", _context, _device); - - s_dog_pass = new ProgramCL("dog_pass", - "__kernel void dog_pass(__read_only image2d_t tex, __read_only image2d_t texp,\n" - " __write_only image2d_t dog, int width, int height) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE |\n" - " CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int2 coord = (int2)(get_global_id(0), get_global_id(1)); \n" - "if( coord.x >= width || coord.y >= height) return;\n" - "float4 cc = read_imagef(tex , sampler, coord); \n" - "float4 cp = read_imagef(texp, sampler, coord);\n" - "write_imagef(dog, coord, cc - cp); }\n", _context, _device); - - s_grad_pass = new ProgramCL("grad_pass", - "__kernel void grad_pass(__read_only image2d_t tex, __read_only image2d_t texp,\n" - " __write_only image2d_t dog, int width, int height,\n" - " __write_only image2d_t grad, __write_only image2d_t rot) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE |\n" - " CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if( x >= width || y >= height) return;\n" - "int2 coord = (int2) (x, y);\n" - "float4 cc = read_imagef(tex , sampler, coord); \n" - "float4 cp = read_imagef(texp, sampler, coord);\n" - "float2 cl = read_imagef(tex, sampler, (int2)(x - 1, y)).yw;\n" - "float2 cr = read_imagef(tex, sampler, (int2)(x + 1, y)).xz;\n" - "float2 cd = read_imagef(tex, sampler, (int2)(x, y - 1)).zw;\n" - "float2 cu = read_imagef(tex, sampler, (int2)(x, y + 1)).xy;\n" - "write_imagef(dog, coord, cc - cp); \n" - "float4 dx = (float4)(cc.y - cl.x, cr.x - cc.x, cc.w - cl.y, cr.y - cc.z);\n" - "float4 dy = (float4)(cc.zw - cd.xy, cu.xy - cc.xy);\n" - "write_imagef(grad, coord, 0.5 * sqrt(dx*dx + dy * dy));\n" - "write_imagef(rot, coord, atan2(dy, dx + (float4) (FLT_MIN)));}\n", _context, _device); - - s_grad_pass2 = new ProgramCL("grad_pass2", - "#define BLOCK_DIMX 32\n" - "#define BLOCK_DIMY 14\n" - "#define BLOCK_SIZE (BLOCK_DIMX * BLOCK_DIMY)\n" - "__kernel void grad_pass2(__read_only image2d_t tex, __read_only image2d_t texp,\n" - " __write_only image2d_t dog, int width, int height,\n" - " __write_only image2d_t grd, __write_only image2d_t rot){\n"//, __local float* block) {\n" - "__local float block[BLOCK_SIZE * 4]; \n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE |\n" - " CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int2 coord = (int2) ( get_global_id(0) - get_group_id(0) * 2 - 1, \n" - " get_global_id(1) - get_group_id(1) * 2- 1); \n" - "int idx = mad24(get_local_id(1), BLOCK_DIMX, get_local_id(0));\n" - "float4 cc = read_imagef(tex, sampler, coord);\n" - "block[idx ] = cc.x;\n" - "block[idx + BLOCK_SIZE ] = cc.y;\n" - "block[idx + BLOCK_SIZE * 2] = cc.z;\n" - "block[idx + BLOCK_SIZE * 3] = cc.w;\n" - "barrier(CLK_LOCAL_MEM_FENCE);\n" - "if( get_local_id(0) == 0 || get_local_id(0) == BLOCK_DIMX - 1) return;\n" - "if( get_local_id(1) == 0 || get_local_id(1) == BLOCK_DIMY - 1) return;\n" - "if( coord.x >= width) return; \n" - "if( coord.y >= height) return;\n" - "float4 cp = read_imagef(texp, sampler, coord);\n" - "float4 dx = (float4)( cc.y - block[idx - 1 + BLOCK_SIZE], \n" - " block[idx + 1] - cc.x, \n" - " cc.w - block[idx - 1 + 3 * BLOCK_SIZE], \n" - " block[idx + 1 + 2 * BLOCK_SIZE] - cc.z);\n" - "float4 dy = (float4)( cc.z - block[idx - BLOCK_DIMX + 2 * BLOCK_SIZE], \n" - " cc.w - block[idx - BLOCK_DIMX + 3 * BLOCK_SIZE]," - //" cc.zw - block[idx - BLOCK_DIMX].zw, \n" - " block[idx + BLOCK_DIMX] - cc.x,\n " - " block[idx + BLOCK_DIMX + BLOCK_SIZE] - cc.y);\n" - //" block[idx + BLOCK_DIMX].xy - cc.xy);\n" - "write_imagef(dog, coord, cc - cp); \n" - "write_imagef(grd, coord, 0.5 * sqrt(dx*dx + dy * dy));\n" - "write_imagef(rot, coord, atan2(dy, dx + (float4) (FLT_MIN)));}\n", _context, _device); -} - -void ProgramBagCL::LoadDynamicShaders(SiftParam& param) -{ - LoadKeypointShader(); - LoadGenListShader(param._dog_level_num, 0); - CreateGaussianFilters(param); -} - - -void ProgramBagCL::SelectInitialSmoothingFilter(int octave_min, SiftParam¶m) -{ - float sigma = param.GetInitialSmoothSigma(octave_min); - if(sigma == 0) - { - f_gaussian_skip0 = NULL; - }else - { - for(unsigned int i = 0; i < f_gaussian_skip0_v.size(); i++) - { - if(f_gaussian_skip0_v[i]->_id == octave_min) - { - f_gaussian_skip0 = f_gaussian_skip0_v[i]; - return ; - } - } - FilterCL * filter = CreateGaussianFilter(sigma); - filter->_id = octave_min; - f_gaussian_skip0_v.push_back(filter); - f_gaussian_skip0 = filter; - } - -} - -void ProgramBagCL::CreateGaussianFilters(SiftParam¶m) -{ - if(param._sigma_skip0>0.0f) - { - f_gaussian_skip0 = CreateGaussianFilter(param._sigma_skip0); - f_gaussian_skip0->_id = GlobalUtil::_octave_min_default; - f_gaussian_skip0_v.push_back(f_gaussian_skip0); - } - if(param._sigma_skip1>0.0f) - { - f_gaussian_skip1 = CreateGaussianFilter(param._sigma_skip1); - } - - f_gaussian_step = new FilterCL*[param._sigma_num]; - for(int i = 0; i< param._sigma_num; i++) - { - f_gaussian_step[i] = CreateGaussianFilter(param._sigma[i]); - } - _gaussian_step_num = param._sigma_num; -} - - -FilterCL* ProgramBagCL::CreateGaussianFilter(float sigma) -{ - //pixel inside 3*sigma box - int sz = int( ceil( GlobalUtil::_FilterWidthFactor * sigma -0.5) ) ;// - int width = 2*sz + 1; - - //filter size truncation - if(GlobalUtil::_MaxFilterWidth >0 && width > GlobalUtil::_MaxFilterWidth) - { - std::cout<<"Filter size truncated from "<>1; - width = 2 * sz + 1; - } - - int i; - float * kernel = new float[width]; - float rv = 1.0f/(sigma*sigma); - float v, ksum =0; - - // pre-compute filter - for( i = -sz ; i <= sz ; ++i) - { - kernel[i+sz] = v = exp(-0.5f * i * i *rv) ; - ksum += v; - } - - //normalize the kernel - rv = 1.0f / ksum; - for(i = 0; i< width ;i++) kernel[i]*=rv; - - FilterCL * filter = CreateFilter(kernel, width); - delete [] kernel; - if(GlobalUtil::_verbose && GlobalUtil::_timingL) std::cout<<"Filter: sigma = "<s_shader_h = CreateFilterH(kernel, width); - filter->s_shader_v = CreateFilterV(kernel, width); - filter->_size = width; - filter->_id = 0; - return filter; -} - -ProgramCL* ProgramBagCL::CreateFilterH(float kernel[], int width) -{ - int halfwidth = width >>1; - float * pf = kernel + halfwidth; - int nhpixel = (halfwidth+1)>>1; //how many neighbour pixels need to be looked up - int npixel = (nhpixel<<1)+1;// - float weight[3]; - - //////////////////////////// - char buffer[10240]; - ostrstream out(buffer, 10240); - out< width_ || y > height_) return; \n" - "float4 pc; int2 coord; \n" - "float4 result = (float4)(0.0);\n"; - for(int i = 0 ; i < npixel ; i++) - { - out<<"coord = (int2)(x + ("<< (i - nhpixel) << "), y);\n"; - out<<"pc= read_imagef(input, sampler, coord);\n"; - if(GlobalUtil::_PreciseBorder) - out<<"if(coord.x < 0) pc = pc.xxzz; else if (coord.x > width_) pc = pc.yyww; \n"; - //for each sub-pixel j in center, the weight of sub-pixel k - int xw = (i - nhpixel)*2; - for(int j = 0; j < 3; j++) - { - int xwn = xw + j -1; - weight[j] = xwn < -halfwidth || xwn > halfwidth? 0 : pf[xwn]; - } - if(weight[1] == 0.0) - { - out<<"result += (float4)("<>1; - float * pf = kernel + halfwidth; - int nhpixel = (halfwidth+1)>>1; //how many neighbour pixels need to be looked up - int npixel = (nhpixel<<1)+1;// - float weight[3]; - - //////////////////////////// - char buffer[10240]; - ostrstream out(buffer, 10240); - out< width_ || y >= height_) return; \n" - "float4 pc; int2 coord; \n" - "float4 result = (float4)(0.0);\n"; - for(int i = 0 ; i < npixel ; i++) - { - out<<"coord = (int2)(x, y + ("<< (i - nhpixel) << "));\n"; - out<<"pc= read_imagef(input, sampler, coord);\n"; - if(GlobalUtil::_PreciseBorder) - out<<"if(coord.y < 0) pc = pc.xyxy; else if (coord.y > height_) pc = pc.zwzw; \n"; - //for each sub-pixel j in center, the weight of sub-pixel k - int xw = (i - nhpixel)*2; - for(int j = 0; j < 3; j++) - { - int xwn = xw + j -1; - weight[j] = xwn < -halfwidth || xwn > halfwidth? 0 : pf[xwn]; - } - if(weight[1] == 0.0) - { - out<<"result += (float4)("<s_shader_h->_kernel; - cl_kernel kernelv = filter->s_shader_v->_kernel; - ////////////////////////////////////////////////////////////////// - - cl_int status, w = dst->GetImgWidth(), h = dst->GetImgHeight(); - cl_int w_ = w - 1, h_ = h - 1; - - size_t dim0 = 16, dim1 = 16; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - - clSetKernelArg(kernelh, 0, sizeof(cl_mem), &src->_clData); - clSetKernelArg(kernelh, 1, sizeof(cl_mem), &tmp->_clData); - clSetKernelArg(kernelh, 2, sizeof(cl_int), &w_); - clSetKernelArg(kernelh, 3, sizeof(cl_int), &h_); - status = clEnqueueNDRangeKernel(_queue, kernelh, 2, NULL, gsz, lsz, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCL::FilterImageH"); - if(status != CL_SUCCESS) return; - - clSetKernelArg(kernelv, 0, sizeof(cl_mem), &tmp->_clData); - clSetKernelArg(kernelv, 1, sizeof(cl_mem), &dst->_clData); - clSetKernelArg(kernelv, 2, sizeof(cl_int), &w_); - clSetKernelArg(kernelv, 3, sizeof(cl_int), &h_); - size_t gsz2[2] = {(w + dim1 - 1) / dim1 * dim1, (h + dim0 - 1) / dim0 * dim0}, lsz2[2] = {dim1, dim0}; - status = clEnqueueNDRangeKernel(_queue, kernelv, 2, NULL, gsz2, lsz2, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCL::FilterImageV"); - //clReleaseEvent(event); -} - -void ProgramBagCL::SampleImageU(CLTexImage *dst, CLTexImage *src, int log_scale) -{ - cl_kernel kernel= s_sampling_u->_kernel; - float scale = 1.0f / (1 << log_scale); - float offset = scale * 0.5f; - cl_int w = dst->GetImgWidth(), h = dst->GetImgHeight(); - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(src->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(dst->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(h)); - clSetKernelArg(kernel, 4, sizeof(cl_float), &(scale)); - clSetKernelArg(kernel, 5, sizeof(cl_float), &(offset)); - - size_t dim0 = 16, dim1 = 16; - //while( w * h / dim0 / dim1 < 8 && dim1 > 1) dim1 /= 2; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCL::SampleImageU"); -} - -void ProgramBagCL::SampleImageD(CLTexImage *dst, CLTexImage *src, int log_scale) -{ - cl_kernel kernel; - cl_int w = dst->GetImgWidth(), h = dst->GetImgHeight(); - if(log_scale == 1) - { - kernel = s_sampling->_kernel; - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(src->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(dst->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(h)); - }else - { - cl_int fullstep = (1 << log_scale); - cl_int halfstep = fullstep >> 1; - kernel = s_sampling_k->_kernel; - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(src->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(dst->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(h)); - clSetKernelArg(kernel, 4, sizeof(cl_int), &(fullstep)); - clSetKernelArg(kernel, 5, sizeof(cl_int), &(halfstep)); - } - size_t dim0 = 128, dim1 = 1; - //while( w * h / dim0 / dim1 < 8 && dim1 > 1) dim1 /= 2; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCL::SampleImageD"); -} - -void ProgramBagCL::FilterInitialImage(CLTexImage* tex, CLTexImage* buf) -{ - if(f_gaussian_skip0) FilterImage(f_gaussian_skip0, tex, tex, buf); -} - -void ProgramBagCL::FilterSampledImage(CLTexImage* tex, CLTexImage* buf) -{ - if(f_gaussian_skip1) FilterImage(f_gaussian_skip1, tex, tex, buf); -} - -void ProgramBagCL::ComputeDOG(CLTexImage*tex, CLTexImage* texp, CLTexImage* dog, CLTexImage* grad, CLTexImage* rot) -{ - int margin = 0, use_gm2 = 1; - bool both_grad_dog = rot->_clData && grad->_clData; - cl_int w = tex->GetImgWidth(), h = tex->GetImgHeight(); - cl_kernel kernel ; size_t dim0, dim1; - if(!both_grad_dog) {kernel = s_dog_pass->_kernel; dim0 = 16; dim1 = 12; } - else if(use_gm2) {kernel = s_grad_pass2->_kernel; dim0 = 32; dim1 = 14; margin = 2; } - else {kernel = s_grad_pass->_kernel; dim0 = 16; dim1 = 20; } - size_t gsz[2] = { (w + dim0 - 1 - margin) / (dim0 - margin) * dim0, - (h + dim1 - 1 - margin) / (dim1 - margin) * dim1}; - size_t lsz[2] = {dim0, dim1}; - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(tex->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(texp->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_mem), &(dog->_clData)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 4, sizeof(cl_int), &(h)); - if(both_grad_dog) - { - clSetKernelArg(kernel, 5, sizeof(cl_mem), &(grad->_clData)); - clSetKernelArg(kernel, 6, sizeof(cl_mem), &(rot->_clData)); - } - /////////////////////////////////////////////////////// - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCL::ComputeDOG"); -} - - -void ProgramBagCL::ComputeKEY(CLTexImage*dog, CLTexImage* key, float Tdog, float Tedge) -{ - cl_kernel kernel = s_keypoint->_kernel; - cl_int w = key->GetImgWidth(), h = key->GetImgHeight(); - float threshold0 = Tdog* (GlobalUtil::_SubpixelLocalization?0.8f:1.0f); - float threshold1 = Tdog; - float threshold2 = (Tedge+1)*(Tedge+1)/Tedge; - - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(dog->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &((dog + 1)->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_mem), &((dog - 1)->_clData)); - clSetKernelArg(kernel, 3, sizeof(cl_mem), &(key->_clData)); - clSetKernelArg(kernel, 4, sizeof(cl_float), &(threshold0)); - clSetKernelArg(kernel, 5, sizeof(cl_float), &(threshold1)); - clSetKernelArg(kernel, 6, sizeof(cl_float), &(threshold2)); - clSetKernelArg(kernel, 7, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 8, sizeof(cl_int), &(h)); - - size_t dim0 = 8, dim1 = 8; - //if( w * h / dim0 / dim1 < 16) dim1 /= 2; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCL::ComputeKEY"); -} - -void ProgramBagCL::UnpackImage(CLTexImage*src, CLTexImage* dst) -{ - cl_kernel kernel = s_unpack->_kernel; - cl_int w = dst->GetImgWidth(), h = dst->GetImgHeight(); - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(src->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(dst->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(h)); - const size_t dim0 = 16, dim1 = 16; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - - CheckErrorCL(status, "ProgramBagCL::UnpackImage"); - FinishCL(); - -} - -void ProgramBagCL::UnpackImageDOG(CLTexImage*src, CLTexImage* dst) -{ - if(s_unpack_dog == NULL) return; - cl_kernel kernel = s_unpack_dog->_kernel; - cl_int w = dst->GetImgWidth(), h = dst->GetImgHeight(); - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(src->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(dst->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(h)); - const size_t dim0 = 16, dim1 = 16; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - - CheckErrorCL(status, "ProgramBagCL::UnpackImage"); - FinishCL(); -} - -void ProgramBagCL::UnpackImageGRD(CLTexImage*src, CLTexImage* dst) -{ - if(s_unpack_grd == NULL) return; - cl_kernel kernel = s_unpack_grd->_kernel; - cl_int w = dst->GetImgWidth(), h = dst->GetImgHeight(); - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(src->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(dst->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(h)); - const size_t dim0 = 16, dim1 = 16; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - - CheckErrorCL(status, "ProgramBagCL::UnpackImage"); - FinishCL(); -} -void ProgramBagCL::UnpackImageKEY(CLTexImage*src, CLTexImage* dog, CLTexImage* dst) -{ - if(s_unpack_key == NULL) return; - cl_kernel kernel = s_unpack_key->_kernel; - cl_int w = dst->GetImgWidth(), h = dst->GetImgHeight(); - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(dog->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(src->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_mem), &(dst->_clData)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 4, sizeof(cl_int), &(h)); - const size_t dim0 = 16, dim1 = 16; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - - CheckErrorCL(status, "ProgramBagCL::UnpackImageKEY"); - FinishCL(); -} -void ProgramBagCL::LoadDescriptorShader() -{ - GlobalUtil::_DescriptorPPT = 16; - LoadDescriptorShaderF2(); -} - -void ProgramBagCL::LoadDescriptorShaderF2() -{ - -} - -void ProgramBagCL::LoadOrientationShader(void) -{ - -} - -void ProgramBagCL::LoadGenListShader(int ndoglev,int nlev) -{ - -} - -void ProgramBagCL::LoadKeypointShader() -{ - int i; char buffer[20240]; - ostrstream out(buffer, 20240); - streampos pos; - - //tex(X)(Y) - //X: (CLR) (CENTER 0, LEFT -1, RIGHT +1) - //Y: (CDU) (CENTER 0, DOWN -1, UP +1) - out<< - "__kernel void keypoint(__read_only image2d_t tex, __read_only image2d_t texU,\n" - " __read_only image2d_t texD, __write_only image2d_t texK,\n" - " float THRESHOLD0, float THRESHOLD1, \n" - " float THRESHOLD2, int width, int height)\n" - "{\n" - " sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | \n" - " CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;" - " int x = get_global_id(0), y = get_global_id(1);\n" - " if(x >= width || y >= height) return; \n" - " int xp = x - 1, xn = x + 1;\n" - " int yp = y - 1, yn = y + 1;\n" - " int2 coord0 = (int2) (x, y); \n" - " int2 coord1 = (int2) (xp, y); \n" - " int2 coord2 = (int2) (xn, y); \n" - " int2 coord3 = (int2) (x, yp); \n" - " int2 coord4 = (int2) (x, yn); \n" - " int2 coord5 = (int2) (xp, yp); \n" - " int2 coord6 = (int2) (xp, yn); \n" - " int2 coord7 = (int2) (xn, yp); \n" - " int2 coord8 = (int2) (xn, yn); \n" - " float4 ccc = read_imagef(tex, sampler,coord0);\n" - " float4 clc = read_imagef(tex, sampler,coord1);\n" - " float4 crc = read_imagef(tex, sampler,coord2);\n" - " float4 ccd = read_imagef(tex, sampler,coord3);\n" - " float4 ccu = read_imagef(tex, sampler,coord4);\n" - " float4 cld = read_imagef(tex, sampler,coord5);\n" - " float4 clu = read_imagef(tex, sampler,coord6);\n" - " float4 crd = read_imagef(tex, sampler,coord7);\n" - " float4 cru = read_imagef(tex, sampler,coord8);\n" - " float4 cc = ccc;\n" - " float4 v1[4], v2[4];\n" - " v1[0] = (float4)(clc.y, ccc.y, ccd.z, ccc.z);\n" - " v1[1] = (float4)(ccc.x, crc.x, ccd.w, ccc.w);\n" - " v1[2] = (float4)(clc.w, ccc.w, ccc.x, ccu.x);\n" - " v1[3] = (float4)(ccc.z, crc.z, ccc.y, ccu.y);\n" - " v2[0] = (float4)(cld.w, clc.w, ccd.w, ccc.w);\n" - " v2[1] = (float4)(ccd.z, ccc.z, crd.z, crc.z);\n" - " v2[2] = (float4)(clc.y, clu.y, ccc.y, ccu.y);\n" - " v2[3] = (float4)(ccc.x, ccu.x, crc.x, cru.x);\n" - " float4 key4 = (float4)(0); \n"; - //test against 8 neighbours - //use variable to identify type of extremum - //1.0 for local maximum and -1.0 for minimum - for(i = 0; i < 4; ++i) - out<< - " if(cc.s"< THRESHOLD0){ \n" - " if(all(isgreater((float4)(cc.s"< - //vector v2 is < (-1,-1), (-1,1), (1,-1), (1, 1)> - for(i = 0; i < 4; ++i) - out << - " if(key4.s"< THRESHOLD2 * score_down)keysum = 0;\n" - " }\n"; - - out << - " if(keysum == 1) {\n"; - //////////////////////////////////////////////// - //read 9 pixels of upper/lower level - out<< - " float4 v4[4], v5[4], v6[4];\n" - " ccc = read_imagef(texU, sampler,coord0);\n" - " clc = read_imagef(texU, sampler,coord1);\n" - " crc = read_imagef(texU, sampler,coord2);\n" - " ccd = read_imagef(texU, sampler,coord3);\n" - " ccu = read_imagef(texU, sampler,coord4);\n" - " cld = read_imagef(texU, sampler,coord5);\n" - " clu = read_imagef(texU, sampler,coord6);\n" - " crd = read_imagef(texU, sampler,coord7);\n" - " cru = read_imagef(texU, sampler,coord8);\n" - " float4 cu = ccc;\n" - " v4[0] = (float4)(clc.y, ccc.y, ccd.z, ccc.z);\n" - " v4[1] = (float4)(ccc.x, crc.x, ccd.w, ccc.w);\n" - " v4[2] = (float4)(clc.w, ccc.w, ccc.x, ccu.x);\n" - " v4[3] = (float4)(ccc.z, crc.z, ccc.y, ccu.y);\n" - " v6[0] = (float4)(cld.w, clc.w, ccd.w, ccc.w);\n" - " v6[1] = (float4)(ccd.z, ccc.z, crd.z, crc.z);\n" - " v6[2] = (float4)(clc.y, clu.y, ccc.y, ccu.y);\n" - " v6[3] = (float4)(ccc.x, ccu.x, crc.x, cru.x);\n"; - - for(i = 0; i < 4; ++i) - out << - " if(key4.s"< cu.s"< cd.s"<= 1e-10 ) \n" - " { \n" - " if(x3.y ==maxa ) \n" - " { \n" - " float4 TEMP = A1; A1 = A0; A0 = TEMP; \n" - " }else if( x3.z == maxa ) \n" - " { \n" - " float4 TEMP = A2; A2 = A0; A0 = TEMP; \n" - " } \n" - " A0 /= A0.x; \n" - " A1 -= A1.x * A0; \n" - " A2 -= A2.x * A0; \n" - " float2 x2 = fabs((float2)(A1.y, A2.y)); \n" - " if( x2.y > x2.x ) \n" - " { \n" - " float4 TEMP = A2.yzwx; \n" - " A2.yzw = A1.yzw; \n" - " A1.yzw = TEMP.xyz; \n" - " x2.x = x2.y; \n" - " } \n" - " if(x2.x >= 1e-10) { \n" - " A1.yzw /= A1.y; \n" - " A2.yzw -= A2.y * A1.yzw; \n" - " if(fabs(A2.z) >= 1e-10) {\n" - " offset.z = A2.w /A2.z; \n" - " offset.y = A1.w - offset.z*A1.z; \n" - " offset.x = A0.w - offset.z*A0.z - offset.y*A0.y; \n" - " if(fabs(cc.s0 + 0.5*dot((float4)(fx[0], fy[0], fs, 0), offset ))<=THRESHOLD1\n" - " || any( isgreater(fabs(offset), (float4)(1.0)))) key4 = (float4)(0.0);\n" - " }\n" - " }\n" - " }\n" - <<"\n" - " float keyv = dot(key4, (float4)(1.0, 2.0, 3.0, 4.0));\n" - " result = (float4)(keyv, offset.xyz);\n" - " }}}}\n" - " write_imagef(texK, coord0, result);\n " - "}\n" <<'\0'; - } - else - { - out << "\n" - " float keyv = dot(key4, (float4)(1.0, 2.0, 3.0, 4.0));\n" - " result = (float4)(keyv, 0, 0, 0);\n" - " }}}}\n" - " write_imagef(texK, coord0, result);\n " - "}\n" <<'\0'; - } - - s_keypoint = new ProgramCL("keypoint", buffer, _context, _device); -} - -void ProgramBagCL::LoadDisplayShaders() -{ - //"uniform sampler2DRect tex; void main(){\n" - //"vec4 pc = texture2DRect(tex, gl_TexCoord[0].xy); bvec2 ff = lessThan(fract(gl_TexCoord[0].xy), vec2(0.5));\n" - //"float v = ff.y?(ff.x? pc.r : pc.g):(ff.x?pc.b:pc.a); gl_FragColor = vec4(vec3(v), 1.0);}"); - s_unpack = new ProgramCL("main", - "__kernel void main(__read_only image2d_t input, __write_only image2d_t output,\n" - " int width, int height) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if(x >= width || y >= height) return;\n" - "int xx = x / 2, yy = y / 2; \n" - "float4 vv = read_imagef(input, sampler, (int2) (xx, yy)); \n" - "float v1 = (x & 1 ? vv.w : vv.z); \n" - "float v2 = (x & 1 ? vv.y : vv.x);\n" - "float v = y & 1 ? v1 : v2;\n" - "float4 result = (float4) (v, v, v, 1);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); - - s_unpack_dog = new ProgramCL("main", - "__kernel void main(__read_only image2d_t input, __write_only image2d_t output,\n" - " int width, int height) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if(x >= width || y >= height) return;\n" - "int xx = x / 2, yy = y / 2; \n" - "float4 vv = read_imagef(input, sampler, (int2) (xx, yy)); \n" - "float v1 = (x & 1 ? vv.w : vv.z); \n" - "float v2 = (x & 1 ? vv.y : vv.x);\n" - "float v0 = y & 1 ? v1 : v2;\n" - "float v = 0.5 + 20.0 * v0;\n " - "float4 result = (float4) (v, v, v, 1);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); - - s_unpack_grd = new ProgramCL("main", - "__kernel void main(__read_only image2d_t input, __write_only image2d_t output,\n" - " int width, int height) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if(x >= width || y >= height) return;\n" - "int xx = x / 2, yy = y / 2; \n" - "float4 vv = read_imagef(input, sampler, (int2) (xx, yy)); \n" - "float v1 = (x & 1 ? vv.w : vv.z); \n" - "float v2 = (x & 1 ? vv.y : vv.x);\n" - "float v0 = y & 1 ? v1 : v2;\n" - "float v = 5.0 * v0;\n " - "float4 result = (float4) (v, v, v, 1);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); - - s_unpack_key = new ProgramCL("main", - "__kernel void main(__read_only image2d_t dog,\n" - " __read_only image2d_t key,\n" - " __write_only image2d_t output,\n" - " int width, int height) {\n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if(x >= width || y >= height) return;\n" - "int xx = x / 2, yy = y / 2; \n" - "float4 kk = read_imagef(key, sampler, (int2) (xx, yy));\n" - "int4 cc = isequal(fabs(kk.xxxx), (float4)(1.0, 2.0, 3.0, 4.0));\n" - "int k1 = (x & 1 ? cc.w : cc.z); \n" - "int k2 = (x & 1 ? cc.y : cc.x);\n" - "int k0 = y & 1 ? k1 : k2;\n" - "float4 result;\n" - "if(k0 != 0){\n" - " //result = kk.x > 0 ? ((float4)(1.0, 0, 0, 1.0)) : ((float4) (0.0, 1.0, 0.0, 1.0)); \n" - " result = kk.x < 0 ? ((float4)(0, 1.0, 0, 1.0)) : ((float4) (1.0, 0.0, 0.0, 1.0)); \n" - "}else{" - "float4 vv = read_imagef(dog, sampler, (int2) (xx, yy));\n" - "float v1 = (x & 1 ? vv.w : vv.z); \n" - "float v2 = (x & 1 ? vv.y : vv.x);\n" - "float v0 = y & 1 ? v1 : v2;\n" - "float v = 0.5 + 20.0 * v0;\n " - "result = (float4) (v, v, v, 1);" - "}\n" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); -} - - -void ProgramBagCL::SetMarginCopyParam(int xmax, int ymax) -{ - -} - -void ProgramBagCL::SetGradPassParam(int texP) -{ - -} - -void ProgramBagCL::SetGenListEndParam(int ktex) -{ - -} - -void ProgramBagCL::SetDogTexParam(int texU, int texD) -{ - -} - -void ProgramBagCL::SetGenListInitParam(int w, int h) -{ - float bbox[4] = {(w -1.0f) * 0.5f +0.25f, (w-1.0f) * 0.5f - 0.25f, (h - 1.0f) * 0.5f + 0.25f, (h-1.0f) * 0.5f - 0.25f}; - -} - - -void ProgramBagCL::SetGenListStartParam(float width, int tex0) -{ - -} - - - -void ProgramBagCL::SetGenListStepParam(int tex, int tex0) -{ - -} - -void ProgramBagCL::SetGenVBOParam(float width, float fwidth, float size) -{ - -} - -void ProgramBagCL::SetSimpleOrientationInput(int oTex, float sigma, float sigma_step) -{ - -} - - -void ProgramBagCL::SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int otex, float step) -{ - - -} - -void ProgramBagCL::SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma) -{ - -} - - - -const char* ProgramBagCL::GetErrorString(cl_int error) -{ - static const char* errorString[] = { - "CL_SUCCESS", - "CL_DEVICE_NOT_FOUND", - "CL_DEVICE_NOT_AVAILABLE", - "CL_COMPILER_NOT_AVAILABLE", - "CL_MEM_OBJECT_ALLOCATION_FAILURE", - "CL_OUT_OF_RESOURCES", - "CL_OUT_OF_HOST_MEMORY", - "CL_PROFILING_INFO_NOT_AVAILABLE", - "CL_MEM_COPY_OVERLAP", - "CL_IMAGE_FORMAT_MISMATCH", - "CL_IMAGE_FORMAT_NOT_SUPPORTED", - "CL_BUILD_PROGRAM_FAILURE", - "CL_MAP_FAILURE", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "CL_INVALID_VALUE", - "CL_INVALID_DEVICE_TYPE", - "CL_INVALID_PLATFORM", - "CL_INVALID_DEVICE", - "CL_INVALID_CONTEXT", - "CL_INVALID_QUEUE_PROPERTIES", - "CL_INVALID_COMMAND_QUEUE", - "CL_INVALID_HOST_PTR", - "CL_INVALID_MEM_OBJECT", - "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR", - "CL_INVALID_IMAGE_SIZE", - "CL_INVALID_SAMPLER", - "CL_INVALID_BINARY", - "CL_INVALID_BUILD_OPTIONS", - "CL_INVALID_PROGRAM", - "CL_INVALID_PROGRAM_EXECUTABLE", - "CL_INVALID_KERNEL_NAME", - "CL_INVALID_KERNEL_DEFINITION", - "CL_INVALID_KERNEL", - "CL_INVALID_ARG_INDEX", - "CL_INVALID_ARG_VALUE", - "CL_INVALID_ARG_SIZE", - "CL_INVALID_KERNEL_ARGS", - "CL_INVALID_WORK_DIMENSION", - "CL_INVALID_WORK_GROUP_SIZE", - "CL_INVALID_WORK_ITEM_SIZE", - "CL_INVALID_GLOBAL_OFFSET", - "CL_INVALID_EVENT_WAIT_LIST", - "CL_INVALID_EVENT", - "CL_INVALID_OPERATION", - "CL_INVALID_GL_OBJECT", - "CL_INVALID_BUFFER_SIZE", - "CL_INVALID_MIP_LEVEL", - "CL_INVALID_GLOBAL_WORK_SIZE", - }; - - const int errorCount = sizeof(errorString) / sizeof(errorString[0]); - - const int index = -error; - - return (index >= 0 && index < errorCount) ? errorString[index] : ""; -} - -bool ProgramBagCL::CheckErrorCL(cl_int error, const char* location) -{ - if(error == CL_SUCCESS) return true; - const char *errstr = GetErrorString(error); - if(errstr && errstr[0]) std::cerr << errstr; - else std::cerr << "Error " << error; - if(location) std::cerr << " at " << location; - std::cerr << "\n"; - exit(0); - return false; - -} - - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -void ProgramBagCLN::LoadFixedShaders() -{ - s_sampling = new ProgramCL("sampling", - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void sampling(__read_only image2d_t input, __write_only image2d_t output, " - " int width, int height) {\n" - "int2 coord = (int2)(get_global_id(0), get_global_id(1)); \n" - "if( coord.x >= width || coord.y >= height) return;\n" - "write_imagef(output, coord, read_imagef(input, sampler, coord << 1)); }" , _context, _device); - - s_sampling_k = new ProgramCL("sampling_k", - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void sampling_k(__read_only image2d_t input, __write_only image2d_t output, " - " int width, int height, int step) {\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if( x >= width || y >= height) return;\n" - "int xa = x * step, ya = y *step; \n" - "float4 v1 = read_imagef(input, sampler, (int2) (xa, ya)); \n" - "write_imagef(output, (int2) (x, y), v1); }" , _context, _device); - - - s_sampling_u = new ProgramCL("sampling_u", - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;\n" - "__kernel void sampling_u(__read_only image2d_t input, \n" - " __write_only image2d_t output,\n" - " int width, int height, float step) {\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if( x >= width || y >= height) return;\n" - "float xa = x * step, ya = y *step; \n" - "float v1 = read_imagef(input, sampler, (float2) (xa, ya)).x; \n" - "write_imagef(output, (int2) (x, y), (float4)(v1)); }" , _context, _device); - - s_dog_pass = new ProgramCL("dog_pass", - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void dog_pass(__read_only image2d_t tex, __read_only image2d_t texp,\n" - " __write_only image2d_t dog, int width, int height) {\n" - "int2 coord = (int2)(get_global_id(0), get_global_id(1)); \n" - "if( coord.x >= width || coord.y >= height) return;\n" - "float cc = read_imagef(tex , sampler, coord).x; \n" - "float cp = read_imagef(texp, sampler, coord).x;\n" - "write_imagef(dog, coord, (float4)(cc - cp)); }\n", _context, _device); - - s_grad_pass = new ProgramCL("grad_pass", - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void grad_pass(__read_only image2d_t tex, __read_only image2d_t texp,\n" - " __write_only image2d_t dog, int width, int height, \n" - " __write_only image2d_t grad, __write_only image2d_t rot) {\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if( x >= width || y >= height) return;\n" - "int2 coord = (int2) (x, y);\n" - "float cl = read_imagef(tex, sampler, (int2)(x - 1, y)).x;\n" - "float cc = read_imagef(tex , sampler, coord).x; \n" - "float cr = read_imagef(tex, sampler, (int2)(x + 1, y)).x;\n" - "float cp = read_imagef(texp, sampler, coord).x;\n" - "write_imagef(dog, coord, (float4)(cc - cp)); \n" - "float cd = read_imagef(tex, sampler, (int2)(x, y - 1)).x;\n" - "float cu = read_imagef(tex, sampler, (int2)(x, y + 1)).x;\n" - "float dx = cr - cl, dy = cu - cd; \n" - "float gg = 0.5 * sqrt(dx*dx + dy * dy);\n" - "write_imagef(grad, coord, (float4)(gg));\n" - "float oo = atan2(dy, dx + FLT_MIN);\n" - "write_imagef(rot, coord, (float4)(oo));}\n", _context, _device); - - s_grad_pass2 = new ProgramCL("grad_pass2", - "#define BLOCK_DIMX 32\n" - "#define BLOCK_DIMY 14\n" - "#define BLOCK_SIZE (BLOCK_DIMX * BLOCK_DIMY)\n" - "__kernel void grad_pass2(__read_only image2d_t tex, __read_only image2d_t texp,\n" - " __write_only image2d_t dog, int width, int height,\n" - " __write_only image2d_t grd, __write_only image2d_t rot){\n"//, __local float* block) {\n" - "__local float block[BLOCK_SIZE]; \n" - "sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE |\n" - " CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "int2 coord = (int2) ( get_global_id(0) - get_group_id(0) * 2 - 1, \n" - " get_global_id(1) - get_group_id(1) * 2 - 1); \n" - "int idx = mad24(get_local_id(1), BLOCK_DIMX, get_local_id(0));\n" - "float cc = read_imagef(tex, sampler, coord).x;\n" - "block[idx] = cc;\n" - "barrier(CLK_LOCAL_MEM_FENCE);\n" - "if( get_local_id(0) == 0 || get_local_id(0) == BLOCK_DIMX - 1) return;\n" - "if( get_local_id(1) == 0 || get_local_id(1) == BLOCK_DIMY - 1) return;\n" - "if( coord.x >= width) return; \n" - "if( coord.y >= height) return;\n" - "float cp = read_imagef(texp, sampler, coord).x;\n" - "float dx = block[idx + 1] - block[idx - 1];\n" - "float dy = block[idx + BLOCK_DIMX ] - block[idx - BLOCK_DIMX];\n" - "write_imagef(dog, coord, (float4)(cc - cp)); \n" - "write_imagef(grd, coord, (float4)(0.5 * sqrt(dx*dx + dy * dy)));\n" - "write_imagef(rot, coord, (float4)(atan2(dy, dx + FLT_MIN)));}\n", _context, _device); -} - -void ProgramBagCLN::LoadDisplayShaders() -{ - s_unpack = new ProgramCL("main", - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void main(__read_only image2d_t input, __write_only image2d_t output,\n" - " int width, int height) {\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if(x >= width || y >= height) return;\n" - "float v = read_imagef(input, sampler, (int2) (x, y)).x; \n" - "float4 result = (float4) (v, v, v, 1);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); - - s_unpack_grd = new ProgramCL("main", - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE |\n" - " CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void main(__read_only image2d_t input, __write_only image2d_t output,\n" - " int width, int height) {\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if(x >= width || y >= height) return;\n" - "float v0 = read_imagef(input, sampler, (int2) (x, y)).x; \n" - "float v = 5.0 * v0; float4 result = (float4) (v, v, v, 1);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); - - s_unpack_dog = new ProgramCL("main", - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void main(__read_only image2d_t input, __write_only image2d_t output,\n" - " int width, int height) {\n" - "int x = get_global_id(0), y = get_global_id(1); \n" - "if(x >= width || y >= height) return;\n" - "float v0 = read_imagef(input, sampler, (int2) (x, y)).x; \n" - "float v = 0.5 + 20.0 * v0; float4 result = (float4) (v, v, v, 1);" - "write_imagef(output, (int2) (x, y), result); }" , _context, _device); -} - -ProgramCL* ProgramBagCLN::CreateFilterH(float kernel[], int width) -{ - //////////////////////////// - char buffer[10240]; - ostrstream out(buffer, 10240); - out << "#define KERNEL_WIDTH " << width << "\n" - << "#define KERNEL_HALF_WIDTH " << (width / 2) << "\n" - "#define BLOCK_WIDTH 128\n" - "#define BLOCK_HEIGHT 1\n" - "#define CACHE_WIDTH (BLOCK_WIDTH + KERNEL_WIDTH - 1)\n" - "#define CACHE_WIDTH_ALIGNED ((CACHE_WIDTH + 15) / 16 * 16)\n" - "#define CACHE_COUNT (2 + (CACHE_WIDTH - 2) / BLOCK_WIDTH)\n" - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void filter_h(__read_only image2d_t input, \n" - " __write_only image2d_t output, int width_, int height_, \n" - " __constant float* weight) {\n" - "__local float data[CACHE_WIDTH]; \n" - "int x = get_global_id(0), y = get_global_id(1);\n" - "#pragma unroll\n" - "for(int j = 0; j < CACHE_COUNT; ++j)\n" - "{\n" - " if(get_local_id(0) + j * BLOCK_WIDTH < CACHE_WIDTH)\n" - " {\n" - " int fetch_index = min(x + j * BLOCK_WIDTH - KERNEL_HALF_WIDTH, width_);\n" - " data[get_local_id(0) + j * BLOCK_WIDTH] = read_imagef(input, sampler, (int2)(fetch_index, y)).x;\n" - " }\n" - "}\n" - "barrier(CLK_LOCAL_MEM_FENCE); \n" - "if( x > width_ || y > height_) return; \n" - "float result = 0; \n" - "#pragma unroll\n" - "for(int i = 0; i < KERNEL_WIDTH; ++i)\n" - "{\n" - " result += data[get_local_id(0) + i] * weight[i];\n" - "}\n" - << "write_imagef(output, (int2)(x, y), (float4)(result)); }\n" << '\0'; - return new ProgramCL("filter_h", buffer, _context, _device); -} - - - -ProgramCL* ProgramBagCLN::CreateFilterV(float kernel[], int width) -{ - //////////////////////////// - char buffer[10240]; - ostrstream out(buffer, 10240); - out << "#define KERNEL_WIDTH " << width << "\n" - << "#define KERNEL_HALF_WIDTH " << (width / 2) << "\n" - "#define BLOCK_WIDTH 128\n" - "#define CACHE_WIDTH (BLOCK_WIDTH + KERNEL_WIDTH - 1)\n" - "#define CACHE_WIDTH_ALIGNED ((CACHE_WIDTH + 15) / 16 * 16)\n" - "#define CACHE_COUNT (2 + (CACHE_WIDTH - 2) / BLOCK_WIDTH)\n" - "const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | \n" - " CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;\n" - "__kernel void filter_v(__read_only image2d_t input, \n" - " __write_only image2d_t output, int width_, int height_, \n" - " __constant float* weight) {\n" - "__local float data[CACHE_WIDTH]; \n" - "int x = get_global_id(0), y = get_global_id(1);\n" - "#pragma unroll\n" - "for(int j = 0; j < CACHE_COUNT; ++j)\n" - "{\n" - " if(get_local_id(1) + j * BLOCK_WIDTH < CACHE_WIDTH)\n" - " {\n" - " int fetch_index = min(y + j * BLOCK_WIDTH - KERNEL_HALF_WIDTH, height_);\n" - " data[get_local_id(1) + j * BLOCK_WIDTH ] = read_imagef(input, sampler, (int2)(x, fetch_index)).x;\n" - " }\n" - "}\n" - "barrier(CLK_LOCAL_MEM_FENCE); \n" - "if( x > width_ || y > height_) return; \n" - "float result = 0; \n" - "#pragma unroll\n" - "for(int i = 0; i < KERNEL_WIDTH; ++i)\n" - "{\n" - " result += data[get_local_id(1) + i] * weight[i];\n" - "}\n" - << "write_imagef(output, (int2)(x, y), (float4)(result)); }\n" << '\0'; - - return new ProgramCL("filter_v", buffer, _context, _device); -} - -FilterCL* ProgramBagCLN::CreateFilter(float kernel[], int width) -{ - FilterCL * filter = new FilterCL; - filter->s_shader_h = CreateFilterH(kernel, width); - filter->s_shader_v = CreateFilterV(kernel, width); - filter->_weight = new CLTexImage(_context, _queue); - filter->_weight->InitBufferTex(width, 1, 1); - filter->_weight->CopyFromHost(kernel); - filter->_size = width; - return filter; -} - - -void ProgramBagCLN::FilterImage(FilterCL* filter, CLTexImage *dst, CLTexImage *src, CLTexImage*tmp) -{ - cl_kernel kernelh = filter->s_shader_h->_kernel; - cl_kernel kernelv = filter->s_shader_v->_kernel; - ////////////////////////////////////////////////////////////////// - - cl_int status, w = dst->GetImgWidth(), h = dst->GetImgHeight(); - cl_mem weight = (cl_mem) filter->_weight->_clData; - cl_int w_ = w - 1, h_ = h - 1; - - - clSetKernelArg(kernelh, 0, sizeof(cl_mem), &src->_clData); - clSetKernelArg(kernelh, 1, sizeof(cl_mem), &tmp->_clData); - clSetKernelArg(kernelh, 2, sizeof(cl_int), &w_); - clSetKernelArg(kernelh, 3, sizeof(cl_int), &h_); - clSetKernelArg(kernelh, 4, sizeof(cl_mem), &weight); - - size_t dim00 = 128, dim01 = 1; - size_t gsz1[2] = {(w + dim00 - 1) / dim00 * dim00, (h + dim01 - 1) / dim01 * dim01}, lsz1[2] = {dim00, dim01}; - status = clEnqueueNDRangeKernel(_queue, kernelh, 2, NULL, gsz1, lsz1, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCLN::FilterImageH"); - if(status != CL_SUCCESS) return; - - - clSetKernelArg(kernelv, 0, sizeof(cl_mem), &tmp->_clData); - clSetKernelArg(kernelv, 1, sizeof(cl_mem), &dst->_clData); - clSetKernelArg(kernelv, 2, sizeof(cl_int), &w_); - clSetKernelArg(kernelv, 3, sizeof(cl_int), &h_); - clSetKernelArg(kernelv, 4, sizeof(cl_mem), &weight); - - size_t dim10 = 1, dim11 = 128; - size_t gsz2[2] = {(w + dim10 - 1) / dim10 * dim10, (h + dim11 - 1) / dim11 * dim11}, lsz2[2] = {dim10, dim11}; - status = clEnqueueNDRangeKernel(_queue, kernelv, 2, NULL, gsz2, lsz2, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCLN::FilterImageV"); - //clReleaseEvent(event); -} - -void ProgramBagCLN::SampleImageD(CLTexImage *dst, CLTexImage *src, int log_scale) -{ - cl_kernel kernel; - cl_int w = dst->GetImgWidth(), h = dst->GetImgHeight(); - - cl_int fullstep = (1 << log_scale); - kernel = log_scale == 1? s_sampling->_kernel : s_sampling_k->_kernel; - clSetKernelArg(kernel, 0, sizeof(cl_mem), &(src->_clData)); - clSetKernelArg(kernel, 1, sizeof(cl_mem), &(dst->_clData)); - clSetKernelArg(kernel, 2, sizeof(cl_int), &(w)); - clSetKernelArg(kernel, 3, sizeof(cl_int), &(h)); - if(log_scale > 1) clSetKernelArg(kernel, 4, sizeof(cl_int), &(fullstep)); - - size_t dim0 = 128, dim1 = 1; - //while( w * h / dim0 / dim1 < 8 && dim1 > 1) dim1 /= 2; - size_t gsz[2] = {(w + dim0 - 1) / dim0 * dim0, (h + dim1 - 1) / dim1 * dim1}, lsz[2] = {dim0, dim1}; - cl_int status = clEnqueueNDRangeKernel(_queue, kernel, 2, NULL, gsz, lsz, 0, NULL, NULL); - CheckErrorCL(status, "ProgramBagCLN::SampleImageD"); -} - - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramCL.h b/3rdparty/SiftGPU/src/SiftGPU/ProgramCL.h deleted file mode 100644 index e134992b..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramCL.h +++ /dev/null @@ -1,164 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ProgramCL.h -// Author: Changchang Wu -// Description : interface for the ProgramCL classes. -// ProgramCL: Cg programs -// ShaderBagCG: All Cg shaders for Sift in a bag -// FilterCL: Cg Gaussian Filters -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#if defined(CL_SIFTGPU_ENABLED) - -#ifndef _PROGRAM_CL_H -#define _PROGRAM_CL_H - -#include "ProgramGPU.h" - -class ProgramCL: public ProgramGPU -{ - cl_program _program; - cl_kernel _kernel; - int _valid; -public: - int IsValidProgram(){return _program && _valid;} - ProgramCL(const char* name, const char * code, cl_context contex, cl_device_id device); - ProgramCL(); - void PrintBuildLog(cl_device_id device, int all); - virtual ~ProgramCL(); - virtual int UseProgram(){return 1;} - virtual void * GetProgramID() {return _kernel;} - friend class ProgramBagCL; - friend class ProgramBagCLN; -}; - -class CLTexImage; -class FilterCL -{ -public: - ProgramCL* s_shader_h; - ProgramCL* s_shader_v; - int _size; - int _id; - CLTexImage * _weight; -public: - FilterCL() : s_shader_h(NULL), s_shader_v(NULL), _size(0), _id(0), _weight(NULL) {} - ~FilterCL() {if(s_shader_h) delete s_shader_h; if(s_shader_v) delete s_shader_v; if(_weight) delete _weight; } -}; - -class SiftParam; - -class ProgramBagCL -{ -protected: - cl_platform_id _platform; - cl_device_id _device; - cl_context _context; - cl_command_queue _queue; -protected: - ProgramCL * s_gray; - ProgramCL * s_sampling; - ProgramCL * s_sampling_k; - ProgramCL * s_sampling_u; - ProgramCL * s_zero_pass; - ProgramCL * s_packup; - ProgramCL * s_unpack; - ProgramCL * s_unpack_dog; - ProgramCL * s_unpack_grd; - ProgramCL * s_unpack_key; - ProgramCL * s_dog_pass; - ProgramCL * s_grad_pass; - ProgramCL * s_grad_pass2; - ProgramCL * s_gray_pack; - ProgramCL * s_keypoint; -public: - FilterCL * f_gaussian_skip0; - vector f_gaussian_skip0_v; - FilterCL * f_gaussian_skip1; - FilterCL ** f_gaussian_step; - int _gaussian_step_num; -public: - ProgramBagCL(); - bool InitializeContext(); - virtual ~ProgramBagCL(); - void FinishCL(); - cl_context GetContextCL() {return _context;} - cl_command_queue GetCommandQueue() {return _queue;} - static const char* GetErrorString(cl_int error); - static bool CheckErrorCL(cl_int error, const char* location = NULL); -public: - FilterCL * CreateGaussianFilter(float sigma); - void CreateGaussianFilters(SiftParam¶m); - void SelectInitialSmoothingFilter(int octave_min, SiftParam¶m); - void FilterInitialImage(CLTexImage* tex, CLTexImage* buf); - void FilterSampledImage(CLTexImage* tex, CLTexImage* buf); - void UnpackImage(CLTexImage*src, CLTexImage* dst); - void UnpackImageDOG(CLTexImage*src, CLTexImage* dst); - void UnpackImageGRD(CLTexImage*src, CLTexImage* dst); - void UnpackImageKEY(CLTexImage*src, CLTexImage* dog, CLTexImage* dst); - void ComputeDOG(CLTexImage*tex, CLTexImage* texp, CLTexImage* dog, CLTexImage* grad, CLTexImage* rot); - void ComputeKEY(CLTexImage*dog, CLTexImage* key, float Tdog, float Tedge); -public: - virtual void SampleImageU(CLTexImage *dst, CLTexImage *src, int log_scale); - virtual void SampleImageD(CLTexImage *dst, CLTexImage *src, int log_scale = 1); - virtual void FilterImage(FilterCL* filter, CLTexImage *dst, CLTexImage *src, CLTexImage*tmp); - virtual ProgramCL* CreateFilterH(float kernel[], int width); - virtual ProgramCL* CreateFilterV(float kernel[], int width); - virtual FilterCL* CreateFilter(float kernel[], int width); -public: - virtual void InitProgramBag(SiftParam¶m); - virtual void LoadDescriptorShader(); - virtual void LoadDescriptorShaderF2(); - virtual void LoadOrientationShader(); - virtual void LoadGenListShader(int ndoglev, int nlev); - virtual void UnloadProgram() ; - virtual void LoadKeypointShader(); - virtual void LoadFixedShaders(); - virtual void LoadDisplayShaders(); - virtual void LoadDynamicShaders(SiftParam& param); -public: - //parameters - virtual void SetGradPassParam(int texP); - virtual void SetGenListEndParam(int ktex); - virtual void SetGenListStartParam(float width, int tex0); - virtual void SetGenListInitParam(int w, int h); - virtual void SetMarginCopyParam(int xmax, int ymax); - virtual void SetDogTexParam(int texU, int texD); - virtual void SetGenListStepParam(int tex, int tex0); - virtual void SetGenVBOParam( float width, float fwidth, float size); - virtual void SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma); - virtual void SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int stex, float step); - virtual void SetSimpleOrientationInput(int oTex, float sigma, float sigma_step); - -}; - -class CLTexImage ; -class ProgramBagCLN: public ProgramBagCL -{ -public: - virtual void SampleImageD(CLTexImage *dst, CLTexImage *src, int log_scale = 1); - virtual FilterCL* CreateFilter(float kernel[], int width); - virtual ProgramCL* CreateFilterH(float kernel[], int width); - virtual ProgramCL* CreateFilterV(float kernel[], int width); - virtual void FilterImage(FilterCL* filter, CLTexImage *dst, CLTexImage *src, CLTexImage*tmp); - virtual void LoadFixedShaders(); - virtual void LoadDisplayShaders(); -}; -#endif -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramCU.cu b/3rdparty/SiftGPU/src/SiftGPU/ProgramCU.cu deleted file mode 100644 index 257dda08..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramCU.cu +++ /dev/null @@ -1,1795 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ProgramCU.cu -// Author: Changchang Wu -// Description : implementation of ProgramCU and all CUDA kernels -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if defined(CUDA_SIFTGPU_ENABLED) - -#include "GL/glew.h" -#include "stdio.h" - -#include "CuTexImage.h" -#include "ProgramCU.h" -#include "GlobalUtil.h" - -//---------------------------------------------------------------- -//Begin SiftGPU setting section. -////////////////////////////////////////////////////////// -#define IMUL(X,Y) __mul24(X,Y) -//#define FDIV(X,Y) ((X)/(Y)) -#define FDIV(X,Y) __fdividef(X,Y) - -///////////////////////////////////////////////////////// -//filter kernel width range (don't change this) -#define KERNEL_MAX_WIDTH 33 -#define KERNEL_MIN_WIDTH 5 - -////////////////////////////////////////////////////////// -//horizontal filter block size (32, 64, 128, 256, 512) -#define FILTERH_TILE_WIDTH 128 -//thread block for vertical filter. FILTERV_BLOCK_WIDTH can be (4, 8 or 16) -#define FILTERV_BLOCK_WIDTH 16 -#define FILTERV_BLOCK_HEIGHT 32 -//The corresponding image patch for a thread block -#define FILTERV_PIXEL_PER_THREAD 4 -#define FILTERV_TILE_WIDTH FILTERV_BLOCK_WIDTH -#define FILTERV_TILE_HEIGHT (FILTERV_PIXEL_PER_THREAD * FILTERV_BLOCK_HEIGHT) - - -////////////////////////////////////////////////////////// -//thread block size for computing Difference of Gaussian -#define DOG_BLOCK_LOG_DIMX 7 -#define DOG_BLOCK_LOG_DIMY 0 -#define DOG_BLOCK_DIMX (1 << DOG_BLOCK_LOG_DIMX) -#define DOG_BLOCK_DIMY (1 << DOG_BLOCK_LOG_DIMY) - -////////////////////////////////////////////////////////// -//thread block size for keypoint detection -#define KEY_BLOCK_LOG_DIMX 3 -#define KEY_BLOCK_LOG_DIMY 3 -#define KEY_BLOCK_DIMX (1< texData; -texture texDataB; -texture texDataF2; -texture texDataF4; -texture texDataI4; -texture texDataList; - -//template __device__ float Conv(float *data) { return Conv(data) + data[i]*d_kernel[i];} -//template<> __device__ float Conv<0>(float *data) { return data[0] * d_kernel[0]; } - - -////////////////////////////////////////////////////////////// -template __global__ void FilterH( float* d_result, int width) -{ - - const int HALF_WIDTH = FW >> 1; - const int CACHE_WIDTH = FILTERH_TILE_WIDTH + FW -1; - const int CACHE_COUNT = 2 + (CACHE_WIDTH - 2)/ FILTERH_TILE_WIDTH; - __shared__ float data[CACHE_WIDTH]; - const int bcol = IMUL(blockIdx.x, FILTERH_TILE_WIDTH); - const int col = bcol + threadIdx.x; - const int index_min = IMUL(blockIdx.y, width); - const int index_max = index_min + width - 1; - int src_index = index_min + bcol - HALF_WIDTH + threadIdx.x; - int cache_index = threadIdx.x; - float value = 0; -#pragma unroll - for(int j = 0; j < CACHE_COUNT; ++j) - { - if(cache_index < CACHE_WIDTH) - { - int fetch_index = src_index < index_min? index_min : (src_index > index_max ? index_max : src_index); - data[cache_index] = tex1Dfetch(texData,fetch_index); - src_index += FILTERH_TILE_WIDTH; - cache_index += FILTERH_TILE_WIDTH; - } - } - __syncthreads(); - if(col >= width) return; -#pragma unroll - for(int i = 0; i < FW; ++i) - { - value += (data[threadIdx.x + i]* d_kernel[i]); - } -// value = Conv(data + threadIdx.x); - d_result[index_min + col] = value; -} - - - -//////////////////////////////////////////////////////////////////// -template __global__ void FilterV(float* d_result, int width, int height) -{ - const int HALF_WIDTH = FW >> 1; - const int CACHE_WIDTH = FW + FILTERV_TILE_HEIGHT - 1; - const int TEMP = CACHE_WIDTH & 0xf; -//add some extra space to avoid bank conflict -#if FILTERV_TILE_WIDTH == 16 - //make the stride 16 * n +/- 1 - const int EXTRA = (TEMP == 1 || TEMP == 0) ? 1 - TEMP : 15 - TEMP; -#elif FILTERV_TILE_WIDTH == 8 - //make the stride 16 * n +/- 2 - const int EXTRA = (TEMP == 2 || TEMP == 1 || TEMP == 0) ? 2 - TEMP : (TEMP == 15? 3 : 14 - TEMP); -#elif FILTERV_TILE_WIDTH == 4 - //make the stride 16 * n +/- 4 - const int EXTRA = (TEMP >=0 && TEMP <=4) ? 4 - TEMP : (TEMP > 12? 20 - TEMP : 12 - TEMP); -#else -#error -#endif - const int CACHE_TRUE_WIDTH = CACHE_WIDTH + EXTRA; - const int CACHE_COUNT = (CACHE_WIDTH + FILTERV_BLOCK_HEIGHT - 1) / FILTERV_BLOCK_HEIGHT; - const int WRITE_COUNT = (FILTERV_TILE_HEIGHT + FILTERV_BLOCK_HEIGHT -1) / FILTERV_BLOCK_HEIGHT; - __shared__ float data[CACHE_TRUE_WIDTH * FILTERV_TILE_WIDTH]; - const int row_block_first = IMUL(blockIdx.y, FILTERV_TILE_HEIGHT); - const int col = IMUL(blockIdx.x, FILTERV_TILE_WIDTH) + threadIdx.x; - const int row_first = row_block_first - HALF_WIDTH; - const int data_index_max = IMUL(height - 1, width) + col; - const int cache_col_start = threadIdx.y; - const int cache_row_start = IMUL(threadIdx.x, CACHE_TRUE_WIDTH); - int cache_index = cache_col_start + cache_row_start; - int data_index = IMUL(row_first + cache_col_start, width) + col; - - if(col < width) - { -#pragma unroll - for(int i = 0; i < CACHE_COUNT; ++i) - { - if(cache_col_start < CACHE_WIDTH - i * FILTERV_BLOCK_HEIGHT) - { - int fetch_index = data_index < col ? col : (data_index > data_index_max? data_index_max : data_index); - data[cache_index + i * FILTERV_BLOCK_HEIGHT] = tex1Dfetch(texData,fetch_index); - data_index += IMUL(FILTERV_BLOCK_HEIGHT, width); - } - } - } - __syncthreads(); - - if(col >= width) return; - - int row = row_block_first + threadIdx.y; - int index_start = cache_row_start + threadIdx.y; -#pragma unroll - for(int i = 0; i < WRITE_COUNT; ++i, - row += FILTERV_BLOCK_HEIGHT, index_start += FILTERV_BLOCK_HEIGHT) - { - if(row < height) - { - int index_dest = IMUL(row, width) + col; - float value = 0; -#pragma unroll - for(int i = 0; i < FW; ++i) - { - value += (data[index_start + i] * d_kernel[i]); - } - d_result[index_dest] = value; - } - } -} - - -template __global__ void UpsampleKernel(float* d_result, int width) -{ - const int SCALE = (1 << LOG_SCALE), SCALE_MASK = (SCALE - 1); - const float INV_SCALE = 1.0f / (float(SCALE)); - int col = IMUL(blockIdx.x, FILTERH_TILE_WIDTH) + threadIdx.x; - if(col >= width) return; - - int row = blockIdx.y >> LOG_SCALE; - int index = row * width + col; - int dst_row = blockIdx.y; - int dst_idx= (width * dst_row + col) * SCALE; - int helper = blockIdx.y & SCALE_MASK; - if (helper) - { - float v11 = tex1Dfetch(texData, index); - float v12 = tex1Dfetch(texData, index + 1); - index += width; - float v21 = tex1Dfetch(texData, index); - float v22 = tex1Dfetch(texData, index + 1); - float w1 = INV_SCALE * helper, w2 = 1.0 - w1; - float v1 = (v21 * w1 + w2 * v11); - float v2 = (v22 * w1 + w2 * v12); - d_result[dst_idx] = v1; -#pragma unroll - for(int i = 1; i < SCALE; ++i) - { - const float r2 = i * INV_SCALE; - const float r1 = 1.0f - r2; - d_result[dst_idx +i] = v1 * r1 + v2 * r2; - } - }else - { - float v1 = tex1Dfetch(texData, index); - float v2 = tex1Dfetch(texData, index + 1); - d_result[dst_idx] = v1; -#pragma unroll - for(int i = 1; i < SCALE; ++i) - { - const float r2 = i * INV_SCALE; - const float r1 = 1.0f - r2; - d_result[dst_idx +i] = v1 * r1 + v2 * r2; - } - } - -} - -//////////////////////////////////////////////////////////////////////////////////////// -void ProgramCU::SampleImageU(CuTexImage *dst, CuTexImage *src, int log_scale) -{ - int width = src->GetImgWidth(), height = src->GetImgHeight(); - src->BindTexture(texData); - dim3 grid((width + FILTERH_TILE_WIDTH - 1)/ FILTERH_TILE_WIDTH, height << log_scale); - dim3 block(FILTERH_TILE_WIDTH); - switch(log_scale) - { - case 1 : UpsampleKernel<1> <<< grid, block>>> ((float*) dst->_cuData, width); break; - case 2 : UpsampleKernel<2> <<< grid, block>>> ((float*) dst->_cuData, width); break; - case 3 : UpsampleKernel<3> <<< grid, block>>> ((float*) dst->_cuData, width); break; - default: break; - } -} - -template __global__ void DownsampleKernel(float* d_result, int src_width, int dst_width) -{ - const int dst_col = IMUL(blockIdx.x, FILTERH_TILE_WIDTH) + threadIdx.x; - if(dst_col >= dst_width) return; - const int src_col = min((dst_col << LOG_SCALE), (src_width - 1)); - const int dst_row = blockIdx.y; - const int src_row = blockIdx.y << LOG_SCALE; - const int src_idx = IMUL(src_row, src_width) + src_col; - const int dst_idx = IMUL(dst_width, dst_row) + dst_col; - d_result[dst_idx] = tex1Dfetch(texData, src_idx); - -} - -__global__ void DownsampleKernel(float* d_result, int src_width, int dst_width, const int log_scale) -{ - const int dst_col = IMUL(blockIdx.x, FILTERH_TILE_WIDTH) + threadIdx.x; - if(dst_col >= dst_width) return; - const int src_col = min((dst_col << log_scale), (src_width - 1)); - const int dst_row = blockIdx.y; - const int src_row = blockIdx.y << log_scale; - const int src_idx = IMUL(src_row, src_width) + src_col; - const int dst_idx = IMUL(dst_width, dst_row) + dst_col; - d_result[dst_idx] = tex1Dfetch(texData, src_idx); - -} - -void ProgramCU::SampleImageD(CuTexImage *dst, CuTexImage *src, int log_scale) -{ - int src_width = src->GetImgWidth(), dst_width = dst->GetImgWidth() ; - - src->BindTexture(texData); - dim3 grid((dst_width + FILTERH_TILE_WIDTH - 1)/ FILTERH_TILE_WIDTH, dst->GetImgHeight()); - dim3 block(FILTERH_TILE_WIDTH); - switch(log_scale) - { - case 1 : DownsampleKernel<1> <<< grid, block>>> ((float*) dst->_cuData, src_width, dst_width); break; - case 2 : DownsampleKernel<2> <<< grid, block>>> ((float*) dst->_cuData, src_width, dst_width); break; - case 3 : DownsampleKernel<3> <<< grid, block>>> ((float*) dst->_cuData, src_width, dst_width); break; - default: DownsampleKernel <<< grid, block>>> ((float*) dst->_cuData, src_width, dst_width, log_scale); - } -} - -__global__ void ChannelReduce_Kernel(float* d_result) -{ - int index = IMUL(blockIdx.x, FILTERH_TILE_WIDTH) + threadIdx.x; - d_result[index] = tex1Dfetch(texData, index*4); -} - -__global__ void ChannelReduce_Convert_Kernel(float* d_result) -{ - int index = IMUL(blockIdx.x, FILTERH_TILE_WIDTH) + threadIdx.x; - float4 rgba = tex1Dfetch(texDataF4, index); - d_result[index] = 0.299f * rgba.x + 0.587f* rgba.y + 0.114f * rgba.z; -} - -void ProgramCU::ReduceToSingleChannel(CuTexImage* dst, CuTexImage* src, int convert_rgb) -{ - int width = src->GetImgWidth(), height = dst->GetImgHeight() ; - - dim3 grid((width * height + FILTERH_TILE_WIDTH - 1)/ FILTERH_TILE_WIDTH); - dim3 block(FILTERH_TILE_WIDTH); - if(convert_rgb) - { - src->BindTexture(texDataF4); - ChannelReduce_Convert_Kernel<<>>((float*)dst->_cuData); - }else - { - src->BindTexture(texData); - ChannelReduce_Kernel<<>>((float*)dst->_cuData); - } -} - -__global__ void ConvertByteToFloat_Kernel(float* d_result) -{ - int index = IMUL(blockIdx.x, FILTERH_TILE_WIDTH) + threadIdx.x; - d_result[index] = tex1Dfetch(texDataB, index); -} - -void ProgramCU::ConvertByteToFloat(CuTexImage*src, CuTexImage* dst) -{ - int width = src->GetImgWidth(), height = dst->GetImgHeight() ; - dim3 grid((width * height + FILTERH_TILE_WIDTH - 1)/ FILTERH_TILE_WIDTH); - dim3 block(FILTERH_TILE_WIDTH); - src->BindTexture(texDataB); - ConvertByteToFloat_Kernel<<>>((float*)dst->_cuData); -} - -void ProgramCU::CreateFilterKernel(float sigma, float* kernel, int& width) -{ - int i, sz = int( ceil( GlobalUtil::_FilterWidthFactor * sigma -0.5) ) ;// - width = 2*sz + 1; - - if(width > KERNEL_MAX_WIDTH) - { - //filter size truncation - sz = KERNEL_MAX_WIDTH >> 1; - width =KERNEL_MAX_WIDTH; - }else if(width < KERNEL_MIN_WIDTH) - { - sz = KERNEL_MIN_WIDTH >> 1; - width =KERNEL_MIN_WIDTH; - } - - float rv = 1.0f/(sigma*sigma), v, ksum =0; - - // pre-compute filter - for( i = -sz ; i <= sz ; ++i) - { - kernel[i+sz] = v = exp(-0.5f * i * i *rv) ; - ksum += v; - } - - //normalize the kernel - rv = 1.0f/ksum; - for(i = 0; i< width ;i++) kernel[i]*=rv; -} - - -template void ProgramCU::FilterImage(CuTexImage *dst, CuTexImage *src, CuTexImage* buf) -{ - int width = src->GetImgWidth(), height = src->GetImgHeight(); - - //horizontal filtering - src->BindTexture(texData); - dim3 gridh((width + FILTERH_TILE_WIDTH - 1)/ FILTERH_TILE_WIDTH, height); - dim3 blockh(FILTERH_TILE_WIDTH); - FilterH<<>>((float*)buf->_cuData, width); - CheckErrorCUDA("FilterH"); - - ///vertical filtering - buf->BindTexture(texData); - dim3 gridv((width + FILTERV_TILE_WIDTH - 1)/ FILTERV_TILE_WIDTH, (height + FILTERV_TILE_HEIGHT - 1)/FILTERV_TILE_HEIGHT); - dim3 blockv(FILTERV_TILE_WIDTH, FILTERV_BLOCK_HEIGHT); - FilterV<<>>((float*)dst->_cuData, width, height); - CheckErrorCUDA("FilterV"); -} - -////////////////////////////////////////////////////////////////////// -// tested on 2048x1500 image, the time on pyramid construction is -// OpenGL version : 18ms -// CUDA version: 28 ms -void ProgramCU::FilterImage(CuTexImage *dst, CuTexImage *src, CuTexImage* buf, float sigma) -{ - float filter_kernel[KERNEL_MAX_WIDTH]; int width; - CreateFilterKernel(sigma, filter_kernel, width); - cudaMemcpyToSymbol(d_kernel, filter_kernel, width * sizeof(float), 0, cudaMemcpyHostToDevice); - - switch(width) - { - case 5: FilterImage< 5>(dst, src, buf); break; - case 7: FilterImage< 7>(dst, src, buf); break; - case 9: FilterImage< 9>(dst, src, buf); break; - case 11: FilterImage<11>(dst, src, buf); break; - case 13: FilterImage<13>(dst, src, buf); break; - case 15: FilterImage<15>(dst, src, buf); break; - case 17: FilterImage<17>(dst, src, buf); break; - case 19: FilterImage<19>(dst, src, buf); break; - case 21: FilterImage<21>(dst, src, buf); break; - case 23: FilterImage<23>(dst, src, buf); break; - case 25: FilterImage<25>(dst, src, buf); break; - case 27: FilterImage<27>(dst, src, buf); break; - case 29: FilterImage<29>(dst, src, buf); break; - case 31: FilterImage<31>(dst, src, buf); break; - case 33: FilterImage<33>(dst, src, buf); break; - default: break; - } - -} - - -texture texC; -texture texP; -texture texN; - -void __global__ ComputeDOG_Kernel(float* d_dog, float2* d_got, int width, int height) -{ - int row = (blockIdx.y << DOG_BLOCK_LOG_DIMY) + threadIdx.y; - int col = (blockIdx.x << DOG_BLOCK_LOG_DIMX) + threadIdx.x; - if(col < width && row < height) - { - int index = IMUL(row, width) + col; - float vp = tex1Dfetch(texP, index); - float v = tex1Dfetch(texC, index); - d_dog[index] = v - vp; - float vxn = tex1Dfetch(texC, index + 1); - float vxp = tex1Dfetch(texC, index - 1); - float vyp = tex1Dfetch(texC, index - width); - float vyn = tex1Dfetch(texC, index + width); - float dx = vxn - vxp, dy = vyn - vyp; - float grd = 0.5f * sqrt(dx * dx + dy * dy); - float rot = (grd == 0.0f? 0.0f : atan2(dy, dx)); - d_got[index] = make_float2(grd, rot); - } -} - -void __global__ ComputeDOG_Kernel(float* d_dog, int width, int height) -{ - int row = (blockIdx.y << DOG_BLOCK_LOG_DIMY) + threadIdx.y; - int col = (blockIdx.x << DOG_BLOCK_LOG_DIMX) + threadIdx.x; - if(col < width && row < height) - { - int index = IMUL(row, width) + col; - float vp = tex1Dfetch(texP, index); - float v = tex1Dfetch(texC, index); - d_dog[index] = v - vp; - } -} - -void ProgramCU::ComputeDOG(CuTexImage* gus, CuTexImage* dog, CuTexImage* got) -{ - int width = gus->GetImgWidth(), height = gus->GetImgHeight(); - dim3 grid((width + DOG_BLOCK_DIMX - 1)/ DOG_BLOCK_DIMX, (height + DOG_BLOCK_DIMY - 1)/DOG_BLOCK_DIMY); - dim3 block(DOG_BLOCK_DIMX, DOG_BLOCK_DIMY); - gus->BindTexture(texC); - (gus -1)->BindTexture(texP); - if(got->_cuData) - ComputeDOG_Kernel<<>>((float*) dog->_cuData, (float2*) got->_cuData, width, height); - else - ComputeDOG_Kernel<<>>((float*) dog->_cuData, width, height); -} - - -#define READ_CMP_DOG_DATA(datai, tex, idx) \ - datai[0] = tex1Dfetch(tex, idx - 1);\ - datai[1] = tex1Dfetch(tex, idx);\ - datai[2] = tex1Dfetch(tex, idx + 1);\ - if(v > nmax)\ - {\ - nmax = max(nmax, datai[0]);\ - nmax = max(nmax, datai[1]);\ - nmax = max(nmax, datai[2]);\ - if(v < nmax) goto key_finish;\ - }else\ - {\ - nmin = min(nmin, datai[0]);\ - nmin = min(nmin, datai[1]);\ - nmin = min(nmin, datai[2]);\ - if(v > nmin) goto key_finish;\ - } - - -void __global__ ComputeKEY_Kernel(float4* d_key, int width, int colmax, int rowmax, - float dog_threshold0, float dog_threshold, float edge_threshold, int subpixel_localization) -{ - float data[3][3], v; - float datap[3][3], datan[3][3]; -#ifdef KEY_OFFSET_ONE - int row = (blockIdx.y << KEY_BLOCK_LOG_DIMY) + threadIdx.y + 1; - int col = (blockIdx.x << KEY_BLOCK_LOG_DIMX) + threadIdx.x + 1; -#else - int row = (blockIdx.y << KEY_BLOCK_LOG_DIMY) + threadIdx.y; - int col = (blockIdx.x << KEY_BLOCK_LOG_DIMX) + threadIdx.x; -#endif - int index = IMUL(row, width) + col; - int idx[3] ={index - width, index, index + width}; - int in_image =0; - float nmax, nmin, result = 0.0f; - float dx = 0, dy = 0, ds = 0; - bool offset_test_passed = true; -#ifdef KEY_OFFSET_ONE - if(row < rowmax && col < colmax) -#else - if(row > 0 && col > 0 && row < rowmax && col < colmax) -#endif - { - in_image = 1; - data[1][1] = v = tex1Dfetch(texC, idx[1]); - if(fabs(v) <= dog_threshold0) goto key_finish; - - data[1][0] = tex1Dfetch(texC, idx[1] - 1); - data[1][2] = tex1Dfetch(texC, idx[1] + 1); - nmax = max(data[1][0], data[1][2]); - nmin = min(data[1][0], data[1][2]); - - if(v <=nmax && v >= nmin) goto key_finish; - //if((v > nmax && v < 0 )|| (v < nmin && v > 0)) goto key_finish; - READ_CMP_DOG_DATA(data[0], texC, idx[0]); - READ_CMP_DOG_DATA(data[2], texC, idx[2]); - - //edge supression - float vx2 = v * 2.0f; - float fxx = data[1][0] + data[1][2] - vx2; - float fyy = data[0][1] + data[2][1] - vx2; - float fxy = 0.25f * (data[2][2] + data[0][0] - data[2][0] - data[0][2]); - float temp1 = fxx * fyy - fxy * fxy; - float temp2 = (fxx + fyy) * (fxx + fyy); - if(temp1 <=0 || temp2 > edge_threshold * temp1) goto key_finish; - - - //read the previous level - READ_CMP_DOG_DATA(datap[0], texP, idx[0]); - READ_CMP_DOG_DATA(datap[1], texP, idx[1]); - READ_CMP_DOG_DATA(datap[2], texP, idx[2]); - - - //read the next level - READ_CMP_DOG_DATA(datan[0], texN, idx[0]); - READ_CMP_DOG_DATA(datan[1], texN, idx[1]); - READ_CMP_DOG_DATA(datan[2], texN, idx[2]); - - if(subpixel_localization) - { - //subpixel localization - float fx = 0.5f * (data[1][2] - data[1][0]); - float fy = 0.5f * (data[2][1] - data[0][1]); - float fs = 0.5f * (datan[1][1] - datap[1][1]); - - float fss = (datan[1][1] + datap[1][1] - vx2); - float fxs = 0.25f* (datan[1][2] + datap[1][0] - datan[1][0] - datap[1][2]); - float fys = 0.25f* (datan[2][1] + datap[0][1] - datan[0][1] - datap[2][1]); - - //need to solve dx, dy, ds; - // |-fx| | fxx fxy fxs | |dx| - // |-fy| = | fxy fyy fys | * |dy| - // |-fs| | fxs fys fss | |ds| - float4 A0 = fxx > 0? make_float4(fxx, fxy, fxs, -fx) : make_float4(-fxx, -fxy, -fxs, fx); - float4 A1 = fxy > 0? make_float4(fxy, fyy, fys, -fy) : make_float4(-fxy, -fyy, -fys, fy); - float4 A2 = fxs > 0? make_float4(fxs, fys, fss, -fs) : make_float4(-fxs, -fys, -fss, fs); - float maxa = max(max(A0.x, A1.x), A2.x); - if(maxa >= 1e-10) - { - if(maxa == A1.x) - { - float4 TEMP = A1; A1 = A0; A0 = TEMP; - }else if(maxa == A2.x) - { - float4 TEMP = A2; A2 = A0; A0 = TEMP; - } - A0.y /= A0.x; A0.z /= A0.x; A0.w/= A0.x; - A1.y -= A1.x * A0.y; A1.z -= A1.x * A0.z; A1.w -= A1.x * A0.w; - A2.y -= A2.x * A0.y; A2.z -= A2.x * A0.z; A2.w -= A2.x * A0.w; - if(abs(A2.y) > abs(A1.y)) - { - float4 TEMP = A2; A2 = A1; A1 = TEMP; - } - if(abs(A1.y) >= 1e-10) - { - A1.z /= A1.y; A1.w /= A1.y; - A2.z -= A2.y * A1.z; A2.w -= A2.y * A1.w; - if(abs(A2.z) >= 1e-10) - { - ds = A2.w / A2.z; - dy = A1.w - ds * A1.z; - dx = A0.w - ds * A0.z - dy * A0.y; - - offset_test_passed = - fabs(data[1][1] + 0.5f * (dx * fx + dy * fy + ds * fs)) > dog_threshold - &&fabs(ds) < 1.0f && fabs(dx) < 1.0f && fabs(dy) < 1.0f; - } - } - } - } - if(offset_test_passed) result = v > nmax ? 1.0 : -1.0; - } -key_finish: - if(in_image) d_key[index] = make_float4(result, dx, dy, ds); -} - - -void ProgramCU::ComputeKEY(CuTexImage* dog, CuTexImage* key, float Tdog, float Tedge) -{ - int width = dog->GetImgWidth(), height = dog->GetImgHeight(); - float Tdog1 = (GlobalUtil::_SubpixelLocalization? 0.8f : 1.0f) * Tdog; - CuTexImage* dogp = dog - 1; - CuTexImage* dogn = dog + 1; -#ifdef KEY_OFFSET_ONE - dim3 grid((width - 1 + KEY_BLOCK_DIMX - 1)/ KEY_BLOCK_DIMX, (height - 1 + KEY_BLOCK_DIMY - 1)/KEY_BLOCK_DIMY); -#else - dim3 grid((width + KEY_BLOCK_DIMX - 1)/ KEY_BLOCK_DIMX, (height + KEY_BLOCK_DIMY - 1)/KEY_BLOCK_DIMY); -#endif - dim3 block(KEY_BLOCK_DIMX, KEY_BLOCK_DIMY); - dogp->BindTexture(texP); - dog ->BindTexture(texC); - dogn->BindTexture(texN); - Tedge = (Tedge+1)*(Tedge+1)/Tedge; - ComputeKEY_Kernel<<>>((float4*) key->_cuData, width, - width -1, height -1, Tdog1, Tdog, Tedge, GlobalUtil::_SubpixelLocalization); - -} - - - -void __global__ InitHist_Kernel(int4* hist, int ws, int wd, int height) -{ - int row = IMUL(blockIdx.y, blockDim.y) + threadIdx.y; - int col = IMUL(blockIdx.x, blockDim.x) + threadIdx.x; - if(row < height && col < wd) - { - int hidx = IMUL(row, wd) + col; - int scol = col << 2; - int sidx = IMUL(row, ws) + scol; - int v[4] = {0, 0, 0, 0}; - if(row > 0 && row < height -1) - { -#pragma unroll - for(int i = 0; i < 4 ; ++i, ++scol) - { - float4 temp = tex1Dfetch(texDataF4, sidx +i); - v[i] = (scol < ws -1 && scol > 0 && temp.x!=0) ? 1 : 0; - } - } - hist[hidx] = make_int4(v[0], v[1], v[2], v[3]); - - } -} - - - -void ProgramCU::InitHistogram(CuTexImage* key, CuTexImage* hist) -{ - int ws = key->GetImgWidth(), hs = key->GetImgHeight(); - int wd = hist->GetImgWidth(), hd = hist->GetImgHeight(); - dim3 grid((wd + HIST_INIT_WIDTH - 1)/ HIST_INIT_WIDTH, hd); - dim3 block(HIST_INIT_WIDTH, 1); - key->BindTexture(texDataF4); - InitHist_Kernel<<>>((int4*) hist->_cuData, ws, wd, hd); -} - - - -void __global__ ReduceHist_Kernel(int4* d_hist, int ws, int wd, int height) -{ - int row = IMUL(blockIdx.y, blockDim.y) + threadIdx.y; - int col = IMUL(blockIdx.x, blockDim.x) + threadIdx.x; - if(row < height && col < wd) - { - int hidx = IMUL(row, wd) + col; - int scol = col << 2; - int sidx = IMUL(row, ws) + scol; - int v[4] = {0, 0, 0, 0}; -#pragma unroll - for(int i = 0; i < 4 && scol < ws; ++i, ++scol) - { - int4 temp = tex1Dfetch(texDataI4, sidx + i); - v[i] = temp.x + temp.y + temp.z + temp.w; - } - d_hist[hidx] = make_int4(v[0], v[1], v[2], v[3]); - } -} - -void ProgramCU::ReduceHistogram(CuTexImage*hist1, CuTexImage* hist2) -{ - int ws = hist1->GetImgWidth(), hs = hist1->GetImgHeight(); - int wd = hist2->GetImgWidth(), hd = hist2->GetImgHeight(); - int temp = (int)floor(logf(float(wd * 2/ 3)) / logf(2.0f)); - const int wi = min(7, max(temp , 0)); - hist1->BindTexture(texDataI4); - - const int BW = 1 << wi, BH = 1 << (7 - wi); - dim3 grid((wd + BW - 1)/ BW, (hd + BH -1) / BH); - dim3 block(BW, BH); - ReduceHist_Kernel<<>>((int4*)hist2->_cuData, ws, wd, hd); -} - - -void __global__ ListGen_Kernel(int4* d_list, int width) -{ - int idx1 = IMUL(blockIdx.x, blockDim.x) + threadIdx.x; - int4 pos = tex1Dfetch(texDataList, idx1); - int idx2 = IMUL(pos.y, width) + pos.x; - int4 temp = tex1Dfetch(texDataI4, idx2); - int sum1 = temp.x + temp.y; - int sum2 = sum1 + temp.z; - pos.x <<= 2; - if(pos.z >= sum2) - { - pos.x += 3; - pos.z -= sum2; - }else if(pos.z >= sum1) - { - pos.x += 2; - pos.z -= sum1; - }else if(pos.z >= temp.x) - { - pos.x += 1; - pos.z -= temp.x; - } - d_list[idx1] = pos; -} - -//input list (x, y) (x, y) .... -void ProgramCU::GenerateList(CuTexImage* list, CuTexImage* hist) -{ - int len = list->GetImgWidth(); - list->BindTexture(texDataList); - hist->BindTexture(texDataI4); - dim3 grid((len + LISTGEN_BLOCK_DIM -1) /LISTGEN_BLOCK_DIM); - dim3 block(LISTGEN_BLOCK_DIM); - ListGen_Kernel<<>>((int4*) list->_cuData, hist->GetImgWidth()); -} - -void __global__ ComputeOrientation_Kernel(float4* d_list, - int list_len, - int width, int height, - float sigma, float sigma_step, - float gaussian_factor, float sample_factor, - int num_orientation, - int existing_keypoint, - int subpixel, - int keepsign) -{ - const float ten_degree_per_radius = 5.7295779513082320876798154814105; - const float radius_per_ten_degrees = 1.0 / 5.7295779513082320876798154814105; - int idx = IMUL(blockDim.x, blockIdx.x) + threadIdx.x; - if(idx >= list_len) return; - float4 key; - if(existing_keypoint) - { - key = tex1Dfetch(texDataF4, idx); - }else - { - int4 ikey = tex1Dfetch(texDataList, idx); - key.x = ikey.x + 0.5f; - key.y = ikey.y + 0.5f; - key.z = sigma; - if(subpixel || keepsign) - { - float4 offset = tex1Dfetch(texDataF4, IMUL(width, ikey.y) + ikey.x); - if(subpixel) - { - key.x += offset.y; - key.y += offset.z; - key.z *= pow(sigma_step, offset.w); - } - if(keepsign) key.z *= offset.x; - } - } - if(num_orientation == 0) - { - key.w = 0; - d_list[idx] = key; - return; - } - float vote[37]; - float gsigma = key.z * gaussian_factor; - float win = fabs(key.z) * sample_factor; - float dist_threshold = win * win + 0.5; - float factor = -0.5f / (gsigma * gsigma); - float xmin = max(1.5f, floor(key.x - win) + 0.5f); - float ymin = max(1.5f, floor(key.y - win) + 0.5f); - float xmax = min(width - 1.5f, floor(key.x + win) + 0.5f); - float ymax = min(height -1.5f, floor(key.y + win) + 0.5f); -#pragma unroll - for(int i = 0; i < 36; ++i) vote[i] = 0.0f; - for(float y = ymin; y <= ymax; y += 1.0f) - { - for(float x = xmin; x <= xmax; x += 1.0f) - { - float dx = x - key.x; - float dy = y - key.y; - float sq_dist = dx * dx + dy * dy; - if(sq_dist >= dist_threshold) continue; - float2 got = tex2D(texDataF2, x, y); - float weight = got.x * exp(sq_dist * factor); - float fidx = floor(got.y * ten_degree_per_radius); - int oidx = fidx; - if(oidx < 0) oidx += 36; - vote[oidx] += weight; - } - } - - //filter the vote - - const float one_third = 1.0 /3.0; -#pragma unroll - for(int i = 0; i < 6; ++i) - { - vote[36] = vote[0]; - float pre = vote[35]; -#pragma unroll - for(int j = 0; j < 36; ++j) - { - float temp = one_third * (pre + vote[j] + vote[j + 1]); - pre = vote[j]; vote[j] = temp; - } - } - - vote[36] = vote[0]; - if(num_orientation == 1 || existing_keypoint) - { - int index_max = 0; - float max_vote = vote[0]; -#pragma unroll - for(int i = 1; i < 36; ++i) - { - index_max = vote[i] > max_vote? i : index_max; - max_vote = max(max_vote, vote[i]); - } - float pre = vote[index_max == 0? 35 : index_max -1]; - float next = vote[index_max + 1]; - float weight = max_vote; - float off = 0.5f * FDIV(next - pre, weight + weight - next - pre); - key.w = radius_per_ten_degrees * (index_max + 0.5f + off); - d_list[idx] = key; - - }else - { - float max_vote = vote[0]; -#pragma unroll - for(int i = 1; i < 36; ++i) max_vote = max(max_vote, vote[i]); - - float vote_threshold = max_vote * 0.8f; - float pre = vote[35]; - float max_rot[2], max_vot[2] = {0, 0}; - int ocount = 0; -#pragma unroll - for(int i =0; i < 36; ++i) - { - float next = vote[i + 1]; - if(vote[i] > vote_threshold && vote[i] > pre && vote[i] > next) - { - float di = 0.5f * FDIV(next - pre, vote[i] + vote[i] - next - pre); - float rot = i + di + 0.5f; - float weight = vote[i]; - /// - if(weight > max_vot[1]) - { - if(weight > max_vot[0]) - { - max_vot[1] = max_vot[0]; - max_rot[1] = max_rot[0]; - max_vot[0] = weight; - max_rot[0] = rot; - } - else - { - max_vot[1] = weight; - max_rot[1] = rot; - } - ocount ++; - } - } - pre = vote[i]; - } - float fr1 = max_rot[0] / 36.0f; - if(fr1 < 0) fr1 += 1.0f; - unsigned short us1 = ocount == 0? 65535 : ((unsigned short )floor(fr1 * 65535.0f)); - unsigned short us2 = 65535; - if(ocount > 1) - { - float fr2 = max_rot[1] / 36.0f; - if(fr2 < 0) fr2 += 1.0f; - us2 = (unsigned short ) floor(fr2 * 65535.0f); - } - unsigned int uspack = (us2 << 16) | us1; - key.w = __int_as_float(uspack); - d_list[idx] = key; - } - -} - - - - -void ProgramCU::ComputeOrientation(CuTexImage* list, CuTexImage* got, CuTexImage*key, - float sigma, float sigma_step, int existing_keypoint) -{ - int len = list->GetImgWidth(); - if(len <= 0) return; - int width = got->GetImgWidth(), height = got->GetImgHeight(); - if(existing_keypoint) - { - list->BindTexture(texDataF4); - }else - { - list->BindTexture(texDataList); - if(GlobalUtil::_SubpixelLocalization) key->BindTexture(texDataF4); - } - got->BindTexture2D(texDataF2); - - const int block_width = len < ORIENTATION_COMPUTE_PER_BLOCK ? 16 : ORIENTATION_COMPUTE_PER_BLOCK; - dim3 grid((len + block_width -1) / block_width); - dim3 block(block_width); - - ComputeOrientation_Kernel<<>>((float4*) list->_cuData, - len, width, height, sigma, sigma_step, - GlobalUtil::_OrientationGaussianFactor, - GlobalUtil::_OrientationGaussianFactor * GlobalUtil::_OrientationWindowFactor, - GlobalUtil::_FixedOrientation? 0 : GlobalUtil::_MaxOrientation, - existing_keypoint, GlobalUtil::_SubpixelLocalization, GlobalUtil::_KeepExtremumSign); - - ProgramCU::CheckErrorCUDA("ComputeOrientation"); -} - -template void __global__ ComputeDescriptor_Kernel(float4* d_des, int num, - int width, int height, float window_factor) -{ - const float rpi = 4.0/ 3.14159265358979323846; - int idx = IMUL(blockIdx.x, blockDim.x) + threadIdx.x; - int fidx = idx >> 4; - if(fidx >= num) return; - float4 key = tex1Dfetch(texDataF4, fidx); - int bidx = idx& 0xf, ix = bidx & 0x3, iy = bidx >> 2; - float spt = fabs(key.z * window_factor); - float s, c; __sincosf(key.w, &s, &c); - float anglef = key.w > 3.14159265358979323846? key.w - (2.0 * 3.14159265358979323846) : key.w ; - float cspt = c * spt, sspt = s * spt; - float crspt = c / spt, srspt = s / spt; - float2 offsetpt, pt; - float xmin, ymin, xmax, ymax, bsz; - offsetpt.x = ix - 1.5f; - offsetpt.y = iy - 1.5f; - pt.x = cspt * offsetpt.x - sspt * offsetpt.y + key.x; - pt.y = cspt * offsetpt.y + sspt * offsetpt.x + key.y; - bsz = fabs(cspt) + fabs(sspt); - xmin = max(1.5f, floor(pt.x - bsz) + 0.5f); - ymin = max(1.5f, floor(pt.y - bsz) + 0.5f); - xmax = min(width - 1.5f, floor(pt.x + bsz) + 0.5f); - ymax = min(height - 1.5f, floor(pt.y + bsz) + 0.5f); - float des[9]; -#pragma unroll - for(int i =0; i < 9; ++i) des[i] = 0.0f; - for(float y = ymin; y <= ymax; y += 1.0f) - { - for(float x = xmin; x <= xmax; x += 1.0f) - { - float dx = x - pt.x; - float dy = y - pt.y; - float nx = crspt * dx + srspt * dy; - float ny = crspt * dy - srspt * dx; - float nxn = fabs(nx); - float nyn = fabs(ny); - if(nxn < 1.0f && nyn < 1.0f) - { - float2 cc = tex2D(texDataF2, x, y); - float dnx = nx + offsetpt.x; - float dny = ny + offsetpt.y; - float ww = exp(-0.125f * (dnx * dnx + dny * dny)); - float wx = 1.0 - nxn; - float wy = 1.0 - nyn; - float weight = ww * wx * wy * cc.x; - float theta = (anglef - cc.y) * rpi; - if(theta < 0) theta += 8.0f; - float fo = floor(theta); - int fidx = fo; - float weight1 = fo + 1.0f - theta; - float weight2 = theta - fo; - if(DYNAMIC_INDEXING) - { - des[fidx] += (weight1 * weight); - des[fidx + 1] += (weight2 * weight); - //this dynamic indexing part might be slow - }else - { - #pragma unroll - for(int k = 0; k < 8; ++k) - { - if(k == fidx) - { - des[k] += (weight1 * weight); - des[k+1] += (weight2 * weight); - } - } - } - } - } - } - des[0] += des[8]; - - int didx = idx << 1; - d_des[didx] = make_float4(des[0], des[1], des[2], des[3]); - d_des[didx+1] = make_float4(des[4], des[5], des[6], des[7]); -} - - -template void __global__ ComputeDescriptorRECT_Kernel(float4* d_des, int num, - int width, int height, float window_factor) -{ - const float rpi = 4.0/ 3.14159265358979323846; - int idx = IMUL(blockIdx.x, blockDim.x) + threadIdx.x; - int fidx = idx >> 4; - if(fidx >= num) return; - float4 key = tex1Dfetch(texDataF4, fidx); - int bidx = idx& 0xf, ix = bidx & 0x3, iy = bidx >> 2; - //float aspect_ratio = key.w / key.z; - //float aspect_sq = aspect_ratio * aspect_ratio; - float sptx = key.z * 0.25, spty = key.w * 0.25; - float xmin, ymin, xmax, ymax; float2 pt; - pt.x = sptx * (ix + 0.5f) + key.x; - pt.y = spty * (iy + 0.5f) + key.y; - xmin = max(1.5f, floor(pt.x - sptx) + 0.5f); - ymin = max(1.5f, floor(pt.y - spty) + 0.5f); - xmax = min(width - 1.5f, floor(pt.x + sptx) + 0.5f); - ymax = min(height - 1.5f, floor(pt.y + spty) + 0.5f); - float des[9]; -#pragma unroll - for(int i =0; i < 9; ++i) des[i] = 0.0f; - for(float y = ymin; y <= ymax; y += 1.0f) - { - for(float x = xmin; x <= xmax; x += 1.0f) - { - float nx = (x - pt.x) / sptx; - float ny = (y - pt.y) / spty; - float nxn = fabs(nx); - float nyn = fabs(ny); - if(nxn < 1.0f && nyn < 1.0f) - { - float2 cc = tex2D(texDataF2, x, y); - float wx = 1.0 - nxn; - float wy = 1.0 - nyn; - float weight = wx * wy * cc.x; - float theta = (- cc.y) * rpi; - if(theta < 0) theta += 8.0f; - float fo = floor(theta); - int fidx = fo; - float weight1 = fo + 1.0f - theta; - float weight2 = theta - fo; - if(DYNAMIC_INDEXING) - { - des[fidx] += (weight1 * weight); - des[fidx + 1] += (weight2 * weight); - //this dynamic indexing part might be slow - }else - { - #pragma unroll - for(int k = 0; k < 8; ++k) - { - if(k == fidx) - { - des[k] += (weight1 * weight); - des[k+1] += (weight2 * weight); - } - } - } - } - } - } - des[0] += des[8]; - - int didx = idx << 1; - d_des[didx] = make_float4(des[0], des[1], des[2], des[3]); - d_des[didx+1] = make_float4(des[4], des[5], des[6], des[7]); -} - -void __global__ NormalizeDescriptor_Kernel(float4* d_des, int num) -{ - float4 temp[32]; - int idx = IMUL(blockIdx.x, blockDim.x) + threadIdx.x; - if(idx >= num) return; - int sidx = idx << 5; - float norm1 = 0, norm2 = 0; -#pragma unroll - for(int i = 0; i < 32; ++i) - { - temp[i] = tex1Dfetch(texDataF4, sidx +i); - norm1 += (temp[i].x * temp[i].x + temp[i].y * temp[i].y + - temp[i].z * temp[i].z + temp[i].w * temp[i].w); - } - norm1 = rsqrt(norm1); - -#pragma unroll - for(int i = 0; i < 32; ++i) - { - temp[i].x = min(0.2f, temp[i].x * norm1); - temp[i].y = min(0.2f, temp[i].y * norm1); - temp[i].z = min(0.2f, temp[i].z * norm1); - temp[i].w = min(0.2f, temp[i].w * norm1); - norm2 += (temp[i].x * temp[i].x + temp[i].y * temp[i].y + - temp[i].z * temp[i].z + temp[i].w * temp[i].w); - } - - norm2 = rsqrt(norm2); -#pragma unroll - for(int i = 0; i < 32; ++i) - { - temp[i].x *= norm2; temp[i].y *= norm2; - temp[i].z *= norm2; temp[i].w *= norm2; - d_des[sidx + i] = temp[i]; - } -} - -void ProgramCU::ComputeDescriptor(CuTexImage*list, CuTexImage* got, CuTexImage* dtex, int rect, int stream) -{ - int num = list->GetImgWidth(); - int width = got->GetImgWidth(); - int height = got->GetImgHeight(); - - dtex->InitTexture(num * 128, 1, 1); - got->BindTexture2D(texDataF2); - list->BindTexture(texDataF4); - int block_width = DESCRIPTOR_COMPUTE_BLOCK_SIZE; - dim3 grid((num * 16 + block_width -1) / block_width); - dim3 block(block_width); - - if(rect) - { - if(GlobalUtil::_UseDynamicIndexing) - ComputeDescriptorRECT_Kernel<<>>((float4*) dtex->_cuData, num, width, height, GlobalUtil::_DescriptorWindowFactor); - else - ComputeDescriptorRECT_Kernel<<>>((float4*) dtex->_cuData, num, width, height, GlobalUtil::_DescriptorWindowFactor); - - }else - { - if(GlobalUtil::_UseDynamicIndexing) - ComputeDescriptor_Kernel<<>>((float4*) dtex->_cuData, num, width, height, GlobalUtil::_DescriptorWindowFactor); - else - ComputeDescriptor_Kernel<<>>((float4*) dtex->_cuData, num, width, height, GlobalUtil::_DescriptorWindowFactor); - } - if(GlobalUtil::_NormalizedSIFT) - { - dtex->BindTexture(texDataF4); - const int block_width = DESCRIPTOR_NORMALIZ_PER_BLOCK; - dim3 grid((num + block_width -1) / block_width); - dim3 block(block_width); - NormalizeDescriptor_Kernel<<>>((float4*) dtex->_cuData, num); - } - CheckErrorCUDA("ComputeDescriptor"); -} - -////////////////////////////////////////////////////// -void ProgramCU::FinishCUDA() -{ - cudaThreadSynchronize(); -} - -int ProgramCU::CheckErrorCUDA(const char* location) -{ - cudaError_t e = cudaGetLastError(); - if(e) - { - if(location) fprintf(stderr, "%s:\t", location); - fprintf(stderr, "%s\n", cudaGetErrorString(e)); - //assert(0); - return 1; - }else - { - return 0; - } -} - -void __global__ ConvertDOG_Kernel(float* d_result, int width, int height) -{ - int row = (blockIdx.y << BLOCK_LOG_DIM) + threadIdx.y; - int col = (blockIdx.x << BLOCK_LOG_DIM) + threadIdx.x; - if(col < width && row < height) - { - int index = row * width + col; - float v = tex1Dfetch(texData, index); - d_result[index] = (col == 0 || row == 0 || col == width -1 || row == height -1)? - 0.5 : saturate(0.5+20.0*v); - } -} -/// -void ProgramCU::DisplayConvertDOG(CuTexImage* dog, CuTexImage* out) -{ - if(out->_cuData == NULL) return; - int width = dog->GetImgWidth(), height = dog ->GetImgHeight(); - dog->BindTexture(texData); - dim3 grid((width + BLOCK_DIM - 1)/ BLOCK_DIM, (height + BLOCK_DIM - 1)/BLOCK_DIM); - dim3 block(BLOCK_DIM, BLOCK_DIM); - ConvertDOG_Kernel<<>>((float*) out->_cuData, width, height); - ProgramCU::CheckErrorCUDA("DisplayConvertDOG"); -} - -void __global__ ConvertGRD_Kernel(float* d_result, int width, int height) -{ - int row = (blockIdx.y << BLOCK_LOG_DIM) + threadIdx.y; - int col = (blockIdx.x << BLOCK_LOG_DIM) + threadIdx.x; - if(col < width && row < height) - { - int index = row * width + col; - float v = tex1Dfetch(texData, index << 1); - d_result[index] = (col == 0 || row == 0 || col == width -1 || row == height -1)? - 0 : saturate(5 * v); - - } -} - - -void ProgramCU::DisplayConvertGRD(CuTexImage* got, CuTexImage* out) -{ - if(out->_cuData == NULL) return; - int width = got->GetImgWidth(), height = got ->GetImgHeight(); - got->BindTexture(texData); - dim3 grid((width + BLOCK_DIM - 1)/ BLOCK_DIM, (height + BLOCK_DIM - 1)/BLOCK_DIM); - dim3 block(BLOCK_DIM, BLOCK_DIM); - ConvertGRD_Kernel<<>>((float*) out->_cuData, width, height); - ProgramCU::CheckErrorCUDA("DisplayConvertGRD"); -} - -void __global__ ConvertKEY_Kernel(float4* d_result, int width, int height) -{ - - int row = (blockIdx.y << BLOCK_LOG_DIM) + threadIdx.y; - int col = (blockIdx.x << BLOCK_LOG_DIM) + threadIdx.x; - if(col < width && row < height) - { - int index = row * width + col; - float4 keyv = tex1Dfetch(texDataF4, index); - int is_key = (keyv.x == 1.0f || keyv.x == -1.0f); - int inside = col > 0 && row > 0 && row < height -1 && col < width - 1; - float v = inside? saturate(0.5 + 20 * tex1Dfetch(texData, index)) : 0.5; - d_result[index] = is_key && inside ? - (keyv.x > 0? make_float4(1.0f, 0, 0, 1.0f) : make_float4(0.0f, 1.0f, 0.0f, 1.0f)): - make_float4(v, v, v, 1.0f) ; - } -} -void ProgramCU::DisplayConvertKEY(CuTexImage* key, CuTexImage* dog, CuTexImage* out) -{ - if(out->_cuData == NULL) return; - int width = key->GetImgWidth(), height = key ->GetImgHeight(); - dog->BindTexture(texData); - key->BindTexture(texDataF4); - dim3 grid((width + BLOCK_DIM - 1)/ BLOCK_DIM, (height + BLOCK_DIM - 1)/BLOCK_DIM); - dim3 block(BLOCK_DIM, BLOCK_DIM); - ConvertKEY_Kernel<<>>((float4*) out->_cuData, width, height); -} - - -void __global__ DisplayKeyPoint_Kernel(float4 * d_result, int num) -{ - int idx = IMUL(blockIdx.x, blockDim.x) + threadIdx.x; - if(idx >= num) return; - float4 v = tex1Dfetch(texDataF4, idx); - d_result[idx] = make_float4(v.x, v.y, 0, 1.0f); -} - -void ProgramCU::DisplayKeyPoint(CuTexImage* ftex, CuTexImage* out) -{ - int num = ftex->GetImgWidth(); - int block_width = 64; - dim3 grid((num + block_width -1) /block_width); - dim3 block(block_width); - ftex->BindTexture(texDataF4); - DisplayKeyPoint_Kernel<<>>((float4*) out->_cuData, num); - ProgramCU::CheckErrorCUDA("DisplayKeyPoint"); -} - -void __global__ DisplayKeyBox_Kernel(float4* d_result, int num) -{ - int idx = IMUL(blockIdx.x, blockDim.x) + threadIdx.x; - if(idx >= num) return; - int kidx = idx / 10, vidx = idx - IMUL(kidx , 10); - float4 v = tex1Dfetch(texDataF4, kidx); - float sz = fabs(v.z * 3.0f); - /////////////////////// - float s, c; __sincosf(v.w, &s, &c); - /////////////////////// - float dx = vidx == 0? 0 : ((vidx <= 4 || vidx >= 9)? sz : -sz); - float dy = vidx <= 1? 0 : ((vidx <= 2 || vidx >= 7)? -sz : sz); - float4 pos; - pos.x = v.x + c * dx - s * dy; - pos.y = v.y + c * dy + s * dx; - pos.z = 0; pos.w = 1.0f; - d_result[idx] = pos; -} - -void ProgramCU::DisplayKeyBox(CuTexImage* ftex, CuTexImage* out) -{ - int len = ftex->GetImgWidth(); - int block_width = 32; - dim3 grid((len * 10 + block_width -1) / block_width); - dim3 block(block_width); - ftex->BindTexture(texDataF4); - DisplayKeyBox_Kernel<<>>((float4*) out->_cuData, len * 10); -} -/////////////////////////////////////////////////////////////////// -inline void CuTexImage:: BindTexture(textureReference& texRef) -{ - cudaBindTexture(NULL, &texRef, _cuData, &texRef.channelDesc, _numBytes); -} - -inline void CuTexImage::BindTexture2D(textureReference& texRef) -{ -#if defined(SIFTGPU_ENABLE_LINEAR_TEX2D) - cudaBindTexture2D(0, &texRef, _cuData, &texRef.channelDesc, _imgWidth, _imgHeight, _imgWidth* _numChannel* sizeof(float)); -#else - cudaChannelFormatDesc desc; - cudaGetChannelDesc(&desc, _cuData2D); - cudaBindTextureToArray(&texRef, _cuData2D, &desc); -#endif -} - -int ProgramCU::CheckCudaDevice(int device) -{ - int count = 0, device_used; - if(cudaGetDeviceCount(&count) != cudaSuccess || count <= 0) - { - ProgramCU::CheckErrorCUDA("CheckCudaDevice"); - return 0; - }else if(count == 1) - { - cudaDeviceProp deviceProp; - if ( cudaGetDeviceProperties(&deviceProp, 0) != cudaSuccess || - (deviceProp.major == 9999 && deviceProp.minor == 9999)) - { - fprintf(stderr, "CheckCudaDevice: no device supporting CUDA.\n"); - return 0; - }else - { - GlobalUtil::_MemCapGPU = deviceProp.totalGlobalMem / 1024; - GlobalUtil::_texMaxDimGL = 32768; - if(GlobalUtil::_verbose) - fprintf(stdout, "NOTE: changing maximum texture dimension to %d\n", GlobalUtil::_texMaxDimGL); - - } - } - if(device >0 && device < count) - { - cudaSetDevice(device); - CheckErrorCUDA("cudaSetDevice\n"); - } - cudaGetDevice(&device_used); - if(device != device_used) - fprintf(stderr, "\nERROR: Cannot set device to %d\n" - "\nWARNING: Use # %d device instead (out of %d)\n", device, device_used, count); - return 1; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// siftmatch funtions -////////////////////////////////////////////////////////////////////////////////////////// - -#define MULT_TBLOCK_DIMX 128 -#define MULT_TBLOCK_DIMY 1 -#define MULT_BLOCK_DIMX (MULT_TBLOCK_DIMX) -#define MULT_BLOCK_DIMY (8 * MULT_TBLOCK_DIMY) - - -texture texDes1; -texture texDes2; - -void __global__ MultiplyDescriptor_Kernel(int* d_result, int num1, int num2, int3* d_temp) -{ - int idx01 = (blockIdx.y * MULT_BLOCK_DIMY), idx02 = (blockIdx.x * MULT_BLOCK_DIMX); - - int idx1 = idx01 + threadIdx.y, idx2 = idx02 + threadIdx.x; - __shared__ int data1[17 * 2 * MULT_BLOCK_DIMY]; - int read_idx1 = idx01 * 8 + threadIdx.x, read_idx2 = idx2 * 8; - int col4 = threadIdx.x & 0x3, row4 = threadIdx.x >> 2; - int cache_idx1 = IMUL(row4, 17) + (col4 << 2); - - /////////////////////////////////////////////////////////////// - //Load feature descriptors - /////////////////////////////////////////////////////////////// -#if MULT_BLOCK_DIMY == 16 - uint4 v = tex1Dfetch(texDes1, read_idx1); - data1[cache_idx1] = v.x; data1[cache_idx1+1] = v.y; - data1[cache_idx1+2] = v.z; data1[cache_idx1+3] = v.w; -#elif MULT_BLOCK_DIMY == 8 - if(threadIdx.x < 64) - { - uint4 v = tex1Dfetch(texDes1, read_idx1); - data1[cache_idx1] = v.x; data1[cache_idx1+1] = v.y; - data1[cache_idx1+2] = v.z; data1[cache_idx1+3] = v.w; - } -#else -#error -#endif - __syncthreads(); - - /// - if(idx2 >= num2) return; - /////////////////////////////////////////////////////////////////////////// - //compare descriptors - - int results[MULT_BLOCK_DIMY]; -#pragma unroll - for(int i = 0; i < MULT_BLOCK_DIMY; ++i) results[i] = 0; - -#pragma unroll - for(int i = 0; i < 8; ++i) - { - uint4 v = tex1Dfetch(texDes2, read_idx2 + i); - unsigned char* p2 = (unsigned char*)(&v); -#pragma unroll - for(int k = 0; k < MULT_BLOCK_DIMY; ++k) - { - unsigned char* p1 = (unsigned char*) (data1 + k * 34 + i * 4 + (i/4)); - results[k] += ( IMUL(p1[0], p2[0]) + IMUL(p1[1], p2[1]) - + IMUL(p1[2], p2[2]) + IMUL(p1[3], p2[3]) - + IMUL(p1[4], p2[4]) + IMUL(p1[5], p2[5]) - + IMUL(p1[6], p2[6]) + IMUL(p1[7], p2[7]) - + IMUL(p1[8], p2[8]) + IMUL(p1[9], p2[9]) - + IMUL(p1[10], p2[10]) + IMUL(p1[11], p2[11]) - + IMUL(p1[12], p2[12]) + IMUL(p1[13], p2[13]) - + IMUL(p1[14], p2[14]) + IMUL(p1[15], p2[15])); - } - } - - int dst_idx = IMUL(idx1, num2) + idx2; - if(d_temp) - { - int3 cmp_result = make_int3(0, -1, 0); - -#pragma unroll - for(int i = 0; i < MULT_BLOCK_DIMY; ++i) - { - if(idx1 + i < num1) - { - cmp_result = results[i] > cmp_result.x? - make_int3(results[i], idx1 + i, cmp_result.x) : - make_int3(cmp_result.x, cmp_result.y, max(cmp_result.z, results[i])); - d_result[dst_idx + IMUL(i, num2)] = results[i]; - } - } - d_temp[ IMUL(blockIdx.y, num2) + idx2] = cmp_result; - }else - { -#pragma unroll - for(int i = 0; i < MULT_BLOCK_DIMY; ++i) - { - if(idx1 + i < num1) d_result[dst_idx + IMUL(i, num2)] = results[i]; - } - } - -} - - -void ProgramCU::MultiplyDescriptor(CuTexImage* des1, CuTexImage* des2, CuTexImage* texDot, CuTexImage* texCRT) -{ - int num1 = des1->GetImgWidth() / 8; - int num2 = des2->GetImgWidth() / 8; - dim3 grid( (num2 + MULT_BLOCK_DIMX - 1)/ MULT_BLOCK_DIMX, - (num1 + MULT_BLOCK_DIMY - 1)/MULT_BLOCK_DIMY); - dim3 block(MULT_TBLOCK_DIMX, MULT_TBLOCK_DIMY); - texDot->InitTexture( num2,num1); - if(texCRT) texCRT->InitTexture(num2, (num1 + MULT_BLOCK_DIMY - 1)/MULT_BLOCK_DIMY, 32); - des1->BindTexture(texDes1); - des2->BindTexture(texDes2); - - MultiplyDescriptor_Kernel<<>>((int*)texDot->_cuData, num1, num2, - (texCRT? (int3*)texCRT->_cuData : NULL)); - ProgramCU::CheckErrorCUDA("MultiplyDescriptor"); -} - -texture texLoc1; -texture texLoc2; -struct Matrix33{float mat[3][3];}; - - - -void __global__ MultiplyDescriptorG_Kernel(int* d_result, int num1, int num2, int3* d_temp, - Matrix33 H, float hdistmax, Matrix33 F, float fdistmax) -{ - int idx01 = (blockIdx.y * MULT_BLOCK_DIMY); - int idx02 = (blockIdx.x * MULT_BLOCK_DIMX); - - int idx1 = idx01 + threadIdx.y; - int idx2 = idx02 + threadIdx.x; - __shared__ int data1[17 * 2 * MULT_BLOCK_DIMY]; - __shared__ float loc1[MULT_BLOCK_DIMY * 2]; - int read_idx1 = idx01 * 8 + threadIdx.x ; - int read_idx2 = idx2 * 8; - int col4 = threadIdx.x & 0x3, row4 = threadIdx.x >> 2; - int cache_idx1 = IMUL(row4, 17) + (col4 << 2); -#if MULT_BLOCK_DIMY == 16 - uint4 v = tex1Dfetch(texDes1, read_idx1); - data1[cache_idx1] = v.x; - data1[cache_idx1+1] = v.y; - data1[cache_idx1+2] = v.z; - data1[cache_idx1+3] = v.w; -#elif MULT_BLOCK_DIMY == 8 - if(threadIdx.x < 64) - { - uint4 v = tex1Dfetch(texDes1, read_idx1); - data1[cache_idx1] = v.x; - data1[cache_idx1+1] = v.y; - data1[cache_idx1+2] = v.z; - data1[cache_idx1+3] = v.w; - } -#else -#error -#endif - __syncthreads(); - if(threadIdx.x < MULT_BLOCK_DIMY * 2) - { - loc1[threadIdx.x] = tex1Dfetch(texLoc1, 2 * idx01 + threadIdx.x); - } - __syncthreads(); - if(idx2 >= num2) return; - int results[MULT_BLOCK_DIMY]; - ///////////////////////////////////////////////////////////////////////////////////////////// - //geometric verification - ///////////////////////////////////////////////////////////////////////////////////////////// - int good_count = 0; - float2 loc2 = tex1Dfetch(texLoc2, idx2); -#pragma unroll - for(int i = 0; i < MULT_BLOCK_DIMY; ++i) - { - - if(idx1 + i < num1) - { - float* loci = loc1 + i * 2; - float locx = loci[0], locy = loci[1]; - //homography - float x[3], diff[2]; - x[0] = H.mat[0][0] * locx + H.mat[0][1] * locy + H.mat[0][2]; - x[1] = H.mat[1][0] * locx + H.mat[1][1] * locy + H.mat[1][2]; - x[2] = H.mat[2][0] * locx + H.mat[2][1] * locy + H.mat[2][2]; - diff[0] = fabs(FDIV(x[0], x[2]) - loc2.x); - diff[1] = fabs(FDIV(x[1], x[2]) - loc2.y); - if(diff[0] < hdistmax && diff[1] < hdistmax) - { - //check fundamental matrix - float fx1[3], ftx2[3], x2fx1, se; - fx1[0] = F.mat[0][0] * locx + F.mat[0][1] * locy + F.mat[0][2]; - fx1[1] = F.mat[1][0] * locx + F.mat[1][1] * locy + F.mat[1][2]; - fx1[2] = F.mat[2][0] * locx + F.mat[2][1] * locy + F.mat[2][2]; - - ftx2[0] = F.mat[0][0] * loc2.x + F.mat[1][0] * loc2.y + F.mat[2][0]; - ftx2[1] = F.mat[0][1] * loc2.x + F.mat[1][1] * loc2.y + F.mat[2][1]; - //ftx2[2] = F.mat[0][2] * loc2.x + F.mat[1][2] * loc2.y + F.mat[2][2]; - - x2fx1 = loc2.x * fx1[0] + loc2.y * fx1[1] + fx1[2]; - se = FDIV(x2fx1 * x2fx1, fx1[0] * fx1[0] + fx1[1] * fx1[1] + ftx2[0] * ftx2[0] + ftx2[1] * ftx2[1]); - results[i] = se < fdistmax? 0: -262144; - }else - { - results[i] = -262144; - } - }else - { - results[i] = -262144; - } - good_count += (results[i] >=0); - } - ///////////////////////////////////////////////////////////////////////////////////////////// - ///compare feature descriptors anyway - ///////////////////////////////////////////////////////////////////////////////////////////// - if(good_count > 0) - { -#pragma unroll - for(int i = 0; i < 8; ++i) - { - uint4 v = tex1Dfetch(texDes2, read_idx2 + i); - unsigned char* p2 = (unsigned char*)(&v); -#pragma unroll - for(int k = 0; k < MULT_BLOCK_DIMY; ++k) - { - unsigned char* p1 = (unsigned char*) (data1 + k * 34 + i * 4 + (i/4)); - results[k] += ( IMUL(p1[0], p2[0]) + IMUL(p1[1], p2[1]) - + IMUL(p1[2], p2[2]) + IMUL(p1[3], p2[3]) - + IMUL(p1[4], p2[4]) + IMUL(p1[5], p2[5]) - + IMUL(p1[6], p2[6]) + IMUL(p1[7], p2[7]) - + IMUL(p1[8], p2[8]) + IMUL(p1[9], p2[9]) - + IMUL(p1[10], p2[10]) + IMUL(p1[11], p2[11]) - + IMUL(p1[12], p2[12]) + IMUL(p1[13], p2[13]) - + IMUL(p1[14], p2[14]) + IMUL(p1[15], p2[15])); - } - } - } - int dst_idx = IMUL(idx1, num2) + idx2; - if(d_temp) - { - int3 cmp_result = make_int3(0, -1, 0); -#pragma unroll - for(int i= 0; i < MULT_BLOCK_DIMY; ++i) - { - if(idx1 + i < num1) - { - cmp_result = results[i] > cmp_result.x? - make_int3(results[i], idx1 + i, cmp_result.x) : - make_int3(cmp_result.x, cmp_result.y, max(cmp_result.z, results[i])); - d_result[dst_idx + IMUL(i, num2)] = max(results[i], 0); - }else - { - break; - } - } - d_temp[ IMUL(blockIdx.y, num2) + idx2] = cmp_result; - }else - { -#pragma unroll - for(int i = 0; i < MULT_BLOCK_DIMY; ++i) - { - if(idx1 + i < num1) d_result[dst_idx + IMUL(i, num2)] = max(results[i], 0); - else break; - } - } - -} - - -void ProgramCU::MultiplyDescriptorG(CuTexImage* des1, CuTexImage* des2, - CuTexImage* loc1, CuTexImage* loc2, CuTexImage* texDot, CuTexImage* texCRT, - float H[3][3], float hdistmax, float F[3][3], float fdistmax) -{ - int num1 = des1->GetImgWidth() / 8; - int num2 = des2->GetImgWidth() / 8; - Matrix33 MatF, MatH; - //copy the matrix - memcpy(MatF.mat, F, 9 * sizeof(float)); - memcpy(MatH.mat, H, 9 * sizeof(float)); - //thread blocks - dim3 grid( (num2 + MULT_BLOCK_DIMX - 1)/ MULT_BLOCK_DIMX, - (num1 + MULT_BLOCK_DIMY - 1)/MULT_BLOCK_DIMY); - dim3 block(MULT_TBLOCK_DIMX, MULT_TBLOCK_DIMY); - //intermediate results - texDot->InitTexture( num2,num1); - if(texCRT) texCRT->InitTexture( num2, (num1 + MULT_BLOCK_DIMY - 1)/MULT_BLOCK_DIMY, 3); - loc1->BindTexture(texLoc1); - loc2->BindTexture(texLoc2); - des1->BindTexture(texDes1); - des2->BindTexture(texDes2); - MultiplyDescriptorG_Kernel<<>>((int*)texDot->_cuData, num1, num2, - (texCRT? (int3*)texCRT->_cuData : NULL), - MatH, hdistmax, MatF, fdistmax); -} - - -texture texDOT; - -#define ROWMATCH_BLOCK_WIDTH 32 -#define ROWMATCH_BLOCK_HEIGHT 1 - -void __global__ RowMatch_Kernel(int*d_dot, int* d_result, int num2, float distmax, float ratiomax) -{ -#if ROWMATCH_BLOCK_HEIGHT == 1 - __shared__ int dotmax[ROWMATCH_BLOCK_WIDTH]; - __shared__ int dotnxt[ROWMATCH_BLOCK_WIDTH]; - __shared__ int dotidx[ROWMATCH_BLOCK_WIDTH]; - int row = blockIdx.y; -#else - __shared__ int x_dotmax[ROWMATCH_BLOCK_HEIGHT][ROWMATCH_BLOCK_WIDTH]; - __shared__ int x_dotnxt[ROWMATCH_BLOCK_HEIGHT][ROWMATCH_BLOCK_WIDTH]; - __shared__ int x_dotidx[ROWMATCH_BLOCK_HEIGHT][ROWMATCH_BLOCK_WIDTH]; - int* dotmax = x_dotmax[threadIdx.y]; - int* dotnxt = x_dotnxt[threadIdx.y]; - int* dotidx = x_dotidx[threadIdx.y]; - int row = IMUL(blockIdx.y, ROWMATCH_BLOCK_HEIGHT) + threadIdx.y; -#endif - - int base_address = IMUL(row , num2); - int t_dotmax = 0, t_dotnxt = 0, t_dotidx = -1; - for(int i = 0; i < num2; i += ROWMATCH_BLOCK_WIDTH) - { - if(threadIdx.x + i < num2) - { - int v = tex1Dfetch(texDOT, base_address + threadIdx.x + i);//d_dot[base_address + threadIdx.x + i];// - bool test = v > t_dotmax; - t_dotnxt = test? t_dotmax : max(t_dotnxt, v); - t_dotidx = test? (threadIdx.x + i) : t_dotidx; - t_dotmax = test? v: t_dotmax; - } - __syncthreads(); - } - dotmax[threadIdx.x] = t_dotmax; - dotnxt[threadIdx.x] = t_dotnxt; - dotidx[threadIdx.x] = t_dotidx; - __syncthreads(); - -#pragma unroll - for(int step = ROWMATCH_BLOCK_WIDTH/2; step >0; step /= 2) - { - if(threadIdx.x < step) - { - int v1 = dotmax[threadIdx.x], v2 = dotmax[threadIdx.x + step]; - bool test = v2 > v1; - dotnxt[threadIdx.x] = test? max(v1, dotnxt[threadIdx.x + step]) :max(dotnxt[threadIdx.x], v2); - dotidx[threadIdx.x] = test? dotidx[threadIdx.x + step] : dotidx[threadIdx.x]; - dotmax[threadIdx.x] = test? v2 : v1; - } - __syncthreads(); - } - if(threadIdx.x == 0) - { - float dist = acos(min(dotmax[0] * 0.000003814697265625f, 1.0)); - float distn = acos(min(dotnxt[0] * 0.000003814697265625f, 1.0)); - //float ratio = dist / distn; - d_result[row] = (dist < distmax) && (dist < distn * ratiomax) ? dotidx[0] : -1;//? : -1; - } - -} - - -void ProgramCU::GetRowMatch(CuTexImage* texDot, CuTexImage* texMatch, float distmax, float ratiomax) -{ - int num1 = texDot->GetImgHeight(); - int num2 = texDot->GetImgWidth(); - dim3 grid(1, num1/ROWMATCH_BLOCK_HEIGHT); - dim3 block(ROWMATCH_BLOCK_WIDTH, ROWMATCH_BLOCK_HEIGHT); - texDot->BindTexture(texDOT); - RowMatch_Kernel<<>>((int*)texDot->_cuData, - (int*)texMatch->_cuData, num2, distmax, ratiomax); -} - -#define COLMATCH_BLOCK_WIDTH 32 - -//texture texCT; - -void __global__ ColMatch_Kernel(int3*d_crt, int* d_result, int height, int num2, float distmax, float ratiomax) -{ - int col = COLMATCH_BLOCK_WIDTH * blockIdx.x + threadIdx.x; - if(col >= num2) return; - int3 result = d_crt[col];//tex1Dfetch(texCT, col); - int read_idx = col + num2; - for(int i = 1; i < height; ++i, read_idx += num2) - { - int3 temp = d_crt[read_idx];//tex1Dfetch(texCT, read_idx); - result = result.x < temp.x? - make_int3(temp.x, temp.y, max(result.x, temp.z)) : - make_int3(result.x, result.y, max(result.z, temp.x)); - } - - float dist = acos(min(result.x * 0.000003814697265625f, 1.0)); - float distn = acos(min(result.z * 0.000003814697265625f, 1.0)); - //float ratio = dist / distn; - d_result[col] = (dist < distmax) && (dist < distn * ratiomax) ? result.y : -1;//? : -1; - -} - -void ProgramCU::GetColMatch(CuTexImage* texCRT, CuTexImage* texMatch, float distmax, float ratiomax) -{ - int height = texCRT->GetImgHeight(); - int num2 = texCRT->GetImgWidth(); - //texCRT->BindTexture(texCT); - dim3 grid((num2 + COLMATCH_BLOCK_WIDTH -1) / COLMATCH_BLOCK_WIDTH); - dim3 block(COLMATCH_BLOCK_WIDTH); - ColMatch_Kernel<<>>((int3*)texCRT->_cuData, (int*) texMatch->_cuData, height, num2, distmax, ratiomax); -} - -#endif diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramCU.h b/3rdparty/SiftGPU/src/SiftGPU/ProgramCU.h deleted file mode 100644 index e261b844..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramCU.h +++ /dev/null @@ -1,74 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ProgramCU.h -// Author: Changchang Wu -// Description : interface for the ProgramCU classes. -// It is basically a wrapper around all the CUDA kernels -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#ifndef _PROGRAM_CU_H -#define _PROGRAM_CU_H -#if defined(CUDA_SIFTGPU_ENABLED) - -class CuTexImage; - -class ProgramCU -{ -public: - //GPU FUNCTIONS - static void FinishCUDA(); - static int CheckErrorCUDA(const char* location); - static int CheckCudaDevice(int device); -public: - ////SIFTGPU FUNCTIONS - static void CreateFilterKernel(float sigma, float* kernel, int& width); - template static void FilterImage(CuTexImage *dst, CuTexImage *src, CuTexImage* buf); - static void FilterImage(CuTexImage *dst, CuTexImage *src, CuTexImage* buf, float sigma); - static void ComputeDOG(CuTexImage* gus, CuTexImage* dog, CuTexImage* got); - static void ComputeKEY(CuTexImage* dog, CuTexImage* key, float Tdog, float Tedge); - static void InitHistogram(CuTexImage* key, CuTexImage* hist); - static void ReduceHistogram(CuTexImage*hist1, CuTexImage* hist2); - static void GenerateList(CuTexImage* list, CuTexImage* hist); - static void ComputeOrientation(CuTexImage*list, CuTexImage* got, CuTexImage*key, - float sigma, float sigma_step, int existing_keypoint); - static void ComputeDescriptor(CuTexImage*list, CuTexImage* got, CuTexImage* dtex, int rect = 0, int stream = 0); - - //data conversion - static void SampleImageU(CuTexImage *dst, CuTexImage *src, int log_scale); - static void SampleImageD(CuTexImage *dst, CuTexImage *src, int log_scale = 1); - static void ReduceToSingleChannel(CuTexImage* dst, CuTexImage* src, int convert_rgb); - static void ConvertByteToFloat(CuTexImage*src, CuTexImage* dst); - - //visualization - static void DisplayConvertDOG(CuTexImage* dog, CuTexImage* out); - static void DisplayConvertGRD(CuTexImage* got, CuTexImage* out); - static void DisplayConvertKEY(CuTexImage* key, CuTexImage* dog, CuTexImage* out); - static void DisplayKeyPoint(CuTexImage* ftex, CuTexImage* out); - static void DisplayKeyBox(CuTexImage* ftex, CuTexImage* out); - - //SIFTMATCH FUNCTIONS - static void MultiplyDescriptor(CuTexImage* tex1, CuTexImage* tex2, CuTexImage* texDot, CuTexImage* texCRT); - static void MultiplyDescriptorG(CuTexImage* texDes1, CuTexImage* texDes2, - CuTexImage* texLoc1, CuTexImage* texLoc2, CuTexImage* texDot, CuTexImage* texCRT, - float H[3][3], float hdistmax, float F[3][3], float fdistmax); - static void GetRowMatch(CuTexImage* texDot, CuTexImage* texMatch, float distmax, float ratiomax); - static void GetColMatch(CuTexImage* texCRT, CuTexImage* texMatch, float distmax, float ratiomax); -}; - -#endif -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramGLSL.cpp b/3rdparty/SiftGPU/src/SiftGPU/ProgramGLSL.cpp deleted file mode 100644 index e95199dc..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramGLSL.cpp +++ /dev/null @@ -1,2690 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ProgramGLSL.cpp -// Author: Changchang Wu -// Description : GLSL related classes -// class ProgramGLSL A simple wrapper of GLSL programs -// class ShaderBagGLSL GLSL shaders for SIFT -// class FilterGLSL GLSL gaussian filters for SIFT -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include "GL/glew.h" -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "GlobalUtil.h" -#include "ProgramGLSL.h" -#include "GLTexImage.h" -#include "ShaderMan.h" -#include "SiftGPU.h" - -ProgramGLSL::ShaderObject::ShaderObject(int shadertype, const char * source, int filesource) -{ - - - _type = shadertype; - _compiled = 0; - - - _shaderID = glCreateShader(shadertype); - if(_shaderID == 0) return; - - if(source) - { - - GLint code_length; - if(filesource ==0) - { - const char* code = source; - code_length = (GLint) strlen(code); - glShaderSource(_shaderID, 1, (const char **) &code, &code_length); - }else - { - char * code; - if((code_length= ReadShaderFile(source, code)) ==0) return; - glShaderSource(_shaderID, 1, (const char **) &code, &code_length); - delete code; - } - - glCompileShader(_shaderID); - - CheckCompileLog(); - - if(!_compiled) std::cout << source; - } - - - - -} - -int ProgramGLSL::ShaderObject::ReadShaderFile(const char *sourcefile, char*& code ) -{ - code = NULL; - FILE * file; - int len=0; - - if(sourcefile == NULL) return 0; - - file = fopen(sourcefile,"rt"); - if(file == NULL) return 0; - - - fseek(file, 0, SEEK_END); - len = ftell(file); - rewind(file); - if(len >1) - { - code = new char[len+1]; - fread(code, sizeof( char), len, file); - code[len] = 0; - }else - { - len = 0; - } - - fclose(file); - - return len; - -} - -void ProgramGLSL::ShaderObject::CheckCompileLog() -{ - - GLint status; - glGetShaderiv(_shaderID, GL_COMPILE_STATUS, &status); - _compiled = (status ==GL_TRUE); - - if(_compiled == 0) PrintCompileLog(std::cout); - - -} - -ProgramGLSL::ShaderObject::~ShaderObject() -{ - if(_shaderID) glDeleteShader(_shaderID); - -} - -int ProgramGLSL::ShaderObject::IsValidFragmentShader() -{ - return _type == GL_FRAGMENT_SHADER && _shaderID && _compiled; -} - -int ProgramGLSL::ShaderObject::IsValidVertexShader() -{ - return _type == GL_VERTEX_SHADER && _shaderID && _compiled; -} - - -void ProgramGLSL::ShaderObject::PrintCompileLog(ostream&os) -{ - GLint len = 0; - - glGetShaderiv(_shaderID, GL_INFO_LOG_LENGTH , &len); - if(len <=1) return; - - char * compileLog = new char[len+1]; - if(compileLog == NULL) return; - - glGetShaderInfoLog(_shaderID, len, &len, compileLog); - - - os<<"Compile Log\n"<= 0) glUniform1i(_TextureParam0, 0); - return true; - } - else - { - return false; - } -} - - -ProgramGLSL::ProgramGLSL(const char *frag_source) -{ - _linked = 0; - _programID = glCreateProgram(); - _TextureParam0 = -1; - ShaderObject shader(GL_FRAGMENT_SHADER, frag_source); - - if(shader.IsValidFragmentShader()) - { - AttachShaderObject(shader); - LinkProgram(); - - if(!_linked) - { - //shader.PrintCompileLog(std::cout); - PrintLinkLog(std::cout); - } else - { - _TextureParam0 = glGetUniformLocation(_programID, "tex"); - } - }else - { - _linked = 0; - } - -} - -/* -ProgramGLSL::ProgramGLSL(char*frag_source, char * vert_source) -{ - _used = 0; - _linked = 0; - _programID = glCreateProgram(); - ShaderObject shader(GL_FRAGMENT_SHADER, frag_source); - ShaderObject vertex_shader(GL_VERTEX_SHADER, vert_source); - AttachShaderObject(shader); - AttachShaderObject(vertex_shader); - LinkProgram(); - if(!_linked) - { - shader.PrintCompileLog(std::cout); - vertex_shader.PrintCompileLog(std::cout); - PrintLinkLog(std::cout); - std::cout<0 && width > GlobalUtil::_MaxFilterWidth) - { - std::cout<<"Filter size truncated from "<>1; - width = 2 * sz + 1; - } - - int i; - float * kernel = new float[width]; - float rv = 1.0f/(sigma*sigma); - float v, ksum =0; - - // pre-compute filter - for( i = -sz ; i <= sz ; ++i) - { - kernel[i+sz] = v = exp(-0.5f * i * i *rv) ; - ksum += v; - } - - //normalize the kernel - rv = 1.0f / ksum; - for(i = 0; i< width ;i++) kernel[i]*=rv; - // - - MakeFilterProgram(kernel, width); - - _size = sz; - - delete[] kernel; - if(GlobalUtil::_verbose && GlobalUtil::_timingL) std::cout<<"Filter: sigma = "<>1; - float * pf = kernel + halfwidth; - int nhpixel = (halfwidth+1)>>1; //how many neighbour pixels need to be looked up - int npixel = (nhpixel<<1)+1;// - float weight[3]; - ostringstream out;; - out< halfwidth? 0 : pf[xwn]; - } - if(weight[1] == 0.0) - { - out<<"result += vec4("<>1; - float * pf = kernel + halfh; - int nhpixel = (halfh+1)>>1; //how many neighbour pixels need to be looked up - int npixel = (nhpixel<<1)+1;// - float weight[3]; - ostringstream out;; - out< halfh? 0 : pf[ywn]; - } - if(weight[1] == 0.0) - { - out<<"result += vec4("< 0) - { - for(int i = 0; i< _gaussian_step_num; i++) - { - delete f_gaussian_step[i]; - } - delete[] f_gaussian_step; - } -} - - -void ShaderBag::SelectInitialSmoothingFilter(int octave_min, SiftParam¶m) -{ - float sigma = param.GetInitialSmoothSigma(octave_min); - if(sigma == 0) - { - f_gaussian_skip0 = NULL; - }else - { - for(unsigned int i = 0; i < f_gaussian_skip0_v.size(); i++) - { - if(f_gaussian_skip0_v[i]->_id == octave_min) - { - f_gaussian_skip0 = f_gaussian_skip0_v[i]; - return ; - } - } - FilterGLSL * filter = new FilterGLSL(sigma); - filter->_id = octave_min; - f_gaussian_skip0_v.push_back(filter); - f_gaussian_skip0 = filter; - } -} - -void ShaderBag::CreateGaussianFilters(SiftParam¶m) -{ - if(param._sigma_skip0>0.0f) - { - FilterGLSL * filter; - f_gaussian_skip0 = filter = new FilterGLSL(param._sigma_skip0); - filter->_id = GlobalUtil::_octave_min_default; - f_gaussian_skip0_v.push_back(filter); - } - if(param._sigma_skip1>0.0f) - { - f_gaussian_skip1 = new FilterGLSL(param._sigma_skip1); - } - - f_gaussian_step = new FilterProgram*[param._sigma_num]; - for(int i = 0; i< param._sigma_num; i++) - { - f_gaussian_step[i] = new FilterGLSL(param._sigma[i]); - } - _gaussian_step_num = param._sigma_num; -} - - -void ShaderBag::LoadDynamicShaders(SiftParam& param) -{ - LoadKeypointShader(param._dog_threshold, param._edge_threshold); - LoadGenListShader(param._dog_level_num, 0); - CreateGaussianFilters(param); -} - - -void ShaderBagGLSL::LoadFixedShaders() -{ - - - s_gray = new ProgramGLSL( - "uniform sampler2DRect tex; void main(void){\n" - "float intensity = dot(vec3(0.299, 0.587, 0.114), texture2DRect(tex, gl_TexCoord[0].st ).rgb);\n" - "gl_FragColor = vec4(intensity, intensity, intensity, 1.0);}"); - - - s_debug = new ProgramGLSL( "void main(void){gl_FragColor.rg = gl_TexCoord[0].st;}"); - - - s_sampling = new ProgramGLSL( - "uniform sampler2DRect tex; void main(void){gl_FragColor.rg= texture2DRect(tex, gl_TexCoord[0].st).rg;}"); - - // - s_grad_pass = new ProgramGLSL( - "uniform sampler2DRect tex; void main ()\n" - "{\n" - " vec4 v1, v2, gg;\n" - " vec4 cc = texture2DRect(tex, gl_TexCoord[0].xy);\n" - " gg.x = texture2DRect(tex, gl_TexCoord[1].xy).r;\n" - " gg.y = texture2DRect(tex, gl_TexCoord[2].xy).r;\n" - " gg.z = texture2DRect(tex, gl_TexCoord[3].xy).r;\n" - " gg.w = texture2DRect(tex, gl_TexCoord[4].xy).r;\n" - " vec2 dxdy = (gg.yw - gg.xz); \n" - " float grad = 0.5*length(dxdy);\n" - " float theta = grad==0.0? 0.0: atan(dxdy.y, dxdy.x);\n" - " gl_FragData[0] = vec4(cc.rg, grad, theta);\n" - "}\n\0"); - - ProgramGLSL * program; - s_margin_copy = program = new ProgramGLSL( - "uniform sampler2DRect tex; uniform vec2 truncate;\n" - "void main(){ gl_FragColor = texture2DRect(tex, min(gl_TexCoord[0].xy, truncate)); }"); - - _param_margin_copy_truncate = glGetUniformLocation(*program, "truncate"); - - - GlobalUtil::_OrientationPack2 = 0; - LoadOrientationShader(); - - if(s_orientation == NULL) - { - //Load a simplified version if the right version is not supported - s_orientation = program = new ProgramGLSL( - "uniform sampler2DRect tex; uniform sampler2DRect oTex;\n" - " uniform float size; void main(){\n" - " vec4 cc = texture2DRect(tex, gl_TexCoord[0].st);\n" - " vec4 oo = texture2DRect(oTex, cc.rg);\n" - " gl_FragColor.rg = cc.rg;\n" - " gl_FragColor.b = oo.a;\n" - " gl_FragColor.a = size;}"); - - _param_orientation_gtex = glGetUniformLocation(*program, "oTex"); - _param_orientation_size = glGetUniformLocation(*program, "size"); - GlobalUtil::_MaxOrientation = 0; - GlobalUtil::_FullSupported = 0; - std::cerr<<"Orientation simplified on this hardware"< 0.9))? size : -size);\n" - "dxy.y = type < 0.2 ? 0.0 : (((type < 0.3) || (type > 0.7) )? -size :size); \n" - "float s = sin(cc.b); float c = cos(cc.b); \n" - "gl_FragColor.x = cc.x + c*dxy.x-s*dxy.y;\n" - "gl_FragColor.y = cc.y + c*dxy.y+s*dxy.x;}\n}\n"); - - _param_genvbo_size = glGetUniformLocation(*program, "sizes"); - - s_display_gaussian = new ProgramGLSL( - "uniform sampler2DRect tex; void main(void){float r = texture2DRect(tex, gl_TexCoord[0].st).r;\n" - "gl_FragColor = vec4(r, r, r, 1);}" ); - - s_display_dog = new ProgramGLSL( - "uniform sampler2DRect tex; void main(void){float g = 0.5+(20.0*texture2DRect(tex, gl_TexCoord[0].st).g);\n" - "gl_FragColor = vec4(g, g, g, 0.0);}" ); - - s_display_grad = new ProgramGLSL( - "uniform sampler2DRect tex; void main(void){\n" - " vec4 cc = texture2DRect(tex, gl_TexCoord[0].st);gl_FragColor = vec4(5.0* cc.bbb, 1.0);}"); - - s_display_keys= new ProgramGLSL( - "uniform sampler2DRect tex; void main(void){\n" - " vec4 cc = texture2DRect(tex, gl_TexCoord[0].st);\n" - " if(cc.r ==0.0) discard; gl_FragColor = (cc.r==1.0? vec4(1.0, 0.0, 0,1.0):vec4(0.0,1.0,0.0,1.0));}"); -} - -void ShaderBagGLSL::LoadKeypointShader(float threshold, float edge_threshold) -{ - float threshold0 = threshold* (GlobalUtil::_SubpixelLocalization?0.8f:1.0f); - float threshold1 = threshold; - float threshold2 = (edge_threshold+1)*(edge_threshold+1)/edge_threshold; - ostringstream out;; - streampos pos; - - //tex(X)(Y) - //X: (CLR) (CENTER 0, LEFT -1, RIGHT +1) - //Y: (CDU) (CENTER 0, DOWN -1, UP +1) - if(GlobalUtil::_DarknessAdaption) - { - out << "#define THRESHOLD0 (" << threshold0 << " * min(2.0 * cc.r + 0.1, 1.0))\n" - "#define THRESHOLD1 (" << threshold1 << " * min(2.0 * cc.r + 0.1, 1.0))\n" - "#define THRESHOLD2 " << threshold2 << "\n"; - }else - { - out << "#define THRESHOLD0 " << threshold0 << "\n" - "#define THRESHOLD1 " << threshold1 << "\n" - "#define THRESHOLD2 " << threshold2 << "\n"; - } - - out<< - "uniform sampler2DRect tex, texU, texD; void main ()\n" - "{\n" - " vec4 v1, v2, gg, temp;\n" - " vec2 TexRU = vec2(gl_TexCoord[2].x, gl_TexCoord[4].y); \n" - " vec4 cc = texture2DRect(tex, gl_TexCoord[0].xy);\n" - " temp = texture2DRect(tex, gl_TexCoord[1].xy);\n" - " v1.x = temp.g; gg.x = temp.r;\n" - " temp = texture2DRect(tex, gl_TexCoord[2].xy) ;\n" - " v1.y = temp.g; gg.y = temp.r;\n" - " temp = texture2DRect(tex, gl_TexCoord[3].xy) ;\n" - " v1.z = temp.g; gg.z = temp.r;\n" - " temp = texture2DRect(tex, gl_TexCoord[4].xy) ;\n" - " v1.w = temp.g; gg.w = temp.r;\n" - " v2.x = texture2DRect(tex, gl_TexCoord[5].xy).g;\n" - " v2.y = texture2DRect(tex, gl_TexCoord[6].xy).g;\n" - " v2.z = texture2DRect(tex, gl_TexCoord[7].xy).g;\n" - " v2.w = texture2DRect(tex, TexRU.xy).g;\n" - " vec2 dxdy = (gg.yw - gg.xz); \n" - " float grad = 0.5*length(dxdy);\n" - " float theta = grad==0.0? 0.0: atan(dxdy.y, dxdy.x);\n" - " gl_FragData[0] = vec4(cc.rg, grad, theta);\n" - - //test against 8 neighbours - //use variable to identify type of extremum - //1.0 for local maximum and 0.5 for minimum - << - " float dog = 0.0; \n" - " gl_FragData[1] = vec4(0, 0, 0, 0); \n" - " dog = cc.g > float(THRESHOLD0) && all(greaterThan(cc.gggg, max(v1, v2)))?1.0: 0.0;\n" - " dog = cc.g < float(-THRESHOLD0) && all(lessThan(cc.gggg, min(v1, v2)))?0.5: dog;\n" - " if(dog == 0.0) return;\n"; - - pos = out.tellp(); - //do edge supression first.. - //vector v1 is < (-1, 0), (1, 0), (0,-1), (0, 1)> - //vector v2 is < (-1,-1), (-1,1), (1,-1), (1, 1)> - - out<< - " float fxx, fyy, fxy; \n" - " vec4 D2 = v1.xyzw - cc.gggg;\n" - " vec2 D4 = v2.xw - v2.yz;\n" - " fxx = D2.x + D2.y;\n" - " fyy = D2.z + D2.w;\n" - " fxy = 0.25*(D4.x + D4.y);\n" - " float fxx_plus_fyy = fxx + fyy;\n" - " float score_up = fxx_plus_fyy*fxx_plus_fyy; \n" - " float score_down = (fxx*fyy - fxy*fxy);\n" - " if( score_down <= 0.0 || score_up > THRESHOLD2 * score_down)return;\n"; - - //... - out<<" \n" - " vec2 D5 = 0.5*(v1.yw-v1.xz); \n" - " float fx = D5.x, fy = D5.y ; \n" - " float fs, fss , fxs, fys ; \n" - " vec2 v3; vec4 v4, v5, v6;\n" - //read 9 pixels of upper level - << - " v3.x = texture2DRect(texU, gl_TexCoord[0].xy).g;\n" - " v4.x = texture2DRect(texU, gl_TexCoord[1].xy).g;\n" - " v4.y = texture2DRect(texU, gl_TexCoord[2].xy).g;\n" - " v4.z = texture2DRect(texU, gl_TexCoord[3].xy).g;\n" - " v4.w = texture2DRect(texU, gl_TexCoord[4].xy).g;\n" - " v6.x = texture2DRect(texU, gl_TexCoord[5].xy).g;\n" - " v6.y = texture2DRect(texU, gl_TexCoord[6].xy).g;\n" - " v6.z = texture2DRect(texU, gl_TexCoord[7].xy).g;\n" - " v6.w = texture2DRect(texU, TexRU.xy).g;\n" - //compare with 9 pixels of upper level - //read and compare with 9 pixels of lower level - //the maximum case - << - " if(dog == 1.0)\n" - " {\n" - " if(cc.g < v3.x || any(lessThan(cc.gggg, v4)) ||any(lessThan(cc.gggg, v6)))return; \n" - " v3.y = texture2DRect(texD, gl_TexCoord[0].xy).g;\n" - " v5.x = texture2DRect(texD, gl_TexCoord[1].xy).g;\n" - " v5.y = texture2DRect(texD, gl_TexCoord[2].xy).g;\n" - " v5.z = texture2DRect(texD, gl_TexCoord[3].xy).g;\n" - " v5.w = texture2DRect(texD, gl_TexCoord[4].xy).g;\n" - " v6.x = texture2DRect(texD, gl_TexCoord[5].xy).g;\n" - " v6.y = texture2DRect(texD, gl_TexCoord[6].xy).g;\n" - " v6.z = texture2DRect(texD, gl_TexCoord[7].xy).g;\n" - " v6.w = texture2DRect(texD, TexRU.xy).g;\n" - " if(cc.g < v3.y || any(lessThan(cc.gggg, v5)) ||any(lessThan(cc.gggg, v6)))return; \n" - " }\n" - //the minimum case - << - " else{\n" - " if(cc.g > v3.x || any(greaterThan(cc.gggg, v4)) ||any(greaterThan(cc.gggg, v6)))return; \n" - " v3.y = texture2DRect(texD, gl_TexCoord[0].xy).g;\n" - " v5.x = texture2DRect(texD, gl_TexCoord[1].xy).g;\n" - " v5.y = texture2DRect(texD, gl_TexCoord[2].xy).g;\n" - " v5.z = texture2DRect(texD, gl_TexCoord[3].xy).g;\n" - " v5.w = texture2DRect(texD, gl_TexCoord[4].xy).g;\n" - " v6.x = texture2DRect(texD, gl_TexCoord[5].xy).g;\n" - " v6.y = texture2DRect(texD, gl_TexCoord[6].xy).g;\n" - " v6.z = texture2DRect(texD, gl_TexCoord[7].xy).g;\n" - " v6.w = texture2DRect(texD, TexRU.xy).g;\n" - " if(cc.g > v3.y || any(greaterThan(cc.gggg, v5)) ||any(greaterThan(cc.gggg, v6)))return; \n" - " }\n"; - - if(GlobalUtil::_SubpixelLocalization) - - // sub-pixel localization FragData1 = vec4(dog, 0, 0, 0); return; - out << - " fs = 0.5*( v3.x - v3.y ); \n" - " fss = v3.x + v3.y - cc.g - cc.g;\n" - " fxs = 0.25 * ( v4.y + v5.x - v4.x - v5.y);\n" - " fys = 0.25 * ( v4.w + v5.z - v4.z - v5.w);\n" - - // - // let dog difference be quatratic function of dx, dy, ds; - // df(dx, dy, ds) = fx * dx + fy*dy + fs * ds + - // + 0.5 * ( fxx * dx * dx + fyy * dy * dy + fss * ds * ds) - // + (fxy * dx * dy + fxs * dx * ds + fys * dy * ds) - // (fx, fy, fs, fxx, fyy, fss, fxy, fxs, fys are the derivatives) - - //the local extremum satisfies - // df/dx = 0, df/dy = 0, df/dz = 0 - - //that is - // |-fx| | fxx fxy fxs | |dx| - // |-fy| = | fxy fyy fys | * |dy| - // |-fs| | fxs fys fss | |ds| - // need to solve dx, dy, ds - - // Use Gauss elimination to solve the linear system - << - " vec3 dxys = vec3(0.0); \n" - " vec4 A0, A1, A2 ; \n" - " A0 = vec4(fxx, fxy, fxs, -fx); \n" - " A1 = vec4(fxy, fyy, fys, -fy); \n" - " A2 = vec4(fxs, fys, fss, -fs); \n" - " vec3 x3 = abs(vec3(fxx, fxy, fxs)); \n" - " float maxa = max(max(x3.x, x3.y), x3.z); \n" - " if(maxa >= 1e-10 ) { \n" - " if(x3.y ==maxa ) \n" - " { \n" - " vec4 TEMP = A1; A1 = A0; A0 = TEMP; \n" - " }else if( x3.z == maxa ) \n" - " { \n" - " vec4 TEMP = A2; A2 = A0; A0 = TEMP; \n" - " } \n" - " A0 /= A0.x; \n" - " A1 -= A1.x * A0; \n" - " A2 -= A2.x * A0; \n" - " vec2 x2 = abs(vec2(A1.y, A2.y)); \n" - " if( x2.y > x2.x ) \n" - " { \n" - " vec3 TEMP = A2.yzw; \n" - " A2.yzw = A1.yzw; \n" - " A1.yzw = TEMP; \n" - " x2.x = x2.y; \n" - " } \n" - " if(x2.x >= 1e-10) { \n" - " A1.yzw /= A1.y; \n" - " A2.yzw -= A2.y * A1.yzw; \n" - " if(abs(A2.z) >= 1e-10) { \n" - // compute dx, dy, ds: - << - " \n" - " dxys.z = A2.w /A2.z; \n" - " dxys.y = A1.w - dxys.z*A1.z; \n" - " dxys.x = A0.w - dxys.z*A0.z - dxys.y*A0.y; \n" - - //one more threshold which I forgot in versions prior to 286 - << - " bool dog_test = (abs(cc.g + 0.5*dot(vec3(fx, fy, fs), dxys ))<= float(THRESHOLD1)) ;\n" - " if(dog_test || any(greaterThan(abs(dxys), vec3(1.0)))) dog = 0.0;\n" - " }\n" - " }\n" - " }\n" - //keep the point when the offset is less than 1 - << - " gl_FragData[1] = vec4( dog, dxys); \n"; - else - - out<< - " gl_FragData[1] = vec4( dog, 0.0, 0.0, 0.0) ; \n"; - - out<< - "}\n" <<'\0'; - - - - ProgramGLSL * program = new ProgramGLSL(out.str().c_str()); - if(program->IsNative()) - { - s_keypoint = program ; - //parameter - }else - { - delete program; - out.seekp(pos); - out << - " gl_FragData[1] = vec4(dog, 0.0, 0.0, 0.0) ; \n" - "}\n" <<'\0'; - s_keypoint = program = new ProgramGLSL(out.str().c_str()); - GlobalUtil::_SubpixelLocalization = 0; - std::cerr<<"Detection simplified on this hardware"<0.0,\n" - "all(lessThan(gl_TexCoord[1].xy , bbox)) && helper.y >0.0,\n" - "all(lessThan(gl_TexCoord[2].xy , bbox)) && helper.z >0.0,\n" - "all(lessThan(gl_TexCoord[3].xy , bbox)) && helper.w >0.0);\n" - "gl_FragColor = vec4(helper2);\n" - "}"); - _param_genlist_init_bbox = glGetUniformLocation( *program, "bbox"); - - - //reduction ... - s_genlist_histo = new ProgramGLSL( - "uniform sampler2DRect tex; void main (void){\n" - "vec4 helper; vec4 helper2; \n" - "helper = texture2DRect(tex, gl_TexCoord[0].xy); helper2.xy = helper.xy + helper.zw; \n" - "helper = texture2DRect(tex, gl_TexCoord[1].xy); helper2.zw = helper.xy + helper.zw; \n" - "gl_FragColor.rg = helper2.xz + helper2.yw;\n" - "helper = texture2DRect(tex, gl_TexCoord[2].xy); helper2.xy = helper.xy + helper.zw; \n" - "helper = texture2DRect(tex, gl_TexCoord[3].xy); helper2.zw = helper.xy + helper.zw; \n" - "gl_FragColor.ba= helper2.xz+helper2.yw;\n" - "}"); - - - //read of the first part, which generates tex coordinates - s_genlist_start= program = LoadGenListStepShader(1, 1); - _param_ftex_width= glGetUniformLocation(*program, "width"); - _param_genlist_start_tex0 = glGetUniformLocation(*program, "tex0"); - //stepping - s_genlist_step = program = LoadGenListStepShader(0, 1); - _param_genlist_step_tex0= glGetUniformLocation(*program, "tex0"); - -} - -void ShaderBagGLSL::SetMarginCopyParam(int xmax, int ymax) -{ - float truncate[2] = {xmax - 0.5f , ymax - 0.5f}; - glUniform2fv(_param_margin_copy_truncate, 1, truncate); -} - -void ShaderBagGLSL::SetGenListInitParam(int w, int h) -{ - float bbox[2] = {w - 1.0f, h - 1.0f}; - glUniform2fv(_param_genlist_init_bbox, 1, bbox); -} -void ShaderBagGLSL::SetGenListStartParam(float width, int tex0) -{ - glUniform1f(_param_ftex_width, width); - glUniform1i(_param_genlist_start_tex0, 0); -} - - -ProgramGLSL* ShaderBagGLSL::LoadGenListStepShader(int start, int step) -{ - int i; - // char chanels[5] = "rgba"; - ostringstream out; - - for(i = 0; i < step; i++) out<<"uniform sampler2DRect tex"<0) - { - out<<"vec2 cpos = vec2(-0.5, 0.5);\t vec2 opos;\n"; - for(i = 0; i < step; i++) - { - - out<<"cc = texture2DRect(tex"<IsNative()) - { - s_orientation = program ; - _param_orientation_gtex = glGetUniformLocation(*program, "gradTex"); - _param_orientation_size = glGetUniformLocation(*program, "size"); - _param_orientation_stex = glGetUniformLocation(*program, "texS"); - }else - { - delete program; - } -} - - -void ShaderBagGLSL::WriteOrientationCodeToStream(std::ostream& out) -{ - //smooth histogram and find the largest -/* - smoothing kernel: (1 3 6 7 6 3 1 )/27 - the same as 3 pass of (1 1 1)/3 averaging - maybe better to use 4 pass on the vectors... -*/ - - - //the inner loop on different array numbers is always unrolled in fp40 - - //bug fixed here:) - out<<"\n" - " //mat3 m1 = mat3(1, 0, 0, 3, 1, 0, 6, 3, 1)/27.0; \n" - " mat3 m1 = mat3(1, 3, 6, 0, 1, 3,0, 0, 1)/27.0; \n" - " mat4 m2 = mat4(7, 6, 3, 1, 6, 7, 6, 3, 3, 6, 7, 6, 1, 3, 6, 7)/27.0;\n" - " #define FILTER_CODE(i) { \\\n" - " vec4 newb = (bins[i]* m2); \\\n" - " newb.xyz += ( prev.yzw * m1); \\\n" - " prev = bins[i]; \\\n" - " newb.wzy += ( bins[i+1].zyx *m1); \\\n" - " bins[i] = newb;}\n" - " for (int j=0; j<2; j++) \n" - " { \n" - " vec4 prev = bins[8]; \n" - " bins[9] = bins[0]; \n"; - - if(GlobalUtil::_KeepShaderLoop) - { - out<< - " for (int i=0; i<9; i++) \n" - " { \n" - " FILTER_CODE(i); \n" - " } \n" - " }"; - - }else - { - //manually unroll the loop for ATI. - out << - " FILTER_CODE(0);\n" - " FILTER_CODE(1);\n" - " FILTER_CODE(2);\n" - " FILTER_CODE(3);\n" - " FILTER_CODE(4);\n" - " FILTER_CODE(5);\n" - " FILTER_CODE(6);\n" - " FILTER_CODE(7);\n" - " FILTER_CODE(8);\n" - " }\n"; - } - //find the maximum voting - out<<"\n" - " vec4 maxh; vec2 maxh2; \n" - " vec4 maxh4 = max(max(max(max(max(max(max(max(bins[0], bins[1]), bins[2]), \n" - " bins[3]), bins[4]), bins[5]), bins[6]), bins[7]), bins[8]);\n" - " maxh2 = max(maxh4.xy, maxh4.zw); maxh = vec4(max(maxh2.x, maxh2.y));"; - - char *testpeak_code; - char *savepeak_code; - - //save two/three/four orientations with the largest votings? - - if(GlobalUtil::_MaxOrientation>1) - { - out<<"\n" - " vec4 Orientations = vec4(0.0, 0.0, 0.0, 0.0); \n" - " vec4 weights = vec4(0.0,0.0,0.0,0.0); "; - - testpeak_code = "\\\n" - " {test = greaterThan(bins[i], hh);"; - - //save the orientations in weight-decreasing order - if(GlobalUtil::_MaxOrientation ==2) - { - savepeak_code = "\\\n" - " if(weight <=weights.g){}\\\n" - " else if(weight >weights.r)\\\n" - " {weights.rg = vec2(weight, weights.r); Orientations.rg = vec2(th, Orientations.r);}\\\n" - " else {weights.g = weight; Orientations.g = th;}"; - }else if(GlobalUtil::_MaxOrientation ==3) - { - savepeak_code = "\\\n" - " if(weight <=weights.b){}\\\n" - " else if(weight >weights.r)\\\n" - " {weights.rgb = vec3(weight, weights.rg); Orientations.rgb = vec3(th, Orientations.rg);}\\\n" - " else if(weight >weights.g)\\\n" - " {weights.gb = vec2(weight, weights.g); Orientations.gb = vec2(th, Orientations.g);}\\\n" - " else {weights.b = weight; Orientations.b = th;}"; - }else - { - savepeak_code = "\\\n" - " if(weight <=weights.a){}\\\n" - " else if(weight >weights.r)\\\n" - " {weights = vec4(weight, weights.rgb); Orientations = vec4(th, Orientations.rgb);}\\\n" - " else if(weight >weights.g)\\\n" - " {weights.gba = vec3(weight, weights.gb); Orientations.gba = vec3(th, Orientations.gb);}\\\n" - " else if(weight >weights.b)\\\n" - " {weights.ba = vec2(weight, weights.b); Orientations.ba = vec2(th, Orientations.b);}\\\n" - " else {weights.a = weight; Orientations.a = th;}"; - } - - }else - { - out<<"\n" - " float Orientation; "; - testpeak_code ="\\\n" - " if(npeaks<=0.0){\\\n" - " test = equal(bins[i], maxh) ;"; - savepeak_code="\\\n" - " npeaks++; \\\n" - " Orientation = th;"; - - } - //find the peaks - out <<"\n" - " #define FINDPEAK(i, k)" < prevb && bins[i].x > bins[i].y ) \\\n" - " { \\\n" - " float di = -0.5 * (bins[i].y-prevb) / (bins[i].y+prevb-bins[i].x - bins[i].x) ; \\\n" - " float th = (k+di+0.5); float weight = bins[i].x;" - < bins[i].z && bins[i].w > bins[i+1].x ) \\\n" - " { \\\n" - " float di = -0.5 * (bins[i+1].x-bins[i].z) / (bins[i+1].x+bins[i].z-bins[i].w - bins[i].w) ; \\\n" - " float th = (k+di+3.5); float weight = bins[i].w; " - <1) - { - out<<"\n" - " if(orientation_mode){\n" - " npeaks = dot(vec4(1,1," - <<(GlobalUtil::_MaxOrientation>2 ? 1 : 0)<<"," - <<(GlobalUtil::_MaxOrientation >3? 1 : 0)<<"), vec4(greaterThan(weights, hh)));\n" - " gl_FragData[0] = vec4(pos, npeaks, sigma);\n" - " gl_FragData[1] = radians((Orientations )*10.0);\n" - " }else{\n" - " gl_FragData[0] = vec4(pos, radians((Orientations.x)*10.0), sigma);\n" - " }\n"; - }else - { - out<<"\n" - " gl_FragData[0] = vec4(pos, radians((Orientation)*10.0), sigma);\n"; - } - //end - out<<"\n" - "}\n"<<'\0'; - - -} - -void ShaderBagGLSL::SetSimpleOrientationInput(int oTex, float sigma, float sigma_step) -{ - glUniform1i(_param_orientation_gtex, 1); - glUniform1f(_param_orientation_size, sigma); -} - - - - -void ShaderBagGLSL::SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int stex, float step) -{ - /// - glUniform1i(_param_orientation_gtex, 1); - - if((GlobalUtil::_SubpixelLocalization || GlobalUtil::_KeepExtremumSign)&& stex) - { - //specify texutre for subpixel subscale localization - glUniform1i(_param_orientation_stex, 2); - } - - float size[4]; - size[0] = (float)width; - size[1] = (float)height; - size[2] = sigma; - size[3] = step; - glUniform4fv(_param_orientation_size, 1, size); -} - - -void ShaderBagGLSL::LoadDescriptorShaderF2() -{ - //one shader outpout 128/8 = 16 , each fragout encodes 4 - //const double twopi = 2.0*3.14159265358979323846; - //const double rpi = 8.0/twopi; - ostringstream out; - out< M_PI) anglef -= TWO_PI;\n" - " float sigma = texture2DRect(tex, coord).w; \n" - " float spt = abs(sigma * WF); //default to be 3*sigma \n"; - - //rotation - out<< - " vec4 cscs, rots; \n" - " cscs.y = sin(anglef); cscs.x = cos(anglef); \n" - " cscs.zw = - cscs.xy; \n" - " rots = cscs /spt; \n" - " cscs *= spt; \n"; - - //here cscs is actually (cos, sin, -cos, -sin) * (factor: 3)*sigma - //and rots is (cos, sin, -cos, -sin ) /(factor*sigma) - //devide the 4x4 sift grid into 16 1x1 block, and each corresponds to a shader thread - //To use linear interoplation, 1x1 is increased to 2x2, by adding 0.5 to each side - - out<< - "vec4 temp; vec2 pt, offsetpt; \n" - " /*the fraction part of idx is .5*/ \n" - " offsetpt.x = 4.0* fract(idx*0.25) - 2.0; \n" - " offsetpt.y = floor(idx*0.25) - 1.5; \n" - " temp = cscs.xwyx*offsetpt.xyxy; \n" - " pt = pos + temp.xz + temp.yw; \n"; - - //get a horizontal bounding box of the rotated rectangle - out<< - " vec2 bwin = abs(cscs.xy); \n" - " float bsz = bwin.x + bwin.y; \n" - " vec4 sz; \n" - " sz.xy = max(pt - vec2(bsz), vec2(1,1));\n" - " sz.zw = min(pt + vec2(bsz), dim - vec2(2, 2)); \n" - " sz = floor(sz)+0.5;"; //move sample point to pixel center - //get voting for two box - - out<<"\n" - " vec4 DA, DB; vec2 spos; \n" - " DA = DB = vec4(0.0, 0.0, 0.0, 0.0); \n" - " for(spos.y = sz.y; spos.y <= sz.w; spos.y+=1.0) \n" - " { \n" - " for(spos.x = sz.x; spos.x <= sz.z; spos.x+=1.0) \n" - " { \n" - " vec2 diff = spos - pt; \n" - " temp = rots.xywx * diff.xyxy;\n" - " vec2 nxy = (temp.xz + temp.yw); \n" - " vec2 nxyn = abs(nxy); \n" - " if(all( lessThan(nxyn, vec2(1.0)) ))\n" - " {\n" - " vec4 cc = texture2DRect(gradTex, spos); \n" - " float mod = cc.b; float angle = cc.a; \n" - " float theta0 = RPI * (anglef - angle); \n" - " float theta = theta0 < 0.0? theta0 + 8.0 : theta0;;\n" - " diff = nxy + offsetpt.xy; \n" - " float ww = exp(-0.125*dot(diff, diff));\n" - " vec2 weights = vec2(1) - nxyn;\n" - " float weight = weights.x * weights.y *mod*ww; \n" - " float theta1 = floor(theta); \n" - " float weight2 = (theta - theta1) * weight;\n" - " float weight1 = weight - weight2;\n" - " DA += vec4(equal(vec4(theta1), vec4(0, 1, 2, 3)))*weight1;\n" - " DA += vec4(equal(vec4(theta1), vec4(7, 0, 1, 2)))*weight2; \n" - " DB += vec4(equal(vec4(theta1), vec4(4, 5, 6, 7)))*weight1;\n" - " DB += vec4(equal(vec4(theta1), vec4(3, 4, 5, 6)))*weight2; \n" - " }\n" - " }\n" - " }\n"; - - out<< - " gl_FragData[0] = DA; gl_FragData[1] = DB;\n" - "}\n"<<'\0'; - - ProgramGLSL * program = new ProgramGLSL(out.str().c_str()); - - if(program->IsNative()) - { - s_descriptor_fp = program ; - _param_descriptor_gtex = glGetUniformLocation(*program, "gradTex"); - _param_descriptor_size = glGetUniformLocation(*program, "size"); - _param_descriptor_dsize = glGetUniformLocation(*program, "dsize"); - }else - { - delete program; - } - - -} - -void ShaderBagGLSL::LoadDescriptorShader() -{ - GlobalUtil::_DescriptorPPT = 16; - LoadDescriptorShaderF2(); -} - - -void ShaderBagGLSL::SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma) -{ - /// - glUniform1i(_param_descriptor_gtex, 1); - - float dsize[4] ={dwidth, 1.0f/dwidth, fwidth, 1.0f/fwidth}; - glUniform4fv(_param_descriptor_dsize, 1, dsize); - float size[3]; - size[0] = width; - size[1] = height; - size[2] = GlobalUtil::_DescriptorWindowFactor; - glUniform3fv(_param_descriptor_size, 1, size); - -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void ShaderBagPKSL::LoadFixedShaders() -{ - ProgramGLSL * program; - - - s_gray = new ProgramGLSL( - "uniform sampler2DRect tex; void main(){\n" - "float intensity = dot(vec3(0.299, 0.587, 0.114), texture2DRect(tex,gl_TexCoord[0].xy ).rgb);\n" - "gl_FragColor= vec4(intensity, intensity, intensity, 1.0);}" ); - - - s_sampling = new ProgramGLSL( - "uniform sampler2DRect tex; void main(){\n" - "gl_FragColor= vec4( texture2DRect(tex,gl_TexCoord[0].st ).r,texture2DRect(tex,gl_TexCoord[1].st ).r,\n" - " texture2DRect(tex,gl_TexCoord[2].st ).r,texture2DRect(tex,gl_TexCoord[3].st ).r);}" ); - - - s_margin_copy = program = new ProgramGLSL( - "uniform sampler2DRect tex; uniform vec4 truncate; void main(){\n" - "vec4 cc = texture2DRect(tex, min(gl_TexCoord[0].xy, truncate.xy)); \n" - "bvec2 ob = lessThan(gl_TexCoord[0].xy, truncate.xy);\n" - "if(ob.y) { gl_FragColor = (truncate.z ==0.0 ? cc.rrbb : cc.ggaa); } \n" - "else if(ob.x) {gl_FragColor = (truncate.w <1.5 ? cc.rgrg : cc.baba);} \n" - "else { vec4 weights = vec4(vec4(0.0, 1.0, 2.0, 3.0) == truncate.wwww);\n" - "float v = dot(weights, cc); gl_FragColor = vec4(v);}}"); - - _param_margin_copy_truncate = glGetUniformLocation(*program, "truncate"); - - - - s_zero_pass = new ProgramGLSL("void main(){gl_FragColor = vec4(0.0);}"); - - - - s_grad_pass = program = new ProgramGLSL( - "uniform sampler2DRect tex; uniform sampler2DRect texp; void main ()\n" - "{\n" - " vec4 v1, v2, gg;\n" - " vec4 cc = texture2DRect(tex, gl_TexCoord[0].xy);\n" - " vec4 cp = texture2DRect(texp, gl_TexCoord[0].xy);\n" - " gl_FragData[0] = cc - cp; \n" - " vec4 cl = texture2DRect(tex, gl_TexCoord[1].xy); vec4 cr = texture2DRect(tex, gl_TexCoord[2].xy);\n" - " vec4 cd = texture2DRect(tex, gl_TexCoord[3].xy); vec4 cu = texture2DRect(tex, gl_TexCoord[4].xy);\n" - " vec4 dx = (vec4(cr.rb, cc.ga) - vec4(cc.rb, cl.ga)).zxwy;\n" - " vec4 dy = (vec4(cu.rg, cc.ba) - vec4(cc.rg, cd.ba)).zwxy;\n" - " vec4 grad = 0.5 * sqrt(dx*dx + dy * dy);\n" - " gl_FragData[1] = grad;\n" - " vec4 invalid = vec4(equal(grad, vec4(0.0))); \n" - " vec4 ov = atan(dy, dx + invalid); \n" - " gl_FragData[2] = ov; \n" - "}\n\0"); //when - - _param_grad_pass_texp = glGetUniformLocation(*program, "texp"); - - - GlobalUtil::_OrientationPack2 = 0; - LoadOrientationShader(); - - if(s_orientation == NULL) - { - //Load a simplified version if the right version is not supported - s_orientation = program = new ProgramGLSL( - "uniform sampler2DRect tex; uniform sampler2DRect oTex; uniform vec2 size; void main(){\n" - " vec4 cc = texture2DRect(tex, gl_TexCoord[0].xy);\n" - " vec2 co = cc.xy * 0.5; \n" - " vec4 oo = texture2DRect(oTex, co);\n" - " bvec2 bo = lessThan(fract(co), vec2(0.5)); \n" - " float o = bo.y? (bo.x? oo.r : oo.g) : (bo.x? oo.b : oo.a); \n" - " gl_FragColor = vec4(cc.rg, o, size.x * pow(size.y, cc.a));}"); - - _param_orientation_gtex= glGetUniformLocation(*program, "oTex"); - _param_orientation_size= glGetUniformLocation(*program, "size"); - GlobalUtil::_MaxOrientation = 0; - GlobalUtil::_FullSupported = 0; - std::cerr<<"Orientation simplified on this hardware"< 0.9))? size : -size);\n" - " dxy.y = type < 0.2 ? 0.0 : (((type < 0.3) || (type > 0.7) )? -size :size); \n" - " s = sin(cc.b); c = cos(cc.b); \n" - " gl_FragColor.x = cc.x + c*dxy.x-s*dxy.y;\n" - " gl_FragColor.y = cc.y + c*dxy.y+s*dxy.x;}\n" - "}\n\0"); - /*gl_FragColor = vec4(tpos, 0.0, 1.0);}\n\0");*/ - - _param_genvbo_size = glGetUniformLocation(*program, "sizes"); - - s_display_gaussian = new ProgramGLSL( - "uniform sampler2DRect tex; void main(){\n" - "vec4 pc = texture2DRect(tex, gl_TexCoord[0].xy); bvec2 ff = lessThan(fract(gl_TexCoord[0].xy), vec2(0.5));\n" - "float v = ff.y?(ff.x? pc.r : pc.g):(ff.x?pc.b:pc.a); gl_FragColor = vec4(vec3(v), 1.0);}"); - - s_display_dog = new ProgramGLSL( - "uniform sampler2DRect tex; void main(){\n" - "vec4 pc = texture2DRect(tex, gl_TexCoord[0].xy); bvec2 ff = lessThan(fract(gl_TexCoord[0].xy), vec2(0.5));\n" - "float v = ff.y ?(ff.x ? pc.r : pc.g):(ff.x ? pc.b : pc.a);float g = (0.5+20.0*v);\n" - "gl_FragColor = vec4(g, g, g, 1.0);}" ); - - - s_display_grad = new ProgramGLSL( - "uniform sampler2DRect tex; void main(){\n" - "vec4 pc = texture2DRect(tex, gl_TexCoord[0].xy); bvec2 ff = lessThan(fract(gl_TexCoord[0].xy), vec2(0.5));\n" - "float v = ff.y ?(ff.x ? pc.r : pc.g):(ff.x ? pc.b : pc.a); gl_FragColor = vec4(5.0 *vec3(v), 1.0); }"); - - s_display_keys= new ProgramGLSL( - "uniform sampler2DRect tex; void main(){\n" - "vec4 oc = texture2DRect(tex, gl_TexCoord[0].xy); \n" - "vec4 cc = vec4(equal(abs(oc.rrrr), vec4(1.0, 2.0, 3.0, 4.0))); \n" - "bvec2 ff = lessThan(fract(gl_TexCoord[0].xy) , vec2(0.5));\n" - "float v = ff.y ?(ff.x ? cc.r : cc.g):(ff.x ? cc.b : cc.a);\n" - "if(v == 0.0) discard; \n" - "else if(oc.r > 0.0) gl_FragColor = vec4(1.0, 0.0, 0,1.0); \n" - "else gl_FragColor = vec4(0.0,1.0,0.0,1.0); }" ); -} - -void ShaderBagPKSL::LoadOrientationShader(void) -{ - ostringstream out; - if(GlobalUtil::_IsNvidia) - { - out << "#pragma optionNV(ifcvt none)\n" - "#pragma optionNV(unroll all)\n"; - } - out<<"\n" - "#define GAUSSIAN_WF float("<IsNative()) - { - s_orientation = program ; - _param_orientation_gtex = glGetUniformLocation(*program, "gtex"); - _param_orientation_otex = glGetUniformLocation(*program, "otex"); - _param_orientation_size = glGetUniformLocation(*program, "size"); - }else - { - delete program; - } -} - -void ShaderBagPKSL::SetGenListStartParam(float width, int tex0) -{ - glUniform1f(_param_ftex_width, width); - glUniform1i(_param_genlist_start_tex0, 0); -} - -void ShaderBagPKSL::LoadGenListShader(int ndoglev,int nlev) -{ - ProgramGLSL * program; - - s_genlist_init_tight = new ProgramGLSL( - "uniform sampler2DRect tex; void main ()\n" - "{\n" - " vec4 key = vec4(texture2DRect(tex, gl_TexCoord[0].xy).r, \n" - " texture2DRect(tex, gl_TexCoord[1].xy).r, \n" - " texture2DRect(tex, gl_TexCoord[2].xy).r, \n" - " texture2DRect(tex, gl_TexCoord[3].xy).r); \n" - " gl_FragColor = vec4(notEqual(key, vec4(0.0))); \n" - "}"); - - s_genlist_init_ex = program = new ProgramGLSL( - "uniform sampler2DRect tex; uniform vec4 bbox; void main ()\n" - "{\n" - " vec4 helper1 = vec4(equal(vec4(abs(texture2DRect(tex, gl_TexCoord[0].xy).r)), vec4(1.0, 2.0, 3.0, 4.0)));\n" - " vec4 helper2 = vec4(equal(vec4(abs(texture2DRect(tex, gl_TexCoord[1].xy).r)), vec4(1.0, 2.0, 3.0, 4.0)));\n" - " vec4 helper3 = vec4(equal(vec4(abs(texture2DRect(tex, gl_TexCoord[2].xy).r)), vec4(1.0, 2.0, 3.0, 4.0)));\n" - " vec4 helper4 = vec4(equal(vec4(abs(texture2DRect(tex, gl_TexCoord[3].xy).r)), vec4(1.0, 2.0, 3.0, 4.0)));\n" - " vec4 bx1 = vec4(lessThan(gl_TexCoord[0].xxyy, bbox)); \n" - " vec4 bx4 = vec4(lessThan(gl_TexCoord[3].xxyy, bbox)); \n" - " vec4 bx2 = vec4(bx4.xy, bx1.zw); \n" - " vec4 bx3 = vec4(bx1.xy, bx4.zw);\n" - " helper1 = min(min(bx1.xyxy, bx1.zzww), helper1);\n" - " helper2 = min(min(bx2.xyxy, bx2.zzww), helper2);\n" - " helper3 = min(min(bx3.xyxy, bx3.zzww), helper3);\n" - " helper4 = min(min(bx4.xyxy, bx4.zzww), helper4);\n" - " gl_FragColor.r = float(any(greaterThan(max(helper1.xy, helper1.zw), vec2(0.0)))); \n" - " gl_FragColor.g = float(any(greaterThan(max(helper2.xy, helper2.zw), vec2(0.0)))); \n" - " gl_FragColor.b = float(any(greaterThan(max(helper3.xy, helper3.zw), vec2(0.0)))); \n" - " gl_FragColor.a = float(any(greaterThan(max(helper4.xy, helper4.zw), vec2(0.0)))); \n" - "}"); - _param_genlist_init_bbox = glGetUniformLocation( *program, "bbox"); - - s_genlist_end = program = new ProgramGLSL( - GlobalUtil::_KeepExtremumSign == 0 ? - - "uniform sampler2DRect tex; uniform sampler2DRect ktex; void main()\n" - "{\n" - " vec4 tc = texture2DRect( tex, gl_TexCoord[0].xy);\n" - " vec2 pos = tc.rg; float index = tc.b;\n" - " vec4 tk = texture2DRect( ktex, pos); \n" - " vec4 keys = vec4(equal(abs(tk.rrrr), vec4(1.0, 2.0, 3.0, 4.0))); \n" - " vec2 opos; \n" - " opos.x = dot(keys, vec4(-0.5, 0.5, -0.5, 0.5));\n" - " opos.y = dot(keys, vec4(-0.5, -0.5, 0.5, 0.5));\n" - " gl_FragColor = vec4(opos + pos * 2.0 + tk.yz, 1.0, tk.w);\n" - "}" : - - "uniform sampler2DRect tex; uniform sampler2DRect ktex; void main()\n" - "{\n" - " vec4 tc = texture2DRect( tex, gl_TexCoord[0].xy);\n" - " vec2 pos = tc.rg; float index = tc.b;\n" - " vec4 tk = texture2DRect( ktex, pos); \n" - " vec4 keys = vec4(equal(abs(tk.rrrr), vec4(1.0, 2.0, 3.0, 4.0))) \n" - " vec2 opos; \n" - " opos.x = dot(keys, vec4(-0.5, 0.5, -0.5, 0.5));\n" - " opos.y = dot(keys, vec4(-0.5, -0.5, 0.5, 0.5));\n" - " gl_FragColor = vec4(opos + pos * 2.0 + tk.yz, sign(tk.r), tk.w);\n" - "}" - ); - - _param_genlist_end_ktex = glGetUniformLocation(*program, "ktex"); - - //reduction ... - s_genlist_histo = new ProgramGLSL( - "uniform sampler2DRect tex; void main ()\n" - "{\n" - " vec4 helper; vec4 helper2; \n" - " helper = texture2DRect(tex, gl_TexCoord[0].xy); helper2.xy = helper.xy + helper.zw; \n" - " helper = texture2DRect(tex, gl_TexCoord[1].xy); helper2.zw = helper.xy + helper.zw; \n" - " gl_FragColor.rg = helper2.xz + helper2.yw;\n" - " helper = texture2DRect(tex, gl_TexCoord[2].xy); helper2.xy = helper.xy + helper.zw; \n" - " helper = texture2DRect(tex, gl_TexCoord[3].xy); helper2.zw = helper.xy + helper.zw; \n" - " gl_FragColor.ba= helper2.xz+helper2.yw;\n" - "}"); - - - //read of the first part, which generates tex coordinates - - s_genlist_start= program = ShaderBagGLSL::LoadGenListStepShader(1, 1); - _param_ftex_width= glGetUniformLocation(*program, "width"); - _param_genlist_start_tex0 = glGetUniformLocation(*program, "tex0"); - //stepping - s_genlist_step = program = ShaderBagGLSL::LoadGenListStepShader(0, 1); - _param_genlist_step_tex0= glGetUniformLocation(*program, "tex0"); - -} -void ShaderBagPKSL::UnloadProgram(void) -{ - glUseProgram(0); -} -void ShaderBagPKSL::LoadKeypointShader(float dog_threshold, float edge_threshold) -{ - float threshold0 = dog_threshold* (GlobalUtil::_SubpixelLocalization?0.8f:1.0f); - float threshold1 = dog_threshold; - float threshold2 = (edge_threshold+1)*(edge_threshold+1)/edge_threshold; - ostringstream out;; - out< float(THRESHOLD0(i)) && all(test1)?1.0: 0.0;\\\n" - " key[i] = cc[i] < float(-THRESHOLD0(i)) && all(test2)? -1.0: key[i];\\\n" - " }\n" - " REPEAT4(KEYTEST_STEP0);\n" - " if(gl_TexCoord[0].x < 1.0) {key.rb = vec2(0.0);}\n" - " if(gl_TexCoord[0].y < 1.0) {key.rg = vec2(0.0);}\n" - " gl_FragColor = vec4(0.0);\n" - " if(any(notEqual(key, vec4(0.0)))) {\n"; - - //do edge supression first.. - //vector v1 is < (-1, 0), (1, 0), (0,-1), (0, 1)> - //vector v2 is < (-1,-1), (-1,1), (1,-1), (1, 1)> - - out<< - " float fxx[4], fyy[4], fxy[4], fx[4], fy[4];\n" - " #define EDGE_SUPPRESION(i) \\\n" - " if(key[i] != 0.0)\\\n" - " {\\\n" - " vec4 D2 = v1[i].xyzw - cc[i];\\\n" - " vec2 D4 = v2[i].xw - v2[i].yz;\\\n" - " vec2 D5 = 0.5*(v1[i].yw-v1[i].xz); \\\n" - " fx[i] = D5.x; fy[i] = D5.y ;\\\n" - " fxx[i] = D2.x + D2.y;\\\n" - " fyy[i] = D2.z + D2.w;\\\n" - " fxy[i] = 0.25*(D4.x + D4.y);\\\n" - " float fxx_plus_fyy = fxx[i] + fyy[i];\\\n" - " float score_up = fxx_plus_fyy*fxx_plus_fyy; \\\n" - " float score_down = (fxx[i]*fyy[i] - fxy[i]*fxy[i]);\\\n" - " if( score_down <= 0.0 || score_up > THRESHOLD2 * score_down)key[i] = 0.0;\\\n" - " }\n" - " REPEAT4(EDGE_SUPPRESION);\n" - " if(any(notEqual(key, vec4(0.0)))) {\n"; - - //////////////////////////////////////////////// - //read 9 pixels of upper/lower level - out<< - " vec4 v4[4], v5[4], v6[4];\n" - " ccc = texture2DRect(texU, gl_TexCoord[0].xy);\n" - " clc = texture2DRect(texU, gl_TexCoord[1].xy);\n" - " crc = texture2DRect(texU, gl_TexCoord[2].xy);\n" - " ccd = texture2DRect(texU, gl_TexCoord[3].xy);\n" - " ccu = texture2DRect(texU, gl_TexCoord[4].xy);\n" - " cld = texture2DRect(texU, gl_TexCoord[5].xy);\n" - " clu = texture2DRect(texU, gl_TexCoord[6].xy);\n" - " crd = texture2DRect(texU, gl_TexCoord[7].xy);\n" - " cru = texture2DRect(texU, TexRU.xy);\n" - " vec4 cu = ccc;\n" - " v4[0] = vec4(clc.g, ccc.g, ccd.b, ccc.b);\n" - " v4[1] = vec4(ccc.r, crc.r, ccd.a, ccc.a);\n" - " v4[2] = vec4(clc.a, ccc.a, ccc.r, ccu.r);\n" - " v4[3] = vec4(ccc.b, crc.b, ccc.g, ccu.g);\n" - " v6[0] = vec4(cld.a, clc.a, ccd.a, ccc.a);\n" - " v6[1] = vec4(ccd.b, ccc.b, crd.b, crc.b);\n" - " v6[2] = vec4(clc.g, clu.g, ccc.g, ccu.g);\n" - " v6[3] = vec4(ccc.r, ccu.r, crc.r, cru.r);\n" - << - " #define KEYTEST_STEP1(i)\\\n" - " if(key[i] == 1.0)\\\n" - " {\\\n" - " bvec4 test = lessThan(vec4(cc[i]), max(v4[i], v6[i])); \\\n" - " if(cc[i] < cu[i] || any(test))key[i] = 0.0; \\\n" - " }else if(key[i] == -1.0)\\\n" - " {\\\n" - " bvec4 test = greaterThan(vec4(cc[i]), min(v4[i], v6[i])); \\\n" - " if(cc[i] > cu[i] || any(test) )key[i] = 0.0; \\\n" - " }\n" - " REPEAT4(KEYTEST_STEP1);\n" - " if(any(notEqual(key, vec4(0.0)))) { \n" - << - " ccc = texture2DRect(texD, gl_TexCoord[0].xy);\n" - " clc = texture2DRect(texD, gl_TexCoord[1].xy);\n" - " crc = texture2DRect(texD, gl_TexCoord[2].xy);\n" - " ccd = texture2DRect(texD, gl_TexCoord[3].xy);\n" - " ccu = texture2DRect(texD, gl_TexCoord[4].xy);\n" - " cld = texture2DRect(texD, gl_TexCoord[5].xy);\n" - " clu = texture2DRect(texD, gl_TexCoord[6].xy);\n" - " crd = texture2DRect(texD, gl_TexCoord[7].xy);\n" - " cru = texture2DRect(texD, TexRU.xy);\n" - " vec4 cd = ccc;\n" - " v5[0] = vec4(clc.g, ccc.g, ccd.b, ccc.b);\n" - " v5[1] = vec4(ccc.r, crc.r, ccd.a, ccc.a);\n" - " v5[2] = vec4(clc.a, ccc.a, ccc.r, ccu.r);\n" - " v5[3] = vec4(ccc.b, crc.b, ccc.g, ccu.g);\n" - " v6[0] = vec4(cld.a, clc.a, ccd.a, ccc.a);\n" - " v6[1] = vec4(ccd.b, ccc.b, crd.b, crc.b);\n" - " v6[2] = vec4(clc.g, clu.g, ccc.g, ccu.g);\n" - " v6[3] = vec4(ccc.r, ccu.r, crc.r, cru.r);\n" - << - " #define KEYTEST_STEP2(i)\\\n" - " if(key[i] == 1.0)\\\n" - " {\\\n" - " bvec4 test = lessThan(vec4(cc[i]), max(v5[i], v6[i]));\\\n" - " if(cc[i] < cd[i] || any(test))key[i] = 0.0; \\\n" - " }else if(key[i] == -1.0)\\\n" - " {\\\n" - " bvec4 test = greaterThan(vec4(cc[i]), min(v5[i], v6[i]));\\\n" - " if(cc[i] > cd[i] || any(test))key[i] = 0.0; \\\n" - " }\n" - " REPEAT4(KEYTEST_STEP2);\n" - " float keysum = dot(abs(key), vec4(1, 1, 1, 1)) ;\n" - " //assume there is only one keypoint in the four. \n" - " if(keysum==1.0) {\n"; - - ////////////////////////////////////////////////////////////////////// - if(GlobalUtil::_SubpixelLocalization) - - out << - " vec3 offset = vec3(0.0, 0.0, 0.0); \n" - " #define TESTMOVE_KEYPOINT(idx) \\\n" - " if(key[idx] != 0.0) \\\n" - " {\\\n" - " cu[0] = cu[idx]; cd[0] = cd[idx]; cc[0] = cc[idx]; \\\n" - " v4[0] = v4[idx]; v5[0] = v5[idx]; \\\n" - " fxy[0] = fxy[idx]; fxx[0] = fxx[idx]; fyy[0] = fyy[idx]; \\\n" - " fx[0] = fx[idx]; fy[0] = fy[idx]; MOVE_EXTRA(idx); \\\n" - " }\n" - " TESTMOVE_KEYPOINT(1);\n" - " TESTMOVE_KEYPOINT(2);\n" - " TESTMOVE_KEYPOINT(3);\n" - << - - " float fs = 0.5*( cu[0] - cd[0] ); \n" - " float fss = cu[0] + cd[0] - cc[0] - cc[0];\n" - " float fxs = 0.25 * (v4[0].y + v5[0].x - v4[0].x - v5[0].y);\n" - " float fys = 0.25 * (v4[0].w + v5[0].z - v4[0].z - v5[0].w);\n" - " vec4 A0, A1, A2 ; \n" - " A0 = vec4(fxx[0], fxy[0], fxs, -fx[0]); \n" - " A1 = vec4(fxy[0], fyy[0], fys, -fy[0]); \n" - " A2 = vec4(fxs, fys, fss, -fs); \n" - " vec3 x3 = abs(vec3(fxx[0], fxy[0], fxs)); \n" - " float maxa = max(max(x3.x, x3.y), x3.z); \n" - " if(maxa >= 1e-10 ) \n" - " { \n" - " if(x3.y ==maxa ) \n" - " { \n" - " vec4 TEMP = A1; A1 = A0; A0 = TEMP; \n" - " }else if( x3.z == maxa ) \n" - " { \n" - " vec4 TEMP = A2; A2 = A0; A0 = TEMP; \n" - " } \n" - " A0 /= A0.x; \n" - " A1 -= A1.x * A0; \n" - " A2 -= A2.x * A0; \n" - " vec2 x2 = abs(vec2(A1.y, A2.y)); \n" - " if( x2.y > x2.x ) \n" - " { \n" - " vec3 TEMP = A2.yzw; \n" - " A2.yzw = A1.yzw; \n" - " A1.yzw = TEMP; \n" - " x2.x = x2.y; \n" - " } \n" - " if(x2.x >= 1e-10) { \n" - " A1.yzw /= A1.y; \n" - " A2.yzw -= A2.y * A1.yzw; \n" - " if(abs(A2.z) >= 1e-10) {\n" - " offset.z = A2.w /A2.z; \n" - " offset.y = A1.w - offset.z*A1.z; \n" - " offset.x = A0.w - offset.z*A0.z - offset.y*A0.y; \n" - " bool test = (abs(cc[0] + 0.5*dot(vec3(fx[0], fy[0], fs), offset ))>float(THRESHOLD1)) ;\n" - " if(!test || any( greaterThan(abs(offset), vec3(1.0)))) key = vec4(0.0);\n" - " }\n" - " }\n" - " }\n" - <<"\n" - " float keyv = dot(key, vec4(1.0, 2.0, 3.0, 4.0));\n" - " gl_FragColor = vec4(keyv, offset);\n" - " }}}}\n" - "}\n" <<'\0'; - - else out << "\n" - " float keyv = dot(key, vec4(1.0, 2.0, 3.0, 4.0));\n" - " gl_FragColor = vec4(keyv, 0.0, 0.0, 0.0);\n" - " }}}}\n" - "}\n" <<'\0'; - - ProgramGLSL * program = new ProgramGLSL(out.str().c_str()); - s_keypoint = program ; - - //parameter - _param_dog_texu = glGetUniformLocation(*program, "texU"); - _param_dog_texd = glGetUniformLocation(*program, "texD"); - if(GlobalUtil::_DarknessAdaption) _param_dog_texi = glGetUniformLocation(*program, "texI"); -} -void ShaderBagPKSL::SetDogTexParam(int texU, int texD) -{ - glUniform1i(_param_dog_texu, 1); - glUniform1i(_param_dog_texd, 2); - if(GlobalUtil::_DarknessAdaption)glUniform1i(_param_dog_texi, 3); -} -void ShaderBagPKSL::SetGenListStepParam(int tex, int tex0) -{ - glUniform1i(_param_genlist_step_tex0, 1); -} - -void ShaderBagPKSL::SetGenVBOParam(float width, float fwidth,float size) -{ - float sizes[4] = {size*3.0f, fwidth, width, 1.0f/width}; - glUniform4fv(_param_genvbo_size, 1, sizes); -} -void ShaderBagPKSL::SetGradPassParam(int texP) -{ - glUniform1i(_param_grad_pass_texp, 1); -} - -void ShaderBagPKSL::LoadDescriptorShader() -{ - GlobalUtil::_DescriptorPPT = 16; - LoadDescriptorShaderF2(); - s_rect_description = LoadDescriptorProgramRECT(); -} - -ProgramGLSL* ShaderBagPKSL::LoadDescriptorProgramRECT() -{ - //one shader outpout 128/8 = 16 , each fragout encodes 4 - //const double twopi = 2.0*3.14159265358979323846; - //const double rpi = 8.0/twopi; - ostringstream out; - out<IsNative()) - { - return program; - } - else - { - delete program; - return NULL; - } -} - -ProgramGLSL* ShaderBagPKSL::LoadDescriptorProgramPKSL() -{ - //one shader outpout 128/8 = 16 , each fragout encodes 4 - //const double twopi = 2.0*3.14159265358979323846; - //const double rpi = 8.0/twopi; - ostringstream out; - out< M_PI) anglef -= TWO_PI;\n" - " float sigma = texture2DRect(tex, coord).w; \n" - " float spt = abs(sigma * WF); //default to be 3*sigma \n"; - //rotation - out<< - " vec4 cscs, rots; \n" - " cscs.x = cos(anglef); cscs.y = sin(anglef); \n" - " cscs.zw = - cscs.xy; \n" - " rots = cscs /spt; \n" - " cscs *= spt; \n"; - - //here cscs is actually (cos, sin, -cos, -sin) * (factor: 3)*sigma - //and rots is (cos, sin, -cos, -sin ) /(factor*sigma) - //devide the 4x4 sift grid into 16 1x1 block, and each corresponds to a shader thread - //To use linear interoplation, 1x1 is increased to 2x2, by adding 0.5 to each side - out<< - " vec4 temp; vec2 pt, offsetpt; \n" - " /*the fraction part of idx is .5*/ \n" - " offsetpt.x = 4.0* fract(idx*0.25) - 2.0; \n" - " offsetpt.y = floor(idx*0.25) - 1.5; \n" - " temp = cscs.xwyx*offsetpt.xyxy; \n" - " pt = pos + temp.xz + temp.yw; \n"; - - //get a horizontal bounding box of the rotated rectangle - out<< - " vec2 bwin = abs(cscs.xy); \n" - " float bsz = bwin.x + bwin.y; \n" - " vec4 sz; \n" - " sz.xy = max(pt - vec2(bsz), vec2(2,2));\n" - " sz.zw = min(pt + vec2(bsz), dim - vec2(3)); \n" - " sz = floor(sz * 0.5)+0.5;"; //move sample point to pixel center - //get voting for two box - - out<<"\n" - " vec4 DA, DB; vec2 spos; \n" - " DA = DB = vec4(0.0, 0.0, 0.0, 0.0); \n" - " vec4 nox = vec4(0.0, rots.xy, rots.x + rots.y); \n" - " vec4 noy = vec4(0.0, rots.wx, rots.w + rots.x); \n" - " for(spos.y = sz.y; spos.y <= sz.w; spos.y+=1.0) \n" - " { \n" - " for(spos.x = sz.x; spos.x <= sz.z; spos.x+=1.0) \n" - " { \n" - " vec2 tpt = spos * 2.0 - pt - 0.5; \n" - " vec4 temp = rots.xywx * tpt.xyxy; \n" - " vec2 temp2 = temp.xz + temp.yw; \n" - " vec4 nx = temp2.x + nox; \n" - " vec4 ny = temp2.y + noy; \n" - " vec4 nxn = abs(nx), nyn = abs(ny); \n" - " bvec4 inside = lessThan(max(nxn, nyn) , vec4(1.0)); \n" - " if(any(inside))\n" - " {\n" - " vec4 gg = texture2DRect(gtex, spos);\n" - " vec4 oo = texture2DRect(otex, spos);\n" - " vec4 theta0 = (anglef - oo)*RPI;\n" - " vec4 theta = 8.0 * fract(1.0 + 0.125 * theta0); \n" - " vec4 theta1 = floor(theta); \n" - " vec4 diffx = nx + offsetpt.x, diffy = ny + offsetpt.y; \n" - " vec4 ww = exp(-0.125 * (diffx * diffx + diffy * diffy )); \n" - " vec4 weight = (vec4(1) - nxn) * (vec4(1) - nyn) * gg * ww; \n" - " vec4 weight2 = (theta - theta1) * weight; \n" - " vec4 weight1 = weight - weight2; \n" - " #define ADD_DESCRIPTOR(i) \\\n" - " if(inside[i])\\\n" - " {\\\n" - " DA += vec4(equal(vec4(theta1[i]), vec4(0, 1, 2, 3)))*weight1[i]; \\\n" - " DA += vec4(equal(vec4(theta1[i]), vec4(7, 0, 1, 2)))*weight2[i]; \\\n" - " DB += vec4(equal(vec4(theta1[i]), vec4(4, 5, 6, 7)))*weight1[i]; \\\n" - " DB += vec4(equal(vec4(theta1[i]), vec4(3, 4, 5, 6)))*weight2[i]; \\\n" - " }\n" - " REPEAT4(ADD_DESCRIPTOR);\n" - " }\n" - " }\n" - " }\n"; - out<< - " gl_FragData[0] = DA; gl_FragData[1] = DB;\n" - "}\n"<<'\0'; - - ProgramGLSL * program = new ProgramGLSL(out.str().c_str()); - if(program->IsNative()) - { - return program; - } - else - { - delete program; - return NULL; - } -} - -void ShaderBagPKSL::LoadDescriptorShaderF2() -{ - - ProgramGLSL * program = LoadDescriptorProgramPKSL(); - if( program ) - { - s_descriptor_fp = program; - _param_descriptor_gtex = glGetUniformLocation(*program, "gtex"); - _param_descriptor_otex = glGetUniformLocation(*program, "otex"); - _param_descriptor_size = glGetUniformLocation(*program, "size"); - _param_descriptor_dsize = glGetUniformLocation(*program, "dsize"); - } -} - - - -void ShaderBagPKSL::SetSimpleOrientationInput(int oTex, float sigma, float sigma_step) -{ - glUniform1i(_param_orientation_gtex, 1); - glUniform2f(_param_orientation_size, sigma, sigma_step); -} - - -void ShaderBagPKSL::SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int otex, float step) -{ - /// - glUniform1i(_param_orientation_gtex, 1); - glUniform1i(_param_orientation_otex, 2); - - float size[4]; - size[0] = (float)width; - size[1] = (float)height; - size[2] = sigma; - size[3] = step; - glUniform4fv(_param_orientation_size, 1, size); -} - -void ShaderBagPKSL::SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma) -{ - if(sigma == 0 && s_rect_description) - { - //rectangle description mode - s_rect_description->UseProgram(); - GLint param_descriptor_gtex = glGetUniformLocation(*s_rect_description, "gtex"); - GLint param_descriptor_otex = glGetUniformLocation(*s_rect_description, "otex"); - GLint param_descriptor_size = glGetUniformLocation(*s_rect_description, "size"); - GLint param_descriptor_dsize = glGetUniformLocation(*s_rect_description, "dsize"); - /// - glUniform1i(param_descriptor_gtex, 1); - glUniform1i(param_descriptor_otex, 2); - - float dsize[4] ={dwidth, 1.0f/dwidth, fwidth, 1.0f/fwidth}; - glUniform4fv(param_descriptor_dsize, 1, dsize); - float size[3]; - size[0] = width; - size[1] = height; - size[2] = GlobalUtil::_DescriptorWindowFactor; - glUniform3fv(param_descriptor_size, 1, size); - }else - { - /// - glUniform1i(_param_descriptor_gtex, 1); - glUniform1i(_param_descriptor_otex, 2); - - - float dsize[4] ={dwidth, 1.0f/dwidth, fwidth, 1.0f/fwidth}; - glUniform4fv(_param_descriptor_dsize, 1, dsize); - float size[3]; - size[0] = width; - size[1] = height; - size[2] = GlobalUtil::_DescriptorWindowFactor; - glUniform3fv(_param_descriptor_size, 1, size); - } - -} - - -void ShaderBagPKSL::SetGenListEndParam(int ktex) -{ - glUniform1i(_param_genlist_end_ktex, 1); -} -void ShaderBagPKSL::SetGenListInitParam(int w, int h) -{ - float bbox[4] = {(w -1.0f) * 0.5f +0.25f, (w-1.0f) * 0.5f - 0.25f, (h - 1.0f) * 0.5f + 0.25f, (h-1.0f) * 0.5f - 0.25f}; - glUniform4fv(_param_genlist_init_bbox, 1, bbox); -} - -void ShaderBagPKSL::SetMarginCopyParam(int xmax, int ymax) -{ - float truncate[4]; - truncate[0] = (xmax - 0.5f) * 0.5f; //((xmax + 1) >> 1) - 0.5f; - truncate[1] = (ymax - 0.5f) * 0.5f; //((ymax + 1) >> 1) - 0.5f; - truncate[2] = (xmax %2 == 1)? 0.0f: 1.0f; - truncate[3] = truncate[2] + (((ymax % 2) == 1)? 0.0f : 2.0f); - glUniform4fv(_param_margin_copy_truncate, 1, truncate); -} diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramGLSL.h b/3rdparty/SiftGPU/src/SiftGPU/ProgramGLSL.h deleted file mode 100644 index cc949539..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramGLSL.h +++ /dev/null @@ -1,267 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ProgramGLSL.h -// Author: Changchang Wu -// Description : Interface for ProgramGLSL classes -// ProgramGLSL: Glsl Program -// FilterGLSL: Glsl Gaussian Filters -// ShaderBag: base class of ShaderBagPKSL and ShaderBagGLSL -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#ifndef _PROGRAM_GLSL_H -#define _PROGRAM_GLSL_H - - -#include "ProgramGPU.h" - -class ProgramGLSL:public ProgramGPU -{ - class ShaderObject - { - GLuint _shaderID; - int _type; - int _compiled; - static int ReadShaderFile(const char * source, char *& code); - void CheckCompileLog(); - public: - void PrintCompileLog(ostream & os ); - int inline IsValidShaderObject(){ return _shaderID && _compiled;} - int IsValidVertexShader(); - int IsValidFragmentShader(); - GLuint GetShaderID(){return _shaderID;} - ~ShaderObject(); - ShaderObject(int shadertype, const char * source, int filesource =0); - }; - -protected: - int _linked; - GLint _TextureParam0; - GLuint _programID; -private: - void AttachShaderObject(ShaderObject& shader); - void DetachShaderObject(ShaderObject& shader); - -public: - void ReLink(); - int IsNative(); - int UseProgram(); - void PrintLinkLog(std::ostream&os); - int ValidateProgram(); - void CheckLinkLog(); - int LinkProgram(); - operator GLuint (){return _programID;} - virtual void * GetProgramID() { return (void*) _programID; } -public: - ProgramGLSL(); - ~ProgramGLSL(); - ProgramGLSL(const char* frag_source); -}; - - -class GLTexImage; -class FilterGLSL : public FilterProgram -{ -private: - ProgramGPU* CreateFilterH(float kernel[], int width); - ProgramGPU* CreateFilterV(float kernel[], int height); - ProgramGPU* CreateFilterHPK(float kernel[], int width); - ProgramGPU* CreateFilterVPK(float kernel[], int height); -public: - void MakeFilterProgram(float kernel[], int width); -public: - FilterGLSL(float sigma) ; -}; - -class SiftParam; - -///////////////////////////////////////////////////////////////////////////////// -//class ShaderBag -//desciption: pure virtual class -// provides storage and usage interface of all the shaders for SIFT -// two implementations are ShaderBagPKSL and ShaderBagGLSL -///////////////////////////////////////////////////////////////////////////////// -class ShaderBag -{ -public: - //shader: rgb to gray - ProgramGPU * s_gray; - //shader: copy keypoint to PBO - ProgramGPU * s_copy_key; - //shader: debug view - ProgramGPU * s_debug; - //shader: orientation - //shader: assign simple orientation to keypoints if hardware is low - ProgramGPU * s_orientation; - //shader: display gaussian levels - ProgramGPU * s_display_gaussian; - //shader: display difference of gassian - ProgramGPU * s_display_dog; - //shader: display gradient - ProgramGPU * s_display_grad; - //shader: display keypoints as red(maximum) and blue (minimum) - ProgramGPU * s_display_keys; - //shader: up/down-sample - ProgramGPU * s_sampling; - //shader: compute gradient/dog - ProgramGPU * s_grad_pass; - ProgramGPU * s_dog_pass; - //shader: keypoint detection in one pass - ProgramGPU * s_keypoint; - ProgramGPU * s_seperate_sp; - //shader: feature list generations.. - ProgramGPU * s_genlist_init_tight; - ProgramGPU * s_genlist_init_ex; - ProgramGPU * s_genlist_histo; - ProgramGPU * s_genlist_start; - ProgramGPU * s_genlist_step; - ProgramGPU * s_genlist_end; - ProgramGPU * s_zero_pass; - //shader: generate vertex to display SIFT as a square - ProgramGPU * s_vertex_list; - //shader: descriptor - ProgramGPU * s_descriptor_fp; - //shader: copy pixels to margin - ProgramGPU * s_margin_copy; -public: - FilterProgram * f_gaussian_skip0; - vector f_gaussian_skip0_v; - FilterProgram * f_gaussian_skip1; - FilterProgram ** f_gaussian_step; - int _gaussian_step_num; -public: - virtual void SetGenListInitParam(int w, int h){}; - virtual void SetGenListEndParam(int ktex){}; - virtual void SetMarginCopyParam(int xmax, int ymax){}; - virtual void LoadDescriptorShader(){}; - virtual void SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma){}; - virtual void SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int stex, float step){}; - virtual void SetSimpleOrientationInput(int oTex, float sigma, float sigma_step){}; - virtual void LoadOrientationShader() =0; - virtual void SetGenListStartParam(float width, int tex0) =0; - virtual void LoadGenListShader(int ndoglev, int nlev)=0; - virtual void UnloadProgram()=0; - virtual void LoadKeypointShader(float threshold, float edgeTrheshold) = 0; - virtual void LoadFixedShaders()=0; - virtual void LoadDisplayShaders() = 0; - virtual void SetDogTexParam(int texU, int texD)=0; - virtual void SetGradPassParam(int texP=0){} - virtual void SetGenListStepParam(int tex, int tex0) = 0; - virtual void SetGenVBOParam( float width, float fwidth, float size)=0; -public: - void CreateGaussianFilters(SiftParam¶m); - void SelectInitialSmoothingFilter(int octave_min, SiftParam¶m); - void LoadDynamicShaders(SiftParam& param); - ShaderBag(); - virtual ~ShaderBag(); -}; - - -class ShaderBagGLSL:public ShaderBag -{ - GLint _param_dog_texu; - GLint _param_dog_texd; - GLint _param_ftex_width; - GLint _param_genlist_start_tex0; - GLint _param_genlist_step_tex0; - GLint _param_genvbo_size; - GLint _param_orientation_gtex; - GLint _param_orientation_size; - GLint _param_orientation_stex; - GLint _param_margin_copy_truncate; - GLint _param_genlist_init_bbox; - GLint _param_descriptor_gtex; - GLint _param_descriptor_size; - GLint _param_descriptor_dsize; -public: - virtual void SetMarginCopyParam(int xmax, int ymax); - void SetSimpleOrientationInput(int oTex, float sigma, float sigma_step); - void LoadOrientationShader(); - void LoadDescriptorShaderF2(); - virtual void LoadDescriptorShader(); - virtual void SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int stex = 0, float step = 1.0f); - virtual void SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma); - static void WriteOrientationCodeToStream(ostream& out); - static ProgramGLSL* LoadGenListStepShader(int start, int step); - virtual void SetGenListInitParam(int w, int h); - virtual void SetGenListStartParam(float width, int tex0); - virtual void LoadGenListShader(int ndoglev, int nlev); - virtual void UnloadProgram(); - virtual void LoadKeypointShader(float threshold, float edgeTrheshold); - virtual void LoadFixedShaders(); - virtual void LoadDisplayShaders(); - virtual void SetDogTexParam(int texU, int texD); - virtual void SetGenListStepParam(int tex, int tex0); - virtual void SetGenVBOParam( float width, float fwidth, float size); - virtual ~ShaderBagGLSL(){} -}; - - -class ShaderBagPKSL:public ShaderBag -{ -private: - GLint _param_dog_texu; - GLint _param_dog_texd; - GLint _param_dog_texi; - GLint _param_margin_copy_truncate; - GLint _param_grad_pass_texp; - GLint _param_genlist_init_bbox; - GLint _param_genlist_start_tex0; - GLint _param_ftex_width; - GLint _param_genlist_step_tex0; - GLint _param_genlist_end_ktex; - GLint _param_genvbo_size; - GLint _param_orientation_gtex; - GLint _param_orientation_otex; - GLint _param_orientation_size; - GLint _param_descriptor_gtex; - GLint _param_descriptor_otex; - GLint _param_descriptor_size; - GLint _param_descriptor_dsize; - - // - ProgramGLSL* s_rect_description; -public: - ShaderBagPKSL () {s_rect_description = NULL; } - virtual ~ShaderBagPKSL() {if(s_rect_description) delete s_rect_description; } - virtual void LoadFixedShaders(); - virtual void LoadDisplayShaders(); - virtual void LoadOrientationShader() ; - virtual void SetGenListStartParam(float width, int tex0) ; - virtual void LoadGenListShader(int ndoglev, int nlev); - virtual void UnloadProgram(); - virtual void LoadKeypointShader(float threshold, float edgeTrheshold) ; - virtual void LoadDescriptorShader(); - virtual void LoadDescriptorShaderF2(); - static ProgramGLSL* LoadDescriptorProgramRECT(); - static ProgramGLSL* LoadDescriptorProgramPKSL(); -///////////////// - virtual void SetDogTexParam(int texU, int texD); - virtual void SetGradPassParam(int texP); - virtual void SetGenListStepParam(int tex, int tex0); - virtual void SetGenVBOParam( float width, float fwidth, float size); - virtual void SetFeatureDescirptorParam(int gtex, int otex, float dwidth, float fwidth, float width, float height, float sigma); - virtual void SetFeatureOrientationParam(int gtex, int width, int height, float sigma, int stex, float step); - virtual void SetSimpleOrientationInput(int oTex, float sigma, float sigma_step); - virtual void SetGenListEndParam(int ktex); - virtual void SetGenListInitParam(int w, int h); - virtual void SetMarginCopyParam(int xmax, int ymax); -}; - - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramGPU.cpp b/3rdparty/SiftGPU/src/SiftGPU/ProgramGPU.cpp deleted file mode 100644 index c5a03ec8..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramGPU.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ProgramGPU.cpp -// Author: Changchang Wu -// Description : Implementation of ProgramGPU and FilterProgram -// This part is independent of GPU language -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include "GL/glew.h" -#include -#include -#include -using namespace std; - -#include "GlobalUtil.h" -#include "GLTexImage.h" -#include "ShaderMan.h" -#include "ProgramGPU.h" -#include "ProgramGLSL.h" -#include "SiftGPU.h" - diff --git a/3rdparty/SiftGPU/src/SiftGPU/ProgramGPU.h b/3rdparty/SiftGPU/src/SiftGPU/ProgramGPU.h deleted file mode 100644 index 203e52db..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ProgramGPU.h +++ /dev/null @@ -1,59 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ProgramGPU.h -// Author: Changchang Wu -// Description : Based class for GPU programs -// ProgramGPU: base class of ProgramGLSL -// FilterProgram: base class of FilterGLSL, FilterPKSL -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#ifndef _PROGRAM_GPU_H -#define _PROGRAM_GPU_H - -//////////////////////////////////////////////////////////////////////////// -//class ProgramGPU -//description: pure virtual class -// provides a common interface for shader programs -/////////////////////////////////////////////////////////////////////////// -class ProgramGPU -{ -public: - //use a gpu program - virtual int UseProgram() = 0; - virtual void* GetProgramID() = 0; - //not used - virtual ~ProgramGPU(){}; -}; - -/////////////////////////////////////////////////////////////////////////// -//class FilterProgram -/////////////////////////////////////////////////////////////////////////// -class FilterProgram -{ -public: - ProgramGPU* s_shader_h; - ProgramGPU* s_shader_v; - int _size; - int _id; -public: - FilterProgram() { s_shader_h = s_shader_v = NULL; _size = _id = 0; } - virtual ~FilterProgram() { if(s_shader_h) delete s_shader_h; if(s_shader_v) delete s_shader_v;} -}; - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/PyramidCL.cpp b/3rdparty/SiftGPU/src/SiftGPU/PyramidCL.cpp deleted file mode 100644 index 3d8d82ae..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/PyramidCL.cpp +++ /dev/null @@ -1,1132 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: PyramidCL.cpp -// Author: Changchang Wu -// Description : implementation of the PyramidCL class. -// OpenCL-based implementation of SiftPyramid -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if defined(CL_SIFTGPU_ENABLED) - - -#include "GL/glew.h" -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "GlobalUtil.h" -#include "GLTexImage.h" -#include "CLTexImage.h" -#include "SiftGPU.h" -#include "SiftPyramid.h" -#include "ProgramCL.h" -#include "PyramidCL.h" - - -#define USE_TIMING() double t, t0, tt; -#define OCTAVE_START() if(GlobalUtil::_timingO){ t = t0 = CLOCK(); cout<<"#"<FinishCL(); tt = CLOCK();cout<<(tt-t)<<"\t"; t = CLOCK();} -#define OCTAVE_FINISH() if(GlobalUtil::_timingO)cout<<"|\t"<<(CLOCK()-t0)<InitProgramBag(sp); - _inputTex = new CLTexImage( _OpenCL->GetContextCL(), - _OpenCL->GetCommandQueue()); - ///////////////////////// - InitializeContext(); -} - -PyramidCL::~PyramidCL() -{ - DestroyPerLevelData(); - DestroySharedData(); - DestroyPyramidData(); - if(_OpenCL) delete _OpenCL; - if(_inputTex) delete _inputTex; - if(_bufferTEX) delete _bufferTEX; -} - -void PyramidCL::InitializeContext() -{ - GlobalUtil::InitGLParam(1); -} - -void PyramidCL::InitPyramid(int w, int h, int ds) -{ - int wp, hp, toobig = 0; - if(ds == 0) - { - _down_sample_factor = 0; - if(GlobalUtil::_octave_min_default>=0) - { - wp = w >> _octave_min_default; - hp = h >> _octave_min_default; - }else - { - //can't upsample by more than 8 - _octave_min_default = max(-3, _octave_min_default); - // - wp = w << (-_octave_min_default); - hp = h << (-_octave_min_default); - } - _octave_min = _octave_min_default; - }else - { - //must use 0 as _octave_min; - _octave_min = 0; - _down_sample_factor = ds; - w >>= ds; - h >>= ds; - wp = w; - hp = h; - } - - while(wp > GlobalUtil::_texMaxDim || hp > GlobalUtil::_texMaxDim ) - { - _octave_min ++; - wp >>= 1; - hp >>= 1; - toobig = 1; - } - if(toobig && GlobalUtil::_verbose && _octave_min > 0) - { - std::cout<< "**************************************************************\n" - "Image larger than allowed dimension, data will be downsampled!\n" - "use -maxd to change the settings\n" - "***************************************************************\n"; - } - - if( wp == _pyramid_width && hp == _pyramid_height && _allocated ) - { - FitPyramid(wp, hp); - }else if(GlobalUtil::_ForceTightPyramid || _allocated ==0) - { - ResizePyramid(wp, hp); - } - else if( wp > _pyramid_width || hp > _pyramid_height ) - { - ResizePyramid(max(wp, _pyramid_width), max(hp, _pyramid_height)); - if(wp < _pyramid_width || hp < _pyramid_height) FitPyramid(wp, hp); - } - else - { - //try use the pyramid allocated for large image on small input images - FitPyramid(wp, hp); - } - - _OpenCL->SelectInitialSmoothingFilter(_octave_min + _down_sample_factor, param); -} - -void PyramidCL::ResizePyramid(int w, int h) -{ - // - unsigned int totalkb = 0; - int _octave_num_new, input_sz, i, j; - // - - if(_pyramid_width == w && _pyramid_height == h && _allocated) return; - - if(w > GlobalUtil::_texMaxDim || h > GlobalUtil::_texMaxDim) return ; - - if(GlobalUtil::_verbose && GlobalUtil::_timingS) std::cout<<"[Allocate Pyramid]:\t" <0) - { - DestroyPerLevelData(); - DestroyPyramidData(); - } - _pyramid_octave_num = _octave_num_new; - } - - _octave_num = _pyramid_octave_num; - - int noct = _octave_num; - int nlev = param._level_num; - int texNum = noct* nlev * DATA_NUM; - - // //initialize the pyramid - if(_allPyramid==NULL) - { - _allPyramid = new CLTexImage[ texNum]; - cl_context context = _OpenCL->GetContextCL(); - cl_command_queue queue = _OpenCL->GetCommandQueue(); - for(i = 0; i < texNum; ++i) _allPyramid[i].SetContext(context, queue); - } - - - - CLTexImage * gus = GetBaseLevel(_octave_min, DATA_GAUSSIAN); - CLTexImage * dog = GetBaseLevel(_octave_min, DATA_DOG); - CLTexImage * grd = GetBaseLevel(_octave_min, DATA_GRAD); - CLTexImage * rot = GetBaseLevel(_octave_min, DATA_ROT); - CLTexImage * key = GetBaseLevel(_octave_min, DATA_KEYPOINT); - - ////////////there could be "out of memory" happening during the allocation - - - - for(i = 0; i< noct; i++) - { - for( j = 0; j< nlev; j++, gus++, dog++, grd++, rot++, key++) - { - gus->InitPackedTex(w, h, GlobalUtil::_usePackedTex); - if(j==0)continue; - dog->InitPackedTex(w, h, GlobalUtil::_usePackedTex); - if(j < 1 + param._dog_level_num) - { - grd->InitPackedTex(w, h, GlobalUtil::_usePackedTex); - rot->InitPackedTex(w, h, GlobalUtil::_usePackedTex); - } - if(j > 1 && j < nlev -1) key->InitPackedTex(w, h, GlobalUtil::_usePackedTex); - } - //////////////////////////////////////// - int tsz = (gus -1)->GetTexPixelCount() * 16; - totalkb += ((nlev *5 -6)* tsz / 1024); - //several auxilary textures are not actually required - w>>=1; - h>>=1; - } - - totalkb += ResizeFeatureStorage(); - - _allocated = 1; - - if(GlobalUtil::_verbose && GlobalUtil::_timingS) std::cout<<"[Allocate Pyramid]:\t" <<(totalkb/1024)<<"MB\n"; - -} - -void PyramidCL::FitPyramid(int w, int h) -{ - _pyramid_octave_first = 0; - // - _octave_num = GlobalUtil::_octave_num_default; - - int _octave_num_max = GetRequiredOctaveNum(min(w, h)); - - if(_octave_num < 1 || _octave_num > _octave_num_max) - { - _octave_num = _octave_num_max; - } - - - int pw = _pyramid_width>>1, ph = _pyramid_height>>1; - while(_pyramid_octave_first + _octave_num < _pyramid_octave_num && - pw >= w && ph >= h) - { - _pyramid_octave_first++; - pw >>= 1; - ph >>= 1; - } - - ////////////////// - for(int i = 0; i < _octave_num; i++) - { - CLTexImage * tex = GetBaseLevel(i + _octave_min); - CLTexImage * dog = GetBaseLevel(i + _octave_min, DATA_DOG); - CLTexImage * grd = GetBaseLevel(i + _octave_min, DATA_GRAD); - CLTexImage * rot = GetBaseLevel(i + _octave_min, DATA_ROT); - CLTexImage * key = GetBaseLevel(i + _octave_min, DATA_KEYPOINT); - for(int j = param._level_min; j <= param._level_max; j++, tex++, dog++, grd++, rot++, key++) - { - tex->SetPackedSize(w, h, GlobalUtil::_usePackedTex); - if(j == param._level_min) continue; - dog->SetPackedSize(w, h, GlobalUtil::_usePackedTex); - if(j < param._level_max - 1) - { - grd->SetPackedSize(w, h, GlobalUtil::_usePackedTex); - rot->SetPackedSize(w, h, GlobalUtil::_usePackedTex); - } - if(j > param._level_min + 1 && j < param._level_max) key->SetPackedSize(w, h, GlobalUtil::_usePackedTex); - } - w>>=1; - h>>=1; - } -} - - -void PyramidCL::SetLevelFeatureNum(int idx, int fcount) -{ - _featureTex[idx].InitBufferTex(fcount, 1, 4); - _levelFeatureNum[idx] = fcount; -} - -int PyramidCL::ResizeFeatureStorage() -{ - int totalkb = 0; - if(_levelFeatureNum==NULL) _levelFeatureNum = new int[_octave_num * param._dog_level_num]; - std::fill(_levelFeatureNum, _levelFeatureNum+_octave_num * param._dog_level_num, 0); - - cl_context context = _OpenCL->GetContextCL(); - cl_command_queue queue = _OpenCL->GetCommandQueue(); - int wmax = GetBaseLevel(_octave_min)->GetImgWidth() * 2; - int hmax = GetBaseLevel(_octave_min)->GetImgHeight() * 2; - int whmax = max(wmax, hmax); - int w, i; - - // - int num = (int)ceil(log(double(whmax))/log(4.0)); - - if( _hpLevelNum != num) - { - _hpLevelNum = num; - if(_histoPyramidTex ) delete [] _histoPyramidTex; - _histoPyramidTex = new CLTexImage[_hpLevelNum]; - for(i = 0; i < _hpLevelNum; ++i) _histoPyramidTex[i].SetContext(context, queue); - } - - for(i = 0, w = 1; i < _hpLevelNum; i++) - { - _histoPyramidTex[i].InitBufferTex(w, whmax, 4); - w<<=2; - } - - // (4 ^ (_hpLevelNum) -1 / 3) pixels - totalkb += (((1 << (2 * _hpLevelNum)) -1) / 3 * 16 / 1024); - - //initialize the feature texture - int idx = 0, n = _octave_num * param._dog_level_num; - if(_featureTex==NULL) - { - _featureTex = new CLTexImage[n]; - for(i = 0; i 1 && GlobalUtil::_OrientationPack2==0 && _orientationTex== NULL) - { - _orientationTex = new CLTexImage[n]; - for(i = 0; i < n; ++i) _orientationTex[i].SetContext(context, queue); - } - - - for(i = 0; i < _octave_num; i++) - { - CLTexImage * tex = GetBaseLevel(i+_octave_min); - int fmax = int(4 * tex->GetTexWidth() * tex->GetTexHeight()*GlobalUtil::_MaxFeaturePercent); - // - if(fmax > GlobalUtil::_MaxLevelFeatureNum) fmax = GlobalUtil::_MaxLevelFeatureNum; - else if(fmax < 32) fmax = 32; //give it at least a space of 32 feature - - for(int j = 0; j < param._dog_level_num; j++, idx++) - { - _featureTex[idx].InitBufferTex(fmax, 1, 4); - totalkb += fmax * 16 /1024; - // - if(GlobalUtil::_MaxOrientation>1 && GlobalUtil::_OrientationPack2 == 0) - { - _orientationTex[idx].InitBufferTex(fmax, 1, 4); - totalkb += fmax * 16 /1024; - } - } - } - - //this just need be initialized once - if(_descriptorTex==NULL) - { - //initialize feature texture pyramid - int fmax = _featureTex->GetImgWidth(); - _descriptorTex = new CLTexImage(context, queue); - totalkb += ( fmax /2); - _descriptorTex->InitBufferTex(fmax *128, 1, 1); - }else - { - totalkb += _descriptorTex->GetDataSize()/1024; - } - return totalkb; -} - -void PyramidCL::GetFeatureDescriptors() -{ - //descriptors... - /*float* pd = &_descriptor_buffer[0]; - vector descriptor_buffer2; - - //use another buffer if we need to re-order the descriptors - if(_keypoint_index.size() > 0) - { - descriptor_buffer2.resize(_descriptor_buffer.size()); - pd = &descriptor_buffer2[0]; - } - - CLTexImage * got, * ftex= _featureTex; - for(int i = 0, idx = 0; i < _octave_num; i++) - { - got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1; - for(int j = 0; j < param._dog_level_num; j++, ftex++, idx++, got++) - { - if(_levelFeatureNum[idx]==0) continue; - ProgramCL::ComputeDescriptor(ftex, got, _descriptorTex);//process - _descriptorTex->CopyToHost(pd); //readback descriptor - pd += 128*_levelFeatureNum[idx]; - } - } - - if(GlobalUtil::_timingS) _OpenCL->FinishCL(); - - if(_keypoint_index.size() > 0) - { - //put the descriptor back to the original order for keypoint list. - for(int i = 0; i < _featureNum; ++i) - { - int index = _keypoint_index[i]; - memcpy(&_descriptor_buffer[index*128], &descriptor_buffer2[i*128], 128 * sizeof(float)); - } - }*/ -} - -void PyramidCL::GenerateFeatureListTex() -{ - - vector list; - int idx = 0; - const double twopi = 2.0*3.14159265358979323846; - float sigma_half_step = powf(2.0f, 0.5f / param._dog_level_num); - float octave_sigma = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; - if(_down_sample_factor>0) octave_sigma *= float(1<<_down_sample_factor); - - _keypoint_index.resize(0); // should already be 0 - for(int i = 0; i < _octave_num; i++, octave_sigma*= 2.0f) - { - for(int j = 0; j < param._dog_level_num; j++, idx++) - { - list.resize(0); - float level_sigma = param.GetLevelSigma(j + param._level_min + 1) * octave_sigma; - float sigma_min = level_sigma / sigma_half_step; - float sigma_max = level_sigma * sigma_half_step; - int fcount = 0 ; - for(int k = 0; k < _featureNum; k++) - { - float * key = &_keypoint_buffer[k*4]; - if( (key[2] >= sigma_min && key[2] < sigma_max) - ||(key[2] < sigma_min && i ==0 && j == 0) - ||(key[2] > sigma_max && i == _octave_num -1 && j == param._dog_level_num - 1)) - { - //add this keypoint to the list - list.push_back((key[0] - offset) / octave_sigma + 0.5f); - list.push_back((key[1] - offset) / octave_sigma + 0.5f); - list.push_back(key[2] / octave_sigma); - list.push_back((float)fmod(twopi-key[3], twopi)); - fcount ++; - //save the index of keypoints - _keypoint_index.push_back(k); - } - - } - - _levelFeatureNum[idx] = fcount; - if(fcount==0)continue; - CLTexImage * ftex = _featureTex+idx; - - SetLevelFeatureNum(idx, fcount); - ftex->CopyFromHost(&list[0]); - } - } - - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - } - -} - -void PyramidCL::ReshapeFeatureListCPU() -{ - int i, szmax =0, sz; - int n = param._dog_level_num*_octave_num; - for( i = 0; i < n; i++) - { - sz = _levelFeatureNum[i]; - if(sz > szmax ) szmax = sz; - } - float * buffer = new float[szmax*16]; - float * buffer1 = buffer; - float * buffer2 = buffer + szmax*4; - - - - _featureNum = 0; - -#ifdef NO_DUPLICATE_DOWNLOAD - const double twopi = 2.0*3.14159265358979323846; - _keypoint_buffer.resize(0); - float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - if(_down_sample_factor>0) os *= float(1<<_down_sample_factor); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; -#endif - - - for(i = 0; i < n; i++) - { - if(_levelFeatureNum[i]==0)continue; - - _featureTex[i].CopyToHost(buffer1); - - int fcount =0; - float * src = buffer1; - float * des = buffer2; - const static double factor = 2.0*3.14159265358979323846/65535.0; - for(int j = 0; j < _levelFeatureNum[i]; j++, src+=4) - { - unsigned short * orientations = (unsigned short*) (&src[3]); - if(orientations[0] != 65535) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = src[2]; - des[3] = float( factor* orientations[0]); - fcount++; - des += 4; - if(orientations[1] != 65535 && orientations[1] != orientations[0]) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = src[2]; - des[3] = float(factor* orientations[1]); - fcount++; - des += 4; - } - } - } - //texture size - SetLevelFeatureNum(i, fcount); - _featureTex[i].CopyFromHost(buffer2); - - if(fcount == 0) continue; - -#ifdef NO_DUPLICATE_DOWNLOAD - float oss = os * (1 << (i / param._dog_level_num)); - _keypoint_buffer.resize((_featureNum + fcount) * 4); - float* ds = &_keypoint_buffer[_featureNum * 4]; - float* fs = buffer2; - for(int k = 0; k < fcount; k++, ds+=4, fs+=4) - { - ds[0] = oss*(fs[0]-0.5f) + offset; //x - ds[1] = oss*(fs[1]-0.5f) + offset; //y - ds[2] = oss*fs[2]; //scale - ds[3] = (float)fmod(twopi-fs[3], twopi); //orientation, mirrored - } -#endif - _featureNum += fcount; - } - delete[] buffer; - if(GlobalUtil::_verbose) - { - std::cout<<"#Features MO:\t"<<_featureNum<DisplayKeyBox(ftex, &texPBO1); - _OpenCL->DisplayKeyPoint(ftex, &texPBO2); - }*/ -} - -void PyramidCL::DestroySharedData() -{ - //histogram reduction - if(_histoPyramidTex) - { - delete[] _histoPyramidTex; - _hpLevelNum = 0; - _histoPyramidTex = NULL; - } - //descriptor storage shared by all levels - if(_descriptorTex) - { - delete _descriptorTex; - _descriptorTex = NULL; - } - //cpu reduction buffer. - if(_histo_buffer) - { - delete[] _histo_buffer; - _histo_buffer = 0; - } -} - -void PyramidCL::DestroyPerLevelData() -{ - //integers vector to store the feature numbers. - if(_levelFeatureNum) - { - delete [] _levelFeatureNum; - _levelFeatureNum = NULL; - } - //texture used to store features - if( _featureTex) - { - delete [] _featureTex; - _featureTex = NULL; - } - //texture used for multi-orientation - if(_orientationTex) - { - delete [] _orientationTex; - _orientationTex = NULL; - } - int no = _octave_num* param._dog_level_num; - - //two sets of vbos used to display the features - if(_featureDisplayVBO) - { - glDeleteBuffers(no, _featureDisplayVBO); - delete [] _featureDisplayVBO; - _featureDisplayVBO = NULL; - } - if( _featurePointVBO) - { - glDeleteBuffers(no, _featurePointVBO); - delete [] _featurePointVBO; - _featurePointVBO = NULL; - } -} - -void PyramidCL::DestroyPyramidData() -{ - if(_allPyramid) - { - delete [] _allPyramid; - _allPyramid = NULL; - } -} - -void PyramidCL::DownloadKeypoints() -{ - const double twopi = 2.0*3.14159265358979323846; - int idx = 0; - float * buffer = &_keypoint_buffer[0]; - vector keypoint_buffer2; - //use a different keypoint buffer when processing with an exisint features list - //without orientation information. - if(_keypoint_index.size() > 0) - { - keypoint_buffer2.resize(_keypoint_buffer.size()); - buffer = &keypoint_buffer2[0]; - } - float * p = buffer, *ps; - CLTexImage * ftex = _featureTex; - ///////////////////// - float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - if(_down_sample_factor>0) os *= float(1<<_down_sample_factor); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; - ///////////////////// - for(int i = 0; i < _octave_num; i++, os *= 2.0f) - { - - for(int j = 0; j < param._dog_level_num; j++, idx++, ftex++) - { - - if(_levelFeatureNum[idx]>0) - { - ftex->CopyToHost(ps = p); - for(int k = 0; k < _levelFeatureNum[idx]; k++, ps+=4) - { - ps[0] = os*(ps[0]-0.5f) + offset; //x - ps[1] = os*(ps[1]-0.5f) + offset; //y - ps[2] = os*ps[2]; - ps[3] = (float)fmod(twopi-ps[3], twopi); //orientation, mirrored - } - p+= 4* _levelFeatureNum[idx]; - } - } - } - - //put the feature into their original order for existing keypoint - if(_keypoint_index.size() > 0) - { - for(int i = 0; i < _featureNum; ++i) - { - int index = _keypoint_index[i]; - memcpy(&_keypoint_buffer[index*4], &keypoint_buffer2[i*4], 4 * sizeof(float)); - } - } -} - -void PyramidCL::GenerateFeatureListCPU() -{ - //no cpu version provided - GenerateFeatureList(); -} - -void PyramidCL::GenerateFeatureList(int i, int j, int reduction_count, vector& hbuffer) -{ - /*int fcount = 0, idx = i * param._dog_level_num + j; - int hist_level_num = _hpLevelNum - _pyramid_octave_first /2; - int ii, k, len; - - CLTexImage * htex, * ftex, * tex, *got; - ftex = _featureTex + idx; - htex = _histoPyramidTex + hist_level_num -1; - tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2 + j; - got = GetBaseLevel(_octave_min + i, DATA_GRAD) + 2 + j; - - _OpenCL->InitHistogram(tex, htex); - - for(k = 0; k < reduction_count - 1; k++, htex--) - { - ProgramCL::ReduceHistogram(htex, htex -1); - } - - //htex has the row reduction result - len = htex->GetImgHeight() * 4; - hbuffer.resize(len); - _OpenCL->FinishCL(); - htex->CopyToHost(&hbuffer[0]); - // - for(ii = 0; ii < len; ++ii) fcount += hbuffer[ii]; - SetLevelFeatureNum(idx, fcount); - - //build the feature list - if(fcount > 0) - { - _featureNum += fcount; - _keypoint_buffer.resize(fcount * 4); - //vector ikbuf(fcount*4); - int* ibuf = (int*) (&_keypoint_buffer[0]); - - for(ii = 0; ii < len; ++ii) - { - int x = ii%4, y = ii / 4; - for(int jj = 0 ; jj < hbuffer[ii]; ++jj, ibuf+=4) - { - ibuf[0] = x; ibuf[1] = y; ibuf[2] = jj; ibuf[3] = 0; - } - } - _featureTex[idx].CopyFromHost(&_keypoint_buffer[0]); - - //////////////////////////////////////////// - ProgramCL::GenerateList(_featureTex + idx, ++htex); - for(k = 2; k < reduction_count; k++) - { - ProgramCL::GenerateList(_featureTex + idx, ++htex); - } - }*/ -} - -void PyramidCL::GenerateFeatureList() -{ - /*double t1, t2; - int ocount = 0, reduction_count; - int reverse = (GlobalUtil::_TruncateMethod == 1); - - vector hbuffer; - _featureNum = 0; - - //for(int i = 0, idx = 0; i < _octave_num; i++) - FOR_EACH_OCTAVE(i, reverse) - { - CLTexImage* tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2; - reduction_count = FitHistogramPyramid(tex); - - if(GlobalUtil::_timingO) - { - t1 = CLOCK(); - ocount = 0; - std::cout<<"#"< 0 && _featureNum > GlobalUtil::_FeatureCountThreshold) continue; - - GenerateFeatureList(i, j, reduction_count, hbuffer); - - ///////////////////////////// - if(GlobalUtil::_timingO) - { - int idx = i * param._dog_level_num + j; - ocount += _levelFeatureNum[idx]; - std::cout<< _levelFeatureNum[idx] <<"\t"; - } - } - if(GlobalUtil::_timingO) - { - t2 = CLOCK(); - std::cout << "| \t" << int(ocount) << " :\t(" << (t2 - t1) << ")\n"; - } - } - ///// - CopyGradientTex(); - ///// - if(GlobalUtil::_timingS)_OpenCL->FinishCL(); - - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - }*/ -} - -GLTexImage* PyramidCL::GetLevelTexture(int octave, int level) -{ - return GetLevelTexture(octave, level, DATA_GAUSSIAN); -} - -GLTexImage* PyramidCL::ConvertTexCL2GL(CLTexImage* tex, int dataName) -{ - - if(_bufferTEX == NULL) _bufferTEX = new GLTexImage; - - /////////////////////////////////////////// - int ratio = GlobalUtil::_usePackedTex ? 2 : 1; - int width = tex->GetImgWidth() * ratio; - int height = tex->GetImgHeight() * ratio; - int tw = max(width, _bufferTEX->GetTexWidth()); - int th = max(height, _bufferTEX->GetTexHeight()); - _bufferTEX->InitTexture(tw, th, 1, GL_RGBA); - _bufferTEX->SetImageSize(width, height); - - ////////////////////////////////// - CLTexImage texCL(_OpenCL->GetContextCL(), _OpenCL->GetCommandQueue()); - texCL.InitTextureGL(*_bufferTEX, width, height, 4); - - switch(dataName) - { - case DATA_GAUSSIAN: _OpenCL->UnpackImage(tex, &texCL); break; - case DATA_DOG:_OpenCL->UnpackImageDOG(tex, &texCL); break; - case DATA_GRAD:_OpenCL->UnpackImageGRD(tex, &texCL); break; - case DATA_KEYPOINT:_OpenCL->UnpackImageKEY(tex, - tex - param._level_num * _pyramid_octave_num, &texCL);break; - default: - break; - } - - - return _bufferTEX; -} - -GLTexImage* PyramidCL::GetLevelTexture(int octave, int level, int dataName) -{ - CLTexImage* tex = GetBaseLevel(octave, dataName) + (level - param._level_min); - return ConvertTexCL2GL(tex, dataName); -} - -void PyramidCL::ConvertInputToCL(GLTexInput* input, CLTexImage* output) -{ - int ws = input->GetImgWidth(), hs = input->GetImgHeight(); - //copy the input image to pixel buffer object - if(input->_pixel_data) - { - output->InitTexture(ws, hs, 1); - output->CopyFromHost(input->_pixel_data); - }else /*if(input->_rgb_converted && input->CopyToPBO(_bufferPBO, ws, hs, GL_LUMINANCE)) - { - output->InitTexture(ws, hs, 1); - output->CopyFromPBO(ws, hs, _bufferPBO); - }else if(input->CopyToPBO(_bufferPBO, ws, hs)) - { - CLTexImage texPBO(ws, hs, 4, _bufferPBO); - output->InitTexture(ws, hs, 1); - ProgramCL::ReduceToSingleChannel(output, &texPBO, !input->_rgb_converted); - }else*/ - { - std::cerr<< "Unable To Convert Intput\n"; - } -} - -void PyramidCL::BuildPyramid(GLTexInput * input) -{ - - USE_TIMING(); - - int i, j; - - for ( i = _octave_min; i < _octave_min + _octave_num; i++) - { - - CLTexImage *tex = GetBaseLevel(i); - CLTexImage *buf = GetBaseLevel(i, DATA_DOG) +2; - FilterCL ** filter = _OpenCL->f_gaussian_step; - j = param._level_min + 1; - - OCTAVE_START(); - - if( i == _octave_min ) - { - if(GlobalUtil::_usePackedTex) - { - ConvertInputToCL(input, _inputTex); - if(i < 0) _OpenCL->SampleImageU(tex, _inputTex, -i- 1); - else _OpenCL->SampleImageD(tex, _inputTex, i + 1); - }else - { - if(i == 0) ConvertInputToCL(input, tex); - else - { - ConvertInputToCL(input, _inputTex); - if(i < 0) _OpenCL->SampleImageU(tex, _inputTex, -i); - else _OpenCL->SampleImageD(tex, _inputTex, i); - } - } - _OpenCL->FilterInitialImage(tex, buf); - }else - { - _OpenCL->SampleImageD(tex, GetBaseLevel(i - 1) + param._level_ds - param._level_min); - _OpenCL->FilterSampledImage(tex, buf); - } - LEVEL_FINISH(); - for( ; j <= param._level_max ; j++, tex++, filter++) - { - // filtering - _OpenCL->FilterImage(*filter, tex + 1, tex, buf); - LEVEL_FINISH(); - } - OCTAVE_FINISH(); - } - if(GlobalUtil::_timingS) _OpenCL->FinishCL(); -} - -void PyramidCL::DetectKeypointsEX() -{ - int i, j; - double t0, t, ts, t1, t2; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose) ts = CLOCK(); - - for(i = _octave_min; i < _octave_min + _octave_num; i++) - { - CLTexImage * gus = GetBaseLevel(i) + 1; - CLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1; - CLTexImage * grd = GetBaseLevel(i, DATA_GRAD) + 1; - CLTexImage * rot = GetBaseLevel(i, DATA_ROT) + 1; - //compute the gradient - for(j = param._level_min +1; j <= param._level_max ; j++, gus++, dog++, grd++, rot++) - { - //input: gus and gus -1 - //output: gradient, dog, orientation - _OpenCL->ComputeDOG(gus, gus - 1, dog, grd, rot); - } - } - if(GlobalUtil::_timingS && GlobalUtil::_verbose) - { - _OpenCL->FinishCL(); - t1 = CLOCK(); - } - //if(GlobalUtil::_timingS) _OpenCL->FinishCL(); - //if(!GlobalUtil::_usePackedTex) return; //not finished - //return; - - for ( i = _octave_min; i < _octave_min + _octave_num; i++) - { - if(GlobalUtil::_timingO) - { - t0 = CLOCK(); - std::cout<<"#"<<(i + _down_sample_factor)<<"\t"; - } - CLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 2; - CLTexImage * key = GetBaseLevel(i, DATA_KEYPOINT) +2; - - - for( j = param._level_min +2; j < param._level_max ; j++, dog++, key++) - { - if(GlobalUtil::_timingL)t = CLOCK(); - //input, dog, dog + 1, dog -1 - //output, key - _OpenCL->ComputeKEY(dog, key, param._dog_threshold, param._edge_threshold); - if(GlobalUtil::_timingL) - { - std::cout<<(CLOCK()-t)<<"\t"; - } - } - if(GlobalUtil::_timingO) - { - std::cout<<"|\t"<<(CLOCK()-t0)<<"\n"; - } - } - - if(GlobalUtil::_timingS) - { - _OpenCL->FinishCL(); - if(GlobalUtil::_verbose) - { - t2 = CLOCK(); - std::cout <<"\t"<<(t1-ts)<<"\n" - <<"\t"<<(t2-t1)<<"\n"; - } - } -} - -void PyramidCL::CopyGradientTex() -{ - /*double ts, t1; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - for(int i = 0, idx = 0; i < _octave_num; i++) - { - CLTexImage * got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1; - //compute the gradient - for(int j = 0; j < param._dog_level_num ; j++, got++, idx++) - { - if(_levelFeatureNum[idx] > 0) got->CopyToTexture2D(); - } - } - if(GlobalUtil::_timingS) - { - ProgramCL::FinishCLDA(); - if(GlobalUtil::_verbose) - { - t1 = CLOCK(); - std::cout <<"\t"<<(t1-ts)<<"\n"; - } - }*/ -} - -void PyramidCL::ComputeGradient() -{ - - /*int i, j; - double ts, t1; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - for(i = _octave_min; i < _octave_min + _octave_num; i++) - { - CLTexImage * gus = GetBaseLevel(i) + 1; - CLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1; - CLTexImage * got = GetBaseLevel(i, DATA_GRAD) + 1; - - //compute the gradient - for(j = 0; j < param._dog_level_num ; j++, gus++, dog++, got++) - { - ProgramCL::ComputeDOG(gus, dog, got); - } - } - if(GlobalUtil::_timingS) - { - ProgramCL::FinishCLDA(); - if(GlobalUtil::_verbose) - { - t1 = CLOCK(); - std::cout <<"\t"<<(t1-ts)<<"\n"; - } - }*/ -} - -int PyramidCL::FitHistogramPyramid(CLTexImage* tex) -{ - CLTexImage *htex; - int hist_level_num = _hpLevelNum - _pyramid_octave_first / 2; - htex = _histoPyramidTex + hist_level_num - 1; - int w = (tex->GetImgWidth() + 2) >> 2; - int h = tex->GetImgHeight(); - int count = 0; - for(int k = 0; k < hist_level_num; k++, htex--) - { - //htex->SetImageSize(w, h); - htex->InitTexture(w, h, 4); - ++count; - if(w == 1) - break; - w = (w + 3)>>2; - } - return count; -} - -void PyramidCL::GetFeatureOrientations() -{ - -/* - CLTexImage * ftex = _featureTex; - int * count = _levelFeatureNum; - float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num); - - for(int i = 0; i < _octave_num; i++) - { - CLTexImage* got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1; - CLTexImage* key = GetBaseLevel(i + _octave_min, DATA_KEYPOINT) + 2; - - for(int j = 0; j < param._dog_level_num; j++, ftex++, count++, got++, key++) - { - if(*count<=0)continue; - - //if(ftex->GetImgWidth() < *count) ftex->InitTexture(*count, 1, 4); - - sigma = param.GetLevelSigma(j+param._level_min+1); - - ProgramCL::ComputeOrientation(ftex, got, key, sigma, sigma_step, _existing_keypoints); - } - } - - if(GlobalUtil::_timingS)ProgramCL::FinishCL(); - */ - - -} - -void PyramidCL::GetSimplifiedOrientation() -{ - //no simplified orientation - GetFeatureOrientations(); -} - -CLTexImage* PyramidCL::GetBaseLevel(int octave, int dataName) -{ - if(octave <_octave_min || octave > _octave_min + _octave_num) return NULL; - int offset = (_pyramid_octave_first + octave - _octave_min) * param._level_num; - int num = param._level_num * _pyramid_octave_num; - return _allPyramid + num * dataName + offset; -} - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/PyramidCL.h b/3rdparty/SiftGPU/src/SiftGPU/PyramidCL.h deleted file mode 100644 index 1ff6b181..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/PyramidCL.h +++ /dev/null @@ -1,83 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: PyramidCL.h -// Author: Changchang Wu -// Description : interface for the PyramdCL -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - - -#ifndef _PYRAMID_CL_H -#define _PYRAMID_CL_H -#if defined(CL_SIFTGPU_ENABLED) - -class CLTexImage; -class SiftPyramid; -class ProgramBagCL; -class PyramidCL: public SiftPyramid -{ - CLTexImage* _inputTex; - CLTexImage* _allPyramid; - CLTexImage* _histoPyramidTex; - CLTexImage* _featureTex; - CLTexImage* _descriptorTex; - CLTexImage* _orientationTex; - ProgramBagCL* _OpenCL; - GLTexImage* _bufferTEX; -public: - virtual void GetFeatureDescriptors(); - virtual void GenerateFeatureListTex(); - virtual void ReshapeFeatureListCPU(); - virtual void GenerateFeatureDisplayVBO(); - virtual void DestroySharedData(); - virtual void DestroyPerLevelData(); - virtual void DestroyPyramidData(); - virtual void DownloadKeypoints(); - virtual void GenerateFeatureListCPU(); - virtual void GenerateFeatureList(); - virtual GLTexImage* GetLevelTexture(int octave, int level); - virtual GLTexImage* GetLevelTexture(int octave, int level, int dataName); - virtual void BuildPyramid(GLTexInput * input); - virtual void DetectKeypointsEX(); - virtual void ComputeGradient(); - virtual void GetFeatureOrientations(); - virtual void GetSimplifiedOrientation(); - virtual void InitPyramid(int w, int h, int ds = 0); - virtual void ResizePyramid(int w, int h); - - ////////// - void CopyGradientTex(); - void FitPyramid(int w, int h); - - void InitializeContext(); - int ResizeFeatureStorage(); - int FitHistogramPyramid(CLTexImage* tex); - void SetLevelFeatureNum(int idx, int fcount); - void ConvertInputToCL(GLTexInput* input, CLTexImage* output); - GLTexImage* ConvertTexCL2GL(CLTexImage* tex, int dataName); - CLTexImage* GetBaseLevel(int octave, int dataName = DATA_GAUSSIAN); -private: - void GenerateFeatureList(int i, int j, int reduction_count, vector& hbuffer); -public: - PyramidCL(SiftParam& sp); - virtual ~PyramidCL(); -}; - - -#endif -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/PyramidCU.cpp b/3rdparty/SiftGPU/src/SiftGPU/PyramidCU.cpp deleted file mode 100644 index 368b6fe6..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/PyramidCU.cpp +++ /dev/null @@ -1,1190 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: PyramidCU.cpp -// Author: Changchang Wu -// Description : implementation of the PyramidCU class. -// CUDA-based implementation of SiftPyramid -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if defined(CUDA_SIFTGPU_ENABLED) - - -#include "GL/glew.h" -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "GlobalUtil.h" -#include "GLTexImage.h" -#include "CuTexImage.h" -#include "SiftGPU.h" -#include "SiftPyramid.h" -#include "ProgramCU.h" -#include "PyramidCU.h" - - -//#include "imdebug/imdebuggl.h" -//#pragma comment (lib, "../lib/imdebug.lib") - - - -#define USE_TIMING() double t, t0, tt; -#define OCTAVE_START() if(GlobalUtil::_timingO){ t = t0 = CLOCK(); cout<<"#"<=0) - { - wp = w >> _octave_min_default; - hp = h >> _octave_min_default; - }else - { - //can't upsample by more than 8 - _octave_min_default = max(-3, _octave_min_default); - // - wp = w << (-_octave_min_default); - hp = h << (-_octave_min_default); - } - _octave_min = _octave_min_default; - }else - { - //must use 0 as _octave_min; - _octave_min = 0; - _down_sample_factor = ds; - w >>= ds; - h >>= ds; - ///// - - TruncateWidth(w); - - wp = w; - hp = h; - - } - - while(wp > GlobalUtil::_texMaxDim || hp > GlobalUtil::_texMaxDim ) - { - _octave_min ++; - wp >>= 1; - hp >>= 1; - toobig = 1; - } - - while(GlobalUtil::_MemCapGPU > 0 && GlobalUtil::_FitMemoryCap && (wp >_pyramid_width || hp > _pyramid_height)&& - max(max(wp, hp), max(_pyramid_width, _pyramid_height)) > 1024 * sqrt(GlobalUtil::_MemCapGPU / 110.0)) - { - _octave_min ++; - wp >>= 1; - hp >>= 1; - toobig = 2; - } - - - if(toobig && GlobalUtil::_verbose && _octave_min > 0) - { - std::cout<<(toobig == 2 ? "[**SKIP OCTAVES**]:\tExceeding Memory Cap (-nomc)\n" : - "[**SKIP OCTAVES**]:\tReaching the dimension limit(-maxd)!\n"); - } - //ResizePyramid(wp, hp); - if( wp == _pyramid_width && hp == _pyramid_height && _allocated ) - { - FitPyramid(wp, hp); - }else if(GlobalUtil::_ForceTightPyramid || _allocated ==0) - { - ResizePyramid(wp, hp); - } - else if( wp > _pyramid_width || hp > _pyramid_height ) - { - ResizePyramid(max(wp, _pyramid_width), max(hp, _pyramid_height)); - if(wp < _pyramid_width || hp < _pyramid_height) FitPyramid(wp, hp); - } - else - { - //try use the pyramid allocated for large image on small input images - FitPyramid(wp, hp); - } -} - -void PyramidCU::ResizePyramid(int w, int h) -{ - // - unsigned int totalkb = 0; - int _octave_num_new, input_sz, i, j; - // - - if(_pyramid_width == w && _pyramid_height == h && _allocated) return; - - if(w > GlobalUtil::_texMaxDim || h > GlobalUtil::_texMaxDim) return ; - - if(GlobalUtil::_verbose && GlobalUtil::_timingS) std::cout<<"[Allocate Pyramid]:\t" <0) - { - DestroyPerLevelData(); - DestroyPyramidData(); - } - _pyramid_octave_num = _octave_num_new; - } - - _octave_num = _pyramid_octave_num; - - int noct = _octave_num; - int nlev = param._level_num; - - // //initialize the pyramid - if(_allPyramid==NULL) _allPyramid = new CuTexImage[ noct* nlev * DATA_NUM]; - - CuTexImage * gus = GetBaseLevel(_octave_min, DATA_GAUSSIAN); - CuTexImage * dog = GetBaseLevel(_octave_min, DATA_DOG); - CuTexImage * got = GetBaseLevel(_octave_min, DATA_GRAD); - CuTexImage * key = GetBaseLevel(_octave_min, DATA_KEYPOINT); - - ////////////there could be "out of memory" happening during the allocation - - for(i = 0; i< noct; i++) - { - int wa = ((w + 3) / 4) * 4; - - totalkb += ((nlev *8 -19)* (wa * h) * 4 / 1024); - for( j = 0; j< nlev; j++, gus++, dog++, got++, key++) - { - gus->InitTexture(wa, h); //nlev - if(j==0)continue; - dog->InitTexture(wa, h); //nlev -1 - if( j >= 1 && j < 1 + param._dog_level_num) - { - got->InitTexture(wa, h, 2); //2 * nlev - 6 - got->InitTexture2D(); - } - if(j > 1 && j < nlev -1) key->InitTexture(wa, h, 4); // nlev -3 ; 4 * nlev - 12 - } - w>>=1; - h>>=1; - } - - totalkb += ResizeFeatureStorage(); - - if(ProgramCU::CheckErrorCUDA("ResizePyramid")) SetFailStatus(); - - _allocated = 1; - - if(GlobalUtil::_verbose && GlobalUtil::_timingS) std::cout<<"[Allocate Pyramid]:\t" <<(totalkb/1024)<<"MB\n"; - -} - -void PyramidCU::FitPyramid(int w, int h) -{ - _pyramid_octave_first = 0; - // - _octave_num = GlobalUtil::_octave_num_default; - - int _octave_num_max = max(1, (int) floor (log ( double(min(w, h)))/log(2.0)) -3 ); - - if(_octave_num < 1 || _octave_num > _octave_num_max) - { - _octave_num = _octave_num_max; - } - - - int pw = _pyramid_width>>1, ph = _pyramid_height>>1; - while(_pyramid_octave_first + _octave_num < _pyramid_octave_num && - pw >= w && ph >= h) - { - _pyramid_octave_first++; - pw >>= 1; - ph >>= 1; - } - - ////////////////// - int nlev = param._level_num; - CuTexImage * gus = GetBaseLevel(_octave_min, DATA_GAUSSIAN); - CuTexImage * dog = GetBaseLevel(_octave_min, DATA_DOG); - CuTexImage * got = GetBaseLevel(_octave_min, DATA_GRAD); - CuTexImage * key = GetBaseLevel(_octave_min, DATA_KEYPOINT); - for(int i = 0; i< _octave_num; i++) - { - int wa = ((w + 3) / 4) * 4; - - for(int j = 0; j< nlev; j++, gus++, dog++, got++, key++) - { - gus->InitTexture(wa, h); //nlev - if(j==0)continue; - dog->InitTexture(wa, h); //nlev -1 - if( j >= 1 && j < 1 + param._dog_level_num) - { - got->InitTexture(wa, h, 2); //2 * nlev - 6 - got->InitTexture2D(); - } - if(j > 1 && j < nlev -1) key->InitTexture(wa, h, 4); // nlev -3 ; 4 * nlev - 12 - } - w>>=1; - h>>=1; - } -} - -int PyramidCU::CheckCudaDevice(int device) -{ - return ProgramCU::CheckCudaDevice(device); -} - -void PyramidCU::SetLevelFeatureNum(int idx, int fcount) -{ - _featureTex[idx].InitTexture(fcount, 1, 4); - _levelFeatureNum[idx] = fcount; -} - -int PyramidCU::ResizeFeatureStorage() -{ - int totalkb = 0; - if(_levelFeatureNum==NULL) _levelFeatureNum = new int[_octave_num * param._dog_level_num]; - std::fill(_levelFeatureNum, _levelFeatureNum+_octave_num * param._dog_level_num, 0); - - int wmax = GetBaseLevel(_octave_min)->GetImgWidth(); - int hmax = GetBaseLevel(_octave_min)->GetImgHeight(); - int whmax = max(wmax, hmax); - int w, i; - - // - int num = (int)ceil(log(double(whmax))/log(4.0)); - - if( _hpLevelNum != num) - { - _hpLevelNum = num; - if(_histoPyramidTex ) delete [] _histoPyramidTex; - _histoPyramidTex = new CuTexImage[_hpLevelNum]; - } - - for(i = 0, w = 1; i < _hpLevelNum; i++) - { - _histoPyramidTex[i].InitTexture(w, whmax, 4); - w<<=2; - } - - // (4 ^ (_hpLevelNum) -1 / 3) pixels - totalkb += (((1 << (2 * _hpLevelNum)) -1) / 3 * 16 / 1024); - - //initialize the feature texture - int idx = 0, n = _octave_num * param._dog_level_num; - if(_featureTex==NULL) _featureTex = new CuTexImage[n]; - if(GlobalUtil::_MaxOrientation >1 && GlobalUtil::_OrientationPack2==0 && _orientationTex== NULL) - _orientationTex = new CuTexImage[n]; - - - for(i = 0; i < _octave_num; i++) - { - CuTexImage * tex = GetBaseLevel(i+_octave_min); - int fmax = int(tex->GetImgWidth() * tex->GetImgHeight()*GlobalUtil::_MaxFeaturePercent); - // - if(fmax > GlobalUtil::_MaxLevelFeatureNum) fmax = GlobalUtil::_MaxLevelFeatureNum; - else if(fmax < 32) fmax = 32; //give it at least a space of 32 feature - - for(int j = 0; j < param._dog_level_num; j++, idx++) - { - _featureTex[idx].InitTexture(fmax, 1, 4); - totalkb += fmax * 16 /1024; - // - if(GlobalUtil::_MaxOrientation>1 && GlobalUtil::_OrientationPack2 == 0) - { - _orientationTex[idx].InitTexture(fmax, 1, 4); - totalkb += fmax * 16 /1024; - } - } - } - - - //this just need be initialized once - if(_descriptorTex==NULL) - { - //initialize feature texture pyramid - int fmax = _featureTex->GetImgWidth(); - _descriptorTex = new CuTexImage; - totalkb += ( fmax /2); - _descriptorTex->InitTexture(fmax *128, 1, 1); - }else - { - totalkb += _descriptorTex->GetDataSize()/1024; - } - return totalkb; -} - -void PyramidCU::GetFeatureDescriptors() -{ - //descriptors... - float* pd = &_descriptor_buffer[0]; - vector descriptor_buffer2; - - //use another buffer if we need to re-order the descriptors - if(_keypoint_index.size() > 0) - { - descriptor_buffer2.resize(_descriptor_buffer.size()); - pd = &descriptor_buffer2[0]; - } - - CuTexImage * got, * ftex= _featureTex; - for(int i = 0, idx = 0; i < _octave_num; i++) - { - got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1; - for(int j = 0; j < param._dog_level_num; j++, ftex++, idx++, got++) - { - if(_levelFeatureNum[idx]==0) continue; - ProgramCU::ComputeDescriptor(ftex, got, _descriptorTex, IsUsingRectDescription());//process - _descriptorTex->CopyToHost(pd); //readback descriptor - pd += 128*_levelFeatureNum[idx]; - } - } - - if(GlobalUtil::_timingS) ProgramCU::FinishCUDA(); - - if(_keypoint_index.size() > 0) - { - //put the descriptor back to the original order for keypoint list. - for(int i = 0; i < _featureNum; ++i) - { - int index = _keypoint_index[i]; - memcpy(&_descriptor_buffer[index*128], &descriptor_buffer2[i*128], 128 * sizeof(float)); - } - } - - if(ProgramCU::CheckErrorCUDA("PyramidCU::GetFeatureDescriptors")) SetFailStatus(); -} - -void PyramidCU::GenerateFeatureListTex() -{ - - vector list; - int idx = 0; - const double twopi = 2.0*3.14159265358979323846; - float sigma_half_step = powf(2.0f, 0.5f / param._dog_level_num); - float octave_sigma = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; - if(_down_sample_factor>0) octave_sigma *= float(1<<_down_sample_factor); - - _keypoint_index.resize(0); // should already be 0 - for(int i = 0; i < _octave_num; i++, octave_sigma*= 2.0f) - { - for(int j = 0; j < param._dog_level_num; j++, idx++) - { - list.resize(0); - float level_sigma = param.GetLevelSigma(j + param._level_min + 1) * octave_sigma; - float sigma_min = level_sigma / sigma_half_step; - float sigma_max = level_sigma * sigma_half_step; - int fcount = 0 ; - for(int k = 0; k < _featureNum; k++) - { - float * key = &_keypoint_buffer[k*4]; - float sigmak = key[2]; - ////////////////////////////////////// - if(IsUsingRectDescription()) sigmak = min(key[2], key[3]) / 12.0f; - - if( (sigmak >= sigma_min && sigmak < sigma_max) - ||(sigmak < sigma_min && i ==0 && j == 0) - ||(sigmak > sigma_max && i == _octave_num -1 && j == param._dog_level_num - 1)) - { - //add this keypoint to the list - list.push_back((key[0] - offset) / octave_sigma + 0.5f); - list.push_back((key[1] - offset) / octave_sigma + 0.5f); - if(IsUsingRectDescription()) - { - list.push_back(key[2] / octave_sigma); - list.push_back(key[3] / octave_sigma); - }else - { - list.push_back(key[2] / octave_sigma); - list.push_back((float)fmod(twopi-key[3], twopi)); - } - fcount ++; - //save the index of keypoints - _keypoint_index.push_back(k); - } - - } - - _levelFeatureNum[idx] = fcount; - if(fcount==0)continue; - CuTexImage * ftex = _featureTex+idx; - - SetLevelFeatureNum(idx, fcount); - ftex->CopyFromHost(&list[0]); - } - } - - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - } - -} - -void PyramidCU::ReshapeFeatureListCPU() -{ - int i, szmax =0, sz; - int n = param._dog_level_num*_octave_num; - for( i = 0; i < n; i++) - { - sz = _levelFeatureNum[i]; - if(sz > szmax ) szmax = sz; - } - float * buffer = new float[szmax*16]; - float * buffer1 = buffer; - float * buffer2 = buffer + szmax*4; - - - - _featureNum = 0; - -#ifdef NO_DUPLICATE_DOWNLOAD - const double twopi = 2.0*3.14159265358979323846; - _keypoint_buffer.resize(0); - float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - if(_down_sample_factor>0) os *= float(1<<_down_sample_factor); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; -#endif - - - for(i = 0; i < n; i++) - { - if(_levelFeatureNum[i]==0)continue; - - _featureTex[i].CopyToHost(buffer1); - - int fcount =0; - float * src = buffer1; - float * des = buffer2; - const static double factor = 2.0*3.14159265358979323846/65535.0; - for(int j = 0; j < _levelFeatureNum[i]; j++, src+=4) - { - unsigned short * orientations = (unsigned short*) (&src[3]); - if(orientations[0] != 65535) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = src[2]; - des[3] = float( factor* orientations[0]); - fcount++; - des += 4; - if(orientations[1] != 65535 && orientations[1] != orientations[0]) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = src[2]; - des[3] = float(factor* orientations[1]); - fcount++; - des += 4; - } - } - } - //texture size - SetLevelFeatureNum(i, fcount); - _featureTex[i].CopyFromHost(buffer2); - - if(fcount == 0) continue; - -#ifdef NO_DUPLICATE_DOWNLOAD - float oss = os * (1 << (i / param._dog_level_num)); - _keypoint_buffer.resize((_featureNum + fcount) * 4); - float* ds = &_keypoint_buffer[_featureNum * 4]; - float* fs = buffer2; - for(int k = 0; k < fcount; k++, ds+=4, fs+=4) - { - ds[0] = oss*(fs[0]-0.5f) + offset; //x - ds[1] = oss*(fs[1]-0.5f) + offset; //y - ds[2] = oss*fs[2]; //scale - ds[3] = (float)fmod(twopi-fs[3], twopi); //orientation, mirrored - } -#endif - _featureNum += fcount; - } - delete[] buffer; - if(GlobalUtil::_verbose) - { - std::cout<<"#Features MO:\t"<<_featureNum< keypoint_buffer2; - //use a different keypoint buffer when processing with an exisint features list - //without orientation information. - if(_keypoint_index.size() > 0) - { - keypoint_buffer2.resize(_keypoint_buffer.size()); - buffer = &keypoint_buffer2[0]; - } - float * p = buffer, *ps; - CuTexImage * ftex = _featureTex; - ///////////////////// - float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - if(_down_sample_factor>0) os *= float(1<<_down_sample_factor); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; - ///////////////////// - for(int i = 0; i < _octave_num; i++, os *= 2.0f) - { - - for(int j = 0; j < param._dog_level_num; j++, idx++, ftex++) - { - - if(_levelFeatureNum[idx]>0) - { - ftex->CopyToHost(ps = p); - for(int k = 0; k < _levelFeatureNum[idx]; k++, ps+=4) - { - ps[0] = os*(ps[0]-0.5f) + offset; //x - ps[1] = os*(ps[1]-0.5f) + offset; //y - ps[2] = os*ps[2]; - ps[3] = (float)fmod(twopi-ps[3], twopi); //orientation, mirrored - } - p+= 4* _levelFeatureNum[idx]; - } - } - } - - //put the feature into their original order for existing keypoint - if(_keypoint_index.size() > 0) - { - for(int i = 0; i < _featureNum; ++i) - { - int index = _keypoint_index[i]; - memcpy(&_keypoint_buffer[index*4], &keypoint_buffer2[i*4], 4 * sizeof(float)); - } - } -} - -void PyramidCU::GenerateFeatureListCPU() -{ - //no cpu version provided - GenerateFeatureList(); -} - -void PyramidCU::GenerateFeatureList(int i, int j, int reduction_count, vector& hbuffer) -{ - int fcount = 0, idx = i * param._dog_level_num + j; - int hist_level_num = _hpLevelNum - _pyramid_octave_first /2; - int ii, k, len; - - CuTexImage * htex, * ftex, * tex, *got; - ftex = _featureTex + idx; - htex = _histoPyramidTex + hist_level_num -1; - tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2 + j; - got = GetBaseLevel(_octave_min + i, DATA_GRAD) + 2 + j; - - ProgramCU::InitHistogram(tex, htex); - - for(k = 0; k < reduction_count - 1; k++, htex--) - { - ProgramCU::ReduceHistogram(htex, htex -1); - } - - //htex has the row reduction result - len = htex->GetImgHeight() * 4; - hbuffer.resize(len); - ProgramCU::FinishCUDA(); - htex->CopyToHost(&hbuffer[0]); - - ////TO DO: track the error found here.. - for(ii = 0; ii < len; ++ii) {if(!(hbuffer[ii]>= 0)) hbuffer[ii] = 0; }//? - - - for(ii = 0; ii < len; ++ii) fcount += hbuffer[ii]; - SetLevelFeatureNum(idx, fcount); - - //build the feature list - if(fcount > 0) - { - _featureNum += fcount; - _keypoint_buffer.resize(fcount * 4); - //vector ikbuf(fcount*4); - int* ibuf = (int*) (&_keypoint_buffer[0]); - - for(ii = 0; ii < len; ++ii) - { - int x = ii%4, y = ii / 4; - for(int jj = 0 ; jj < hbuffer[ii]; ++jj, ibuf+=4) - { - ibuf[0] = x; ibuf[1] = y; ibuf[2] = jj; ibuf[3] = 0; - } - } - _featureTex[idx].CopyFromHost(&_keypoint_buffer[0]); - - //////////////////////////////////////////// - ProgramCU::GenerateList(_featureTex + idx, ++htex); - for(k = 2; k < reduction_count; k++) - { - ProgramCU::GenerateList(_featureTex + idx, ++htex); - } - } -} - -void PyramidCU::GenerateFeatureList() -{ - double t1, t2; - int ocount = 0, reduction_count; - int reverse = (GlobalUtil::_TruncateMethod == 1); - - vector hbuffer; - _featureNum = 0; - - //for(int i = 0, idx = 0; i < _octave_num; i++) - FOR_EACH_OCTAVE(i, reverse) - { - CuTexImage* tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2; - reduction_count = FitHistogramPyramid(tex); - - if(GlobalUtil::_timingO) - { - t1 = CLOCK(); - ocount = 0; - std::cout<<"#"< 0 && _featureNum > GlobalUtil::_FeatureCountThreshold) continue; - - GenerateFeatureList(i, j, reduction_count, hbuffer); - - ///////////////////////////// - if(GlobalUtil::_timingO) - { - int idx = i * param._dog_level_num + j; - ocount += _levelFeatureNum[idx]; - std::cout<< _levelFeatureNum[idx] <<"\t"; - } - } - if(GlobalUtil::_timingO) - { - t2 = CLOCK(); - std::cout << "| \t" << int(ocount) << " :\t(" << (t2 - t1) << ")\n"; - } - } - ///// - CopyGradientTex(); - ///// - if(GlobalUtil::_timingS)ProgramCU::FinishCUDA(); - - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - } - - if(ProgramCU::CheckErrorCUDA("PyramidCU::GenerateFeatureList")) SetFailStatus(); -} - -GLTexImage* PyramidCU::GetLevelTexture(int octave, int level) -{ - return GetLevelTexture(octave, level, DATA_GAUSSIAN); -} - -GLTexImage* PyramidCU::ConvertTexCU2GL(CuTexImage* tex, int dataName) -{ - - GLenum format = GL_LUMINANCE; - int convert_done = 1; - if(_bufferPBO == 0) glGenBuffers(1, &_bufferPBO); - if(_bufferTEX == NULL) _bufferTEX = new GLTexImage; - switch(dataName) - { - case DATA_GAUSSIAN: - { - convert_done = tex->CopyToPBO(_bufferPBO); - break; - } - case DATA_DOG: - { - CuTexImage texPBO(tex->GetImgWidth(), tex->GetImgHeight(), 1, _bufferPBO); - if(texPBO._cuData == 0 || tex->_cuData == NULL) convert_done = 0; - else ProgramCU::DisplayConvertDOG(tex, &texPBO); - break; - } - case DATA_GRAD: - { - CuTexImage texPBO(tex->GetImgWidth(), tex->GetImgHeight(), 1, _bufferPBO); - if(texPBO._cuData == 0 || tex->_cuData == NULL) convert_done = 0; - else ProgramCU::DisplayConvertGRD(tex, &texPBO); - break; - } - case DATA_KEYPOINT: - { - CuTexImage * dog = tex - param._level_num * _pyramid_octave_num; - format = GL_RGBA; - CuTexImage texPBO(tex->GetImgWidth(), tex->GetImgHeight(), 4, _bufferPBO); - if(texPBO._cuData == 0 || tex->_cuData == NULL) convert_done = 0; - else ProgramCU::DisplayConvertKEY(tex, dog, &texPBO); - break; - } - default: - convert_done = 0; - break; - } - - if(convert_done) - { - _bufferTEX->InitTexture(max(_bufferTEX->GetTexWidth(), tex->GetImgWidth()), max(_bufferTEX->GetTexHeight(), tex->GetImgHeight())); - _bufferTEX->CopyFromPBO(_bufferPBO, tex->GetImgWidth(), tex->GetImgHeight(), format); - }else - { - _bufferTEX->SetImageSize(0, 0); - } - - return _bufferTEX; -} - -GLTexImage* PyramidCU::GetLevelTexture(int octave, int level, int dataName) -{ - CuTexImage* tex = GetBaseLevel(octave, dataName) + (level - param._level_min); - //CuTexImage* gus = GetBaseLevel(octave, DATA_GAUSSIAN) + (level - param._level_min); - return ConvertTexCU2GL(tex, dataName); -} - -void PyramidCU::ConvertInputToCU(GLTexInput* input) -{ - int ws = input->GetImgWidth(), hs = input->GetImgHeight(); - TruncateWidth(ws); - //copy the input image to pixel buffer object - if(input->_pixel_data) - { - _inputTex->InitTexture(ws, hs, 1); - _inputTex->CopyFromHost(input->_pixel_data); - }else - { - if(_bufferPBO == 0) glGenBuffers(1, &_bufferPBO); - if(input->_rgb_converted && input->CopyToPBO(_bufferPBO, ws, hs, GL_LUMINANCE)) - { - _inputTex->InitTexture(ws, hs, 1); - _inputTex->CopyFromPBO(ws, hs, _bufferPBO); - }else if(input->CopyToPBO(_bufferPBO, ws, hs)) - { - CuTexImage texPBO(ws, hs, 4, _bufferPBO); - _inputTex->InitTexture(ws, hs, 1); - ProgramCU::ReduceToSingleChannel(_inputTex, &texPBO, !input->_rgb_converted); - }else - { - std::cerr<< "Unable To Convert Intput\n"; - } - } -} - -void PyramidCU::BuildPyramid(GLTexInput * input) -{ - - USE_TIMING(); - - int i, j; - - for ( i = _octave_min; i < _octave_min + _octave_num; i++) - { - - float* filter_sigma = param._sigma; - CuTexImage *tex = GetBaseLevel(i); - CuTexImage *buf = GetBaseLevel(i, DATA_KEYPOINT) +2; - j = param._level_min + 1; - - OCTAVE_START(); - - if( i == _octave_min ) - { - ConvertInputToCU(input); - - if(i == 0) - { - ProgramCU::FilterImage(tex, _inputTex, buf, - param.GetInitialSmoothSigma(_octave_min + _down_sample_factor)); - }else - { - if(i < 0) ProgramCU::SampleImageU(tex, _inputTex, -i); - else ProgramCU::SampleImageD(tex, _inputTex, i); - ProgramCU::FilterImage(tex, tex, buf, - param.GetInitialSmoothSigma(_octave_min + _down_sample_factor)); - } - }else - { - ProgramCU::SampleImageD(tex, GetBaseLevel(i - 1) + param._level_ds - param._level_min); - if(param._sigma_skip1 > 0) - { - ProgramCU::FilterImage(tex, tex, buf, param._sigma_skip1); - } - } - LEVEL_FINISH(); - for( ; j <= param._level_max ; j++, tex++, filter_sigma++) - { - // filtering - ProgramCU::FilterImage(tex + 1, tex, buf, *filter_sigma); - LEVEL_FINISH(); - } - OCTAVE_FINISH(); - } - if(GlobalUtil::_timingS) ProgramCU::FinishCUDA(); - - if(ProgramCU::CheckErrorCUDA("PyramidCU::BuildPyramid")) SetFailStatus(); -} - -void PyramidCU::DetectKeypointsEX() -{ - - - int i, j; - double t0, t, ts, t1, t2; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - for(i = _octave_min; i < _octave_min + _octave_num; i++) - { - CuTexImage * gus = GetBaseLevel(i) + 1; - CuTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1; - CuTexImage * got = GetBaseLevel(i, DATA_GRAD) + 1; - //compute the gradient - for(j = param._level_min +1; j <= param._level_max ; j++, gus++, dog++, got++) - { - //input: gus and gus -1 - //output: gradient, dog, orientation - ProgramCU::ComputeDOG(gus, dog, got); - } - } - if(GlobalUtil::_timingS && GlobalUtil::_verbose) - { - ProgramCU::FinishCUDA(); - t1 = CLOCK(); - } - - for ( i = _octave_min; i < _octave_min + _octave_num; i++) - { - if(GlobalUtil::_timingO) - { - t0 = CLOCK(); - std::cout<<"#"<<(i + _down_sample_factor)<<"\t"; - } - CuTexImage * dog = GetBaseLevel(i, DATA_DOG) + 2; - CuTexImage * key = GetBaseLevel(i, DATA_KEYPOINT) +2; - - - for( j = param._level_min +2; j < param._level_max ; j++, dog++, key++) - { - if(GlobalUtil::_timingL)t = CLOCK(); - //input, dog, dog + 1, dog -1 - //output, key - ProgramCU::ComputeKEY(dog, key, param._dog_threshold, param._edge_threshold); - if(GlobalUtil::_timingL) - { - std::cout<<(CLOCK()-t)<<"\t"; - } - } - if(GlobalUtil::_timingO) - { - std::cout<<"|\t"<<(CLOCK()-t0)<<"\n"; - } - } - - if(GlobalUtil::_timingS) - { - ProgramCU::FinishCUDA(); - if(GlobalUtil::_verbose) - { - t2 = CLOCK(); - std::cout <<"\t"<<(t1-ts)<<"\n" - <<"\t"<<(t2-t1)<<"\n"; - } - } -} - -void PyramidCU::CopyGradientTex() -{ - double ts, t1; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - for(int i = 0, idx = 0; i < _octave_num; i++) - { - CuTexImage * got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1; - //compute the gradient - for(int j = 0; j < param._dog_level_num ; j++, got++, idx++) - { - if(_levelFeatureNum[idx] > 0) got->CopyToTexture2D(); - } - } - if(GlobalUtil::_timingS) - { - ProgramCU::FinishCUDA(); - if(GlobalUtil::_verbose) - { - t1 = CLOCK(); - std::cout <<"\t"<<(t1-ts)<<"\n"; - } - } -} - -void PyramidCU::ComputeGradient() -{ - - int i, j; - double ts, t1; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - for(i = _octave_min; i < _octave_min + _octave_num; i++) - { - CuTexImage * gus = GetBaseLevel(i) + 1; - CuTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1; - CuTexImage * got = GetBaseLevel(i, DATA_GRAD) + 1; - - //compute the gradient - for(j = 0; j < param._dog_level_num ; j++, gus++, dog++, got++) - { - ProgramCU::ComputeDOG(gus, dog, got); - } - } - if(GlobalUtil::_timingS) - { - ProgramCU::FinishCUDA(); - if(GlobalUtil::_verbose) - { - t1 = CLOCK(); - std::cout <<"\t"<<(t1-ts)<<"\n"; - } - } -} - -int PyramidCU::FitHistogramPyramid(CuTexImage* tex) -{ - CuTexImage *htex; - int hist_level_num = _hpLevelNum - _pyramid_octave_first / 2; - htex = _histoPyramidTex + hist_level_num - 1; - int w = (tex->GetImgWidth() + 2) >> 2; - int h = tex->GetImgHeight(); - int count = 0; - for(int k = 0; k < hist_level_num; k++, htex--) - { - //htex->SetImageSize(w, h); - htex->InitTexture(w, h, 4); - ++count; - if(w == 1) - break; - w = (w + 3)>>2; - } - return count; -} - -void PyramidCU::GetFeatureOrientations() -{ - - CuTexImage * ftex = _featureTex; - int * count = _levelFeatureNum; - float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num); - - for(int i = 0; i < _octave_num; i++) - { - CuTexImage* got = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1; - CuTexImage* key = GetBaseLevel(i + _octave_min, DATA_KEYPOINT) + 2; - - for(int j = 0; j < param._dog_level_num; j++, ftex++, count++, got++, key++) - { - if(*count<=0)continue; - - //if(ftex->GetImgWidth() < *count) ftex->InitTexture(*count, 1, 4); - - sigma = param.GetLevelSigma(j+param._level_min+1); - - ProgramCU::ComputeOrientation(ftex, got, key, sigma, sigma_step, _existing_keypoints); - } - } - - if(GlobalUtil::_timingS)ProgramCU::FinishCUDA(); - if(ProgramCU::CheckErrorCUDA("PyramidCU::GetFeatureOrientations")) SetFailStatus(); - -} - -void PyramidCU::GetSimplifiedOrientation() -{ - //no simplified orientation - GetFeatureOrientations(); -} - -CuTexImage* PyramidCU::GetBaseLevel(int octave, int dataName) -{ - if(octave <_octave_min || octave > _octave_min + _octave_num) return NULL; - int offset = (_pyramid_octave_first + octave - _octave_min) * param._level_num; - int num = param._level_num * _pyramid_octave_num; - if (dataName == DATA_ROT) dataName = DATA_GRAD; - return _allPyramid + num * dataName + offset; -} - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/PyramidCU.h b/3rdparty/SiftGPU/src/SiftGPU/PyramidCU.h deleted file mode 100644 index feb7adeb..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/PyramidCU.h +++ /dev/null @@ -1,86 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: PyramidCU.h -// Author: Changchang Wu -// Description : interface for the PyramdCU -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - - -#ifndef _PYRAMID_CU_H -#define _PYRAMID_CU_H -#if defined(CUDA_SIFTGPU_ENABLED) - -class GLTexImage; -class CuTexImage; -class SiftPyramid; -class PyramidCU:public SiftPyramid -{ - CuTexImage* _inputTex; - CuTexImage* _allPyramid; - CuTexImage* _histoPyramidTex; - CuTexImage* _featureTex; - CuTexImage* _descriptorTex; - CuTexImage* _orientationTex; - GLuint _bufferPBO; - GLTexImage* _bufferTEX; -public: - virtual void GetFeatureDescriptors(); - virtual void GenerateFeatureListTex(); - virtual void ReshapeFeatureListCPU(); - virtual void GenerateFeatureDisplayVBO(); - virtual void DestroySharedData(); - virtual void DestroyPerLevelData(); - virtual void DestroyPyramidData(); - virtual void DownloadKeypoints(); - virtual void GenerateFeatureListCPU(); - virtual void GenerateFeatureList(); - virtual GLTexImage* GetLevelTexture(int octave, int level); - virtual GLTexImage* GetLevelTexture(int octave, int level, int dataName); - virtual void BuildPyramid(GLTexInput * input); - virtual void DetectKeypointsEX(); - virtual void ComputeGradient(); - virtual void GetFeatureOrientations(); - virtual void GetSimplifiedOrientation(); - virtual void InitPyramid(int w, int h, int ds = 0); - virtual void ResizePyramid(int w, int h); - virtual int IsUsingRectDescription(){return _existing_keypoints & SIFT_RECT_DESCRIPTION; } - ////////// - void CopyGradientTex(); - void FitPyramid(int w, int h); - - void InitializeContext(); - int ResizeFeatureStorage(); - int FitHistogramPyramid(CuTexImage* tex); - void SetLevelFeatureNum(int idx, int fcount); - void ConvertInputToCU(GLTexInput* input); - GLTexImage* ConvertTexCU2GL(CuTexImage* tex, int dataName); - CuTexImage* GetBaseLevel(int octave, int dataName = DATA_GAUSSIAN); - void TruncateWidth(int& w) { w = GLTexInput::TruncateWidthCU(w); } - ////////////////////////// - static int CheckCudaDevice(int device); -private: - void GenerateFeatureList(int i, int j, int reduction_count, vector& hbuffer); -public: - PyramidCU(SiftParam& sp); - virtual ~PyramidCU(); -}; - - - -#endif -#endif diff --git a/3rdparty/SiftGPU/src/SiftGPU/PyramidGL.cpp b/3rdparty/SiftGPU/src/SiftGPU/PyramidGL.cpp deleted file mode 100644 index 18c37d6a..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/PyramidGL.cpp +++ /dev/null @@ -1,2805 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: PyramidGL.cpp -// Author: Changchang Wu -// Description : implementation of PyramidGL/PyramidNaive/PyramidPackdc . -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#include "GL/glew.h" -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "GlobalUtil.h" -#include "GLTexImage.h" -#include "SiftGPU.h" -#include "ShaderMan.h" -#include "SiftPyramid.h" -#include "ProgramGLSL.h" -#include "PyramidGL.h" -#include "FrameBufferObject.h" - - -#if defined(__SSE__) || _MSC_VER > 1200 -#define USE_SSE_FOR_SIFTGPU -#include -#else -//#pragma message( "SSE optimization off!\n" ) -#endif - - -#define USE_TIMING() double t, t0, tt; -#define OCTAVE_START() if(GlobalUtil::_timingO){ t = t0 = CLOCK(); cout<<"#"<GetImgWidth() >> 1; - int h = tex->GetImgHeight() >> 1; - - for(int k = 0; k GetImgHeight()!= h || htex->GetImgWidth() != w) - { - htex->SetImageSize(w, h); - htex->ZeroHistoMargin(); - } - - w = (w + 1)>>1; h = (h + 1) >> 1; - } -} - -void PyramidNaive::FitPyramid(int w, int h) -{ - //(w, h) <= (_pyramid_width, _pyramid_height); - - _pyramid_octave_first = 0; - // - _octave_num = GlobalUtil::_octave_num_default; - - int _octave_num_max = GetRequiredOctaveNum(min(w, h)); - - if(_octave_num < 1 || _octave_num > _octave_num_max) - { - _octave_num = _octave_num_max; - } - - - int pw = _pyramid_width>>1, ph = _pyramid_height>>1; - while(_pyramid_octave_first + _octave_num < _pyramid_octave_num && - pw >= w && ph >= h) - { - _pyramid_octave_first++; - pw >>= 1; - ph >>= 1; - } - - for(int i = 0; i < _octave_num; i++) - { - GLTexImage * tex = GetBaseLevel(i + _octave_min); - GLTexImage * aux = GetBaseLevel(i + _octave_min, DATA_KEYPOINT); - for(int j = param._level_min; j <= param._level_max; j++, tex++, aux++) - { - tex->SetImageSize(w, h); - aux->SetImageSize(w, h); - } - w>>=1; - h>>=1; - } -} -void PyramidNaive::InitPyramid(int w, int h, int ds) -{ - int wp, hp, toobig = 0; - if(ds == 0) - { - _down_sample_factor = 0; - if(GlobalUtil::_octave_min_default>=0) - { - wp = w >> GlobalUtil::_octave_min_default; - hp = h >> GlobalUtil::_octave_min_default; - }else - { - wp = w << (-GlobalUtil::_octave_min_default); - hp = h << (-GlobalUtil::_octave_min_default); - } - _octave_min = _octave_min_default; - }else - { - //must use 0 as _octave_min; - _octave_min = 0; - _down_sample_factor = ds; - w >>= ds; - h >>= ds; - wp = w; - hp = h; - - } - - while(wp > GlobalUtil::_texMaxDim || hp > GlobalUtil::_texMaxDim) - { - _octave_min ++; - wp >>= 1; - hp >>= 1; - toobig = 1; - } - - while(GlobalUtil::_MemCapGPU > 0 && GlobalUtil::_FitMemoryCap && (wp >_pyramid_width || hp > _pyramid_height) && - max(max(wp, hp), max(_pyramid_width, _pyramid_height)) > 1024 * sqrt(GlobalUtil::_MemCapGPU / 140.0)) - { - _octave_min ++; - wp >>= 1; - hp >>= 1; - toobig = 2; - } - - if(toobig && GlobalUtil::_verbose) - { - std::cout<<(toobig == 2 ? "[**SKIP OCTAVES**]:\tExceeding Memory Cap (-nomc)\n" : - "[**SKIP OCTAVES**]:\tReaching the dimension limit (-maxd)!\n"); - } - - if( wp == _pyramid_width && hp == _pyramid_height && _allocated ) - { - FitPyramid(wp, hp); - }else if(GlobalUtil::_ForceTightPyramid || _allocated ==0) - { - ResizePyramid(wp, hp); - } - else if( wp > _pyramid_width || hp > _pyramid_height ) - { - ResizePyramid(max(wp, _pyramid_width), max(hp, _pyramid_height)); - if(wp < _pyramid_width || hp < _pyramid_height) FitPyramid(wp, hp); - } - else - { - //try use the pyramid allocated for large image on small input images - FitPyramid(wp, hp); - } - - //select the initial smoothing filter according to the new _octave_min - ShaderMan::SelectInitialSmoothingFilter(_octave_min + _down_sample_factor, param); -} - -void PyramidNaive::ResizePyramid( int w, int h) -{ - // - unsigned int totalkb = 0; - int _octave_num_new, input_sz; - int i, j; - GLTexImage * tex, *aux; - // - - if(_pyramid_width == w && _pyramid_height == h && _allocated) return; - - if(w > GlobalUtil::_texMaxDim || h > GlobalUtil::_texMaxDim) return ; - - if(GlobalUtil::_verbose && GlobalUtil::_timingS) std::cout<<"[Allocate Pyramid]:\t" <0) - { - DestroyPerLevelData(); - DestroyPyramidData(); - } - _pyramid_octave_num = _octave_num_new; - } - - _octave_num = _pyramid_octave_num; - - int noct = _octave_num; - int nlev = param._level_num; - - // //initialize the pyramid - if(_texPyramid==NULL) _texPyramid = new GLTexImage[ noct* nlev ]; - if(_auxPyramid==NULL) _auxPyramid = new GLTexImage[ noct* nlev ]; - - - tex = GetBaseLevel(_octave_min, DATA_GAUSSIAN); - aux = GetBaseLevel(_octave_min, DATA_KEYPOINT); - for(i = 0; i< noct; i++) - { - totalkb += (nlev * w * h * 16 / 1024); - for( j = 0; j< nlev; j++, tex++) - { - tex->InitTexture(w, h); - //tex->AttachToFBO(0); - } - //several auxilary textures are not actually required - totalkb += ((nlev - 3) * w * h * 16 /1024); - for( j = 0; j< nlev ; j++, aux++) - { - if(j < 2) continue; - if(j >= nlev - 1) continue; - aux->InitTexture(w, h, 0); - //aux->AttachToFBO(0); - } - - w>>=1; - h>>=1; - } - - totalkb += ResizeFeatureStorage(); - - - // - _allocated = 1; - - if(GlobalUtil::_verbose && GlobalUtil::_timingS) std::cout<<"[Allocate Pyramid]:\t" <<(totalkb/1024)<<"MB\n"; - -} - - -int PyramidGL::ResizeFeatureStorage() -{ - int totalkb = 0; - if(_levelFeatureNum==NULL) _levelFeatureNum = new int[_octave_num * param._dog_level_num]; - std::fill(_levelFeatureNum, _levelFeatureNum+_octave_num * param._dog_level_num, 0); - - int wmax = GetBaseLevel(_octave_min)->GetDrawWidth(); - int hmax = GetBaseLevel(_octave_min)->GetDrawHeight(); - int w ,h, i; - - //use a fbo to initialize textures.. - FrameBufferObject fbo; - - // - if(_histo_buffer == NULL) _histo_buffer = new float[((size_t)1) << (2 + 2 * GlobalUtil::_ListGenSkipGPU)]; - //histogram for feature detection - - int num = (int)ceil(log(double(max(wmax, hmax)))/log(2.0)); - - if( _hpLevelNum != num) - { - _hpLevelNum = num; - if(GlobalUtil::_ListGenGPU) - { - if(_histoPyramidTex ) delete [] _histoPyramidTex; - _histoPyramidTex = new GLTexImage[_hpLevelNum]; - w = h = 1 ; - for(i = 0; i < _hpLevelNum; i++) - { - _histoPyramidTex[i].InitTexture(w, h, 0); - _histoPyramidTex[i].AttachToFBO(0); - w<<=1; - h<<=1; - } - } - } - - // (4 ^ (_hpLevelNum) -1 / 3) pixels - if(GlobalUtil::_ListGenGPU) totalkb += (((1 << (2 * _hpLevelNum)) -1) / 3 * 16 / 1024); - - - - //initialize the feature texture - - int idx = 0, n = _octave_num * param._dog_level_num; - if(_featureTex==NULL) _featureTex = new GLTexImage[n]; - if(GlobalUtil::_MaxOrientation >1 && GlobalUtil::_OrientationPack2==0) - { - if(_orientationTex== NULL) _orientationTex = new GLTexImage[n]; - } - - - for(i = 0; i < _octave_num; i++) - { - GLTexImage * tex = GetBaseLevel(i+_octave_min); - int fmax = int(tex->GetImgWidth()*tex->GetImgHeight()*GlobalUtil::_MaxFeaturePercent); - int fw, fh; - // - if(fmax > GlobalUtil::_MaxLevelFeatureNum) fmax = GlobalUtil::_MaxLevelFeatureNum; - else if(fmax < 32) fmax = 32; //give it at least a space of 32 feature - - GetTextureStorageSize(fmax, fw, fh); - - for(int j = 0; j < param._dog_level_num; j++, idx++) - { - - _featureTex[idx].InitTexture(fw, fh, 0); - _featureTex[idx].AttachToFBO(0); - // - if(_orientationTex) - { - _orientationTex[idx].InitTexture(fw, fh, 0); - _orientationTex[idx].AttachToFBO(0); - } - } - totalkb += fw * fh * 16 * param._dog_level_num * (_orientationTex? 2 : 1) /1024; - } - - - //this just need be initialized once - if(_descriptorTex==NULL) - { - //initialize feature texture pyramid - wmax = _featureTex->GetImgWidth(); - hmax = _featureTex->GetImgHeight(); - - int nf, ns; - if(GlobalUtil::_DescriptorPPT) - { - //32*4 = 128. - nf = 32 / GlobalUtil::_DescriptorPPT; // how many textures we need - ns = max(4, GlobalUtil::_DescriptorPPT); // how many point in one texture for one descriptor - }else - { - //at least one, resue for visualization and other work - nf = 1; ns = 4; - } - // - _alignment = ns; - // - _descriptorTex = new GLTexImage[nf]; - - int fw, fh; - GetAlignedStorageSize(hmax*wmax* max(ns, 10), _alignment, fw, fh); - - if(fh < hmax ) fh = hmax; - if(fw < wmax ) fw = wmax; - - totalkb += ( fw * fh * nf * 16 /1024); - for(i =0; i < nf; i++) - { - _descriptorTex[i].InitTexture(fw, fh); - } - }else - { - int nf = GlobalUtil::_DescriptorPPT? 32 / GlobalUtil::_DescriptorPPT: 1; - totalkb += nf * _descriptorTex[0].GetTexWidth() * _descriptorTex[0].GetTexHeight() * 16 /1024; - } - return totalkb; -} - - -void PyramidNaive::BuildPyramid(GLTexInput *input) -{ - USE_TIMING(); - GLTexPacked * tex; - FilterProgram** filter; - FrameBufferObject fbo; - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - input->FitTexViewPort(); - - for (int i = _octave_min; i < _octave_min + _octave_num; i++) - { - - tex = (GLTexPacked*)GetBaseLevel(i); - filter = ShaderMan::s_bag->f_gaussian_step; - - OCTAVE_START(); - - if( i == _octave_min ) - { - if(i < 0) TextureUpSample(tex, input, 1<<(-i) ); - else TextureDownSample(tex, input, 1< _octave_min + _octave_num) return NULL; - switch(dataName) - { - case DATA_GAUSSIAN: - case DATA_DOG: - case DATA_GRAD: - case DATA_ROT: - return _texPyramid+ (_pyramid_octave_first + octave - _octave_min) * param._level_num + (level - param._level_min); - case DATA_KEYPOINT: - return _auxPyramid + (_pyramid_octave_first + octave - _octave_min) * param._level_num + (level - param._level_min); - default: - return NULL; - } -} - -GLTexImage* PyramidNaive::GetLevelTexture(int octave, int level) -{ - return _texPyramid+ (_pyramid_octave_first + octave - _octave_min) * param._level_num - + (level - param._level_min); -} - -//in the packed implementation -// DATA_GAUSSIAN, DATA_DOG, DATA_GAD will be stored in different textures. -GLTexImage* PyramidNaive::GetBaseLevel(int octave, int dataName) -{ - if(octave <_octave_min || octave > _octave_min + _octave_num) return NULL; - switch(dataName) - { - case DATA_GAUSSIAN: - case DATA_DOG: - case DATA_GRAD: - case DATA_ROT: - return _texPyramid+ (_pyramid_octave_first + octave - _octave_min) * param._level_num; - case DATA_KEYPOINT: - return _auxPyramid + (_pyramid_octave_first + octave - _octave_min) * param._level_num; - default: - return NULL; - } -} - - - - - - - - - -void PyramidNaive::ComputeGradient() -{ - - int i, j; - double ts, t1; - GLTexImage * tex; - FrameBufferObject fbo; - - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - - for ( i = _octave_min; i < _octave_min + _octave_num; i++) - { - for( j = param._level_min + 1 ; j < param._level_max ; j++) - { - tex = GetLevelTexture(i, j); - tex->FitTexViewPort(); - tex->AttachToFBO(0); - tex->BindTex(); - ShaderMan::UseShaderGradientPass(); - tex->DrawQuadMT4(); - } - } - - if(GlobalUtil::_timingS && GlobalUtil::_verbose) - { - glFinish(); - t1 = CLOCK(); - std::cout<<"\t"<<(t1-ts)<<"\n"; - } - - UnloadProgram(); - GLTexImage::UnbindMultiTex(3); - fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT); -} - - -//keypoint detection with subpixel localization -void PyramidNaive::DetectKeypointsEX() -{ - int i, j; - double t0, t, ts, t1, t2; - GLTexImage * tex, *aux; - FrameBufferObject fbo; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - //extra gradient data required for visualization - int gradient_only_levels[2] = {param._level_min +1, param._level_max}; - int n_gradient_only_level = GlobalUtil::_UseSiftGPUEX ? 2 : 1; - for ( i = _octave_min; i < _octave_min + _octave_num; i++) - { - for( j =0; j < n_gradient_only_level ; j++) - { - tex = GetLevelTexture(i, gradient_only_levels[j]); - tex->FitTexViewPort(); - tex->AttachToFBO(0); - tex->BindTex(); - ShaderMan::UseShaderGradientPass(); - tex->DrawQuadMT4(); - } - } - - if(GlobalUtil::_timingS && GlobalUtil::_verbose) - { - glFinish(); - t1 = CLOCK(); - } - - GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; - glDrawBuffers(2, buffers); - for ( i = _octave_min; i < _octave_min + _octave_num; i++) - { - if(GlobalUtil::_timingO) - { - t0 = CLOCK(); - std::cout<<"#"<<(i + _down_sample_factor)<<"\t"; - } - tex = GetBaseLevel(i) + 2; - aux = GetBaseLevel(i, DATA_KEYPOINT) +2; - aux->FitTexViewPort(); - - for( j = param._level_min + 2; j < param._level_max ; j++, aux++, tex++) - { - if(GlobalUtil::_timingL)t = CLOCK(); - tex->AttachToFBO(0); - aux->AttachToFBO(1); - glActiveTexture(GL_TEXTURE0); - tex->BindTex(); - glActiveTexture(GL_TEXTURE1); - (tex+1)->BindTex(); - glActiveTexture(GL_TEXTURE2); - (tex-1)->BindTex(); - ShaderMan::UseShaderKeypoint((tex+1)->GetTexID(), (tex-1)->GetTexID()); - aux->DrawQuadMT8(); - - if(GlobalUtil::_timingL) - { - glFinish(); - std::cout<<(CLOCK()-t)<<"\t"; - } - tex->DetachFBO(0); - aux->DetachFBO(1); - } - if(GlobalUtil::_timingO) - { - std::cout<<"|\t"<<(CLOCK()-t0)<<"\n"; - } - } - - if(GlobalUtil::_timingS) - { - glFinish(); - t2 = CLOCK(); - if(GlobalUtil::_verbose) - std::cout <<"\t"<<(t2-t1)<<"\n" - <<"\t"<<(t1-ts)<<"\n"; - } - UnloadProgram(); - GLTexImage::UnbindMultiTex(3); - fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT); - - -} - -void PyramidNaive::GenerateFeatureList(int i, int j) -{ - int hist_level_num = _hpLevelNum - _pyramid_octave_first; - int hist_skip_gpu = GlobalUtil::_ListGenSkipGPU; - int idx = i * param._dog_level_num + j; - GLTexImage* htex, *ftex, *tex; - tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2 + j; - ftex = _featureTex + idx; - htex = _histoPyramidTex + hist_level_num - 1 - i; - - /// - glActiveTexture(GL_TEXTURE0); - tex->BindTex(); - htex->AttachToFBO(0); - int tight = ((htex->GetImgWidth() * 2 == tex->GetImgWidth() -1 || tex->GetTexWidth() == tex->GetImgWidth()) && - (htex->GetImgHeight() *2 == tex->GetImgHeight()-1 || tex->GetTexHeight() == tex->GetImgHeight())); - ShaderMan::UseShaderGenListInit(tex->GetImgWidth(), tex->GetImgHeight(), tight); - htex->FitTexViewPort(); - //this uses the fact that no feature is on the edge. - htex->DrawQuadReduction(); - - //reduction.. - htex--; - - //this part might have problems on several GPUS - //because the output of one pass is the input of the next pass - //need to call glFinish to make it right - //but too much glFinish makes it slow - for(int k = 0; k AttachToFBO(0); - htex->FitTexViewPort(); - (htex+1)->BindTex(); - ShaderMan::UseShaderGenListHisto(); - htex->DrawQuadReduction(); - } - - // - if(hist_skip_gpu == 0) - { - //read back one pixel - float fn[4], fcount; - glReadPixels(0, 0, 1, 1, GL_RGBA , GL_FLOAT, fn); - fcount = (fn[0] + fn[1] + fn[2] + fn[3]); - if(fcount < 1) fcount = 0; - - - _levelFeatureNum[ idx] = (int)(fcount); - SetLevelFeatureNum(idx, (int)fcount); - _featureNum += int(fcount); - - // - if(fcount < 1.0) return; - - - ///generate the feature texture - - htex= _histoPyramidTex; - - htex->BindTex(); - - //first pass - ftex->AttachToFBO(0); - if(GlobalUtil::_MaxOrientation>1) - { - //this is very important... - ftex->FitRealTexViewPort(); - glClear(GL_COLOR_BUFFER_BIT); - glFinish(); - }else - { - ftex->FitTexViewPort(); - //glFinish(); - } - - - ShaderMan::UseShaderGenListStart((float)ftex->GetImgWidth(), htex->GetTexID()); - - ftex->DrawQuad(); - //make sure it finishes before the next step - ftex->DetachFBO(0); - - //pass on each pyramid level - htex++; - }else - { - - int tw = htex[1].GetDrawWidth(), th = htex[1].GetDrawHeight(); - int fc = 0; - glReadPixels(0, 0, tw, th, GL_RGBA , GL_FLOAT, _histo_buffer); - _keypoint_buffer.resize(0); - for(int y = 0, pos = 0; y < th; y++) - { - for(int x= 0; x < tw; x++) - { - for(int c = 0; c < 4; c++, pos++) - { - int ss = (int) _histo_buffer[pos]; - if(ss == 0) continue; - float ft[4] = {2 * x + (c%2? 1.5f: 0.5f), 2 * y + (c>=2? 1.5f: 0.5f), 0, 1 }; - for(int t = 0; t < ss; t++) - { - ft[2] = (float) t; - _keypoint_buffer.insert(_keypoint_buffer.end(), ft, ft+4); - } - fc += (int)ss; - } - } - } - _levelFeatureNum[ idx] = fc; - SetLevelFeatureNum(idx, fc); - if(fc == 0) return; - _featureNum += fc; - ///////////////////// - ftex->AttachToFBO(0); - if(GlobalUtil::_MaxOrientation>1) - { - ftex->FitRealTexViewPort(); - glClear(GL_COLOR_BUFFER_BIT); - glFlush(); - }else - { - ftex->FitTexViewPort(); - glFlush(); - } - _keypoint_buffer.resize(ftex->GetDrawWidth() * ftex->GetDrawHeight()*4, 0); - /////////// - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, ftex->GetDrawWidth(), - ftex->GetDrawHeight(), GL_RGBA, GL_FLOAT, &_keypoint_buffer[0]); - htex += 2; - } - - for(int lev = 1 + hist_skip_gpu; lev < hist_level_num - i; lev++, htex++) - { - - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - ftex->AttachToFBO(0); - glActiveTexture(GL_TEXTURE1); - htex->BindTex(); - ShaderMan::UseShaderGenListStep(ftex->GetTexID(), htex->GetTexID()); - ftex->DrawQuad(); - ftex->DetachFBO(0); - } - GLTexImage::UnbindMultiTex(2); - -} - -//generate feature list on GPU -void PyramidNaive::GenerateFeatureList() -{ - //generate the histogram0pyramid - FrameBufferObject fbo; - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - double t1, t2; - int ocount, reverse = (GlobalUtil::_TruncateMethod == 1); - _featureNum = 0; - - FitHistogramPyramid(); - - //for(int i = 0, idx = 0; i < _octave_num; i++) - FOR_EACH_OCTAVE(i, reverse) - { - //output - if(GlobalUtil::_timingO) - { - t1= CLOCK(); - ocount = 0; - std::cout<<"#"< 0 - && _featureNum > GlobalUtil::_FeatureCountThreshold) - { - _levelFeatureNum[i * param._dog_level_num + j] = 0; - continue; - }else - { - GenerateFeatureList(i, j); - if(GlobalUtil::_timingO) - { - int idx = i * param._dog_level_num + j; - std::cout<< _levelFeatureNum[idx] <<"\t"; - ocount += _levelFeatureNum[idx]; - } - } - } - if(GlobalUtil::_timingO) - { - t2 = CLOCK(); - std::cout << "| \t" << int(ocount) << " :\t(" << (t2 - t1) << ")\n"; - } - } - if(GlobalUtil::_timingS)glFinish(); - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - } -} - - -void PyramidGL::GenerateFeatureDisplayVBO() -{ - //use a big VBO to save all the SIFT box vertices - int w, h, esize; GLint bsize; - int nvbo = _octave_num * param._dog_level_num; - //initialize the vbos - if(_featureDisplayVBO==NULL) - { - _featureDisplayVBO = new GLuint[nvbo]; - glGenBuffers( nvbo, _featureDisplayVBO ); - } - if(_featurePointVBO == NULL) - { - _featurePointVBO = new GLuint[nvbo]; - glGenBuffers(nvbo, _featurePointVBO); - } - - FrameBufferObject fbo; - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - glActiveTexture(GL_TEXTURE0); - // - GLTexImage & tempTex = *_descriptorTex; - // - for(int i = 0, idx = 0; i < _octave_num; i++) - { - for(int j = 0; j < param._dog_level_num; j ++, idx++) - { - GLTexImage * ftex = _featureTex + idx; - if(_levelFeatureNum[idx]<=0)continue; - - //copy the texture into vbo - fbo.BindFBO(); - tempTex.AttachToFBO(0); - - ftex->BindTex(); - ftex->FitTexViewPort(); - ShaderMan::UseShaderCopyKeypoint(); - ftex->DrawQuad(); - - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _featurePointVBO[ idx]); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - esize = ftex->GetImgHeight() * ftex->GetImgWidth()*sizeof(float) *4; - - //increase size when necessary - if(bsize < esize) - { - glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize*3/2 , NULL, GL_STATIC_DRAW_ARB); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - } - - //read back if we have enough buffer - if(bsize >= esize) glReadPixels(0, 0, ftex->GetImgWidth(), ftex->GetImgHeight(), GL_RGBA, GL_FLOAT, 0); - else glBufferData(GL_PIXEL_PACK_BUFFER_ARB, 0, NULL, GL_STATIC_DRAW_ARB); - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); - - - //box display vbo - int count = _levelFeatureNum[idx]* 10; - GetAlignedStorageSize(count, _alignment, w, h); - w = (int)ceil(double(count)/ h); - - //input - fbo.BindFBO(); - ftex->BindTex(); - - //output - tempTex.AttachToFBO(0); - GlobalUtil::FitViewPort(w, h); - //shader - ShaderMan::UseShaderGenVBO( (float)ftex->GetImgWidth(), (float) w, - param.GetLevelSigma(j + param._level_min + 1)); - GLTexImage::DrawQuad(0, (float)w, 0, (float)h); - - // - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _featureDisplayVBO[ idx]); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - esize = w*h * sizeof(float)*4; - //increase size when necessary - if(bsize < esize) - { - glBufferData(GL_PIXEL_PACK_BUFFER_ARB, esize*3/2, NULL, GL_STATIC_DRAW_ARB); - glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER_ARB, GL_BUFFER_SIZE, &bsize); - } - - //read back if we have enough buffer - if(bsize >= esize) glReadPixels(0, 0, w, h, GL_RGBA, GL_FLOAT, 0); - else glBufferData(GL_PIXEL_PACK_BUFFER_ARB, 0, NULL, GL_STATIC_DRAW_ARB); - glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); - - - - - } - } - glReadBuffer(GL_NONE); - glFinish(); - -} - - - - - -void PyramidNaive::GetFeatureOrientations() -{ - GLTexImage * gtex; - GLTexImage * stex = NULL; - GLTexImage * ftex = _featureTex; - GLTexImage * otex = _orientationTex; - int sid = 0; - int * count = _levelFeatureNum; - float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num); - FrameBufferObject fbo; - if(_orientationTex) - { - GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; - glDrawBuffers(2, buffers); - }else - { - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - } - for(int i = 0; i < _octave_num; i++) - { - gtex = GetLevelTexture(i+_octave_min, param._level_min + 1); - if(GlobalUtil::_SubpixelLocalization || GlobalUtil::_KeepExtremumSign) - stex = GetBaseLevel(i+_octave_min, DATA_KEYPOINT) + 2; - - for(int j = 0; j < param._dog_level_num; j++, ftex++, otex++, count++, gtex++, stex++) - { - if(*count<=0)continue; - - sigma = param.GetLevelSigma(j+param._level_min+1); - - // - ftex->FitTexViewPort(); - - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - glActiveTexture(GL_TEXTURE1); - gtex->BindTex(); - // - ftex->AttachToFBO(0); - if(_orientationTex) otex->AttachToFBO(1); - if(!_existing_keypoints && (GlobalUtil::_SubpixelLocalization|| GlobalUtil::_KeepExtremumSign)) - { - glActiveTexture(GL_TEXTURE2); - stex->BindTex(); - sid = * stex; - } - ShaderMan::UseShaderOrientation(gtex->GetTexID(), - gtex->GetImgWidth(), gtex->GetImgHeight(), - sigma, sid, sigma_step, _existing_keypoints); - ftex->DrawQuad(); - // glFinish(); - - } - } - - GLTexImage::UnbindMultiTex(3); - if(GlobalUtil::_timingS)glFinish(); - - if(_orientationTex) fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT); - -} - - - -//to compare with GPU feature list generation -void PyramidNaive::GenerateFeatureListCPU() -{ - - FrameBufferObject fbo; - _featureNum = 0; - GLTexImage * tex = GetBaseLevel(_octave_min); - float * mem = new float [tex->GetTexWidth()*tex->GetTexHeight()]; - vector list; - int idx = 0; - for(int i = 0; i < _octave_num; i++) - { - for(int j = 0; j < param._dog_level_num; j++, idx++) - { - tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + j + 2; - tex->BindTex(); - glGetTexImage(GlobalUtil::_texTarget, 0, GL_RED, GL_FLOAT, mem); - //tex->AttachToFBO(0); - //tex->FitTexViewPort(); - //glReadPixels(0, 0, tex->GetTexWidth(), tex->GetTexHeight(), GL_RED, GL_FLOAT, mem); - // - //make a list of - list.resize(0); - float * p = mem; - int fcount = 0 ; - for(int k = 0; k < tex->GetTexHeight(); k++) - { - for( int m = 0; m < tex->GetTexWidth(); m ++, p++) - { - if(*p==0)continue; - if(m ==0 || k ==0 || k >= tex->GetImgHeight() -1 || m >= tex->GetImgWidth() -1 ) continue; - list.push_back(m+0.5f); - list.push_back(k+0.5f); - list.push_back(0); - list.push_back(1); - fcount ++; - - - } - } - if(fcount==0)continue; - - - - GLTexImage * ftex = _featureTex+idx; - _levelFeatureNum[idx] = (fcount); - SetLevelFeatureNum(idx, fcount); - - _featureNum += (fcount); - - - int fw = ftex->GetImgWidth(); - int fh = ftex->GetImgHeight(); - - list.resize(4*fh*fw); - - ftex->BindTex(); - ftex->AttachToFBO(0); - // glTexImage2D(GlobalUtil::_texTarget, 0, GlobalUtil::_iTexFormat, fw, fh, 0, GL_BGRA, GL_FLOAT, &list[0]); - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, fw, fh, GL_RGBA, GL_FLOAT, &list[0]); - // - } - } - GLTexImage::UnbindTex(); - delete[] mem; - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - } -} - -#define FEATURELIST_USE_PBO - -void PyramidGL::ReshapeFeatureListCPU() -{ - //make a compact feature list, each with only one orientation - //download orientations and the featue list - //reshape it and upload it - - FrameBufferObject fbo; - int i, szmax =0, sz; - int n = param._dog_level_num*_octave_num; - for( i = 0; i < n; i++) - { - sz = _featureTex[i].GetImgWidth() * _featureTex[i].GetImgHeight(); - if(sz > szmax ) szmax = sz; - } - float * buffer = new float[szmax*24]; - float * buffer1 = buffer; - float * buffer2 = buffer + szmax*4; - float * buffer3 = buffer + szmax*8; - - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - -#ifdef FEATURELIST_USE_PBO - GLuint ListUploadPBO; - glGenBuffers(1, &ListUploadPBO); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, ListUploadPBO); - glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, szmax * 8 * sizeof(float), NULL, GL_STREAM_DRAW); -#endif - - _featureNum = 0; - -#ifdef NO_DUPLICATE_DOWNLOAD - const double twopi = 2.0*3.14159265358979323846; - _keypoint_buffer.resize(0); - float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - if(_down_sample_factor>0) os *= float(1<<_down_sample_factor); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; -#endif - - for(i = 0; i < n; i++) - { - if(_levelFeatureNum[i]==0)continue; - - _featureTex[i].AttachToFBO(0); - _featureTex[i].FitTexViewPort(); - glReadPixels(0, 0, _featureTex[i].GetImgWidth(), _featureTex[i].GetImgHeight(),GL_RGBA, GL_FLOAT, buffer1); - - int fcount =0, ocount; - float * src = buffer1; - float * orientation = buffer2; - float * des = buffer3; - if(GlobalUtil::_OrientationPack2 == 0) - { - //read back orientations from another texture - _orientationTex[i].AttachToFBO(0); - glReadPixels(0, 0, _orientationTex[i].GetImgWidth(), _orientationTex[i].GetImgHeight(),GL_RGBA, GL_FLOAT, buffer2); - //make the feature list - for(int j = 0; j < _levelFeatureNum[i]; j++, src+=4, orientation+=4) - { - if(_existing_keypoints) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = orientation[0]; - des[3] = src[3]; - fcount++; - des += 4; - }else - { - ocount = (int)src[2]; - for(int k = 0 ; k < ocount; k++, des+=4) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = orientation[k]; - des[3] = src[3]; - fcount++; - } - } - } - }else - { - _featureTex[i].DetachFBO(0); - const static double factor = 2.0*3.14159265358979323846/65535.0; - for(int j = 0; j < _levelFeatureNum[i]; j++, src+=4) - { - unsigned short * orientations = (unsigned short*) (&src[2]); - if(_existing_keypoints) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = float( factor* orientations[0]); - des[3] = src[3]; - fcount++; - des += 4; - }else - { - if(orientations[0] != 65535) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = float( factor* orientations[0]); - des[3] = src[3]; - fcount++; - des += 4; - - if(orientations[1] != 65535) - { - des[0] = src[0]; - des[1] = src[1]; - des[2] = float(factor* orientations[1]); - des[3] = src[3]; - fcount++; - des += 4; - } - } - } - } - } - - if (fcount == 0){ _levelFeatureNum[i] = 0; continue; } - - //texture size -------------- - SetLevelFeatureNum(i, fcount); - int nfw = _featureTex[i].GetImgWidth(); - int nfh = _featureTex[i].GetImgHeight(); - int sz = nfh * nfw; - if(sz > fcount) memset(des, 0, sizeof(float) * (sz - fcount) * 4); - -#ifndef FEATURELIST_USE_PBO - _featureTex[i].BindTex(); - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, nfw, nfh, GL_RGBA, GL_FLOAT, buffer3); - _featureTex[i].UnbindTex(); -#else - float* mem = (float*) glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY); - memcpy(mem, buffer3, sz * 4 * sizeof(float) ); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); - _featureTex[i].BindTex(); - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, nfw, nfh, GL_RGBA, GL_FLOAT, 0); - _featureTex[i].UnbindTex(); -#endif - -#ifdef NO_DUPLICATE_DOWNLOAD - if(fcount > 0) - { - float oss = os * (1 << (i / param._dog_level_num)); - _keypoint_buffer.resize((_featureNum + fcount) * 4); - float* ds = &_keypoint_buffer[_featureNum * 4]; - float* fs = buffer3; - for(int k = 0; k < fcount; k++, ds+=4, fs+=4) - { - ds[0] = oss*(fs[0]-0.5f) + offset; //x - ds[1] = oss*(fs[1]-0.5f) + offset; //y - ds[3] = (float)fmod(twopi-fs[2], twopi); //orientation, mirrored - ds[2] = oss*fs[3]; //scale - } - } -#endif - _levelFeatureNum[i] = fcount; - _featureNum += fcount; - } - - delete[] buffer; - if(GlobalUtil::_verbose) - { - std::cout<<"#Features MO:\t"<<_featureNum< ftex->GetTexWidth()*ftex->GetTexHeight()) - { - ftex->InitTexture(fw, fh, 0); - if(_orientationTex) _orientationTex[idx].InitTexture(fw, fh, 0); - - } - if(GlobalUtil::_NarrowFeatureTex) - fh = fcount ==0? 0:(int)ceil(double(fcount)/fw); - else - fw = fcount ==0? 0:(int)ceil(double(fcount)/fh); - ftex->SetImageSize(fw, fh); - if(_orientationTex) _orientationTex[idx].SetImageSize(fw, fh); -} - -void PyramidGL::CleanUpAfterSIFT() -{ - GLTexImage::UnbindMultiTex(3); - ShaderMan::UnloadProgram(); - FrameBufferObject::DeleteGlobalFBO(); - GlobalUtil::CleanupOpenGL(); -} - -void PyramidNaive::GetSimplifiedOrientation() -{ - // - int idx = 0; -// int n = _octave_num * param._dog_level_num; - float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num); - GLTexImage * ftex = _featureTex; - - FrameBufferObject fbo; - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - for(int i = 0; i < _octave_num; i++) - { - GLTexImage *gtex = GetLevelTexture(i+_octave_min, 2+param._level_min); - for(int j = 0; j < param._dog_level_num; j++, ftex++, gtex++, idx ++) - { - if(_levelFeatureNum[idx]<=0)continue; - sigma = param.GetLevelSigma(j+param._level_min+1); - - // - ftex->AttachToFBO(0); - ftex->FitTexViewPort(); - - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - glActiveTexture(GL_TEXTURE1); - gtex->BindTex(); - - ShaderMan::UseShaderSimpleOrientation(gtex->GetTexID(), sigma, sigma_step); - ftex->DrawQuad(); - } - } - - GLTexImage::UnbindMultiTex(2); - -} - - -#ifdef USE_SSE_FOR_SIFTGPU - static inline float dotproduct_128d(float * p) - { - float z = 0.0f; - __m128 sse =_mm_load_ss(&z); - float* pf = (float*) (&sse); - for( int i = 0; i < 32; i++, p+=4) - { - __m128 ps = _mm_loadu_ps(p); - sse = _mm_add_ps(sse, _mm_mul_ps(ps, ps)); - } - return pf[0] + pf[1] + pf[2] + pf[3]; - - } - static inline void multiply_and_truncate_128d(float* p, float m) - { - float z = 0.2f; - __m128 t = _mm_load_ps1(&z); - __m128 r = _mm_load_ps1(&m); - for(int i = 0; i < 32; i++, p+=4) - { - __m128 ps = _mm_loadu_ps(p); - _mm_storeu_ps(p, _mm_min_ps(_mm_mul_ps(ps, r), t)); - } - } - static inline void multiply_128d(float* p, float m) - { - __m128 r = _mm_load_ps1(&m); - for(int i = 0; i < 32; i++, p+=4) - { - __m128 ps = _mm_loadu_ps(p); - _mm_storeu_ps(p, _mm_mul_ps(ps, r)); - } - } -#endif - - -inline void PyramidGL::NormalizeDescriptor(int num, float*pd) -{ - -#ifdef USE_SSE_FOR_SIFTGPU - for(int k = 0; k < num; k++, pd +=128) - { - float sq; - //normalize and truncate to .2 - sq = dotproduct_128d(pd); sq = 1.0f / sqrtf(sq); - multiply_and_truncate_128d(pd, sq); - - //renormalize - sq = dotproduct_128d(pd); sq = 1.0f / sqrtf(sq); - multiply_128d(pd, sq); - } -#else - //descriptor normalization runs on cpu for OpenGL implemenations - for(int k = 0; k < num; k++, pd +=128) - { - int v; - float* ppd, sq = 0; - //int v; - //normalize - ppd = pd; - for(v = 0 ; v < 128; v++, ppd++) sq += (*ppd)*(*ppd); - sq = 1.0f / sqrtf(sq); - //truncate to .2 - ppd = pd; - for(v = 0; v < 128; v ++, ppd++) *ppd = min(*ppd*sq, 0.2f); - - //renormalize - ppd = pd; sq = 0; - for(v = 0; v < 128; v++, ppd++) sq += (*ppd)*(*ppd); - sq = 1.0f / sqrtf(sq); - - ppd = pd; - for(v = 0; v < 128; v ++, ppd++) *ppd = *ppd*sq; - } - -#endif -} - -inline void PyramidGL::InterlaceDescriptorF2(int w, int h, float* buf, float* pd, int step) -{ - /* - if(GlobalUtil::_DescriptorPPR == 8) - { - const int dstep = w * 128; - float* pp1 = buf; - float* pp2 = buf + step; - - for(int u = 0; u < h ; u++, pd+=dstep) - { - int v; - float* ppd = pd; - for(v= 0; v < w; v++) - { - for(int t = 0; t < 8; t++) - { - *ppd++ = *pp1++;*ppd++ = *pp1++;*ppd++ = *pp1++;*ppd++ = *pp1++; - *ppd++ = *pp2++;*ppd++ = *pp2++;*ppd++ = *pp2++;*ppd++ = *pp2++; - } - ppd += 64; - } - ppd = pd + 64; - for(v= 0; v < w; v++) - { - for(int t = 0; t < 8; t++) - { - *ppd++ = *pp1++;*ppd++ = *pp1++;*ppd++ = *pp1++;*ppd++ = *pp1++; - *ppd++ = *pp2++;*ppd++ = *pp2++;*ppd++ = *pp2++;*ppd++ = *pp2++; - } - ppd += 64; - } - } - - }else */ - if(GlobalUtil::_DescriptorPPR == 8) - { - //interlace - for(int k = 0; k < 2; k++) - { - float* pp = buf + k * step; - float* ppd = pd + k * 4; - for(int u = 0; u < h ; u++) - { - int v; - for(v= 0; v < w; v++) - { - for(int t = 0; t < 8; t++) - { - ppd[0] = pp[0]; - ppd[1] = pp[1]; - ppd[2] = pp[2]; - ppd[3] = pp[3]; - ppd += 8; - pp+= 4; - } - ppd += 64; - } - ppd += ( 64 - 128 * w ); - for(v= 0; v < w; v++) - { - for(int t = 0; t < 8; t++) - { - ppd[0] = pp[0]; - ppd[1] = pp[1]; - ppd[2] = pp[2]; - ppd[3] = pp[3]; - - ppd += 8; - pp+= 4; - } - ppd += 64; - } - ppd -=64; - } - } - }else if(GlobalUtil::_DescriptorPPR == 4) - { - - } - - - -} -void PyramidGL::GetFeatureDescriptors() -{ - //descriptors... - float sigma; - int idx, i, j, k, w, h; - int ndf = 32 / GlobalUtil::_DescriptorPPT; //number of textures - int block_width = GlobalUtil::_DescriptorPPR; - int block_height = GlobalUtil::_DescriptorPPT/GlobalUtil::_DescriptorPPR; - float* pd = &_descriptor_buffer[0], * pbuf = NULL; - vectorread_buffer, descriptor_buffer2; - - //use another buffer, if we need to re-order the descriptors - if(_keypoint_index.size() > 0) - { - descriptor_buffer2.resize(_descriptor_buffer.size()); - pd = &descriptor_buffer2[0]; - } - FrameBufferObject fbo; - - GLTexImage * gtex, *otex, * ftex; - GLenum buffers[8] = { - GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT , - GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT , - GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT , - GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT , - }; - - glDrawBuffers(ndf, buffers); - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - - - for( i = 0, idx = 0, ftex = _featureTex; i < _octave_num; i++) - { - gtex = GetBaseLevel(i + _octave_min, DATA_GRAD) + 1; - otex = GetBaseLevel(i + _octave_min, DATA_ROT) + 1; - for( j = 0; j < param._dog_level_num; j++, ftex++, idx++, gtex++, otex++) - { - if(_levelFeatureNum[idx]==0)continue; - - sigma = IsUsingRectDescription()? 0 : param.GetLevelSigma(j+param._level_min+1); - int count = _levelFeatureNum[idx] * block_width; - GetAlignedStorageSize(count, block_width, w, h); - h = ((int)ceil(double(count) / w)) * block_height; - - //not enought space for holding the descriptor data - if(w > _descriptorTex[0].GetTexWidth() || h > _descriptorTex[0].GetTexHeight()) - { - for(k = 0; k < ndf; k++)_descriptorTex[k].InitTexture(w, h); - } - for(k = 0; k < ndf; k++) _descriptorTex[k].AttachToFBO(k); - GlobalUtil::FitViewPort(w, h); - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - glActiveTexture(GL_TEXTURE1); - gtex->BindTex(); - if(otex!=gtex) - { - glActiveTexture(GL_TEXTURE2); - otex->BindTex(); - } - - ShaderMan::UseShaderDescriptor(gtex->GetTexID(), otex->GetTexID(), - w, ftex->GetImgWidth(), gtex->GetImgWidth(), gtex->GetImgHeight(), sigma); - GLTexImage::DrawQuad(0, (float)w, 0, (float)h); - - //read back float format descriptors and do normalization on CPU - int step = w*h*4; - if((unsigned int)step*ndf > read_buffer.size()) - { - read_buffer.resize(ndf*step); - } - pbuf = &read_buffer[0]; - - //read back - for(k = 0; k < ndf; k++, pbuf+=step) - { - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + k); - if(GlobalUtil::_IsNvidia || w * h <= 16384) //were - { - glReadPixels(0, 0, w, h, GL_RGBA, GL_FLOAT, pbuf); - }else - { - int hstep = 16384 / w; - for(int kk = 0; kk < h; kk += hstep) - glReadPixels(0, kk, w, min(hstep, h - kk), GL_RGBA, GL_FLOAT, pbuf + w * kk * 4); - } - } - - //the following two steps run on cpu, so better cpu better speed - //and release version can be a lot faster than debug version - //interlace data on the two texture to get the descriptor - InterlaceDescriptorF2(w / block_width, h / block_height, &read_buffer[0], pd, step); - - //need to do normalization - //the new version uses SSE to speed up this part - if(GlobalUtil::_NormalizedSIFT) NormalizeDescriptor(_levelFeatureNum[idx], pd); - - pd += 128*_levelFeatureNum[idx]; - glReadBuffer(GL_NONE); - } - } - - - //finally, put the descriptor back to their original order for existing keypoint list. - if(_keypoint_index.size() > 0) - { - for(i = 0; i < _featureNum; ++i) - { - int index = _keypoint_index[i]; - memcpy(&_descriptor_buffer[index*128], &descriptor_buffer2[i*128], 128 * sizeof(float)); - } - } - - //////////////////////// - GLTexImage::UnbindMultiTex(3); - glDrawBuffer(GL_NONE); - ShaderMan::UnloadProgram(); - if(GlobalUtil::_timingS)glFinish(); - for(i = 0; i < ndf; i++) fbo.UnattachTex(GL_COLOR_ATTACHMENT0_EXT +i); - -} - - -void PyramidGL::DownloadKeypoints() -{ - const double twopi = 2.0*3.14159265358979323846; - int idx = 0; - float * buffer = &_keypoint_buffer[0]; - vector keypoint_buffer2; - //use a different keypoint buffer when processing with an exisint features list - //without orientation information. - if(_keypoint_index.size() > 0) - { - keypoint_buffer2.resize(_keypoint_buffer.size()); - buffer = &keypoint_buffer2[0]; - } - float * p = buffer, *ps, sigma; - GLTexImage * ftex = _featureTex; - FrameBufferObject fbo; - ftex->FitRealTexViewPort(); - ///////////////////// - float os = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - if(_down_sample_factor>0) os *= float(1<<_down_sample_factor); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; - ///////////////////// - for(int i = 0; i < _octave_num; i++, os *= 2.0f) - { - - for(int j = 0; j < param._dog_level_num; j++, idx++, ftex++) - { - - if(_levelFeatureNum[idx]>0) - { - ftex->AttachToFBO(0); - glReadPixels(0, 0, ftex->GetImgWidth(), ftex->GetImgHeight(),GL_RGBA, GL_FLOAT, p); - ps = p; - for(int k = 0; k < _levelFeatureNum[idx]; k++, ps+=4) - { - ps[0] = os*(ps[0]-0.5f) + offset; //x - ps[1] = os*(ps[1]-0.5f) + offset; //y - sigma = os*ps[3]; - ps[3] = (float)fmod(twopi-ps[2], twopi); //orientation, mirrored - ps[2] = sigma; //scale - } - p+= 4* _levelFeatureNum[idx]; - } - } - } - - //put the feature into their original order - - if(_keypoint_index.size() > 0) - { - for(int i = 0; i < _featureNum; ++i) - { - int index = _keypoint_index[i]; - memcpy(&_keypoint_buffer[index*4], &keypoint_buffer2[i*4], 4 * sizeof(float)); - } - } -} - - -void PyramidGL::GenerateFeatureListTex() -{ - //generate feature list texture from existing keypoints - //do feature sorting in the same time? - - FrameBufferObject fbo; - vector list; - int idx = 0; - const double twopi = 2.0*3.14159265358979323846; - float sigma_half_step = powf(2.0f, 0.5f / param._dog_level_num); - float octave_sigma = _octave_min>=0? float(1<<_octave_min): 1.0f/(1<<(-_octave_min)); - float offset = GlobalUtil::_LoweOrigin? 0 : 0.5f; - if(_down_sample_factor>0) octave_sigma *= float(1<<_down_sample_factor); - - - std::fill(_levelFeatureNum, _levelFeatureNum + _octave_num * param._dog_level_num, 0); - - _keypoint_index.resize(0); // should already be 0 - for(int i = 0; i < _octave_num; i++, octave_sigma*= 2.0f) - { - for(int j = 0; j < param._dog_level_num; j++, idx++) - { - list.resize(0); - float level_sigma = param.GetLevelSigma(j + param._level_min + 1) * octave_sigma; - float sigma_min = level_sigma / sigma_half_step; - float sigma_max = level_sigma * sigma_half_step; - int fcount = 0 ; - for(int k = 0; k < _featureNum; k++) - { - float * key = &_keypoint_buffer[k*4]; - float sigmak = key[2]; - - ////////////////////////////////////// - if(IsUsingRectDescription()) sigmak = min(key[2], key[3]) / 12.0f; - - if( (sigmak >= sigma_min && sigmak < sigma_max) - ||(sigmak < sigma_min && i ==0 && j == 0) - ||(sigmak > sigma_max && j == param._dog_level_num - 1&& - (i == _octave_num -1 || GlobalUtil::_KeyPointListForceLevel0))) - { - //add this keypoint to the list - list.push_back((key[0] - offset) / octave_sigma + 0.5f); - list.push_back((key[1] - offset) / octave_sigma + 0.5f); - if(IsUsingRectDescription()) - { - list.push_back(key[2] / octave_sigma); - list.push_back(key[3] / octave_sigma); - }else - { - list.push_back((float)fmod(twopi-key[3], twopi)); - list.push_back(key[2] / octave_sigma); - } - fcount ++; - //save the index of keypoints - _keypoint_index.push_back(k); - } - } - - _levelFeatureNum[idx] = fcount; - if(fcount==0)continue; - GLTexImage * ftex = _featureTex+idx; - - SetLevelFeatureNum(idx, fcount); - - int fw = ftex->GetImgWidth(); - int fh = ftex->GetImgHeight(); - - list.resize(4*fh*fw); - - ftex->BindTex(); - ftex->AttachToFBO(0); - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, fw, fh, GL_RGBA, GL_FLOAT, &list[0]); - - if( fcount == _featureNum) _keypoint_index.resize(0); - } - if( GlobalUtil::_KeyPointListForceLevel0 ) break; - } - GLTexImage::UnbindTex(); - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - } -} - - - -PyramidPacked::PyramidPacked(SiftParam& sp): PyramidGL(sp) -{ - _allPyramid = NULL; -} - -PyramidPacked::~PyramidPacked() -{ - DestroyPyramidData(); -} - - -//build the gaussian pyrmaid - -void PyramidPacked::BuildPyramid(GLTexInput * input) -{ - // - USE_TIMING(); - GLTexImage * tex, *tmp; - FilterProgram ** filter; - FrameBufferObject fbo; - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - input->FitTexViewPort(); - - for (int i = _octave_min; i < _octave_min + _octave_num; i++) - { - tex = GetBaseLevel(i); - tmp = GetBaseLevel(i, DATA_DOG) + 2; //use this as a temperory texture - - - filter = ShaderMan::s_bag->f_gaussian_step; - - OCTAVE_START(); - - if( i == _octave_min ) - { - if(i < 0) TextureUpSample(tex, input, 1<<(-i-1)); - else TextureDownSample(tex, input, 1<<(i+1)); - ShaderMan::FilterInitialImage(tex, tmp); - }else - { - TextureDownSample(tex, GetLevelTexture(i-1, param._level_ds)); - ShaderMan::FilterSampledImage(tex, tmp); - } - LEVEL_FINISH(); - - for(int j = param._level_min + 1; j <= param._level_max ; j++, tex++, filter++) - { - // filtering - ShaderMan::FilterImage(*filter, tex+1, tex, tmp); - LEVEL_FINISH(); - } - - OCTAVE_FINISH(); - - } - if(GlobalUtil::_timingS) glFinish(); - UnloadProgram(); -} - -void PyramidPacked::ComputeGradient() -{ - - //first pass, compute dog, gradient, orientation - GLenum buffers[4] = { - GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT , - GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT - }; - - int i, j; - double ts, t1; - FrameBufferObject fbo; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - for(i = _octave_min; i < _octave_min + _octave_num; i++) - { - GLTexImage * gus = GetBaseLevel(i) + 1; - GLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1; - GLTexImage * grd = GetBaseLevel(i, DATA_GRAD) + 1; - GLTexImage * rot = GetBaseLevel(i, DATA_ROT) + 1; - glDrawBuffers(3, buffers); - gus->FitTexViewPort(); - //compute the gradient - for(j = 0; j < param._dog_level_num ; j++, gus++, dog++, grd++, rot++) - { - //gradient, dog, orientation - glActiveTexture(GL_TEXTURE0); - gus->BindTex(); - glActiveTexture(GL_TEXTURE1); - (gus-1)->BindTex(); - //output - dog->AttachToFBO(0); - grd->AttachToFBO(1); - rot->AttachToFBO(2); - ShaderMan::UseShaderGradientPass((gus-1)->GetTexID()); - //compute - dog->DrawQuadMT4(); - } - } - if(GlobalUtil::_timingS) - { - glFinish(); - if(GlobalUtil::_verbose) - { - t1 = CLOCK(); - std::cout <<"\t"<<(t1-ts)<<"\n"; - } - } - GLTexImage::DetachFBO(1); - GLTexImage::DetachFBO(2); - UnloadProgram(); - GLTexImage::UnbindMultiTex(3); - fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT); -} - -void PyramidPacked::DetectKeypointsEX() -{ - - //first pass, compute dog, gradient, orientation - GLenum buffers[4] = { - GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT , - GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT - }; - - int i, j; - double t0, t, ts, t1, t2; - FrameBufferObject fbo; - - if(GlobalUtil::_timingS && GlobalUtil::_verbose)ts = CLOCK(); - - for(i = _octave_min; i < _octave_min + _octave_num; i++) - { - GLTexImage * gus = GetBaseLevel(i) + 1; - GLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 1; - GLTexImage * grd = GetBaseLevel(i, DATA_GRAD) + 1; - GLTexImage * rot = GetBaseLevel(i, DATA_ROT) + 1; - glDrawBuffers(3, buffers); - gus->FitTexViewPort(); - //compute the gradient - for(j = param._level_min +1; j <= param._level_max ; j++, gus++, dog++, grd++, rot++) - { - //gradient, dog, orientation - glActiveTexture(GL_TEXTURE0); - gus->BindTex(); - glActiveTexture(GL_TEXTURE1); - (gus-1)->BindTex(); - //output - dog->AttachToFBO(0); - grd->AttachToFBO(1); - rot->AttachToFBO(2); - ShaderMan::UseShaderGradientPass((gus-1)->GetTexID()); - //compute - dog->DrawQuadMT4(); - } - } - if(GlobalUtil::_timingS && GlobalUtil::_verbose) - { - glFinish(); - t1 = CLOCK(); - } - GLTexImage::DetachFBO(1); - GLTexImage::DetachFBO(2); - //glDrawBuffers(1, buffers); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - - - GlobalUtil::CheckErrorsGL(); - - for ( i = _octave_min; i < _octave_min + _octave_num; i++) - { - if(GlobalUtil::_timingO) - { - t0 = CLOCK(); - std::cout<<"#"<<(i + _down_sample_factor)<<"\t"; - } - GLTexImage * dog = GetBaseLevel(i, DATA_DOG) + 2; - GLTexImage * key = GetBaseLevel(i, DATA_KEYPOINT) +2; - GLTexImage * gus = GetBaseLevel(i) + 2; - key->FitTexViewPort(); - - for( j = param._level_min +2; j < param._level_max ; j++, dog++, key++, gus++) - { - if(GlobalUtil::_timingL)t = CLOCK(); - key->AttachToFBO(0); - glActiveTexture(GL_TEXTURE0); - dog->BindTex(); - glActiveTexture(GL_TEXTURE1); - (dog+1)->BindTex(); - glActiveTexture(GL_TEXTURE2); - (dog-1)->BindTex(); - if(GlobalUtil::_DarknessAdaption) - { - glActiveTexture(GL_TEXTURE3); - gus->BindTex(); - } - ShaderMan::UseShaderKeypoint((dog+1)->GetTexID(), (dog-1)->GetTexID()); - key->DrawQuadMT8(); - if(GlobalUtil::_timingL) - { - glFinish(); - std::cout<<(CLOCK()-t)<<"\t"; - } - } - if(GlobalUtil::_timingO) - { - glFinish(); - std::cout<<"|\t"<<(CLOCK()-t0)<<"\n"; - } - } - - if(GlobalUtil::_timingS) - { - glFinish(); - if(GlobalUtil::_verbose) - { - t2 = CLOCK(); - std::cout <<"\t"<<(t1-ts)<<"\n" - <<"\t"<<(t2-t1)<<"\n"; - } - - } - UnloadProgram(); - GLTexImage::UnbindMultiTex(3); - fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT); -} - - -void PyramidPacked::GenerateFeatureList(int i, int j) -{ - float fcount = 0.0f; - int hist_skip_gpu = GlobalUtil::_ListGenSkipGPU; - int idx = i * param._dog_level_num + j; - int hist_level_num = _hpLevelNum - _pyramid_octave_first; - GLTexImage * htex, * ftex, * tex; - htex = _histoPyramidTex + hist_level_num - 1 - i; - ftex = _featureTex + idx; - tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + 2 + j; - - - //fill zero to an extra row/col if the height/width is odd - glActiveTexture(GL_TEXTURE0); - tex->BindTex(); - htex->AttachToFBO(0); - int tight = (htex->GetImgWidth() * 4 == tex->GetImgWidth() -1 && htex->GetImgHeight() *4 == tex->GetImgHeight()-1 ); - ShaderMan::UseShaderGenListInit(tex->GetImgWidth(), tex->GetImgHeight(), tight); - htex->FitTexViewPort(); - //this uses the fact that no feature is on the edge. - htex->DrawQuadReduction(); - //reduction.. - htex--; - - //this part might have problems on several GPUS - //because the output of one pass is the input of the next pass - //may require glFinish to make it right, but too much glFinish makes it slow - for(int k = 0; k AttachToFBO(0); - htex->FitTexViewPort(); - (htex+1)->BindTex(); - ShaderMan::UseShaderGenListHisto(); - htex->DrawQuadReduction(); - } - - if(hist_skip_gpu == 0) - { - //read back one pixel - float fn[4]; - glReadPixels(0, 0, 1, 1, GL_RGBA , GL_FLOAT, fn); - fcount = (fn[0] + fn[1] + fn[2] + fn[3]); - if(fcount < 1) fcount = 0; - - _levelFeatureNum[ idx] = (int)(fcount); - SetLevelFeatureNum(idx, (int)fcount); - - //save number of features - _featureNum += int(fcount); - - // - if(fcount < 1.0) return;; - - - ///generate the feature texture - htex= _histoPyramidTex; - - htex->BindTex(); - - //first pass - ftex->AttachToFBO(0); - if(GlobalUtil::_MaxOrientation>1) - { - //this is very important... - ftex->FitRealTexViewPort(); - glClear(GL_COLOR_BUFFER_BIT); - glFinish(); - }else - { - ftex->FitTexViewPort(); - //glFinish(); - } - - - ShaderMan::UseShaderGenListStart((float)ftex->GetImgWidth(), htex->GetTexID()); - - ftex->DrawQuad(); - //make sure it finishes before the next step - ftex->DetachFBO(0); - //pass on each pyramid level - htex++; - }else - { - - int tw = htex[1].GetDrawWidth(), th = htex[1].GetDrawHeight(); - int fc = 0; - glReadPixels(0, 0, tw, th, GL_RGBA , GL_FLOAT, _histo_buffer); - _keypoint_buffer.resize(0); - for(int y = 0, pos = 0; y < th; y++) - { - for(int x= 0; x < tw; x++) - { - for(int c = 0; c < 4; c++, pos++) - { - int ss = (int) _histo_buffer[pos]; - if(ss == 0) continue; - float ft[4] = {2 * x + (c%2? 1.5f: 0.5f), 2 * y + (c>=2? 1.5f: 0.5f), 0, 1 }; - for(int t = 0; t < ss; t++) - { - ft[2] = (float) t; - _keypoint_buffer.insert(_keypoint_buffer.end(), ft, ft+4); - } - fc += (int)ss; - } - } - } - _levelFeatureNum[ idx] = fc; - SetLevelFeatureNum(idx, fc); - if(fc == 0) return; - - fcount = (float) fc; - _featureNum += fc; - ///////////////////// - ftex->AttachToFBO(0); - if(GlobalUtil::_MaxOrientation>1) - { - ftex->FitRealTexViewPort(); - glClear(GL_COLOR_BUFFER_BIT); - glFlush(); - }else - { - ftex->FitTexViewPort(); - glFlush(); - } - _keypoint_buffer.resize(ftex->GetDrawWidth() * ftex->GetDrawHeight()*4, 0); - /////////// - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, ftex->GetDrawWidth(), - ftex->GetDrawHeight(), GL_RGBA, GL_FLOAT, &_keypoint_buffer[0]); - htex += 2; - } - - for(int lev = 1 + hist_skip_gpu; lev < hist_level_num - i; lev++, htex++) - { - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - ftex->AttachToFBO(0); - glActiveTexture(GL_TEXTURE1); - htex->BindTex(); - ShaderMan::UseShaderGenListStep(ftex->GetTexID(), htex->GetTexID()); - ftex->DrawQuad(); - ftex->DetachFBO(0); - } - - ftex->AttachToFBO(0); - glActiveTexture(GL_TEXTURE1); - tex->BindTex(); - ShaderMan::UseShaderGenListEnd(tex->GetTexID()); - ftex->DrawQuad(); - GLTexImage::UnbindMultiTex(2); - -} - -void PyramidPacked::GenerateFeatureList() -{ - //generate the histogram pyramid - FrameBufferObject fbo; - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - double t1, t2; - int ocount= 0, reverse = (GlobalUtil::_TruncateMethod == 1); - _featureNum = 0; - - FitHistogramPyramid(); - //for(int i = 0, idx = 0; i < _octave_num; i++) - FOR_EACH_OCTAVE(i, reverse) - { - if(GlobalUtil::_timingO) - { - t1= CLOCK(); - ocount = 0; - std::cout<<"#"< 0 - && _featureNum > GlobalUtil::_FeatureCountThreshold) - { - _levelFeatureNum[i * param._dog_level_num + j] = 0; - continue; - } - - GenerateFeatureList(i, j); - - if(GlobalUtil::_timingO) - { - int idx = i * param._dog_level_num + j; - ocount += _levelFeatureNum[idx]; - std::cout<< _levelFeatureNum[idx] <<"\t"; - } - } - if(GlobalUtil::_timingO) - { - t2 = CLOCK(); - std::cout << "| \t" << int(ocount) << " :\t(" << (t2 - t1) << ")\n"; - } - } - if(GlobalUtil::_timingS)glFinish(); - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - } - -} - -void PyramidPacked::GenerateFeatureListCPU() -{ - FrameBufferObject fbo; - _featureNum = 0; - GLTexImage * tex = GetBaseLevel(_octave_min); - float * mem = new float [tex->GetTexWidth()*tex->GetTexHeight()*4]; - vector list; - int idx = 0; - for(int i = 0; i < _octave_num; i++) - { - for(int j = 0; j < param._dog_level_num; j++, idx++) - { - tex = GetBaseLevel(_octave_min + i, DATA_KEYPOINT) + j + 2; - tex->BindTex(); - glGetTexImage(GlobalUtil::_texTarget, 0, GL_RGBA, GL_FLOAT, mem); - //tex->AttachToFBO(0); - //tex->FitTexViewPort(); - //glReadPixels(0, 0, tex->GetTexWidth(), tex->GetTexHeight(), GL_RED, GL_FLOAT, mem); - // - //make a list of - list.resize(0); - float *pl = mem; - int fcount = 0 ; - for(int k = 0; k < tex->GetDrawHeight(); k++) - { - float * p = pl; - pl += tex->GetTexWidth() * 4; - for( int m = 0; m < tex->GetDrawWidth(); m ++, p+=4) - { - // if(m ==0 || k ==0 || k == tex->GetDrawHeight() -1 || m == tex->GetDrawWidth() -1) continue; - // if(*p == 0) continue; - int t = ((int) fabs(p[0])) - 1; - if(t < 0) continue; - int xx = m + m + ( (t %2)? 1 : 0); - int yy = k + k + ( (t <2)? 0 : 1); - if(xx ==0 || yy == 0) continue; - if(xx >= tex->GetImgWidth() - 1 || yy >= tex->GetImgHeight() - 1)continue; - list.push_back(xx + 0.5f + p[1]); - list.push_back(yy + 0.5f + p[2]); - list.push_back(GlobalUtil::_KeepExtremumSign && p[0] < 0 ? -1.0f : 1.0f); - list.push_back(p[3]); - fcount ++; - } - } - if(fcount==0)continue; - - if(GlobalUtil::_timingL) std::cout<GetImgWidth(); - int fh = ftex->GetImgHeight(); - - list.resize(4*fh*fw); - - ftex->BindTex(); - ftex->AttachToFBO(0); - // glTexImage2D(GlobalUtil::_texTarget, 0, GlobalUtil::_iTexFormat, fw, fh, 0, GL_BGRA, GL_FLOAT, &list[0]); - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, fw, fh, GL_RGBA, GL_FLOAT, &list[0]); - // - } - } - GLTexImage::UnbindTex(); - delete[] mem; - if(GlobalUtil::_verbose) - { - std::cout<<"#Features:\t"<<_featureNum<<"\n"; - } -} - - - -void PyramidPacked::GetFeatureOrientations() -{ - GLTexImage * gtex, * otex; - GLTexImage * ftex = _featureTex; - GLTexImage * fotex = _orientationTex; - int * count = _levelFeatureNum; - float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num); - - - FrameBufferObject fbo; - if(_orientationTex) - { - GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; - glDrawBuffers(2, buffers); - }else - { - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - } - - for(int i = 0; i < _octave_num; i++) - { - gtex = GetBaseLevel(i+_octave_min, DATA_GRAD) + 1; - otex = GetBaseLevel(i+_octave_min, DATA_ROT) + 1; - - for(int j = 0; j < param._dog_level_num; j++, ftex++, otex++, count++, gtex++, fotex++) - { - if(*count<=0)continue; - - sigma = param.GetLevelSigma(j+param._level_min+1); - - - ftex->FitTexViewPort(); - - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - glActiveTexture(GL_TEXTURE1); - gtex->BindTex(); - glActiveTexture(GL_TEXTURE2); - otex->BindTex(); - // - ftex->AttachToFBO(0); - if(_orientationTex) fotex->AttachToFBO(1); - - GlobalUtil::CheckFramebufferStatus(); - - ShaderMan::UseShaderOrientation(gtex->GetTexID(), - gtex->GetImgWidth(), gtex->GetImgHeight(), - sigma, otex->GetTexID(), sigma_step, _existing_keypoints); - ftex->DrawQuad(); - } - } - - GLTexImage::UnbindMultiTex(3); - if(GlobalUtil::_timingS)glFinish(); - if(_orientationTex) fbo.UnattachTex(GL_COLOR_ATTACHMENT1_EXT); - -} - - -void PyramidPacked::GetSimplifiedOrientation() -{ - // - int idx = 0; -// int n = _octave_num * param._dog_level_num; - float sigma, sigma_step = powf(2.0f, 1.0f/param._dog_level_num); - GLTexImage * ftex = _featureTex; - - FrameBufferObject fbo; - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - for(int i = 0; i < _octave_num; i++) - { - GLTexImage *otex = GetBaseLevel(i + _octave_min, DATA_ROT) + 2; - for(int j = 0; j < param._dog_level_num; j++, ftex++, otex++, idx ++) - { - if(_levelFeatureNum[idx]<=0)continue; - sigma = param.GetLevelSigma(j+param._level_min+1); - // - ftex->AttachToFBO(0); - ftex->FitTexViewPort(); - - glActiveTexture(GL_TEXTURE0); - ftex->BindTex(); - glActiveTexture(GL_TEXTURE1); - otex->BindTex(); - - ShaderMan::UseShaderSimpleOrientation(otex->GetTexID(), sigma, sigma_step); - ftex->DrawQuad(); - } - } - GLTexImage::UnbindMultiTex(2); -} - -void PyramidPacked::InitPyramid(int w, int h, int ds) -{ - int wp, hp, toobig = 0; - if(ds == 0) - { - _down_sample_factor = 0; - if(GlobalUtil::_octave_min_default>=0) - { - wp = w >> GlobalUtil::_octave_min_default; - hp = h >> GlobalUtil::_octave_min_default; - }else - { - wp = w << (-GlobalUtil::_octave_min_default); - hp = h << (-GlobalUtil::_octave_min_default); - } - _octave_min = _octave_min_default; - }else - { - //must use 0 as _octave_min; - _octave_min = 0; - _down_sample_factor = ds; - w >>= ds; - h >>= ds; - wp = w; - hp = h; - } - - while(wp > GlobalUtil::_texMaxDim || hp > GlobalUtil::_texMaxDim ) - { - _octave_min ++; - wp >>= 1; - hp >>= 1; - toobig = 1; - } - - while(GlobalUtil::_MemCapGPU > 0 && GlobalUtil::_FitMemoryCap && (wp >_pyramid_width || hp > _pyramid_height) && - max(max(wp, hp), max(_pyramid_width, _pyramid_height)) > 1024 * sqrt(GlobalUtil::_MemCapGPU / 96.0) ) - { - _octave_min ++; - wp >>= 1; - hp >>= 1; - toobig = 2; - } - - if(toobig && GlobalUtil::_verbose) - { - std::cout<<(toobig == 2 ? "[**SKIP OCTAVES**]:\tExceeding Memory Cap (-nomc)\n" : - "[**SKIP OCTAVES**]:\tReaching the dimension limit (-maxd)!\n"); - } - - if( wp == _pyramid_width && hp == _pyramid_height && _allocated ) - { - FitPyramid(wp, hp); - }else if(GlobalUtil::_ForceTightPyramid || _allocated ==0) - { - ResizePyramid(wp, hp); - } - else if( wp > _pyramid_width || hp > _pyramid_height ) - { - ResizePyramid(max(wp, _pyramid_width), max(hp, _pyramid_height)); - if(wp < _pyramid_width || hp < _pyramid_height) FitPyramid(wp, hp); - } - else - { - //try use the pyramid allocated for large image on small input images - FitPyramid(wp, hp); - } - - //select the initial smoothing filter according to the new _octave_min - ShaderMan::SelectInitialSmoothingFilter(_octave_min + _down_sample_factor, param); -} - - - -void PyramidPacked::FitPyramid(int w, int h) -{ - //(w, h) <= (_pyramid_width, _pyramid_height); - - _pyramid_octave_first = 0; - // - _octave_num = GlobalUtil::_octave_num_default; - - int _octave_num_max = GetRequiredOctaveNum(min(w, h)); - - if(_octave_num < 1 || _octave_num > _octave_num_max) - { - _octave_num = _octave_num_max; - } - - - int pw = _pyramid_width>>1, ph = _pyramid_height>>1; - while(_pyramid_octave_first + _octave_num < _pyramid_octave_num && - pw >= w && ph >= h) - { - _pyramid_octave_first++; - pw >>= 1; - ph >>= 1; - } - - for(int i = 0; i < _octave_num; i++) - { - GLTexImage * tex = GetBaseLevel(i + _octave_min); - GLTexImage * dog = GetBaseLevel(i + _octave_min, DATA_DOG); - GLTexImage * grd = GetBaseLevel(i + _octave_min, DATA_GRAD); - GLTexImage * rot = GetBaseLevel(i + _octave_min, DATA_ROT); - GLTexImage * key = GetBaseLevel(i + _octave_min, DATA_KEYPOINT); - for(int j = param._level_min; j <= param._level_max; j++, tex++, dog++, grd++, rot++, key++) - { - tex->SetImageSize(w, h); - if(j == param._level_min) continue; - dog->SetImageSize(w, h); - grd->SetImageSize(w, h); - rot->SetImageSize(w, h); - if(j == param._level_min + 1 || j == param._level_max) continue; - key->SetImageSize(w, h); - } - w>>=1; - h>>=1; - } -} - - -void PyramidPacked::ResizePyramid( int w, int h) -{ - // - unsigned int totalkb = 0; - int _octave_num_new, input_sz, i, j; - // - - if(_pyramid_width == w && _pyramid_height == h && _allocated) return; - - if(w > GlobalUtil::_texMaxDim || h > GlobalUtil::_texMaxDim) return ; - - if(GlobalUtil::_verbose && GlobalUtil::_timingS) std::cout<<"[Allocate Pyramid]:\t" <0) - { - DestroyPerLevelData(); - DestroyPyramidData(); - } - _pyramid_octave_num = _octave_num_new; - } - - _octave_num = _pyramid_octave_num; - - int noct = _octave_num; - int nlev = param._level_num; - - // //initialize the pyramid - if(_allPyramid==NULL) _allPyramid = new GLTexPacked[ noct* nlev * DATA_NUM]; - - - GLTexPacked * gus = (GLTexPacked *) GetBaseLevel(_octave_min, DATA_GAUSSIAN); - GLTexPacked * dog = (GLTexPacked *) GetBaseLevel(_octave_min, DATA_DOG); - GLTexPacked * grd = (GLTexPacked *) GetBaseLevel(_octave_min, DATA_GRAD); - GLTexPacked * rot = (GLTexPacked *) GetBaseLevel(_octave_min, DATA_ROT); - GLTexPacked * key = (GLTexPacked *) GetBaseLevel(_octave_min, DATA_KEYPOINT); - - - ////////////there could be "out of memory" happening during the allocation - - for(i = 0; i< noct; i++) - { - for( j = 0; j< nlev; j++, gus++, dog++, grd++, rot++, key++) - { - gus->InitTexture(w, h); - if(j==0)continue; - dog->InitTexture(w, h); - grd->InitTexture(w, h, 0); - rot->InitTexture(w, h); - if(j<=1 || j >=nlev -1) continue; - key->InitTexture(w, h, 0); - } - int tsz = (gus -1)->GetTexPixelCount() * 16; - totalkb += ((nlev *5 -6)* tsz / 1024); - //several auxilary textures are not actually required - w>>=1; - h>>=1; - } - - totalkb += ResizeFeatureStorage(); - - _allocated = 1; - - if(GlobalUtil::_verbose && GlobalUtil::_timingS) std::cout<<"[Allocate Pyramid]:\t" <<(totalkb/1024)<<"MB\n"; - -} - -void PyramidPacked::DestroyPyramidData() -{ - if(_allPyramid) - { - delete [] _allPyramid; - _allPyramid = NULL; - } -} - - -GLTexImage* PyramidPacked::GetLevelTexture(int octave, int level, int dataName) -{ - return _allPyramid+ (_pyramid_octave_first + octave - _octave_min) * param._level_num - + param._level_num * _pyramid_octave_num * dataName - + (level - param._level_min); - -} - -GLTexImage* PyramidPacked::GetLevelTexture(int octave, int level) -{ - return _allPyramid+ (_pyramid_octave_first + octave - _octave_min) * param._level_num - + (level - param._level_min); -} - -//in the packed implementation( still in progress) -// DATA_GAUSSIAN, DATA_DOG, DATA_GAD will be stored in different textures. - -GLTexImage* PyramidPacked::GetBaseLevel(int octave, int dataName) -{ - if(octave <_octave_min || octave > _octave_min + _octave_num) return NULL; - int offset = (_pyramid_octave_first + octave - _octave_min) * param._level_num; - int num = param._level_num * _pyramid_octave_num; - return _allPyramid + num *dataName + offset; -} - - -void PyramidPacked::FitHistogramPyramid() -{ - GLTexImage * tex, *htex; - int hist_level_num = _hpLevelNum - _pyramid_octave_first; - - tex = GetBaseLevel(_octave_min , DATA_KEYPOINT) + 2; - htex = _histoPyramidTex + hist_level_num - 1; - int w = (tex->GetImgWidth() + 2) >> 2; - int h = (tex->GetImgHeight() + 2)>> 2; - - - //4n+1 -> n; 4n+2,2, 3 -> n+1 - for(int k = 0; k GetImgHeight()!= h || htex->GetImgWidth() != w) - { - htex->SetImageSize(w, h); - htex->ZeroHistoMargin(); - } - - w = (w + 1)>>1; h = (h + 1) >> 1; - } -} - diff --git a/3rdparty/SiftGPU/src/SiftGPU/PyramidGL.h b/3rdparty/SiftGPU/src/SiftGPU/PyramidGL.h deleted file mode 100644 index a5baafc2..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/PyramidGL.h +++ /dev/null @@ -1,119 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: PyramidGL.h -// Author: Changchang Wu -// Description : interface for the PyramdGL -// class PyramidNaive and PyramidPacked are derived from PyramidGL -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - - -#ifndef _PYRAMID_GL_H -#define _PYRAMID_GL_H - -class GLTexImage; -class SiftParam; -class ProgramGPU; -class ShaderMan; -class GlobalUtil; -class SiftPyramid; - -class PyramidGL:public SiftPyramid -{ -protected: - GLTexImage* _histoPyramidTex; - GLTexImage* _featureTex; - GLTexImage* _descriptorTex; - GLTexImage* _orientationTex; -public: - void InitializeContext(); - void SetLevelFeatureNum(int idx, int num); - void GetTextureStorageSize(int num, int &fw, int& fh); - void GetAlignedStorageSize(int num, int align, int &fw, int &fh); - static void InterlaceDescriptorF2(int w, int h, float* buf, float* pd, int step); - static void NormalizeDescriptor(int num, float*pd); - virtual void DownloadKeypoints(); - virtual int ResizeFeatureStorage(); - //////////////////////////// - virtual void DestroyPerLevelData(); - virtual void DestroySharedData(); - virtual void GetFeatureDescriptors(); - virtual void GenerateFeatureListTex(); - virtual void ReshapeFeatureListCPU(); - virtual void GenerateFeatureDisplayVBO(); - virtual void CleanUpAfterSIFT(); - virtual GLTexImage* GetBaseLevel(int octave, int dataName = DATA_GAUSSIAN)=0; -public: - PyramidGL(SiftParam&sp); - virtual ~PyramidGL(); -}; - -class PyramidNaive:public PyramidGL, public ShaderMan -{ -protected: - GLTexImage * _texPyramid; - GLTexImage * _auxPyramid; -public: - void DestroyPyramidData(); - void GetSimplifiedOrientation(); - void GenerateFeatureListCPU(); - virtual void GetFeatureOrientations(); - virtual void GenerateFeatureList(); - void DetectKeypointsEX(); - void ComputeGradient(); - GLTexImage* GetLevelTexture(int octave, int level); - GLTexImage* GetBaseLevel(int octave, int dataName = DATA_GAUSSIAN); - GLTexImage* GetLevelTexture(int octave, int level, int dataName); - void BuildPyramid(GLTexInput * input); - void InitPyramid(int w, int h, int ds); - void FitPyramid(int w, int h); - void ResizePyramid(int w, int h); - void FitHistogramPyramid(); - PyramidNaive(SiftParam & sp); - ~PyramidNaive(); -private: - void GenerateFeatureList(int i, int j); -}; - - -class PyramidPacked:public PyramidGL, public ShaderMan -{ - GLTexPacked * _allPyramid; -public: - PyramidPacked(SiftParam& sp); - ~PyramidPacked(); - void DestroyPyramidData(); - void DetectKeypointsEX(); - void ComputeGradient(); - void BuildPyramid(GLTexInput * input); - void InitPyramid(int w, int h, int ds); - void FitPyramid(int w, int h); - void ResizePyramid(int w, int h); - void FitHistogramPyramid(); - void GenerateFeatureListCPU(); - void GenerateFeatureList(); - void GetSimplifiedOrientation(); - void GetFeatureOrientations(); - GLTexImage* GetBaseLevel(int octave, int dataName = DATA_GAUSSIAN); - GLTexImage* GetLevelTexture(int octave, int level); - GLTexImage* GetLevelTexture(int octave, int level, int dataName); - virtual int IsUsingRectDescription(){return _existing_keypoints & SIFT_RECT_DESCRIPTION; } -private: - void GenerateFeatureList(int i, int j); -}; - -#endif diff --git a/3rdparty/SiftGPU/src/SiftGPU/ShaderMan.cpp b/3rdparty/SiftGPU/src/SiftGPU/ShaderMan.cpp deleted file mode 100644 index bddc0b2e..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ShaderMan.cpp +++ /dev/null @@ -1,349 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ShaderMan.cpp -// Author: Changchang Wu -// Description : implementation of the ShaderMan class. -// A Shader Manager that calls different implementation of shaders -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include "GL/glew.h" -#include -#include -#include -#include -using std::vector; -using std::ostream; -using std::endl; - - -#include "ProgramGLSL.h" -#include "GlobalUtil.h" -#include "GLTexImage.h" -#include "SiftGPU.h" -#include "ShaderMan.h" - -/// -ShaderBag * ShaderMan::s_bag = NULL; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -void ShaderMan::InitShaderMan(SiftParam¶m) -{ - if(s_bag) return; - - if(GlobalUtil::_usePackedTex ) s_bag = new ShaderBagPKSL; - else s_bag =new ShaderBagGLSL; - - GlobalUtil::StartTimer("Load Programs"); - s_bag->LoadFixedShaders(); - s_bag->LoadDynamicShaders(param); - if(GlobalUtil::_UseSiftGPUEX) s_bag->LoadDisplayShaders(); - GlobalUtil::StopTimer(); - - GlobalUtil::CheckErrorsGL("InitShaderMan"); -} - - -void ShaderMan::DestroyShaders() -{ - if(s_bag) delete s_bag; - s_bag = NULL; -} - -void ShaderMan::UnloadProgram() -{ - if(s_bag) s_bag->UnloadProgram(); -} - -void ShaderMan::FilterImage(FilterProgram* filter, GLTexImage *dst, GLTexImage *src, GLTexImage*tmp) -{ - if(filter == NULL) return; - - ////////////////////////////// - src->FillMargin(filter->_size, 0); - - //output parameter - if(tmp) tmp->AttachToFBO(0); - else dst->AttachToFBO(0); - - - //input parameter - src->BindTex(); - dst->FitTexViewPort(); - - //horizontal filter - filter->s_shader_h->UseProgram(); - dst->DrawQuad(); - - //parameters - if(tmp) - { - // fill margin for out-of-boundary lookup - tmp->DetachFBO(0); - tmp->AttachToFBO(0); - tmp->FillMargin(0, filter->_size); - tmp->DetachFBO(0); - dst->AttachToFBO(0); - tmp->BindTex(); - } - else - { - glFinish(); - // fill margin for out-of-boundary lookup - dst->FillMargin(0, filter->_size); - dst->BindTex(); - } - - //vertical filter - filter->s_shader_v->UseProgram(); - dst->DrawQuad(); - - - //clean up - dst->UnbindTex(); - dst->DetachFBO(0); - - // - ShaderMan::UnloadProgram(); -} - - -void ShaderMan::FilterInitialImage(GLTexImage* tex, GLTexImage* buf) -{ - if(s_bag->f_gaussian_skip0) FilterImage(s_bag->f_gaussian_skip0, tex, tex, buf); -} - -void ShaderMan::FilterSampledImage(GLTexImage* tex, GLTexImage* buf) -{ - if(s_bag->f_gaussian_skip1) FilterImage(s_bag->f_gaussian_skip1, tex, tex, buf); -} - -void ShaderMan::TextureCopy(GLTexImage*dst, GLTexImage*src) -{ - - dst->AttachToFBO(0); - - src->BindTex(); - - dst->FitTexViewPort(); - - dst->DrawQuad(); - - dst->UnbindTex(); -// ShaderMan::UnloadProgram(); - dst->DetachFBO(0); - return; -} -void ShaderMan::TextureDownSample(GLTexImage *dst, GLTexImage *src, int scale) -{ - //output parameter - - dst->AttachToFBO(0); - - //input parameter - src->BindTex(); - - // - dst->FitTexViewPort(); - - s_bag->s_sampling->UseProgram(); - - dst->DrawQuadDS(scale); - src->UnbindTex(); - - UnloadProgram(); - - dst->DetachFBO(0); -} - -void ShaderMan::TextureUpSample(GLTexImage *dst, GLTexImage *src, int scale) -{ - - //output parameter - dst->AttachToFBO(0); - //input parameter - src->BindTex(); - - dst->FitTexViewPort(); - - GlobalUtil::SetTextureParameterUS(); - - if(GlobalUtil::_usePackedTex) - { - s_bag->s_sampling->UseProgram(); - } - - dst->DrawQuadUS(scale); - src->UnbindTex(); - - UnloadProgram(); - - dst->DetachFBO(0); - - GlobalUtil::SetTextureParameter(); -} - - - -void ShaderMan::UseShaderDisplayGaussian() -{ - if(s_bag && s_bag->s_display_gaussian) s_bag->s_display_gaussian->UseProgram(); -} - -void ShaderMan::UseShaderDisplayDOG() -{ - if(s_bag && s_bag->s_display_dog) s_bag->s_display_dog->UseProgram(); -} - - - -void ShaderMan::UseShaderRGB2Gray() -{ - if(s_bag && s_bag->s_gray)s_bag->s_gray->UseProgram(); -} - - -void ShaderMan::UseShaderDisplayGrad() -{ - if(s_bag && s_bag->s_display_grad) s_bag->s_display_grad->UseProgram(); -} - - -void ShaderMan::UseShaderDisplayKeypoints() -{ - if(s_bag && s_bag->s_display_keys) s_bag->s_display_keys->UseProgram(); -} - - - - - -void ShaderMan::UseShaderGradientPass(int texP) -{ - s_bag->s_grad_pass->UseProgram(); - s_bag->SetGradPassParam(texP); -} - - -void ShaderMan::UseShaderKeypoint(int texU, int texD) -{ - s_bag->s_keypoint->UseProgram(); - s_bag->SetDogTexParam(texU, texD); -} - - - -void ShaderMan::UseShaderGenListInit(int w, int h, int tight) -{ - if(tight) - { - s_bag->s_genlist_init_tight->UseProgram(); - }else - { - s_bag->s_genlist_init_ex->UseProgram(); - s_bag->SetGenListInitParam(w, h); - } -} - -void ShaderMan::UseShaderGenListHisto() -{ - s_bag->s_genlist_histo->UseProgram(); - -} - - - - -void ShaderMan::UseShaderGenListStart(float fw, int tex0) -{ - s_bag->s_genlist_start->UseProgram(); - s_bag->SetGenListStartParam(fw, tex0); -} - -void ShaderMan::UseShaderGenListStep(int tex, int tex0) -{ - s_bag->s_genlist_step->UseProgram(); - s_bag->SetGenListStepParam( tex, tex0); -} - -void ShaderMan::UseShaderGenListEnd(int ktex) -{ - s_bag->s_genlist_end->UseProgram(); - s_bag->SetGenListEndParam(ktex); -} - -void ShaderMan::UseShaderDebug() -{ - if(s_bag->s_debug) s_bag->s_debug->UseProgram(); -} - -void ShaderMan::UseShaderZeroPass() -{ - if(s_bag->s_zero_pass) s_bag->s_zero_pass->UseProgram(); -} - -void ShaderMan::UseShaderGenVBO( float width, float fwidth, float size) -{ - s_bag->s_vertex_list->UseProgram(); - s_bag->SetGenVBOParam(width, fwidth, size); -} -void ShaderMan::UseShaderMarginCopy(int xmax, int ymax) -{ - s_bag->s_margin_copy->UseProgram(); - s_bag->SetMarginCopyParam(xmax, ymax); - -} -void ShaderMan::UseShaderCopyKeypoint() -{ - s_bag->s_copy_key->UseProgram(); -} - -void ShaderMan::UseShaderSimpleOrientation(int oTex, float sigma, float sigma_step) -{ - s_bag->s_orientation->UseProgram(); - s_bag->SetSimpleOrientationInput(oTex, sigma, sigma_step); -} - - - -void ShaderMan::UseShaderOrientation(int gtex, int width, int height, float sigma, int auxtex, float step, int keypoint_list) -{ - s_bag->s_orientation->UseProgram(); - - //changes in v345. - //set sigma to 0 to identify keypoit list mode - //set sigma to negative to identify fixed_orientation - if(keypoint_list) sigma = 0.0f; - else if(GlobalUtil::_FixedOrientation) sigma = - sigma; - - s_bag->SetFeatureOrientationParam(gtex, width, height, sigma, auxtex, step); -} - -void ShaderMan::UseShaderDescriptor(int gtex, int otex, int dwidth, int fwidth, int width, int height, float sigma) -{ - s_bag->s_descriptor_fp->UseProgram(); - s_bag->SetFeatureDescirptorParam(gtex, otex, (float)dwidth, (float)fwidth, (float)width, (float)height, sigma); -} - -void ShaderMan::SelectInitialSmoothingFilter(int octave_min, SiftParam¶m) -{ - s_bag->SelectInitialSmoothingFilter(octave_min, param); -} diff --git a/3rdparty/SiftGPU/src/SiftGPU/ShaderMan.h b/3rdparty/SiftGPU/src/SiftGPU/ShaderMan.h deleted file mode 100644 index b5e49a9a..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/ShaderMan.h +++ /dev/null @@ -1,80 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: ShaderMan.h -// Author: Changchang Wu -// Description : interface for the ShaderMan class. -// This is a class that manages all the shaders for SIFT -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - - -#ifndef _SIFT_SHADER_MAN_H -#define _SIFT_SHADER_MAN_H - - -#include "ProgramGPU.h" -#include "ProgramGLSL.h" -/////////////////////////////////////////////////////////////////// -//class ShaderMan -//description: pure static class -// wrapper of shaders from different GPU languages -/////////////////////////////////////////////////////////////////// -class SiftParam; -class FilterGLSL; - -class ShaderMan -{ -public: - static ShaderBag* s_bag; -public: - static void SelectInitialSmoothingFilter(int octave_min, SiftParam¶m); - static void UseShaderMarginCopy(int xmax, int ymax); - static void UseShaderOrientation(int gtex, int width, int height, float sigma, int auxtex, float step, int keypoint_list); - static void UseShaderDescriptor(int gtex, int otex, int dwidth, int fwidth, int width, int height, float sigma); - static void UseShaderSimpleOrientation(int oTex, float sigma, float sigma_step); - static void UseShaderCopyKeypoint(); - static void UseShaderGenVBO( float width, float fwidth, float size); - static void UseShaderDebug(); - static void UseShaderZeroPass(); - static void UseShaderGenListStart(float fw, int tex0); - static void UseShaderGenListStep(int tex, int tex0); - static void UseShaderGenListEnd(int ktex); - static void UseShaderGenListHisto(); - static void UseShaderGenListInit(int w, int h, int tight = 1); - static void UseShaderKeypoint(int texU, int texD); - static void UseShaderGradientPass(int texP = 0); - static void UseShaderDisplayKeypoints(); - static void UseShaderDisplayGrad(); - static void UseShaderRGB2Gray(); - static void UseShaderDisplayDOG(); - static void UseShaderDisplayGaussian(); - /////////////////////////////////////////// - static void FilterInitialImage(GLTexImage* tex, GLTexImage* buf); - static void FilterSampledImage(GLTexImage* tex, GLTexImage* buf); - static void FilterImage(FilterProgram* filter, GLTexImage *dst, GLTexImage *src, GLTexImage*tmp); - static void TextureCopy(GLTexImage*dst, GLTexImage*src); - static void TextureDownSample(GLTexImage* dst, GLTexImage*src, int scale = 2); - static void TextureUpSample(GLTexImage* dst, GLTexImage*src, int scale); - /////////////////////////////////////////////// - static void InitShaderMan(SiftParam¶m); - static void DestroyShaders(); - static int HaveShaderMan(){return s_bag != NULL;} - static void UnloadProgram(); -}; - -#endif diff --git a/3rdparty/SiftGPU/src/SiftGPU/SiftGPU.cpp b/3rdparty/SiftGPU/src/SiftGPU/SiftGPU.cpp deleted file mode 100644 index 3827a6d1..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/SiftGPU.cpp +++ /dev/null @@ -1,1440 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SiftGPU.cpp -// Author: Changchang Wu -// Description : Implementation of the SIFTGPU classes. -// SiftGPU: The SiftGPU Tool. -// SiftGPUEX: SiftGPU + viewer -// SiftParam: Sift Parameters -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include "GL/glew.h" -#include -#include -#include -#include -#include -#include -#include - -#include -using namespace std; - - -#include "GlobalUtil.h" -#include "SiftGPU.h" -#include "GLTexImage.h" -#include "ShaderMan.h" -#include "FrameBufferObject.h" -#include "SiftPyramid.h" -#include "PyramidGL.h" - -//CUDA works only with vc8 or higher -#if defined(CUDA_SIFTGPU_ENABLED) -#include "PyramidCU.h" -#endif - -#if defined(CL_SIFTGPU_ENABLED) -#include "PyramidCL.h" -#endif - - -//// -#if defined(_WIN32) - #include "direct.h" - #pragma warning (disable : 4786) - #pragma warning (disable : 4996) -#else - //compatible with linux - #define _stricmp strcasecmp - #include - #include - #include -#endif - -#if !defined(_MAX_PATH) - #if defined (PATH_MAX) - #define _MAX_PATH PATH_MAX - #else - #define _MAX_PATH 512 - #endif -#endif - -////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////// -// -//just want to make this class invisible -class ImageList:public std::vector {}; - -SiftGPU::SiftGPU(int np) -{ - _texImage = new GLTexInput; - _imgpath = new char[_MAX_PATH]; - _outpath = new char[_MAX_PATH]; - _imgpath[0] = _outpath[0] = 0; - _initialized = 0; - _image_loaded = 0; - _current = 0; - _list = new ImageList(); - _pyramid = NULL; -} - - - -SiftGPUEX::SiftGPUEX() -{ - _view = _sub_view = 0; - _view_debug = 0; - GlobalUtil::_UseSiftGPUEX = 1; - srand((unsigned int)time(NULL)); - RandomizeColor(); -} - -void* SiftGPU::operator new (size_t size){ - void * p = malloc(size); - if (p == 0) - { - const std::bad_alloc ba; - throw ba; - } - return p; -} - - -void SiftGPUEX::RandomizeColor() -{ - float hsv[3] = {0, 0.8f, 1.0f}; - for(int i = 0; i < COLOR_NUM*3; i+=3) - { - hsv[0] = (rand()%100)*0.01f; //i/float(COLOR_NUM); - HSVtoRGB(hsv, _colors+i); - } -} - -SiftGPU::~SiftGPU() -{ - if(_pyramid) delete _pyramid; - delete _texImage; - delete _list; - delete[] _imgpath; - delete[] _outpath; -} - - -inline void SiftGPU::InitSiftGPU() -{ - if(_initialized || GlobalUtil::_GoodOpenGL ==0) return; - - //Parse sift parameters - ParseSiftParam(); - -#if !defined(CUDA_SIFTGPU_ENABLED) - if(GlobalUtil::_UseCUDA) - { - GlobalUtil::_UseCUDA = 0; - std::cerr << "---------------------------------------------------------------------------\n" - << "CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable\n" - << "solution for VS2005+ or set siftgpu_enable_cuda to 1 in makefile\n" - << "----------------------------------------------------------------------------\n"; - } -#else - if(GlobalUtil::_UseCUDA == 0 && GlobalUtil::_UseOpenCL == 0) - { - GlobalUtil::InitGLParam(0); - } - if(GlobalUtil::_GoodOpenGL == 0) - { - GlobalUtil::_UseCUDA = 1; - std::cerr << "Switch from OpenGL to CUDA\n"; - } - - if(GlobalUtil::_UseCUDA && !PyramidCU::CheckCudaDevice(GlobalUtil::_DeviceIndex)) - { - std::cerr << "Switch from CUDA to OpenGL\n"; - GlobalUtil::_UseCUDA = 0; - } -#endif - - if(GlobalUtil::_verbose) std::cout <<"\n[SiftGPU Language]:\t" - << (GlobalUtil::_UseCUDA? "CUDA" : - (GlobalUtil::_UseOpenCL? "OpenCL" : "GLSL")) <<"\n"; - -#if defined(CUDA_SIFTGPU_ENABLED) - if(GlobalUtil::_UseCUDA) - _pyramid = new PyramidCU(*this); - else -#endif -#if defined(CL_SIFTGPU_ENABLED) - if(GlobalUtil::_UseOpenCL) - _pyramid = new PyramidCL(*this); - else -#endif - if(GlobalUtil::_usePackedTex) - _pyramid = new PyramidPacked(*this); - else - _pyramid = new PyramidNaive(*this); - - - if(GlobalUtil::_GoodOpenGL && GlobalUtil::_InitPyramidWidth > 0 && GlobalUtil::_InitPyramidHeight > 0) - { - GlobalUtil::StartTimer("Initialize Pyramids"); - _pyramid->InitPyramid(GlobalUtil::_InitPyramidWidth, GlobalUtil::_InitPyramidHeight, 0); - GlobalUtil::StopTimer(); - } - - ClockTimer::InitHighResolution(); - _initialized = 1; -} - -int SiftGPU::RunSIFT(int index) -{ - if(_list->size()>0 ) - { - index = index % _list->size(); - if(strcmp(_imgpath, _list->at(index).data())) - { - strcpy(_imgpath, _list->at(index).data()); - _image_loaded = 0; - _current = index; - } - return RunSIFT(); - }else - { - return 0; - } - -} - -int SiftGPU::RunSIFT( int width, int height, const void * data, unsigned int gl_format, unsigned int gl_type) -{ - - if(GlobalUtil::_GoodOpenGL ==0 ) return 0; - if(!_initialized) InitSiftGPU(); - else GlobalUtil::SetGLParam(); - if(GlobalUtil::_GoodOpenGL ==0 ) return 0; - - if(width > 0 && height >0 && data != NULL) - { - _imgpath[0] = 0; - //try downsample the image on CPU - GlobalUtil::StartTimer("Upload Image data"); - if(_texImage->SetImageData(width, height, data, gl_format, gl_type)) - { - _image_loaded = 2; //gldata; - GlobalUtil::StopTimer(); - _timing[0] = GlobalUtil::GetElapsedTime(); - - //if the size of image is different, the pyramid need to be reallocated. - GlobalUtil::StartTimer("Initialize Pyramid"); - _pyramid->InitPyramid(width, height, _texImage->_down_sampled); - GlobalUtil::StopTimer(); - _timing[1] = GlobalUtil::GetElapsedTime(); - - return RunSIFT(); - }else - { - return 0; - } - }else - { - return 0; - } - -} - -int SiftGPU::RunSIFT(const char * imgpath) -{ - if(imgpath && imgpath[0]) - { - //set the new image - strcpy(_imgpath, imgpath); - _image_loaded = 0; - return RunSIFT(); - }else - { - return 0; - } - - -} - -int SiftGPU::RunSIFT(int num, const SiftKeypoint * keys, int keys_have_orientation) -{ - if(num <=0) return 0; - _pyramid->SetKeypointList(num, (const float*) keys, 1, keys_have_orientation); - return RunSIFT(); -} - -int SiftGPU::RunSIFT() -{ - //check image data - if(_imgpath[0]==0 && _image_loaded == 0) return 0; - - //check OpenGL support - if(GlobalUtil::_GoodOpenGL ==0 ) return 0; - - ClockTimer timer; - - if(!_initialized) - { - //initialize SIFT GPU for once - InitSiftGPU(); - if(GlobalUtil::_GoodOpenGL ==0 ) return 0; - }else - { - //in case some OpenGL parameters are changed by users - GlobalUtil::SetGLParam(); - } - - timer.StartTimer("RUN SIFT"); - //process input image file - if( _image_loaded ==0) - { - int width, height; - //load and try down-sample on cpu - GlobalUtil::StartTimer("Load Input Image"); - if(!_texImage->LoadImageFile(_imgpath, width, height)) return 0; - _image_loaded = 1; - GlobalUtil::StopTimer(); - _timing[0] = GlobalUtil::GetElapsedTime(); - - //make sure the pyrmid can hold the new image. - GlobalUtil::StartTimer("Initialize Pyramid"); - _pyramid->InitPyramid(width, height, _texImage->_down_sampled); - GlobalUtil::StopTimer(); - _timing[1] = GlobalUtil::GetElapsedTime(); - - }else - { - //change some global states - if(!GlobalUtil::_UseCUDA && !GlobalUtil::_UseOpenCL) - { - GlobalUtil::FitViewPort(1,1); - _texImage->FitTexViewPort(); - } - if(_image_loaded == 1) - { - _timing[0] = _timing[1] = 0; - }else - {//2 - _image_loaded = 1; - } - } - - if(_pyramid->_allocated ==0 ) return 0; - - -#ifdef DEBUG_SIFTGPU - _pyramid->BeginDEBUG(_imgpath); -#endif - - //process the image - _pyramid->RunSIFT(_texImage); - - //read back the timing - _pyramid->GetPyramidTiming(_timing + 2); - - //write output once if there is only one input - if(_outpath[0] ){ SaveSIFT(_outpath); _outpath[0] = 0;} - - //terminate the process when -exit is provided. - if(GlobalUtil::_ExitAfterSIFT && GlobalUtil::_UseSiftGPUEX) exit(0); - - timer.StopTimer(); - if(GlobalUtil::_verbose)std::cout<GetSucessStatus(); -} - - -void SiftGPU::SetKeypointList(int num, const SiftKeypoint * keys, int keys_have_orientation) -{ - _pyramid->SetKeypointList(num, (const float*)keys, 0, keys_have_orientation); -} - -void SiftGPUEX::DisplayInput() -{ - if(_texImage==NULL) return; - _texImage->VerifyTexture(); - _texImage->BindTex(); - _texImage->DrawImage(); - _texImage->UnbindTex(); - -} - -void SiftGPU::SetVerbose(int verbose) -{ - GlobalUtil::_timingO = verbose>2; - GlobalUtil::_timingL = verbose>3; - if(verbose == -1) - { - //Loop between verbose level 0, 1, 2 - if(GlobalUtil::_verbose) - { - GlobalUtil::_verbose = GlobalUtil::_timingS; - GlobalUtil::_timingS = 0; - if(GlobalUtil::_verbose ==0 && GlobalUtil::_UseSiftGPUEX) - std::cout << "Console ouput disabled, press Q/V to enable\n\n"; - }else - { - GlobalUtil::_verbose = 1; - GlobalUtil::_timingS = 1; - } - }else if(verbose == -2) - { - //trick for disabling all output (still keeps the timing level) - GlobalUtil::_verbose = 0; - GlobalUtil::_timingS = 1; - }else - { - GlobalUtil::_verbose = verbose>0; - GlobalUtil::_timingS = verbose>1; - } -} - - -SiftParam::SiftParam() -{ - - _level_min = -1; - _dog_level_num = 3; - _level_max = 0; - _sigma0 = 0; - _sigman = 0; - _edge_threshold = 0; - _dog_threshold = 0; - - -} - -float SiftParam::GetInitialSmoothSigma(int octave_min) -{ - float sa = _sigma0 * powf(2.0f, float(_level_min)/float(_dog_level_num)) ; - float sb = _sigman / powf(2.0f, float(octave_min)) ;// - float sigma_skip0 = sa > sb + 0.001?sqrt(sa*sa - sb*sb): 0.0f; - return sigma_skip0; -} - -void SiftParam::ParseSiftParam() -{ - - if(_dog_level_num ==0) _dog_level_num = 3; - if(_level_max ==0) _level_max = _dog_level_num + 1; - if(_sigma0 ==0.0f) _sigma0 = 1.6f * powf(2.0f, 1.0f / _dog_level_num) ; - if(_sigman == 0.0f) _sigman = 0.5f; - - - _level_num = _level_max -_level_min + 1; - - _level_ds = _level_min + _dog_level_num; - if(_level_ds > _level_max ) _level_ds = _level_max ; - - /// - float _sigmak = powf(2.0f, 1.0f / _dog_level_num) ; - float dsigma0 = _sigma0 * sqrt (1.0f - 1.0f / (_sigmak*_sigmak) ) ; - float sa, sb; - - - sa = _sigma0 * powf(_sigmak, (float)_level_min) ; - sb = _sigman / powf(2.0f, (float)GlobalUtil::_octave_min_default) ;// - - _sigma_skip0 = sa>sb+ 0.001?sqrt(sa*sa - sb*sb): 0.0f; - - sa = _sigma0 * powf(_sigmak, float(_level_min )) ; - sb = _sigma0 * powf(_sigmak, float(_level_ds - _dog_level_num)) ; - - _sigma_skip1 = sa>sb + 0.001? sqrt(sa*sa - sb*sb): 0.0f; - - _sigma_num = _level_max - _level_min; - _sigma = new float[_sigma_num]; - - for(int i = _level_min + 1; i <= _level_max; i++) - { - _sigma[i-_level_min -1] = dsigma0 * powf(_sigmak, float(i)) ; - } - - if(_dog_threshold ==0) _dog_threshold = 0.02f / _dog_level_num ; - if(_edge_threshold==0) _edge_threshold = 10.0f; -} - - -void SiftGPUEX::DisplayOctave(void (*UseDisplayShader)(), int i) -{ - if(_pyramid == NULL)return; - const int grid_sz = (int)ceil(_level_num/2.0); - double scale = 1.0/grid_sz ; - int gx=0, gy=0, dx, dy; - - if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min); - else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min)); - - - i = i% _pyramid->_octave_num; // - if(i<0 ) i+= _pyramid->_octave_num; - - scale *= ( 1<<(i)); - - - - - UseDisplayShader(); - - glPushMatrix(); - glScaled(scale, scale, scale); - for(int level = _level_min; level<= _level_max; level++) - { - GLTexImage * tex = _pyramid->GetLevelTexture(i+_pyramid->_octave_min, level); - - dx = tex->GetImgWidth(); - dy = tex->GetImgHeight(); - - glPushMatrix(); - - glTranslated(dx*gx, dy*gy, 0); - - tex->BindTex(); - - tex->DrawImage(); - tex->UnbindTex(); - - glPopMatrix(); - - gx++; - if(gx>=grid_sz) - { - gx =0; - gy++; - } - - } - - glPopMatrix(); - ShaderMan::UnloadProgram(); -} - -void SiftGPUEX::DisplayPyramid( void (*UseDisplayShader)(), int dataName, int nskip1, int nskip2) -{ - - if(_pyramid == NULL)return; - int grid_sz = (_level_num -nskip1 - nskip2); - if(grid_sz > 4) grid_sz = (int)ceil(grid_sz*0.5); - double scale = 1.0/grid_sz; - int stepx = 0, stepy = 0, dx, dy=0, nstep; - - if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min); - else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min)); - - - glPushMatrix(); - glScaled(scale, scale, scale); - - for(int i = _pyramid->_octave_min; i < _pyramid->_octave_min+_pyramid->_octave_num; i++) - { - - nstep = i==_pyramid->_octave_min? grid_sz: _level_num; - dx = 0; - UseDisplayShader(); - for(int j = _level_min + nskip1; j <= _level_max-nskip2; j++) - { - GLTexImage * tex = _pyramid->GetLevelTexture(i, j, dataName); - if(tex->GetImgWidth() == 0 || tex->GetImgHeight() == 0) continue; - stepx = tex->GetImgWidth(); - stepy = tex->GetImgHeight(); - //// - if(j == _level_min + nskip1 + nstep) - { - dy += stepy; - dx = 0; - } - - glPushMatrix(); - glTranslated(dx, dy, 0); - tex->BindTex(); - tex->DrawImage(); - tex->UnbindTex(); - glPopMatrix(); - - dx += stepx; - - } - - ShaderMan::UnloadProgram(); - - dy+= stepy; - } - - glPopMatrix(); -} - - -void SiftGPUEX::DisplayLevel(void (*UseDisplayShader)(), int i) -{ - if(_pyramid == NULL)return; - - i = i%(_level_num * _pyramid->_octave_num); - if (i<0 ) i+= (_level_num * _pyramid->_octave_num); - int octave = _pyramid->_octave_min + i/_level_num; - int level = _level_min + i%_level_num; - double scale = 1.0; - - if(octave >0) scale *= (1<GetLevelTexture(octave, level); - - UseDisplayShader(); - - glPushMatrix(); - glScaled(scale, scale, scale); - tex->BindTex(); - tex->DrawImage(); - tex->UnbindTex(); - glPopMatrix(); - ShaderMan::UnloadProgram(); -} - -void SiftGPUEX::DisplaySIFT() -{ - if(_pyramid == NULL) return; - glEnable(GlobalUtil::_texTarget); - switch(_view) - { - case 0: - DisplayInput(); - DisplayFeatureBox(_sub_view); - break; - case 1: - DisplayPyramid(ShaderMan::UseShaderDisplayGaussian, SiftPyramid::DATA_GAUSSIAN); - break; - case 2: - DisplayOctave(ShaderMan::UseShaderDisplayGaussian, _sub_view); - break; - case 3: - DisplayLevel(ShaderMan::UseShaderDisplayGaussian, _sub_view); - break; - case 4: - DisplayPyramid(ShaderMan::UseShaderDisplayDOG, SiftPyramid::DATA_DOG, 1); - break; - case 5: - DisplayPyramid(ShaderMan::UseShaderDisplayGrad, SiftPyramid::DATA_GRAD, 1); - break; - case 6: - DisplayPyramid(ShaderMan::UseShaderDisplayDOG, SiftPyramid::DATA_DOG,2, 1); - DisplayPyramid(ShaderMan::UseShaderDisplayKeypoints, SiftPyramid::DATA_KEYPOINT, 2,1); - } -} - - -void SiftGPUEX::SetView(int view, int sub_view, char *title) -{ - const char* view_titles[] = - { - "Original Image", - "Gaussian Pyramid", - "Octave Images", - "Level Image", - "Difference of Gaussian", - "Gradient", - "Keypoints" - }; - const int view_num = 7; - _view = view % view_num; - if(_view <0) _view +=view_num; - _sub_view = sub_view; - - if(_view_debug) - strcpy(title, "Debug..."); - else - strcpy(title, view_titles[_view]); - -} - - -void SiftGPU::PrintUsage() -{ - std::cout - <<"SiftGPU Usage:\n" - <<"-h -help : Parameter information\n" - <<"-i : Filename(s) of the input image(s)\n" - <<"-il : Filename of an image list file\n" - <<"-o : Where to save SIFT features\n" - <<"-f : Filter width factor; Width will be 2*factor+1 (default : 4.0)\n" - <<"-w : Orientation sample window factor (default: 2.0)\n" - <<"-dw * : Descriptor grid size factor (default : 3.0)\n" - <<"-fo * : First octave to detect DOG keypoints(default : 0)\n" - <<"-no : Maximum number of Octaves (default : no limit)\n" - <<"-d : Number of DOG levels in an octave (default : 3)\n" - <<"-t : DOG threshold (default : 0.02/3)\n" - <<"-e : Edge Threshold (default : 10.0)\n" - <<"-m : Multi Feature Orientations (default : 1)\n" - <<"-m2p : 2 Orientations packed as one float\n" - <<"-s : Sub-Pixel, Sub-Scale Localization, Multi-Refinement(num)\n" - <<"-lcpu -lc : CPU/GPU mixed Feature List Generation (defaut : 6)\n" - <<" Use GPU first, and use CPU when reduction size <= pow(2,num)\n" - <<" When is missing or equals -1, no GPU will be used\n" - <<"-noprep : Upload raw data to GPU (default: RGB->LUM and down-sample on CPU)\n" - <<"-sd : Skip descriptor computation if specified\n" - <<"-unn * : Write unnormalized descriptor if specified\n" - <<"-b * : Write binary sift file if specified\n" - <<"-fs : Block Size for freature storage \n" - <<"-cuda : Use CUDA SiftGPU, and specifiy the device index\n" - <<"-tight : Automatically resize pyramid to fit new images tightly\n" - <<"-p x : Inititialize the pyramids to contain image of WxH (eg -p 1024x768)\n" - <<"-tc[1|2|3] *: Threshold for limiting the overall number of features (3 methods)\n" - <<"-v : Level of timing details. Same as calling Setverbose() function\n" - <<"-loweo : (0, 0) at center of top-left pixel (defaut: corner)\n" - <<"-maxd * : Max working dimension (default : 2560 (unpacked) / 3200 (packed))\n" - <<"-nomc : Disabling auto-downsamping that try to fit GPU memory cap\n" - <<"-exit : Exit program after processing the input image\n" - <<"-unpack : Use the old unpacked implementation\n" - <<"-di : Use dynamic array indexing if available (defualt : no)\n" - <<" It could make computation faster on cards like GTX 280\n" - <<"-ofix * : use 0 as feature orientations.\n" - <<"-ofix-not * : disable -ofix.\n" - <<"-winpos x * : Screen coordinate used in Win32 to select monitor/GPU.\n" - <<"-display *: Display name used in Linux/Mac to select monitor/GPU.\n" - <<"\n" - <<"NOTE: parameters marked with * can be changed after initialization\n" - <<"\n"; -} - -void SiftGPU::ParseParam(int argc, char **argv) -{ - #define CHAR1_TO_INT(x) ((x >= 'A' && x <= 'Z') ? x + 32 : x) - #define CHAR2_TO_INT(str, i) (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR1_TO_INT(str[i+1]) << 8) : 0) - #define CHAR3_TO_INT(str, i) (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR2_TO_INT(str, i + 1) << 8) : 0) - #define STRING_TO_INT(str) (CHAR1_TO_INT(str[0]) + (CHAR3_TO_INT(str, 1) << 8)) - -#ifdef _MSC_VER - //charizing is microsoft only - #define MAKEINT1(a) (#@a ) -#else - #define mychar0 '0' - #define mychar1 '1' - #define mychar2 '2' - #define mychar3 '3' - #define mychara 'a' - #define mycharb 'b' - #define mycharc 'c' - #define mychard 'd' - #define mychare 'e' - #define mycharf 'f' - #define mycharg 'g' - #define mycharh 'h' - #define mychari 'i' - #define mycharj 'j' - #define mychark 'k' - #define mycharl 'l' - #define mycharm 'm' - #define mycharn 'n' - #define mycharo 'o' - #define mycharp 'p' - #define mycharq 'q' - #define mycharr 'r' - #define mychars 's' - #define mychart 't' - #define mycharu 'u' - #define mycharv 'v' - #define mycharw 'w' - #define mycharx 'x' - #define mychary 'y' - #define mycharz 'z' - #define MAKEINT1(a) (mychar##a ) -#endif - #define MAKEINT2(a, b) (MAKEINT1(a) + (MAKEINT1(b) << 8)) - #define MAKEINT3(a, b, c) (MAKEINT1(a) + (MAKEINT2(b, c) << 8)) - #define MAKEINT4(a, b, c, d) (MAKEINT1(a) + (MAKEINT3(b, c, d) << 8)) - - - char* arg, *param, * opt; - int setMaxD = 0, opti; - for(int i = 0; i< argc; i++) - { - arg = argv[i]; - if(arg == NULL || arg[0] != '-' || !arg[1])continue; - opt = arg+1; - opti = STRING_TO_INT(opt); - param = argv[i+1]; - - //////////////////////////////// - switch(opti) - { - case MAKEINT1(h): - case MAKEINT4(h, e, l, p): - PrintUsage(); - break; - case MAKEINT4(c, u, d, a): -#if defined(CUDA_SIFTGPU_ENABLED) - - if(!_initialized) - { - GlobalUtil::_UseCUDA = 1; - int device = -1; - if(i+1 =0) - { - GlobalUtil::_DeviceIndex = device; - i++; - } - } -#else - std::cerr << "---------------------------------------------------------------------------\n" - << "CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable\n" - << "solution for VS2005+ or set siftgpu_enable_cuda to 1 in makefile\n" - << "----------------------------------------------------------------------------\n"; -#endif - break; - case MAKEINT2(c, l): -#if defined(CL_SIFTGPU_ENABLED) - if(!_initialized) GlobalUtil::_UseOpenCL = 1; -#else - std::cerr << "---------------------------------------------------------------------------\n" - << "OpenCL not supported in this binary! Define CL_CUDA_SIFTGPU_ENABLED to..\n" - << "----------------------------------------------------------------------------\n"; -#endif - break; - - case MAKEINT4(p, a, c, k): - if(!_initialized) GlobalUtil::_usePackedTex = 1; - break; - case MAKEINT4(u, n, p, a): //unpack - if(!_initialized) - { - GlobalUtil::_usePackedTex = 0; - if(!setMaxD) GlobalUtil::_texMaxDim = 2560; - } - break; - case MAKEINT4(l, c, p, u): - case MAKEINT2(l, c): - if(!_initialized) - { - int gskip = -1; - if(i+1 = 0) - { - GlobalUtil::_ListGenSkipGPU = gskip; - }else - { - GlobalUtil::_ListGenGPU = 0; - } - } - break; - case MAKEINT4(p, r, e, p): - GlobalUtil::_PreProcessOnCPU = 1; - break; - case MAKEINT4(n, o, p, r): //noprep - GlobalUtil::_PreProcessOnCPU = 0; - break; - case MAKEINT4(f, b, o, 1): - FrameBufferObject::UseSingleFBO =1; - break; - case MAKEINT4(f, b, o, s): - FrameBufferObject::UseSingleFBO = 0; - break; - case MAKEINT2(s, d): - if(!_initialized) GlobalUtil::_DescriptorPPT =0; - break; - case MAKEINT3(u, n, n): - GlobalUtil::_NormalizedSIFT =0; - break; - case MAKEINT4(n, d, e, s): - GlobalUtil::_NormalizedSIFT =1; - break; - case MAKEINT1(b): - GlobalUtil::_BinarySIFT = 1; - break; - case MAKEINT4(t, i, g, h): //tight - GlobalUtil::_ForceTightPyramid = 1; - break; - case MAKEINT4(e, x, i, t): - GlobalUtil::_ExitAfterSIFT = 1; - break; - case MAKEINT2(d, i): - GlobalUtil::_UseDynamicIndexing = 1; - break; - case MAKEINT4(s, i, g, n): - if(!_initialized || GlobalUtil::_UseCUDA) GlobalUtil::_KeepExtremumSign = 1; - break; - case MAKEINT1(m): - case MAKEINT2(m, o): - if(!_initialized) - { - int mo = 2; //default multi-orientation - if(i+1 = argc) break; - switch(opti) - { - case MAKEINT1(i): - strcpy(_imgpath, param); - i++; - //get the file list.. - _list->push_back(param); - while( i+1 < argc && argv[i+1][0] !='-') - { - _list->push_back(argv[++i]); - } - break; - case MAKEINT2(i, l): - LoadImageList(param); - i++; - break; - case MAKEINT1(o): - strcpy(_outpath, param); - i++; - break; - case MAKEINT1(f): - { - float factor = 0.0f; - if(sscanf(param, "%f", &factor) && factor > 0 ) - { - GlobalUtil::_FilterWidthFactor = factor; - i++; - } - } - break; - case MAKEINT2(o, t): - { - float factor = 0.0f; - if(sscanf(param, "%f", &factor) && factor>0 ) - { - GlobalUtil::_MulitiOrientationThreshold = factor; - i++; - } - break; - } - case MAKEINT1(w): - { - float factor = 0.0f; - if(sscanf(param, "%f", &factor) && factor>0 ) - { - GlobalUtil::_OrientationWindowFactor = factor; - i++; - } - break; - } - case MAKEINT2(d, w): - { - float factor = 0.0f; - if(sscanf(param, "%f", &factor) && factor > 0 ) - { - GlobalUtil::_DescriptorWindowFactor = factor; - i++; - } - break; - } - case MAKEINT2(f, o): - { - int first_octave = -3; - if(sscanf(param, "%d", &first_octave) && first_octave >=-2 ) - { - GlobalUtil::_octave_min_default = first_octave; - i++; - } - break; - } - case MAKEINT2(n, o): - if(!_initialized) - { - int octave_num=-1; - if(sscanf(param, "%d", &octave_num)) - { - octave_num = max(-1, octave_num); - if(octave_num ==-1 || octave_num >=1) - { - GlobalUtil::_octave_num_default = octave_num; - i++; - } - } - } - break; - case MAKEINT1(t): - { - float threshold = 0.0f; - if(sscanf(param, "%f", &threshold) && threshold >0 && threshold < 0.5f) - { - SiftParam::_dog_threshold = threshold; - i++; - } - break; - } - case MAKEINT1(e): - { - float threshold = 0.0f; - if(sscanf(param, "%f", &threshold) && threshold >0 ) - { - SiftParam::_edge_threshold = threshold; - i++; - } - break; - } - case MAKEINT1(d): - { - int num = 0; - if(sscanf(param, "%d", &num) && num >=1 && num <=10) - { - SiftParam::_dog_level_num = num; - i++; - } - break; - } - case MAKEINT2(f, s): - { - int num = 0; - if(sscanf(param, "%d", &num) && num >=1) - { - GlobalParam::_FeatureTexBlock = num; - i++; - } - break; - } - case MAKEINT1(p): - { - int w =0, h=0; - if(sscanf(param, "%dx%d", &w, &h) == 2 && w >0 && h>0) - { - GlobalParam::_InitPyramidWidth = w; - GlobalParam::_InitPyramidHeight = h; - i++; - } - break; - } - case MAKEINT4(w, i, n, p): //winpos - { - int x =0, y=0; - if(sscanf(param, "%dx%d", &x, &y) == 2) - { - GlobalParam::_WindowInitX = x; - GlobalParam::_WindowInitY = y; - i++; - } - break; - } - case MAKEINT4(d, i, s, p): //display - { - GlobalParam::_WindowDisplay = param; - i++; - break; - } - case MAKEINT2(l, m): - { - int num = 0; - if(sscanf(param, "%d", &num) && num >=1000) - { - GlobalParam::_MaxLevelFeatureNum = num; - i++; - } - break; - } - case MAKEINT3(l, m, p): - { - float num = 0.0f; - if(sscanf(param, "%f", &num) && num >=0.001) - { - GlobalParam::_MaxFeaturePercent = num; - i++; - } - break; - } - case MAKEINT3(t, c, 2): //downward - case MAKEINT3(t, c, 3): - case MAKEINT2(t, c): //tc - case MAKEINT3(t, c, 1): // - { - switch (opti) - { - case MAKEINT3(t, c, 2): GlobalUtil::_TruncateMethod = 1; break; - case MAKEINT3(t, c, 3): GlobalUtil::_TruncateMethod = 2; break; - default: GlobalUtil::_TruncateMethod = 0; break; - } - int num = -1; - if(sscanf(param, "%d", &num) && num > 0) - { - GlobalParam::_FeatureCountThreshold = num; - i++; - } - break; - } - case MAKEINT1(v): - { - int num = 0; - if(sscanf(param, "%d", &num) && num >=0 && num <= 4) - { - SetVerbose(num); - } - break; - } - case MAKEINT4(m, a, x, d): - { - int num = 0; - if(sscanf(param, "%d", &num) && num > 0) - { - GlobalUtil::_texMaxDim = num; - setMaxD = 1; - } - break; - } - case MAKEINT4(m, i, n, d): - { - int num = 0; - if(sscanf(param, "%d", &num) && num >= 8) - { - GlobalUtil::_texMinDim = num; - } - break; - } - default: - break; - } - break; - } - } - - //////////////////////// - GlobalUtil::SelectDisplay(); - - - //do not write result if there are more than one input images - if(_outpath[0] && _list->size()>1) _outpath[0] = 0; - -} - -void SiftGPU::SetImageList(int nimage, const char** filelist) -{ - _list->resize(0); - for(int i = 0; i < nimage; i++) - { - _list->push_back(filelist[i]); - } - _current = 0; - -} -void SiftGPU:: LoadImageList(const char *imlist) -{ - char filename[_MAX_PATH]; - ifstream in(imlist); - while(in>>filename) - { - _list->push_back(filename); - } - in.close(); - - - if(_list->size()>0) - { - strcpy(_imgpath, _list->at(0).data()); - strcpy(filename, imlist); - char * slash = strrchr(filename, '\\'); - if(slash == 0) slash = strrchr(filename, '/'); - if(slash ) - { - slash[1] = 0; - chdir(filename); - } - } - _image_loaded = 0; - - -} -float SiftParam::GetLevelSigma( int lev) -{ - return _sigma0 * powf( 2.0f, float(lev) / float(_dog_level_num )); //bug fix 9/12/2007 -} - - - -void SiftGPUEX::DisplayFeatureBox(int view ) -{ - view = view%3; - if(view<0)view+=3; - if(view ==2) return; - int idx = 0; - const int *fnum = _pyramid->GetLevelFeatureNum(); - const GLuint *vbo = _pyramid->GetFeatureDipslayVBO(); - const GLuint *vbop = _pyramid->GetPointDisplayVBO(); - if(vbo == NULL || vbop == NULL) return; - //int nvbo = _dog_level_num * _pyramid->_octave_num; - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glEnableClientState(GL_VERTEX_ARRAY); - glPushMatrix(); -// glTranslatef(0.0f, 0.0f, -1.0f); - glPointSize(2.0f); - - float scale = 1.0f; - if(_pyramid->_octave_min >0) scale *= (1<<_pyramid->_octave_min); - else if(_pyramid->_octave_min < 0) scale /= (1<<(-_pyramid->_octave_min)); - glScalef(scale, scale, 1.0f); - - - for(int i = 0; i < _pyramid->_octave_num; i++) - { - - for(int j = 0; j < _dog_level_num; j++, idx++) - { - if(fnum[idx]>0) - { - if(view ==0) - { - glColor3f(0.2f, 1.0f, 0.2f); - glBindBuffer(GL_ARRAY_BUFFER_ARB, vbop[idx]); - glVertexPointer( 4, GL_FLOAT,4*sizeof(float), (char *) 0); - glDrawArrays( GL_POINTS, 0, fnum[idx]); - glFlush(); - }else - { - - //glColor3f(1.0f, 0.0f, 0.0f); - glColor3fv(_colors+ (idx%COLOR_NUM)*3); - glBindBuffer(GL_ARRAY_BUFFER_ARB, vbo[idx]); - glVertexPointer( 4, GL_FLOAT,4*sizeof(float), (char *) 0); - glDrawArrays( GL_LINES, 0, fnum[idx]*10 ); - glFlush(); - } - - } - - } - glTranslatef(-.5f, -.5f, 0.0f); - glScalef(2.0f, 2.0f, 1.0f); - - } - glPopMatrix(); - glDisableClientState(GL_VERTEX_ARRAY); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glPointSize(1.0f); - -} - -void SiftGPUEX::ToggleDisplayDebug() -{ - _view_debug = !_view_debug; -} - -void SiftGPUEX::DisplayDebug() -{ - glPointSize(1.0f); - glColor3f(1.0f, 0.0f, 0.0f); - ShaderMan::UseShaderDebug(); - glBegin(GL_POINTS); - for(int i = 0; i < 100; i++) - { - glVertex2f(i*4.0f+0.5f, i*4.0f+0.5f); - } - glEnd(); - ShaderMan::UnloadProgram(); -} - -int SiftGPU::CreateContextGL() -{ - if(GlobalUtil::_UseOpenCL || GlobalUtil::_UseCUDA) - { - //do nothing - } - else if(!GlobalUtil::CreateWindowEZ()) - { -#if CUDA_SIFTGPU_ENABLED - GlobalUtil::_UseCUDA = 1; -#else - return 0; -#endif - } - - return VerifyContextGL(); -} - -int SiftGPU::VerifyContextGL() -{ - InitSiftGPU(); - return (GlobalUtil::_GoodOpenGL > 0) + GlobalUtil::_FullSupported; -} - -int SiftGPU::IsFullSupported() -{ - return GlobalUtil::_GoodOpenGL > 0 && GlobalUtil::_FullSupported; -} - -void SiftGPU::SaveSIFT(const char * szFileName) -{ - _pyramid->SaveSIFT(szFileName); -} - -int SiftGPU::GetFeatureNum() -{ - return _pyramid->GetFeatureNum(); -} - -void SiftGPU::GetFeatureVector(SiftKeypoint * keys, float * descriptors) -{ -// keys.resize(_pyramid->GetFeatureNum()); - if(GlobalUtil::_DescriptorPPT) - { - // descriptors.resize(128*_pyramid->GetFeatureNum()); - _pyramid->CopyFeatureVector((float*) (&keys[0]), &descriptors[0]); - }else - { - //descriptors.resize(0); - _pyramid->CopyFeatureVector((float*) (&keys[0]), NULL); - } -} - -void SiftGPU::SetTightPyramid(int tight) -{ - GlobalUtil::_ForceTightPyramid = tight; -} - -int SiftGPU::AllocatePyramid(int width, int height) -{ - _pyramid->_down_sample_factor = 0; - _pyramid->_octave_min = GlobalUtil::_octave_min_default; - if(GlobalUtil::_octave_min_default>=0) - { - width >>= GlobalUtil::_octave_min_default; - height >>= GlobalUtil::_octave_min_default; - }else - { - width <<= (-GlobalUtil::_octave_min_default); - height <<= (-GlobalUtil::_octave_min_default); - } - _pyramid->ResizePyramid(width, height); - return _pyramid->_pyramid_height == height && width == _pyramid->_pyramid_width ; -} - -void SiftGPU::SetMaxDimension(int sz) -{ - if(sz < GlobalUtil::_texMaxDimGL) - { - GlobalUtil::_texMaxDim = sz; - } -} -int SiftGPU::GetImageCount() -{ - return _list->size(); -} - -void SiftGPUEX::HSVtoRGB(float hsv[3],float rgb[3] ) -{ - - int i; - float q, t, p; - float hh,f, v = hsv[2]; - if(hsv[1]==0.0f) - { - rgb[0]=rgb[1]=rgb[2]=v; - } - else - { - ////////////// - hh =hsv[0]*6.0f ; // sector 0 to 5 - i =(int)hh ; - f = hh- i; // factorial part of h - ////////// - p= v * ( 1 - hsv[1] ); - q = v * ( 1 - hsv[1] * f ); - t = v * ( 1 - hsv[1] * ( 1 - f ) ); - switch( i ) { - case 0:rgb[0] = v;rgb[1] = t;rgb[2] = p;break; - case 1:rgb[0] = q;rgb[1] = v;rgb[2] = p;break; - case 2:rgb[0] = p;rgb[1] = v;rgb[2] = t;break; - case 3:rgb[0] = p;rgb[1] = q;rgb[2] = v;break; - case 4:rgb[0] = t;rgb[1] = p;rgb[2] = v;break; - case 5:rgb[0] = v;rgb[1] = p;rgb[2] = q;break; - default:rgb[0]= 0;rgb[1] = 0;rgb[2] = 0; - } - } -} - -void SiftGPUEX::GetImageDimension( int &w, int &h) -{ - w = _texImage->GetImgWidth(); - h = _texImage->GetImgHeight(); - -} - -void SiftGPUEX::GetInitWindowPotition(int&x, int&y) -{ - x = GlobalUtil::_WindowInitX; - y = GlobalUtil::_WindowInitY; -} - -SiftGPU* CreateNewSiftGPU(int np) -{ - return new SiftGPU(np); -} - -///////////////////////////////////////////////////// -void* ComboSiftGPU::operator new (size_t size){ - void * p = malloc(size); - if (p == 0) - { - const std::bad_alloc ba; - throw ba; - } - return p; -} - -ComboSiftGPU* CreateComboSiftGPU() -{ - return new ComboSiftGPU(); -} - diff --git a/3rdparty/SiftGPU/src/SiftGPU/SiftGPU.h b/3rdparty/SiftGPU/src/SiftGPU/SiftGPU.h deleted file mode 100644 index b76c14c4..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/SiftGPU.h +++ /dev/null @@ -1,379 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SiftGPU.h -// Author: Changchang Wu -// Description : interface for the SIFTGPU class. -// SiftGPU: The SiftGPU Tool. -// SiftGPUEX: SiftGPU + viewer -// SiftParam: Sift Parameters -// SiftMatchGPU: GPU SIFT Matcher; -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#ifndef GPU_SIFT_H -#define GPU_SIFT_H - -#if defined(_WIN32) - #ifdef SIFTGPU_DLL - #ifdef DLL_EXPORT - #define SIFTGPU_EXPORT __declspec(dllexport) - #else - #define SIFTGPU_EXPORT __declspec(dllimport) - #endif - #else - #define SIFTGPU_EXPORT - #endif - - #define SIFTGPU_EXPORT_EXTERN SIFTGPU_EXPORT - - #if _MSC_VER > 1000 - #pragma once - #endif -#else - #define SIFTGPU_EXPORT - #define SIFTGPU_EXPORT_EXTERN extern "C" -#endif - -/////////////////////////////////////////////////////////////////// -//clss SiftParam -//description: SIFT parameters -//////////////////////////////////////////////////////////////////// -class GlobalUtil; -class SiftParam -{ -public: - float* _sigma; - float _sigma_skip0; // - float _sigma_skip1; // - - //sigma of the first level - float _sigma0; - float _sigman; - int _sigma_num; - - //how many dog_level in an octave - int _dog_level_num; - int _level_num; - - //starting level in an octave - int _level_min; - int _level_max; - int _level_ds; - //dog threshold - float _dog_threshold; - //edge elimination - float _edge_threshold; - void ParseSiftParam(); -public: - float GetLevelSigma(int lev); - float GetInitialSmoothSigma(int octave_min); - SIFTGPU_EXPORT SiftParam(); -}; - -class LiteWindow; -class GLTexInput; -class ShaderMan; -class SiftPyramid; -class ImageList; -//////////////////////////////////////////////////////////////// -//class SIftGPU -//description: Interface of SiftGPU lib -//////////////////////////////////////////////////////////////// -class SiftGPU:public SiftParam -{ -public: - enum - { - SIFTGPU_NOT_SUPPORTED = 0, - SIFTGPU_PARTIAL_SUPPORTED = 1, // detction works, but not orientation/descriptor - SIFTGPU_FULL_SUPPORTED = 2 - }; - typedef struct SiftKeypoint - { - float x, y, s, o; //x, y, scale, orientation. - }SiftKeypoint; -protected: - //when more than one images are specified - //_current indicates the active one - int _current; - //_initialized indicates if the shaders and OpenGL/SIFT parameters are initialized - //they are initialized only once for one SiftGPU inistance - //that is, SIFT parameters will not be changed - int _initialized; - //_image_loaded indicates if the current images are loaded - int _image_loaded; - //the name of current input image - char* _imgpath; - //_outpath containes the name of the output file - char* _outpath; - //the list of image filenames - ImageList * _list; - //the texture that holds loaded input image - GLTexInput * _texImage; - //the SiftPyramid - SiftPyramid * _pyramid; - //print out the command line options - static void PrintUsage(); - //Initialize OpenGL and SIFT paremeters, and create the shaders accordingly - void InitSiftGPU(); - //load the image list from a file - void LoadImageList(const char *imlist); -public: - //timing results for 10 steps - float _timing[10]; - inline const char* GetCurrentImagePath() {return _imgpath; } -public: - //set the image list for processing - SIFTGPU_EXPORT virtual void SetImageList(int nimage, const char** filelist); - //get the number of SIFT features in current image - SIFTGPU_EXPORT virtual int GetFeatureNum(); - //save the SIFT result as a ANSCII/BINARY file - SIFTGPU_EXPORT virtual void SaveSIFT(const char * szFileName); - //Copy the SIFT result to two vectors - SIFTGPU_EXPORT virtual void GetFeatureVector(SiftKeypoint * keys, float * descriptors); - //Set keypoint list before running sift to get descriptors - SIFTGPU_EXPORT virtual void SetKeypointList(int num, const SiftKeypoint * keys, int keys_have_orientation = 1); - //Enable downloading results to CPU. - //create a new OpenGL context for processing - //call VerifyContextGL instead if you want to crate openGL context yourself, or your are - //mixing mixing siftgpu with other openGL code - SIFTGPU_EXPORT virtual int CreateContextGL(); - //verify the current opengl context.. - //(for example, you call wglmakecurrent yourself and verify the current context) - SIFTGPU_EXPORT virtual int VerifyContextGL(); - //check if all siftgpu functions are supported - SIFTGPU_EXPORT virtual int IsFullSupported(); - //set verbose mode - SIFTGPU_EXPORT virtual void SetVerbose(int verbose = 4); - //set SiftGPU to brief display mode, which is faster - inline void SetVerboseBrief(){SetVerbose(2);}; - //parse SiftGPU parameters - SIFTGPU_EXPORT virtual void ParseParam(int argc, char **argv); - //run SIFT on a new image given filename - SIFTGPU_EXPORT virtual int RunSIFT(const char * imgpath); - //run SIFT on an image in the image list given the file index - SIFTGPU_EXPORT virtual int RunSIFT(int index); - //run SIFT on a new image given the pixel data and format/type; - //gl_format (e.g. GL_LUMINANCE, GL_RGB) is the format of the pixel data - //gl_type (e.g. GL_UNSIGNED_BYTE, GL_FLOAT) is the data type of the pixel data; - //Check glTexImage2D(...format, type,...) for the accepted values - //Using image data of GL_LUMINANCE + GL_UNSIGNED_BYTE can minimize transfer time - SIFTGPU_EXPORT virtual int RunSIFT(int width, int height, const void * data, - unsigned int gl_format, unsigned int gl_type); - //run SIFT on current image (specified by arguments), or processing the current image again - SIFTGPU_EXPORT virtual int RunSIFT(); - //run SIFT with keypoints on current image again. - SIFTGPU_EXPORT virtual int RunSIFT(int num, const SiftKeypoint * keys, int keys_have_orientation = 1); - //constructor, the parameter np is ignored.. - SIFTGPU_EXPORT SiftGPU(int np = 1); - //destructor - SIFTGPU_EXPORT virtual ~SiftGPU(); - //set the active pyramid...dropped function - SIFTGPU_EXPORT virtual void SetActivePyramid(int index) {} - //retrieve the number of images in the image list - SIFTGPU_EXPORT virtual int GetImageCount(); - //set parameter GlobalUtil::_ForceTightPyramid - SIFTGPU_EXPORT virtual void SetTightPyramid(int tight = 1); - //allocate pyramid for a given size of image - SIFTGPU_EXPORT virtual int AllocatePyramid(int width, int height); - //none of the texture in processing can be larger - //automatic down-sample is used if necessary. - SIFTGPU_EXPORT virtual void SetMaxDimension(int sz); - /// -public: - //overload the new operator because delete operator is virtual - //and it is operating on the heap inside the dll (due to the - //compiler setting of /MT and /MTd). Without the overloaded operator - //deleting a SiftGPU object will cause a heap corruption in the - //static link case (but not for the runtime dll loading). - SIFTGPU_EXPORT void* operator new (size_t size); -}; - - - -//////////////////////////////////////////////////////////////// -//class SIftGPUEX -//description: adds some visualization functions to the interface of SiftGPU -//////////////////////////////////////////////////////////////// - -class SiftGPUEX:public SiftGPU -{ - //view mode - int _view; - //sub view mode - int _sub_view; - //whether display a debug view - int _view_debug; - //colors for SIFT feature display - enum{COLOR_NUM = 36}; - float _colors[COLOR_NUM*3]; - //display functions - void DisplayInput(); //display gray level image of input image - void DisplayDebug(); //display debug view - void DisplayFeatureBox(int i); //display SIFT features - void DisplayLevel(void (*UseDisplayShader)(), int i); //display one level image - void DisplayOctave(void (*UseDisplayShader)(), int i); //display all images in one octave - //display different content of Pyramid by specifying different data and display shader - //the first nskip1 levels and the last nskip2 levels are skiped in display - void DisplayPyramid( void (*UseDisplayShader)(), int dataName, int nskip1 = 0, int nskip2 = 0); - //use HSVtoRGB to generate random colors - static void HSVtoRGB(float hsv[3],float rgb[3]); - -public: - SIFTGPU_EXPORT SiftGPUEX(); - //change view mode - SIFTGPU_EXPORT void SetView(int view, int sub_view, char * title); - //display current view - SIFTGPU_EXPORT void DisplaySIFT(); - //toggle debug mode on/off - SIFTGPU_EXPORT void ToggleDisplayDebug(); - //randomize the display colors - SIFTGPU_EXPORT void RandomizeColor(); - //retrieve the size of current input image - SIFTGPU_EXPORT void GetImageDimension(int &w, int&h); - //get the location of the window specified by user - SIFTGPU_EXPORT void GetInitWindowPotition(int& x, int& y); -}; - -///matcher export -//This is a gpu-based sift match implementation. -class SiftMatchGPU -{ -public: - enum SIFTMATCH_LANGUAGE { - SIFTMATCH_SAME_AS_SIFTGPU = 0, //when siftgpu already initialized. - SIFTMATCH_GLSL = 2, - SIFTMATCH_CUDA = 3, - SIFTMATCH_CUDA_DEVICE0 = 3 //to use device i, use SIFTMATCH_CUDA_DEVICE0 + i - }; -private: - int __max_sift; - int __language; - SiftMatchGPU * __matcher; - virtual void InitSiftMatch(){} -protected: - //move the two functions here for derived class - SIFTGPU_EXPORT virtual int _CreateContextGL(); - SIFTGPU_EXPORT virtual int _VerifyContextGL(); -public: - //OpenGL Context creation/verification, initialization is done automatically inside - inline int CreateContextGL() {return _CreateContextGL();} - inline int VerifyContextGL() {return _VerifyContextGL();} - - //Consructor, the argument specifies the maximum number of features to match - SIFTGPU_EXPORT SiftMatchGPU(int max_sift = 4096); - - //change gpu_language, check the enumerants in SIFTMATCH_LANGUAGE. - SIFTGPU_EXPORT virtual void SetLanguage(int gpu_language); - - //after calling SetLanguage, you can call SetDeviceParam to select GPU - //-winpos, -display, -cuda [device_id] - //This is only used when you call CreateContextGL.. - //This function doesn't change the language. - SIFTGPU_EXPORT virtual void SetDeviceParam(int argc, char**argv); - - //change the maximum of features to match whenever you want - SIFTGPU_EXPORT virtual void SetMaxSift(int max_sift); - //desctructor - SIFTGPU_EXPORT virtual ~SiftMatchGPU(); - - //Specifiy descriptors to match, index = [0/1] for two features sets respectively - //Option1, use float descriptors, and they be already normalized to 1.0 - SIFTGPU_EXPORT virtual void SetDescriptors(int index, int num, const float* descriptors, int id = -1); - //Option 2 unsigned char descriptors. They must be already normalized to 512 - SIFTGPU_EXPORT virtual void SetDescriptors(int index, int num, const unsigned char * descriptors, int id = -1); - - //match two sets of features, the function RETURNS the number of matches. - //Given two normalized descriptor d1,d2, the distance here is acos(d1 *d2); - SIFTGPU_EXPORT virtual int GetSiftMatch( - int max_match, // the length of the match_buffer. - int match_buffer[][2], //buffer to receive the matched feature indices - float distmax = 0.7, //maximum distance of sift descriptor - float ratiomax = 0.8, //maximum distance ratio - int mutual_best_match = 1); //mutual best match or one way - - //two functions for guded matching, two constraints can be used - //one homography and one fundamental matrix, the use is as follows - //1. for each image, first call SetDescriptor then call SetFeatureLocation - //2. Call GetGuidedSiftMatch - //input feature location is a vector of [float x, float y, float skip[gap]] - SIFTGPU_EXPORT virtual void SetFeautreLocation(int index, const float* locations, int gap = 0); - inline void SetFeatureLocation(int index, const SiftGPU::SiftKeypoint * keys) - { - SetFeautreLocation(index, (const float*) keys, 2); - } - - //use a guiding Homography H and a guiding Fundamental Matrix F to compute feature matches - //the function returns the number of matches. - SIFTGPU_EXPORT virtual int GetGuidedSiftMatch( - int max_match, int match_buffer[][2], //buffer to recieve - float H[3][3], //homography matrix, (Set NULL to skip) - float F[3][3], //fundamental matrix, (Set NULL to skip) - float distmax = 0.7, //maximum distance of sift descriptor - float ratiomax = 0.8, //maximum distance ratio - float hdistmax = 32, //threshold for |H * x1 - x2|_1 - float fdistmax = 16, //threshold for sampson error of x2'FX1 - int mutual_best_match = 1); //mutual best or one way - -public: - //overload the new operator, the same reason as SiftGPU above - SIFTGPU_EXPORT void* operator new (size_t size); -}; - -typedef SiftGPU::SiftKeypoint SiftKeypoint; - -//Two exported global functions used to create SiftGPU and SiftMatchGPU -SIFTGPU_EXPORT_EXTERN SiftGPU * CreateNewSiftGPU(int np =1); -SIFTGPU_EXPORT_EXTERN SiftMatchGPU* CreateNewSiftMatchGPU(int max_sift = 4096); - - -//////////////////////////////////////////////////////////////////////////// -class ComboSiftGPU: public SiftGPU, public SiftMatchGPU -{ -public: - /////////////////////////////////////////////// - SIFTGPU_EXPORT void* operator new (size_t size); -}; -SIFTGPU_EXPORT_EXTERN ComboSiftGPU* CreateComboSiftGPU(); - -///////////////////////////////////////////////////////////////////////////////////////////// -//Multi-process mode and remote mode -SIFTGPU_EXPORT_EXTERN ComboSiftGPU* CreateRemoteSiftGPU(int port = 7777, char* remote_server = NULL); -//Run SiftGPU computation on a remote computer/process/thread -//if( remote_server == NULL) -// a local server is created in a different process and connected -// multiple-GPU can be used by creating multiple instances -// GPU selection done through SiftGPU::ParseParam function -//otherwise, -// Assumes the existenc of a remote server and connects to it -// GPU selection skipped if already done on the server-end -// RUN server: server_siftgpu -server port [siftgpu_param] -//example: -// ComboSiftGPU * combo = CreateRemoteSiftGPU(7777, "my.gpuserver.com"); -// SiftGPU* siftgpu = combo, SiftMatchGPU * matcher = combo; -// siftgpu->ParseParam... siftgpu->CreateContextGL.. -// matcher->SetLanguage...matcher->VerifyContextGL... -// // GPU-selection is done throught siftgpu->ParseParam, -// // it doesn't really initialize SiftGPU untill you call CreateContextGL/VerifyContextGL -// delete combo; - -//////////////////////////////////////////////////////////////////////// -//two internally used function. -SIFTGPU_EXPORT int CreateLiteWindow(LiteWindow* window); -SIFTGPU_EXPORT void RunServerLoop(int port, int argc, char** argv); -#endif diff --git a/3rdparty/SiftGPU/src/SiftGPU/SiftMatch.cpp b/3rdparty/SiftGPU/src/SiftGPU/SiftMatch.cpp deleted file mode 100644 index ea805591..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/SiftMatch.cpp +++ /dev/null @@ -1,687 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SiftMatch.cpp -// Author: Changchang Wu -// Description : implementation of SiftMatchGPU and SiftMatchGL -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#include "GL/glew.h" -#include -#include -#include -#include -#include -using namespace std; -#include -#include "GlobalUtil.h" - -#include "ProgramGLSL.h" -#include "GLTexImage.h" -#include "SiftGPU.h" -#include "SiftMatch.h" -#include "FrameBufferObject.h" - -#if defined(CUDA_SIFTGPU_ENABLED) -#include "CuTexImage.h" -#include "SiftMatchCU.h" -#endif - - -SiftMatchGL::SiftMatchGL(int max_sift, int use_glsl): SiftMatchGPU() -{ - s_multiply = s_col_max = s_row_max = s_guided_mult = NULL; - _num_sift[0] = _num_sift[1] = 0; - _id_sift[0] = _id_sift[1] = 0; - _have_loc[0] = _have_loc[1] = 0; - _max_sift = max_sift <=0 ? 4096 : ((max_sift + 31)/ 32 * 32) ; - _pixel_per_sift = 32; //must be 32 - _sift_num_stripe = 1; - _sift_per_stripe = 1; - _sift_per_row = _sift_per_stripe * _sift_num_stripe; - _initialized = 0; -} - -SiftMatchGL::~SiftMatchGL() -{ - if(s_multiply) delete s_multiply; - if(s_guided_mult) delete s_guided_mult; - if(s_col_max) delete s_col_max; - if(s_row_max) delete s_row_max; -} - -void SiftMatchGL::SetMaxSift(int max_sift) -{ - - max_sift = ((max_sift + 31)/32)*32; - if(max_sift > GlobalUtil::_texMaxDimGL) max_sift = GlobalUtil::_texMaxDimGL; - if(max_sift > _max_sift) - { - _max_sift = max_sift; - AllocateSiftMatch(); - _have_loc[0] = _have_loc[1] = 0; - _id_sift[0] = _id_sift[1] = -1; - _num_sift[0] = _num_sift[1] = 1; - }else - { - _max_sift = max_sift; - } - -} - -void SiftMatchGL::AllocateSiftMatch() -{ - //parameters, number of sift is limited by the texture size - if(_max_sift > GlobalUtil::_texMaxDimGL) _max_sift = GlobalUtil::_texMaxDimGL; - /// - int h = _max_sift / _sift_per_row; - int n = (GlobalUtil::_texMaxDimGL + h - 1) / GlobalUtil::_texMaxDimGL; - if ( n > 1) {_sift_num_stripe *= n; _sift_per_row *= n; } - - //initialize - - _texDes[0].InitTexture(_sift_per_row * _pixel_per_sift, _max_sift / _sift_per_row, 0,GL_RGBA8); - _texDes[1].InitTexture(_sift_per_row * _pixel_per_sift, _max_sift / _sift_per_row, 0, GL_RGBA8); - _texLoc[0].InitTexture(_sift_per_row , _max_sift / _sift_per_row, 0); - _texLoc[1].InitTexture(_sift_per_row , _max_sift / _sift_per_row, 0); - - if(GlobalUtil::_SupportNVFloat || GlobalUtil::_SupportTextureRG) - { - //use single-component texture to save memory -#ifndef GL_R32F -#define GL_R32F 0x822E -#endif - GLuint format = GlobalUtil::_SupportNVFloat ? GL_FLOAT_R_NV : GL_R32F; - _texDot.InitTexture(_max_sift, _max_sift, 0, format); - _texMatch[0].InitTexture(16, _max_sift / 16, 0, format); - _texMatch[1].InitTexture(16, _max_sift / 16, 0, format); - }else - { - _texDot.InitTexture(_max_sift, _max_sift, 0); - _texMatch[0].InitTexture(16, _max_sift / 16, 0); - _texMatch[1].InitTexture(16, _max_sift / 16, 0); - } - -} -void SiftMatchGL::InitSiftMatch() -{ - if(_initialized) return; - GlobalUtil::InitGLParam(0); - if(GlobalUtil::_GoodOpenGL == 0) return; - AllocateSiftMatch(); - LoadSiftMatchShadersGLSL(); - _initialized = 1; -} - - -void SiftMatchGL::SetDescriptors(int index, int num, const unsigned char* descriptors, int id) -{ - if(_initialized == 0) return; - if (index > 1) index = 1; - if (index < 0) index = 0; - _have_loc[index] = 0; - - //the same feature is already set - if(id !=-1 && id == _id_sift[index]) return ; - _id_sift[index] = id; - - if(num > _max_sift) num = _max_sift; - - sift_buffer.resize(num * 128 /4); - memcpy(&sift_buffer[0], descriptors, 128 * num); - _num_sift[index] = num; - int w = _sift_per_row * _pixel_per_sift; - int h = (num + _sift_per_row - 1)/ _sift_per_row; - sift_buffer.resize(w * h * 4, 0); - _texDes[index].SetImageSize(w , h); - _texDes[index].BindTex(); - if(_sift_num_stripe == 1) - { - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &sift_buffer[0]); - }else - { - for(int i = 0; i < _sift_num_stripe; ++i) - { - int ws = _sift_per_stripe * _pixel_per_sift; - int x = i * ws; - int pos = i * ws * h * 4; - glTexSubImage2D(GlobalUtil::_texTarget, 0, x, 0, ws, h, GL_RGBA, GL_UNSIGNED_BYTE, &sift_buffer[pos]); - } - } - _texDes[index].UnbindTex(); - -} - -void SiftMatchGL::SetFeautreLocation(int index, const float* locations, int gap) -{ - if(_num_sift[index] <=0) return; - int w = _sift_per_row ; - int h = (_num_sift[index] + _sift_per_row - 1)/ _sift_per_row; - sift_buffer.resize(_num_sift[index] * 2); - if(gap == 0) - { - memcpy(&sift_buffer[0], locations, _num_sift[index] * 2 * sizeof(float)); - }else - { - for(int i = 0; i < _num_sift[index]; ++i) - { - sift_buffer[i*2] = *locations++; - sift_buffer[i*2+1]= *locations ++; - locations += gap; - } - } - sift_buffer.resize(w * h * 2, 0); - _texLoc[index].SetImageSize(w , h); - _texLoc[index].BindTex(); - if(_sift_num_stripe == 1) - { - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, w, h, GL_LUMINANCE_ALPHA , GL_FLOAT , &sift_buffer[0]); - }else - { - for(int i = 0; i < _sift_num_stripe; ++i) - { - int ws = _sift_per_stripe; - int x = i * ws; - int pos = i * ws * h * 2; - glTexSubImage2D(GlobalUtil::_texTarget, 0, x, 0, ws, h, GL_LUMINANCE_ALPHA , GL_FLOAT, &sift_buffer[pos]); - } - } - _texLoc[index].UnbindTex(); - _have_loc[index] = 1; -} - -void SiftMatchGL::SetDescriptors(int index, int num, const float* descriptors, int id) -{ - if(_initialized == 0) return; - if (index > 1) index = 1; - if (index < 0) index = 0; - _have_loc[index] = 0; - - //the same feature is already set - if(id !=-1 && id == _id_sift[index]) return ; - _id_sift[index] = id; - - if(num > _max_sift) num = _max_sift; - - sift_buffer.resize(num * 128 /4); - unsigned char * pub = (unsigned char*) &sift_buffer[0]; - for(int i = 0; i < 128 * num; ++i) - { - pub[i] = int(512 * descriptors[i] + 0.5); - } - _num_sift[index] = num; - int w = _sift_per_row * _pixel_per_sift; - int h = (num + _sift_per_row - 1)/ _sift_per_row; - sift_buffer.resize(w * h * 4, 0); - _texDes[index].SetImageSize(w, h); - _texDes[index].BindTex(); - if(_sift_num_stripe == 1) - { - glTexSubImage2D(GlobalUtil::_texTarget, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, &sift_buffer[0]); - }else - { - for(int i = 0; i < _sift_num_stripe; ++i) - { - int ws = _sift_per_stripe * _pixel_per_sift; - int x = i * ws; - int pos = i * ws * h * 4; - glTexSubImage2D(GlobalUtil::_texTarget, 0, x, 0, ws, h, GL_RGBA, GL_UNSIGNED_BYTE, &sift_buffer[pos]); - } - } - _texDes[index].UnbindTex(); -} - - -void SiftMatchGL::LoadSiftMatchShadersGLSL() -{ - ProgramGLSL * program; - ostringstream out; - if(GlobalUtil::_IsNvidia) - out << "#pragma optionNV(ifcvt none)\n" - "#pragma optionNV(unroll all)\n"; - - out << "#define SIFT_PER_STRIPE " << _sift_per_stripe << ".0\n" - "#define PIXEL_PER_SIFT " << _pixel_per_sift << "\n" - "uniform sampler2DRect tex1, tex2; uniform vec2 size;\n" - "void main() \n" - "{\n" - << " vec4 val = vec4(0.0, 0.0, 0.0, 0.0), data1, buf;\n" - " vec2 index = gl_FragCoord.yx; \n" - " vec2 stripe_size = size.xy * SIFT_PER_STRIPE;\n" - " vec2 temp_div1 = index / stripe_size;\n" - " vec2 stripe_index = floor(temp_div1);\n" - " index = floor(stripe_size * (temp_div1 - stripe_index));\n" - " vec2 temp_div2 = index * vec2(1.0 / float(SIFT_PER_STRIPE));\n" - " vec2 temp_floor2 = floor(temp_div2);\n" - " vec2 index_v = temp_floor2 + vec2(0.5);\n " - " vec2 index_h = vec2(SIFT_PER_STRIPE)* (temp_div2 - temp_floor2);\n" - " vec2 tx = (index_h + stripe_index * vec2(SIFT_PER_STRIPE))* vec2(PIXEL_PER_SIFT) + 0.5;\n" - " vec2 tpos1, tpos2; \n" - " vec4 tpos = vec4(tx, index_v);\n" - ////////////////////////////////////////////////////// - " for(int i = 0; i < PIXEL_PER_SIFT; ++i){\n" - " buf = texture2DRect(tex2, tpos.yw);\n" - " data1 = texture2DRect(tex1, tpos.xz);\n" - " val += (data1 * buf);\n" - " tpos.xy = tpos.xy + vec2(1.0, 1.0);\n" - " }\n" - " const float factor = 0.248050689697265625; \n" - " gl_FragColor =vec4(dot(val, vec4(factor)), index, 0);\n" - "}" - << '\0'; - - s_multiply = program= new ProgramGLSL(out.str().c_str()); - - _param_multiply_tex1 = glGetUniformLocation(*program, "tex1"); - _param_multiply_tex2 = glGetUniformLocation(*program, "tex2"); - _param_multiply_size = glGetUniformLocation(*program, "size"); - - out.seekp(ios::beg); - if(GlobalUtil::_IsNvidia) - out << "#pragma optionNV(ifcvt none)\n" - "#pragma optionNV(unroll all)\n"; - - out << "#define SIFT_PER_STRIPE " << _sift_per_stripe << ".0\n" - "#define PIXEL_PER_SIFT " << _pixel_per_sift << "\n" - "uniform sampler2DRect tex1, tex2;\n" - "uniform sampler2DRect texL1;\n" - "uniform sampler2DRect texL2; \n" - "uniform mat3 H; \n" - "uniform mat3 F; \n" - "uniform vec4 size; \n" - "void main() \n" - "{\n" - << " vec4 val = vec4(0.0, 0.0, 0.0, 0.0), data1, buf;\n" - " vec2 index = gl_FragCoord.yx; \n" - " vec2 stripe_size = size.xy * SIFT_PER_STRIPE;\n" - " vec2 temp_div1 = index / stripe_size;\n" - " vec2 stripe_index = floor(temp_div1);\n" - " index = floor(stripe_size * (temp_div1 - stripe_index));\n" - " vec2 temp_div2 = index * vec2(1.0/ float(SIFT_PER_STRIPE));\n" - " vec2 temp_floor2 = floor(temp_div2);\n" - " vec2 index_v = temp_floor2 + vec2(0.5);\n " - " vec2 index_h = vec2(SIFT_PER_STRIPE)* (temp_div2 - temp_floor2);\n" - - //read feature location data - " vec4 tlpos = vec4((index_h + stripe_index * vec2(SIFT_PER_STRIPE)) + 0.5, index_v);\n" - " vec3 loc1 = vec3(texture2DRect(texL1, tlpos.xz).xw, 1.0);\n" - " vec3 loc2 = vec3(texture2DRect(texL2, tlpos.yw).xw, 1.0);\n" - - //check the guiding homography - " vec3 hxloc1 = H* loc1;\n" - " vec2 diff = abs(loc2.xy- (hxloc1.xy/hxloc1.z));\n" - " float disth = max(diff.x, diff.y);\n" - " if(disth > size.z ) {gl_FragColor = vec4(0.0, index, 0.0); return;}\n" - - //check the guiding fundamental - " vec3 fx1 = (F * loc1), ftx2 = (loc2 * F);\n" - " float x2tfx1 = dot(loc2, fx1);\n" - " vec4 temp = vec4(fx1.xy, ftx2.xy); \n" - " float sampson_error = (x2tfx1 * x2tfx1) / dot(temp, temp);\n" - " if(sampson_error > size.w) {gl_FragColor = vec4(0.0, index, 0.0); return;}\n" - - //compare feature descriptor - " vec2 tx = (index_h + stripe_index * SIFT_PER_STRIPE)* vec2(PIXEL_PER_SIFT) + 0.5;\n" - " vec2 tpos1, tpos2; \n" - " vec4 tpos = vec4(tx, index_v);\n" - " for(int i = 0; i < PIXEL_PER_SIFT; ++i){\n" - " buf = texture2DRect(tex2, tpos.yw);\n" - " data1 = texture2DRect(tex1, tpos.xz);\n" - " val += data1 * buf;\n" - " tpos.xy = tpos.xy + vec2(1.0, 1.0);\n" - " }\n" - " const float factor = 0.248050689697265625; \n" - " gl_FragColor =vec4(dot(val, vec4(factor)), index, 0.0);\n" - "}" - << '\0'; - - s_guided_mult = program= new ProgramGLSL(out.str().c_str()); - - _param_guided_mult_tex1 = glGetUniformLocation(*program, "tex1"); - _param_guided_mult_tex2= glGetUniformLocation(*program, "tex2"); - _param_guided_mult_texl1 = glGetUniformLocation(*program, "texL1"); - _param_guided_mult_texl2 = glGetUniformLocation(*program, "texL2"); - _param_guided_mult_h = glGetUniformLocation(*program, "H"); - _param_guided_mult_f = glGetUniformLocation(*program, "F"); - _param_guided_mult_param = glGetUniformLocation(*program, "size"); - - //row max - out.seekp(ios::beg); - out << "#define BLOCK_WIDTH 16.0\n" - "uniform sampler2DRect tex; uniform vec3 param;\n" - "void main ()\n" - "{\n" - " float index = gl_FragCoord.x + floor(gl_FragCoord.y) * BLOCK_WIDTH; \n" - " vec2 bestv = vec2(-1.0); float imax = -1.0;\n" - " for(float i = 0.0; i < param.x; i ++){\n " - " float v = texture2DRect(tex, vec2(i + 0.5, index)).r; \n" - " imax = v > bestv.r ? i : imax; \n " - " bestv = v > bestv.r? vec2(v, bestv.r) : max(bestv, vec2(v));\n " - " }\n" - " bestv = acos(min(bestv, 1.0));\n" - " if(bestv.x >= param.y || bestv.x >= param.z * bestv.y) imax = -1.0;\n" - " gl_FragColor = vec4(imax, bestv, index);\n" - "}" - << '\0'; - s_row_max = program= new ProgramGLSL(out.str().c_str()); - _param_rowmax_param = glGetUniformLocation(*program, "param"); - - out.seekp(ios::beg); - out << "#define BLOCK_WIDTH 16.0\n" - "uniform sampler2DRect tex; uniform vec3 param;\n" - "void main ()\n" - "{\n" - " float index = gl_FragCoord.x + floor(gl_FragCoord.y) * BLOCK_WIDTH; \n" - " vec2 bestv = vec2(-1.0); float imax = -1.0;\n" - " for(float i = 0.0; i < param.x; i ++){\n " - " float v = texture2DRect(tex, vec2(index, i + 0.5)).r; \n" - " imax = (v > bestv.r)? i : imax; \n " - " bestv = v > bestv.r? vec2(v, bestv.r) : max(bestv, vec2(v));\n " - " }\n" - " bestv = acos(min(bestv, 1.0));\n" - " if(bestv.x >= param.y || bestv.x >= param.z * bestv.y) imax = -1.0;\n" - " gl_FragColor = vec4(imax, bestv, index);\n" - "}" - << '\0'; - s_col_max = program =new ProgramGLSL(out.str().c_str()); - _param_colmax_param = glGetUniformLocation(*program, "param"); - - -} - -int SiftMatchGL::GetGuidedSiftMatch(int max_match, int match_buffer[][2], float H[3][3], float F[3][3], - float distmax, float ratiomax, float hdistmax, float fdistmax, int mbm) -{ - - int dw = _num_sift[1]; - int dh = _num_sift[0]; - if(_initialized ==0) return 0; - if(dw <= 0 || dh <=0) return 0; - if(_have_loc[0] == 0 || _have_loc[1] == 0) return 0; - - FrameBufferObject fbo; - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - _texDot.SetImageSize(dw, dh); - - - //data - _texDot.AttachToFBO(0); - _texDot.FitTexViewPort(); - glActiveTexture(GL_TEXTURE0); - _texDes[0].BindTex(); - glActiveTexture(GL_TEXTURE1); - _texDes[1].BindTex(); - glActiveTexture(GL_TEXTURE2); - _texLoc[0].BindTex(); - glActiveTexture(GL_TEXTURE3); - _texLoc[1].BindTex(); - - //multiply the descriptor matrices - s_guided_mult->UseProgram(); - - - //set parameters glsl - float dot_param[4] = {(float)_texDes[0].GetDrawHeight(), (float) _texDes[1].GetDrawHeight(), hdistmax, fdistmax}; - glUniform1i(_param_guided_mult_tex1, 0); - glUniform1i(_param_guided_mult_tex2, 1); - glUniform1i(_param_guided_mult_texl1, 2); - glUniform1i(_param_guided_mult_texl2, 3); - glUniformMatrix3fv(_param_guided_mult_h, 1, GL_TRUE, H[0]); - glUniformMatrix3fv(_param_guided_mult_f, 1, GL_TRUE, F[0]); - glUniform4fv(_param_guided_mult_param, 1, dot_param); - - _texDot.DrawQuad(); - - GLTexImage::UnbindMultiTex(4); - - return GetBestMatch(max_match, match_buffer, distmax, ratiomax, mbm); -} - -int SiftMatchGL::GetBestMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mbm) -{ - - glActiveTexture(GL_TEXTURE0); - _texDot.BindTex(); - - //readback buffer - sift_buffer.resize(_num_sift[0] + _num_sift[1] + 16); - float * buffer1 = &sift_buffer[0], * buffer2 = &sift_buffer[_num_sift[0]]; - - //row max - _texMatch[0].AttachToFBO(0); - _texMatch[0].SetImageSize(16, ( _num_sift[0] + 15) / 16); - _texMatch[0].FitTexViewPort(); - - ///set parameter glsl - s_row_max->UseProgram(); - glUniform3f(_param_rowmax_param, (float)_num_sift[1], distmax, ratiomax); - - _texMatch[0].DrawQuad(); - glReadPixels(0, 0, 16, (_num_sift[0] + 15)/16, GL_RED, GL_FLOAT, buffer1); - - //col max - if(mbm) - { - _texMatch[1].AttachToFBO(0); - _texMatch[1].SetImageSize(16, (_num_sift[1] + 15) / 16); - _texMatch[1].FitTexViewPort(); - //set parameter glsl - s_col_max->UseProgram(); - glUniform3f(_param_rowmax_param, (float)_num_sift[0], distmax, ratiomax); - _texMatch[1].DrawQuad(); - glReadPixels(0, 0, 16, (_num_sift[1] + 15) / 16, GL_RED, GL_FLOAT, buffer2); - } - - - //unload - glUseProgram(0); - - GLTexImage::UnbindMultiTex(2); - GlobalUtil::CleanupOpenGL(); - - //write back the matches - int nmatch = 0, j ; - for(int i = 0; i < _num_sift[0] && nmatch < max_match; ++i) - { - j = int(buffer1[i]); - if( j>= 0 && (!mbm ||int(buffer2[j]) == i)) - { - match_buffer[nmatch][0] = i; - match_buffer[nmatch][1] = j; - nmatch++; - } - } - return nmatch; -} - -int SiftMatchGL::GetSiftMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mbm) -{ - int dw = _num_sift[1]; - int dh = _num_sift[0]; - if(_initialized ==0) return 0; - if(dw <= 0 || dh <=0) return 0; - - FrameBufferObject fbo; - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - _texDot.SetImageSize(dw, dh); - - //data - _texDot.AttachToFBO(0); - _texDot.FitTexViewPort(); - glActiveTexture(GL_TEXTURE0); - _texDes[0].BindTex(); - glActiveTexture(GL_TEXTURE1); - _texDes[1].BindTex(); - - ////////////////// - //multiply the descriptor matrices - s_multiply->UseProgram(); - //set parameters - float heights[2] = {(float)_texDes[0].GetDrawHeight(), (float)_texDes[1].GetDrawHeight()}; - - glUniform1i(_param_multiply_tex1, 0); - glUniform1i(_param_multiply_tex2 , 1); - glUniform2fv(_param_multiply_size, 1, heights); - - _texDot.DrawQuad(); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GlobalUtil::_texTarget, 0); - - return GetBestMatch(max_match, match_buffer, distmax, ratiomax, mbm); -} - - -int SiftMatchGPU::_CreateContextGL() -{ - //Create an OpenGL Context? - if (__language >= SIFTMATCH_CUDA) {} - else if(!GlobalUtil::CreateWindowEZ()) - { -#if CUDA_SIFTGPU_ENABLED - __language = SIFTMATCH_CUDA; -#else - return 0; -#endif - } - return VerifyContextGL(); -} - - -int SiftMatchGPU::_VerifyContextGL() -{ - if(__matcher) return GlobalUtil::_GoodOpenGL; - -#ifdef CUDA_SIFTGPU_ENABLED - - if(__language >= SIFTMATCH_CUDA) {} - else if(__language == SIFTMATCH_SAME_AS_SIFTGPU && GlobalUtil::_UseCUDA){} - else GlobalUtil::InitGLParam(0); - if(GlobalUtil::_GoodOpenGL == 0) __language = SIFTMATCH_CUDA; - - if(((__language == SIFTMATCH_SAME_AS_SIFTGPU && GlobalUtil::_UseCUDA) || __language >= SIFTMATCH_CUDA) - && SiftMatchCU::CheckCudaDevice (GlobalUtil::_DeviceIndex)) - { - __language = SIFTMATCH_CUDA; - __matcher = new SiftMatchCU(__max_sift); - }else -#else - if((__language == SIFTMATCH_SAME_AS_SIFTGPU && GlobalUtil::_UseCUDA) || __language >= SIFTMATCH_CUDA) - { - std::cerr << "---------------------------------------------------------------------------\n" - << "CUDA not supported in this binary! To enable it, please use SiftGPU_CUDA_Enable\n" - << "Project for VS2005+ or set siftgpu_enable_cuda to 1 in makefile\n" - << "----------------------------------------------------------------------------\n"; - } -#endif - { - __language = SIFTMATCH_GLSL; - __matcher = new SiftMatchGL(__max_sift, 1); - } - - if(GlobalUtil::_verbose) - std::cout << "[SiftMatchGPU]: " << (__language == SIFTMATCH_CUDA? "CUDA" : "GLSL") <<"\n\n"; - - __matcher->InitSiftMatch(); - return GlobalUtil::_GoodOpenGL; -} - -void* SiftMatchGPU::operator new (size_t size){ - void * p = malloc(size); - if (p == 0) - { - const std::bad_alloc ba; - throw ba; - } - return p; -} - - -SiftMatchGPU::SiftMatchGPU(int max_sift) -{ - __max_sift = max(max_sift, 1024); - __language = 0; - __matcher = NULL; -} - -void SiftMatchGPU::SetLanguage(int language) -{ - if(__matcher) return; - //////////////////////// -#ifdef CUDA_SIFTGPU_ENABLED - if(language >= SIFTMATCH_CUDA) GlobalUtil::_DeviceIndex = language - SIFTMATCH_CUDA; -#endif - __language = language > SIFTMATCH_CUDA ? SIFTMATCH_CUDA : language; -} - -void SiftMatchGPU::SetDeviceParam(int argc, char**argv) -{ - if(__matcher) return; - GlobalUtil::SetDeviceParam(argc, argv); -} - -void SiftMatchGPU::SetMaxSift(int max_sift) -{ - if(__matcher) __matcher->SetMaxSift(max(128, max_sift)); - else __max_sift = max(128, max_sift); -} - -SiftMatchGPU::~SiftMatchGPU() -{ - if(__matcher) delete __matcher; -} - -void SiftMatchGPU::SetDescriptors(int index, int num, const unsigned char* descriptors, int id) -{ - __matcher->SetDescriptors(index, num, descriptors, id); -} - -void SiftMatchGPU::SetDescriptors(int index, int num, const float* descriptors, int id) -{ - __matcher->SetDescriptors(index, num, descriptors, id); -} - -void SiftMatchGPU::SetFeautreLocation(int index, const float* locations, int gap) -{ - __matcher->SetFeautreLocation(index, locations, gap); - -} -int SiftMatchGPU::GetGuidedSiftMatch(int max_match, int match_buffer[][2], float H[3][3], float F[3][3], - float distmax, float ratiomax, float hdistmax, float fdistmax, int mutual_best_match) -{ - if(H == NULL && F == NULL) - { - return __matcher->GetSiftMatch(max_match, match_buffer, distmax, ratiomax, mutual_best_match); - }else - { - float Z[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, ti = (1.0e+20F); - - return __matcher->GetGuidedSiftMatch(max_match, match_buffer, H? H : Z, F? F : Z, - distmax, ratiomax, H? hdistmax: ti, F? fdistmax: ti, mutual_best_match); - } -} - -int SiftMatchGPU::GetSiftMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mutual_best_match) -{ - return __matcher->GetSiftMatch(max_match, match_buffer, distmax, ratiomax, mutual_best_match); -} - -SiftMatchGPU* CreateNewSiftMatchGPU(int max_sift) -{ - return new SiftMatchGPU(max_sift); -} - diff --git a/3rdparty/SiftGPU/src/SiftGPU/SiftMatch.h b/3rdparty/SiftGPU/src/SiftGPU/SiftMatch.h deleted file mode 100644 index 5f913e7f..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/SiftMatch.h +++ /dev/null @@ -1,93 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SiftMatch.h -// Author: Changchang Wu -// Description : interface for the SiftMatchGL -//// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#ifndef GPU_SIFT_MATCH_H -#define GPU_SIFT_MATCH_H -class GLTexImage; -class ProgramGPU; - -class SiftMatchGL:public SiftMatchGPU -{ - typedef GLint ParameterGL; -private: - //tex storage - GLTexImage _texLoc[2]; - GLTexImage _texDes[2]; - GLTexImage _texDot; - GLTexImage _texMatch[2]; - - //programs - ProgramGPU * s_multiply; - ProgramGPU * s_guided_mult; - ProgramGPU * s_col_max; - ProgramGPU * s_row_max; - - //matching parameters - ParameterGL _param_multiply_tex1; - ParameterGL _param_multiply_tex2; - ParameterGL _param_multiply_size; - ParameterGL _param_rowmax_param; - ParameterGL _param_colmax_param; - - ///guided matching - ParameterGL _param_guided_mult_tex1; - ParameterGL _param_guided_mult_tex2; - ParameterGL _param_guided_mult_texl1; - ParameterGL _param_guided_mult_texl2; - ParameterGL _param_guided_mult_h; - ParameterGL _param_guided_mult_f; - ParameterGL _param_guided_mult_param; - // - int _max_sift; - int _num_sift[2]; - int _id_sift[2]; - int _have_loc[2]; - - //gpu parameter - int _sift_per_stripe; - int _sift_num_stripe; - int _sift_per_row; - int _pixel_per_sift; - int _initialized; - // - vector sift_buffer; -private: - void AllocateSiftMatch(); - void LoadSiftMatchShadersGLSL(); - int GetBestMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mbm); -public: - SiftMatchGL(int max_sift, int use_glsl); - virtual ~SiftMatchGL(); -public: - void InitSiftMatch(); - void SetMaxSift(int max_sift); - void SetDescriptors(int index, int num, const unsigned char * descriptor, int id = -1); - void SetDescriptors(int index, int num, const float * descriptor, int id = -1); - void SetFeautreLocation(int index, const float* locatoins, int gap); - int GetSiftMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mbm); - int GetGuidedSiftMatch(int max_match, int match_buffer[][2], float H[3][3], float F[3][3], - float distmax, float ratiomax, float hdistmax,float fdistmax, int mbm); -}; - - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/SiftMatchCU.cpp b/3rdparty/SiftGPU/src/SiftGPU/SiftMatchCU.cpp deleted file mode 100644 index 77d333e8..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/SiftMatchCU.cpp +++ /dev/null @@ -1,176 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SiftMatchCU.cpp -// Author: Changchang Wu -// Description : implementation of the SiftMatchCU class. -// CUDA-based implementation of SiftMatch -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if defined(CUDA_SIFTGPU_ENABLED) - -#include "GL/glew.h" -#include -#include -#include -#include -#include -using namespace std; - - -#include "GlobalUtil.h" -#include "CuTexImage.h" -#include "SiftGPU.h" -#include "ProgramCU.h" -#include "SiftMatchCU.h" - - -SiftMatchCU::SiftMatchCU(int max_sift):SiftMatchGPU() -{ - _num_sift[0] = _num_sift[1] = 0; - _id_sift[0] = _id_sift[1] = 0; - _have_loc[0] = _have_loc[1] = 0; - _max_sift = max_sift <=0 ? 4096 : ((max_sift + 31)/ 32 * 32) ; - _initialized = 0; -} - -void SiftMatchCU::SetMaxSift(int max_sift) -{ - max_sift = ((max_sift + 31)/32)*32; - if(max_sift > GlobalUtil::_texMaxDimGL) max_sift = GlobalUtil::_texMaxDimGL; - _max_sift = max_sift; -} - - -int SiftMatchCU::CheckCudaDevice(int device) -{ - return ProgramCU::CheckCudaDevice(device); -} - -void SiftMatchCU::InitSiftMatch() -{ - if(_initialized) return; - GlobalUtil::_GoodOpenGL = max(GlobalUtil::_GoodOpenGL, 1); - _initialized = 1; -} - - -void SiftMatchCU::SetDescriptors(int index, int num, const unsigned char* descriptors, int id) -{ - if(_initialized == 0) return; - if (index > 1) index = 1; - if (index < 0) index = 0; - _have_loc[index] = 0; - //the same feature is already set - if(id !=-1 && id == _id_sift[index]) return ; - _id_sift[index] = id; - if(num > _max_sift) num = _max_sift; - _num_sift[index] = num; - _texDes[index].InitTexture(8 * num, 1, 4); - _texDes[index].CopyFromHost((void*)descriptors); -} - - -void SiftMatchCU::SetDescriptors(int index, int num, const float* descriptors, int id) -{ - if(_initialized == 0) return; - if (index > 1) index = 1; - if (index < 0) index = 0; - if(num > _max_sift) num = _max_sift; - - sift_buffer.resize(num * 128 /4); - unsigned char * pub = (unsigned char*) &sift_buffer[0]; - for(int i = 0; i < 128 * num; ++i) - { - pub[i] = int(512 * descriptors[i] + 0.5); - } - SetDescriptors(index, num, pub, id); -} - - -void SiftMatchCU::SetFeautreLocation(int index, const float* locations, int gap) -{ - if(_num_sift[index] <=0) return; - _texLoc[index].InitTexture(_num_sift[index], 1, 2); - if(gap == 0) - { - _texLoc[index].CopyFromHost(locations); - }else - { - sift_buffer.resize(_num_sift[index] * 2); - float* pbuf = (float*) (&sift_buffer[0]); - for(int i = 0; i < _num_sift[index]; ++i) - { - pbuf[i*2] = *locations++; - pbuf[i*2+1]= *locations ++; - locations += gap; - } - _texLoc[index].CopyFromHost(pbuf); - } - _have_loc[index] = 1; -} - -int SiftMatchCU::GetGuidedSiftMatch(int max_match, int match_buffer[][2], float H[3][3], float F[3][3], - float distmax, float ratiomax, float hdistmax, float fdistmax, int mbm) -{ - - if(_initialized ==0) return 0; - if(_num_sift[0] <= 0 || _num_sift[1] <=0) return 0; - if(_have_loc[0] == 0 || _have_loc[1] == 0) return 0; - ProgramCU::MultiplyDescriptorG(_texDes, _texDes+1, _texLoc, _texLoc + 1, - &_texDot, (mbm? &_texCRT: NULL), H, hdistmax, F, fdistmax); - return GetBestMatch(max_match, match_buffer, distmax, ratiomax, mbm); -} - - -int SiftMatchCU::GetSiftMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mbm) -{ - if(_initialized ==0) return 0; - if(_num_sift[0] <= 0 || _num_sift[1] <=0) return 0; - ProgramCU::MultiplyDescriptor(_texDes, _texDes + 1, &_texDot, (mbm? &_texCRT: NULL)); - return GetBestMatch(max_match, match_buffer, distmax, ratiomax, mbm); -} - - -int SiftMatchCU::GetBestMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mbm) -{ - sift_buffer.resize(_num_sift[0] + _num_sift[1]); - int * buffer1 = (int*) &sift_buffer[0], * buffer2 = (int*) &sift_buffer[_num_sift[0]]; - _texMatch[0].InitTexture(_num_sift[0], 1); - ProgramCU::GetRowMatch(&_texDot, _texMatch, distmax, ratiomax); - _texMatch[0].CopyToHost(buffer1); - if(mbm) - { - _texMatch[1].InitTexture(_num_sift[1], 1); - ProgramCU::GetColMatch(&_texCRT, _texMatch + 1, distmax, ratiomax); - _texMatch[1].CopyToHost(buffer2); - } - int nmatch = 0, j ; - for(int i = 0; i < _num_sift[0] && nmatch < max_match; ++i) - { - j = int(buffer1[i]); - if( j>= 0 && (!mbm ||int(buffer2[j]) == i)) - { - match_buffer[nmatch][0] = i; - match_buffer[nmatch][1] = j; - nmatch++; - } - } - return nmatch; -} - -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/SiftMatchCU.h b/3rdparty/SiftGPU/src/SiftGPU/SiftMatchCU.h deleted file mode 100644 index 626e814b..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/SiftMatchCU.h +++ /dev/null @@ -1,68 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SiftMatchCU.h -// Author: Changchang Wu -// Description : interface for the SiftMatchCU -//// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - - -#ifndef CU_SIFT_MATCH_H -#define CU_SIFT_MATCH_H -#if defined(CUDA_SIFTGPU_ENABLED) - -class CuTexImage; -class SiftMatchCU:public SiftMatchGPU -{ -private: - //tex storage - CuTexImage _texLoc[2]; - CuTexImage _texDes[2]; - CuTexImage _texDot; - CuTexImage _texMatch[2]; - CuTexImage _texCRT; - - //programs - // - int _max_sift; - int _num_sift[2]; - int _id_sift[2]; - int _have_loc[2]; - - //gpu parameter - int _initialized; - vector sift_buffer; -private: - int GetBestMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mbm); -public: - SiftMatchCU(int max_sift); - virtual ~SiftMatchCU(){}; - void InitSiftMatch(); - void SetMaxSift(int max_sift); - void SetDescriptors(int index, int num, const unsigned char * descriptor, int id = -1); - void SetDescriptors(int index, int num, const float * descriptor, int id = -1); - void SetFeautreLocation(int index, const float* locatoins, int gap); - int GetSiftMatch(int max_match, int match_buffer[][2], float distmax, float ratiomax, int mbm); - int GetGuidedSiftMatch(int max_match, int match_buffer[][2], float H[3][3], float F[3][3], - float distmax, float ratiomax, float hdistmax, float fdistmax, int mbm); - ////////////////////////////// - static int CheckCudaDevice(int device); -}; - -#endif -#endif - diff --git a/3rdparty/SiftGPU/src/SiftGPU/SiftPyramid.cpp b/3rdparty/SiftGPU/src/SiftGPU/SiftPyramid.cpp deleted file mode 100644 index ab8766c4..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/SiftPyramid.cpp +++ /dev/null @@ -1,406 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SiftPyramid.cpp -// Author: Changchang Wu -// Description : Implementation of the SiftPyramid class. -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include "GL/glew.h" -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "GlobalUtil.h" -#include "SiftPyramid.h" -#include "SiftGPU.h" - - -#ifdef DEBUG_SIFTGPU -#include "IL/il.h" -#include "direct.h" -#include "io.h" -#include -#endif - - - -void SiftPyramid::RunSIFT(GLTexInput*input) -{ - CleanupBeforeSIFT(); - - if(_existing_keypoints & SIFT_SKIP_FILTERING) - { - - }else - { - GlobalUtil::StartTimer("Build Pyramid"); - BuildPyramid(input); - GlobalUtil::StopTimer(); - _timing[0] = GetElapsedTime(); - } - - - if(_existing_keypoints) - { - //existing keypoint list should at least have the locations and scale - GlobalUtil::StartTimer("Upload Feature List"); - if(!(_existing_keypoints & SIFT_SKIP_FILTERING)) ComputeGradient(); - GenerateFeatureListTex(); - GlobalUtil::StopTimer(); - _timing[2] = GetElapsedTime(); - }else - { - - GlobalUtil::StartTimer("Detect Keypoints"); - DetectKeypointsEX(); - GlobalUtil::StopTimer(); - _timing[1] = GetElapsedTime(); - - if(GlobalUtil::_ListGenGPU ==1) - { - GlobalUtil::StartTimer("Get Feature List"); - GenerateFeatureList(); - GlobalUtil::StopTimer(); - - }else - { - GlobalUtil::StartTimer("Transfer Feature List"); - GenerateFeatureListCPU(); - GlobalUtil::StopTimer(); - } - LimitFeatureCount(0); - _timing[2] = GetElapsedTime(); - } - - - - if(_existing_keypoints& SIFT_SKIP_ORIENTATION) - { - //use exisitng feature orientation or - }else if(GlobalUtil::_MaxOrientation>0) - { - //some extra tricks are done to handle existing keypoint list - GlobalUtil::StartTimer("Feature Orientations"); - GetFeatureOrientations(); - GlobalUtil::StopTimer(); - _timing[3] = GetElapsedTime(); - - //for existing keypoint list, only the strongest orientation is kept. - if(GlobalUtil::_MaxOrientation >1 && !_existing_keypoints && !GlobalUtil::_FixedOrientation) - { - GlobalUtil::StartTimer("MultiO Feature List"); - ReshapeFeatureListCPU(); - LimitFeatureCount(1); - GlobalUtil::StopTimer(); - _timing[4] = GetElapsedTime(); - } - }else - { - GlobalUtil::StartTimer("Feature Orientations"); - GetSimplifiedOrientation(); - GlobalUtil::StopTimer(); - _timing[3] = GetElapsedTime(); - } - - PrepareBuffer(); - - if(_existing_keypoints & SIFT_SKIP_ORIENTATION) - { - //no need to read back feature if all fields of keypoints are already specified - }else - { - GlobalUtil::StartTimer("Download Keypoints"); -#ifdef NO_DUPLICATE_DOWNLOAD - if(GlobalUtil::_MaxOrientation < 2 || GlobalUtil::_FixedOrientation) -#endif - DownloadKeypoints(); - GlobalUtil::StopTimer(); - _timing[5] = GetElapsedTime(); - } - - - - if(GlobalUtil::_DescriptorPPT) - { - //desciprotrs are downloaded in descriptor computation of each level - GlobalUtil::StartTimer("Get Descriptor"); - GetFeatureDescriptors(); - GlobalUtil::StopTimer(); - _timing[6] = GetElapsedTime(); - } - - //reset the existing keypoints - _existing_keypoints = 0; - _keypoint_index.resize(0); - - if(GlobalUtil::_UseSiftGPUEX) - { - GlobalUtil::StartTimer("Gen. Display VBO"); - GenerateFeatureDisplayVBO(); - GlobalUtil::StopTimer(); - _timing[7] = GlobalUtil::GetElapsedTime(); - } - //clean up - CleanUpAfterSIFT(); -} - - -void SiftPyramid::LimitFeatureCount(int have_keylist) -{ - - if(GlobalUtil::_FeatureCountThreshold <= 0 || _existing_keypoints) return; - /////////////////////////////////////////////////////////////// - //skip the lowest levels to reduce number of features. - - if(GlobalUtil::_TruncateMethod == 2) - { - int i = 0, new_feature_num = 0, level_num = param._dog_level_num * _octave_num; - for(; new_feature_num < _FeatureCountThreshold && i < level_num; ++i) new_feature_num += _levelFeatureNum[i]; - for(; i < level_num; ++i) _levelFeatureNum[i] = 0; - - if(new_feature_num < _featureNum) - { - _featureNum = new_feature_num; - if(GlobalUtil::_verbose ) - { - std::cout<<"#Features Reduced:\t"<<_featureNum< _FeatureCountThreshold) - { - num_to_erase += _levelFeatureNum[i]; - _featureNum -= _levelFeatureNum[i]; - _levelFeatureNum[i++] = 0; - } - if(num_to_erase > 0 && have_keylist) - { - _keypoint_buffer.erase(_keypoint_buffer.begin(), _keypoint_buffer.begin() + num_to_erase * 4); - } - if(GlobalUtil::_verbose && num_to_erase > 0) - { - std::cout<<"#Features Reduced:\t"<<_featureNum< i - 3... - //768 in [2^9, 2^10) -> 6 -> smallest will be 768 / 32 = 24 - int num = (int) floor (log ( inputsz * 2.0 / GlobalUtil::_texMinDim )/log(2.0)); - return num <= 0 ? 1 : num; -} - -void SiftPyramid::CopyFeatureVector(float*keys, float *descriptors) -{ - if(keys) memcpy(keys, &_keypoint_buffer[0], 4*_featureNum*sizeof(float)); - if(descriptors) memcpy(descriptors, &_descriptor_buffer[0], 128*_featureNum*sizeof(float)); -} - -void SiftPyramid:: SetKeypointList(int num, const float * keys, int run_on_current, int skip_orientation) -{ - //for each input keypoint - //sort the key point list by size, and assign them to corresponding levels - if(num <=0) return; - _featureNum = num; - ///copy the keypoints - _keypoint_buffer.resize(num * 4); - memcpy(&_keypoint_buffer[0], keys, 4 * num * sizeof(float)); - //location and scale can be skipped - _existing_keypoints = SIFT_SKIP_DETECTION; - //filtering is skipped if it is running on the same image - if(run_on_current) _existing_keypoints |= SIFT_SKIP_FILTERING; - //orientation can be skipped if specified - if(skip_orientation) _existing_keypoints |= SIFT_SKIP_ORIENTATION; - //hacking parameter for using rectangle description mode - if(skip_orientation == -1) _existing_keypoints |= SIFT_RECT_DESCRIPTION; -} - - -void SiftPyramid::SaveSIFT(const char * szFileName) -{ - if (_featureNum <=0) return; - float * pk = &_keypoint_buffer[0]; - - if(GlobalUtil::_BinarySIFT) - { - std::ofstream out(szFileName, ios::binary); - out.write((char* )(&_featureNum), sizeof(int)); - - if(GlobalUtil::_DescriptorPPT) - { - int dim = 128; - out.write((char* )(&dim), sizeof(int)); - float * pd = &_descriptor_buffer[0] ; - for(int i = 0; i < _featureNum; i++, pk+=4, pd +=128) - { - out.write((char* )(pk +1), sizeof(float)); - out.write((char* )(pk), sizeof(float)); - out.write((char* )(pk+2), 2 * sizeof(float)); - out.write((char* )(pd), 128 * sizeof(float)); - } - }else - { - int dim = 0; - out.write((char* )(&dim), sizeof(int)); - for(int i = 0; i < _featureNum; i++, pk+=4) - { - out.write((char* )(pk +1), sizeof(float)); - out.write((char* )(pk), sizeof(float)); - out.write((char* )(pk+2), 2 * sizeof(float)); - } - } - }else - { - std::ofstream out(szFileName); - out.flags(ios::fixed); - - if(GlobalUtil::_DescriptorPPT) - { - float * pd = &_descriptor_buffer[0] ; - out<<_featureNum<<" 128"<GetImgWidth(); - int height = tex->GetImgHeight(); - float* buffer1 = new float[ width * height * 4]; - float* buffer2 = new float[ width * height * 4]; - - //read data back - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); - tex->AttachToFBO(0); - tex->FitTexViewPort(); - glReadPixels(0, 0, width, height, GL_RGBA , GL_FLOAT, buffer1); - - //Tiffs saved with IL are flipped - for(int i = 0; i < height; i++) - { - memcpy(buffer2 + i * width * 4, - buffer1 + (height - i - 1) * width * 4, - width * 4 * sizeof(float)); - } - - //save data as floating point tiff file - ilGenImages(1, &imID); - ilBindImage(imID); - ilEnable(IL_FILE_OVERWRITE); - ilTexImage(width, height, 1, 4, IL_RGBA, IL_FLOAT, buffer2); - ilSave(IL_TIF, name); - ilDeleteImages(1, &imID); - - delete buffer1; - delete buffer2; - glReadBuffer(GL_NONE); -} - - -#endif diff --git a/3rdparty/SiftGPU/src/SiftGPU/SiftPyramid.h b/3rdparty/SiftGPU/src/SiftGPU/SiftPyramid.h deleted file mode 100644 index 0b9c58b2..00000000 --- a/3rdparty/SiftGPU/src/SiftGPU/SiftPyramid.h +++ /dev/null @@ -1,190 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SiftPyramid.h -// Author: Changchang Wu -// Description : interface for the SiftPyramid class. -// SiftPyramid: data storage for SIFT -// |---PyramidGL: OpenGL based implementation -// | |--PyramidNaive: Unpacked version -// | |--PyramidPacked: packed version -// |--PyramidCU: CUDA-based implementation -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - - -#ifndef _SIFT_PYRAMID_H -#define _SIFT_PYRAMID_H - - -class GLTexImage; -class GLTexInput; -class SiftParam; -class GlobalUtil; - -///////////////////////////////////////////////////////////////////////////// -//class SiftPyramid -//description: virutal class of SIFT data pyramid -// provides functions for SiftPU to run steps of GPU SIFT -// class PyramidNaive is the first implementation -// class PyramidPacked is a better OpenGL implementation -// class PyramidCU is a CUDA based implementation -///////////////////////////////////////////////////////////////////////////// - -#define NO_DUPLICATE_DOWNLOAD - -class SiftPyramid : public GlobalUtil -{ -public: - enum{ - DATA_GAUSSIAN = 0, - DATA_DOG = 1, - DATA_KEYPOINT = 2, - DATA_GRAD = 3, - DATA_ROT = 4, - DATA_NUM = 5 - }; - enum{ - SIFT_SKIP_FILTERING = 0x01, - SIFT_SKIP_DETECTION = 0x02, - SIFT_SKIP_ORIENTATION = 0x04, - SIFT_RECT_DESCRIPTION = 0x08 - }; -protected: - SiftParam& param; - int _hpLevelNum; - int* _levelFeatureNum; - int _featureNum; - float* _histo_buffer; - //keypoint list - int _existing_keypoints; - vector _keypoint_index; - //display vbo - GLuint* _featureDisplayVBO; - GLuint* _featurePointVBO; -public: - // - float _timing[8]; - //image size related - //first octave - int _octave_min; - //how many octaves - int _octave_num; - //pyramid storage - int _pyramid_octave_num; - int _pyramid_octave_first; - int _pyramid_width; - int _pyramid_height; - int _down_sample_factor; - int _allocated; - int _alignment; - int _siftgpu_failed; -public: - vector _keypoint_buffer; - vector _descriptor_buffer; -private: - inline void PrepareBuffer(); - inline void LimitFeatureCount(int have_keylist = 0); -public: - //shared by all implementations - virtual void RunSIFT(GLTexInput*input); - virtual void SaveSIFT(const char * szFileName); - virtual void CopyFeatureVector(float*keys, float *descriptors); - virtual void SetKeypointList(int num, const float * keys, int run_on_current, int skip_orientation); - //implementation-dependent functions - virtual void GetFeatureDescriptors() = 0; - virtual void GenerateFeatureListTex() =0; - virtual void ReshapeFeatureListCPU() =0; - virtual void GenerateFeatureDisplayVBO() =0; - virtual void DownloadKeypoints() = 0; - virtual void GenerateFeatureListCPU()=0; - virtual void GenerateFeatureList()=0; - virtual GLTexImage* GetLevelTexture(int octave, int level)=0; - virtual GLTexImage* GetLevelTexture(int octave, int level, int dataName) = 0; - virtual void BuildPyramid(GLTexInput * input)=0; - virtual void ResizePyramid(int w, int h) = 0; - virtual void InitPyramid(int w, int h, int ds = 0)=0; - virtual void DetectKeypointsEX() = 0; - virtual void ComputeGradient() = 0; - virtual void GetFeatureOrientations() = 0; - virtual void GetSimplifiedOrientation() = 0; - - //////////////////////////////// - virtual void CleanUpAfterSIFT() {} - virtual int IsUsingRectDescription() {return 0; } - static int GetRequiredOctaveNum(int inputsz); - - ///inline functions, shared by all implementations - inline void SetFailStatus() {_siftgpu_failed = 1; } - inline int GetSucessStatus() {return _siftgpu_failed == 0; } - inline int GetFeatureNum(){return _featureNum;} - inline int GetHistLevelNum(){return _hpLevelNum;} - inline const GLuint * GetFeatureDipslayVBO(){return _featureDisplayVBO;} - inline const GLuint * GetPointDisplayVBO(){return _featurePointVBO;} - inline const int * GetLevelFeatureNum(){return _levelFeatureNum;} - inline void GetPyramidTiming(float * timing){ for(int i = 0; i < 8; i++) timing[i] = _timing[i]; } - inline void CleanupBeforeSIFT() - { - _siftgpu_failed = 0; - for(int i = 0; i < 8; ++i) _timing[i] = 0; - } - SiftPyramid(SiftParam&sp):param(sp) - { - _featureNum = 0; - _featureDisplayVBO = 0; - _featurePointVBO = 0; - _levelFeatureNum = NULL; - _histo_buffer = NULL; - _hpLevelNum = 0; - - //image size - _octave_num = 0; - _octave_min = 0; - _alignment = 1; - _pyramid_octave_num = _pyramid_octave_first = 0; - _pyramid_width = _pyramid_height = 0; - _allocated = 0; - _down_sample_factor = 0; - - ///// - _existing_keypoints = 0; - } - virtual ~SiftPyramid() {}; - -#ifdef DEBUG_SIFTGPU -private: - void StopDEBUG(); - void BeginDEBUG(const char* imagepath); - void WriteTextureForDEBUG(GLTexImage * tex, const char * namet, ...); -#endif -}; - -#define SIFTGPU_ENABLE_REVERSE_ORDER -#ifdef SIFTGPU_ENABLE_REVERSE_ORDER -#define FIRST_OCTAVE(R) (R? _octave_num - 1 : 0) -#define NOT_LAST_OCTAVE(i, R) (R? (i >= 0) : (i < _octave_num)) -#define GOTO_NEXT_OCTAVE(i, R) (R? (--i) : (++i)) -#define FIRST_LEVEL(R) (R? param._dog_level_num - 1 : 0) -#define GOTO_NEXT_LEVEL(j, R) (R? (--j) : (++j)) -#define NOT_LAST_LEVEL(j, R) (R? (j >= 0) : (j < param._dog_level_num)) -#define FOR_EACH_OCTAVE(i, R) for(int i = FIRST_OCTAVE(R); NOT_LAST_OCTAVE(i, R); GOTO_NEXT_OCTAVE(i, R)) -#define FOR_EACH_LEVEL(j, R) for(int j = FIRST_LEVEL(R); NOT_LAST_LEVEL(j, R); GOTO_NEXT_LEVEL(j, R)) -#else -#define FOR_EACH_OCTAVE(i, R) for(int i = 0; i < _octave_num; ++i) -#define FOR_EACH_LEVEL(j, R) for(int j = 0; j < param._dog_level_num; ++j) -#endif - -#endif diff --git a/3rdparty/SiftGPU/src/TestWin/BasicTestWin.cpp b/3rdparty/SiftGPU/src/TestWin/BasicTestWin.cpp deleted file mode 100644 index 57774141..00000000 --- a/3rdparty/SiftGPU/src/TestWin/BasicTestWin.cpp +++ /dev/null @@ -1,322 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: BasicTestWin.cpp -// Author: Changchang Wu -// Description : implementation of the BasicTestWin class. -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// -#ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #include - #define SIFTGPU_DLL - #include -#else - #include -#endif - -#include "stdlib.h" -#include -using std::iostream; - -#ifdef __APPLE__ - #include "OpenGL/OpenGL.h" -#else - #include "GL/gl.h" -#endif - -#include "../SiftGPU/SiftGPU.h" -#include "BasicTestWin.h" - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -BasicTestWin::BasicTestWin() -{ - _view = 0; - _sub_view = 0; - _motion = 0; - _looping = 0; - _current = 0; - - - // - _win_w = _win_h = 0; - _imgWidth = _imgHeight = 0; - _displayScale = 1.0f; - _sift = new SiftGPUEX(); -} - -BasicTestWin::~BasicTestWin() -{ - _motion = 0; - _looping = 0; -} - - - -void BasicTestWin::Display() -{ - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glClear(GL_COLOR_BUFFER_BIT); - _transform.transform(_displayScale); - if(_sift) _sift->DisplaySIFT(); - glFlush(); - glFinish(); - -} - -void BasicTestWin::OnIdle() -{ - if(_looping && ! _motion) - { - KeyInput('r'); - UpdateDisplay(); - } - -} -void BasicTestWin::KeyInput(int key) -{ - switch(key) - { - case '+': - case '=': - _transform.scaleup(); - break; - case '-': - _transform.scaledown(); - break; - case '\r': - _view++; - _sub_view =0; - SetView(); - break; - case '\b': - _view--; - _sub_view = 0; - SetView(); - break; - case ' ': - case '.': - _sub_view++; - SetView(); - break; - case ',': - _sub_view--; - SetView(); - break; - case 'o': - case 'O': - _transform.reset(); - break; - case 'd': - case 'D': - if(_sift) _sift->ToggleDisplayDebug(); - break; - case 'r': - case 'R': - if(_sift) - { - _sift->RunSIFT(++_current); - _stat_frames++; - FitWindow(); - } - break; - case 'c': - case 'C': - if(_sift) _sift->RandomizeColor(); - break; - case 'q': - case 'Q': - if(_sift) _sift->SetVerbose(-1); - break; - case 'v': - if(_sift) _sift->SetVerbose(4); - break; - case 'x': - case 'X': - case 27: - exit(0); - break; - case 'l': - case 'L': - _looping = ! _looping; - if(_looping) - { - _stat_tstart = myclock(); - _stat_frames = 0; - }else - { - float t = (myclock() - _stat_tstart); - float fps = _stat_frames/t; - std::cout<<"************************************\n" - <RunSIFT()) - { - _sift->SetVerbose(2); - FitWindow(); - }else - { - exit(0); - } -} - -void BasicTestWin::ParseSiftParam(int argc, char** argv) -{ - _sift->ParseParam(argc, argv); - _sift->SetVerbose(5); - _win_x = _win_y = -1; - _sift->GetInitWindowPotition(_win_x, _win_y); -} - - - - -void BasicTestWin::FitWindow() -{ - int w, h , dw, dh; - _sift->GetImageDimension(w, h); - - - if(w <=0 || h <=0 ) return; - - - if( w == _imgWidth || h == _imgHeight) - { - ReShape(_win_w, _win_h); - return; - } - - - _transform.setcenter(w*0.5, h*0.5); - - /// - - dw =_imgWidth = w; - dh =_imgHeight = h; - - _displayScale = 1.0; - - while(dw>1024 || dh >1024) - { - dw>>=1; - dh>>=1; - _displayScale *= 0.5; - } - - while(dw < 512 && dh < 512) - { - dw <<= 1; - dh <<= 1; - _displayScale*= 2.0; - } - - if ( dw > _win_w || dh > _win_h) - { - _win_w = dw; - _win_h = dh; - SetDisplaySize(dw, dh); - }else - { - ReShape(_win_w, _win_h); - } -} - - - - -void BasicTestWin::SetView() -{ - if(_sift) - { - _sift->SetView(_view, _sub_view, _title); - SetWindowTitle(_title); - } -} - -void BasicTestWin::StartMotion(int x, int y) -{ - _motion = 1; - _motion_x = x; - _motion_y = y; -} - -void BasicTestWin::EndMotion() -{ - _motion = 0; -} - - -void BasicTestWin::SetVerbose() -{ - _sift->SetVerbose(); -} - -float BasicTestWin::myclock() -{ -#if defined(_WIN32) - return clock() * 1.0 / CLOCKS_PER_SEC; -#else - static int started = 0; - static struct timeval tstart; - if(started == 0) - { - gettimeofday(&tstart, NULL); - started = 1; - return 0; - }else - { - struct timeval now; - gettimeofday(&now, NULL) ; - return (now.tv_usec - tstart.tv_usec + (now.tv_sec - tstart.tv_sec) * 1000000)/1000000.f; - } -#endif -} diff --git a/3rdparty/SiftGPU/src/TestWin/BasicTestWin.h b/3rdparty/SiftGPU/src/TestWin/BasicTestWin.h deleted file mode 100644 index 51aaf35e..00000000 --- a/3rdparty/SiftGPU/src/TestWin/BasicTestWin.h +++ /dev/null @@ -1,97 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: BasicTestWin.h -// Author: Changchang Wu -// Description : -// BasicTestWin: basic viewer of SiftGPU -// both TestWinGlut and GLTestWndare derived from this -// SiftDriver: A simple driver of SiftGPU -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#if !defined(BASIC_TEST_WIN_H) -#define BASIC_TEST_WIN_H - -#if _WIN32 && _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -#include "GLTransform.h" - -class SiftParam; -class SiftGPUEX; - -////////////////////////////////////////////////////////////////////////// -//class TestDriver -//description: simple SiftGPU driver -///////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////////////// -//class BasicTestWin -//description: basic SiftGPU viewer -// two implementations are GLTestWnd and TestWinGlut -/////////////////////////////////////////////////////////////////////////// - - -class BasicTestWin -{ - GlTransform _transform; - int _looping; - int _motion; - int _motion_x, _motion_y; - char _title[512]; - int _view; - int _sub_view; - int _win_w, _win_h; - -protected: - float _displayScale; - int _imgWidth, _imgHeight; - int _win_x, _win_y; - int _current; -private: - // - float _stat_tstart; - int _stat_frames; -protected: - SiftGPUEX* _sift; -public: - void SetVerbose(); - void FitWindow(); - void OnIdle(); - void EndMotion(); - void StartMotion(int x, int y); - void SetView(); - void ReShape(int w, int h); - void MoveMouse(int x, int y); - void KeyInput(int key); - void Display(); - virtual void UpdateDisplay()=0; - BasicTestWin(); - virtual ~BasicTestWin(); - void ParseSiftParam(int argc, char** argv); - void RunSiftGPU(); - static float myclock(); -protected: - virtual void SetWindowTitle(char * title)=0; - virtual void SetDisplaySize(int w, int h)=0; -}; - -#endif // !defined(BASIC_TEST_WIN_H) - diff --git a/3rdparty/SiftGPU/src/TestWin/CMakeLists.txt b/3rdparty/SiftGPU/src/TestWin/CMakeLists.txt deleted file mode 100644 index 0bbaa8f2..00000000 --- a/3rdparty/SiftGPU/src/TestWin/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -find_package(OpenGL REQUIRED) -find_package(GLUT REQUIRED) -find_package(Glew REQUIRED) - -include_directories( ${GLEW_INCLUDE_DIRS} ) - -ADD_EXECUTABLE(SimpleSIFT SimpleSIFT.cpp) -TARGET_LINK_LIBRARIES(SimpleSIFT siftgpu) - -ADD_EXECUTABLE(TestWinGlut TestWinGlut.cpp BasicTestWin.cpp ) -TARGET_LINK_LIBRARIES(TestWinGlut siftgpu) - -set(CMAKE_VERBOSE_MAKEFILE ON) diff --git a/3rdparty/SiftGPU/src/TestWin/GLTestWnd.cpp b/3rdparty/SiftGPU/src/TestWin/GLTestWnd.cpp deleted file mode 100644 index 46e0fe9d..00000000 --- a/3rdparty/SiftGPU/src/TestWin/GLTestWnd.cpp +++ /dev/null @@ -1,305 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: GLTestWnd.cpp -// Author: Changchang Wu -// Description : implementation of the GLTestWnd class. -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include "GL/gl.h" -#include - -///////////////////////// -#include "BasicTestWin.h" -#include "GLTestWnd.h" - -#ifdef _WINDOWS -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - LPSTR lpCmdLine, int nCmdShow) -{ - ////////////////////////////////////////// - //create a window - GLTestWnd win(lpCmdLine); -#else -int main(int argc, char** argv) -{ - GLTestWnd win(argc, argv); -#endif - - /////////////////////////////////////// - MSG msg; // - while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - //on idle - if(PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)==0)SendMessage(GetActiveWindow(), WM_MY_IDLE, 0, 0); - } - return (int) msg.wParam; -} - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - - -GLTestWnd::GLTestWnd(LPSTR cmd) -{ - /////////////////////// - //Parse Command Line - if(cmd) ParseCommandLine(cmd); - - ////////////////////// - //create the window - CreateWindowGL(); -} - -GLTestWnd::GLTestWnd(int argc, char**argv) -{ - BasicTestWin::ParseSiftParam(argc, argv); - CreateWindowGL(); -} - -GLTestWnd::~GLTestWnd() -{ - -} - -void GLTestWnd::CreateWindowGL() -{ - _hWndMain = NULL; - RegisterWindowClass(); - HWND hWnd = CreateWindow("SIFT_GPU_WND", "SIFT_GPU", - WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, - CW_USEDEFAULT, CW_USEDEFAULT, - 600, 450, NULL, NULL, NULL, this); - ShowWindow(hWnd, SW_SHOW); - UpdateWindow(hWnd); - -} -LRESULT CALLBACK GLTestWnd::___WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - static int nWnd=0; - GLTestWnd *pWnd; - if(message==WM_CREATE) - { - LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam; - pWnd = (GLTestWnd*)cs->lpCreateParams; - pWnd->_hWndMain = hWnd; - SetWindowLong(hWnd,0,(long)(pWnd)); - nWnd++; - - }else if(message== WM_DESTROY) - { - //pWnd=(GLTestWnd*)GetWindowLong(hWnd,0); - //delete pWnd; - SetWindowLong(hWnd,0,0); - nWnd--; - if(nWnd==0) PostQuitMessage(0); - pWnd = NULL; - }else - { - pWnd=(GLTestWnd*)GetWindowLong(hWnd,0); - } - if(pWnd) - return pWnd->_WndProc(message,wParam,lParam); - else - return DefWindowProc(hWnd, message, wParam, lParam); - -} - -void GLTestWnd::RegisterWindowClass() -{ - static int registered = 0; - if(registered) return; - WNDCLASSEX wcex; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wcex.lpfnWndProc = (WNDPROC)___WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 4; - wcex.hInstance = 0; - wcex.hIcon = NULL; - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wcex.lpszMenuName = NULL;; - wcex.lpszClassName = "SIFT_GPU_WND"; - wcex.hIconSm = NULL; - RegisterClassEx(&wcex); - registered = 1; -} - - -LRESULT GLTestWnd::_WndProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - - - switch (message) - { - case WM_CREATE: - { - if(_win_x !=-1) - { - LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam; - MoveWindow(_hWndMain, _win_x, _win_y, cs->cx, cs->cy, 0); - } - SetDisplaySize(600, 450); - HDC hdc = GetDC(_hWndMain); - glCreateRC(hdc); - if(_hglrc == NULL) exit(0); - ReleaseDC(_hWndMain,hdc); - - } - break; - case WM_SIZE: - { - glResize(LOWORD(lParam),HIWORD(lParam)); - } - break; - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc = BeginPaint(_hWndMain, &ps); - /// - glPaint(hdc); - /// - EndPaint(_hWndMain, &ps); - } - break; - case WM_CHAR: - KeyInput((int) wParam); - InvalidateRect(_hWndMain, NULL, FALSE); - break; - case WM_LBUTTONDOWN: - { - int xPos = GET_X_LPARAM(lParam); - int yPos = GET_Y_LPARAM(lParam); - StartMotion(xPos, yPos); - } - break; - case WM_LBUTTONUP: - EndMotion(); - break; - case WM_MOUSEMOVE: - if( wParam & MK_LBUTTON) - { - int xPos = GET_X_LPARAM(lParam); - int yPos = GET_Y_LPARAM(lParam); - MoveMouse(xPos, yPos); - } - case WM_ERASEBKGND: - return TRUE; - case WM_MY_IDLE: - OnIdle(); - return TRUE; - case WM_DESTROY: - PostQuitMessage(0); - break; - default: - return DefWindowProc(_hWndMain, message, wParam, lParam); - } - return 0; -} -void GLTestWnd::glCreateRC(HDC hdc) -{ - int pixelformat; - PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR),1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA,24,0, 0, 0, 0, 0, 0,0,0,0,0, 0, 0, 0,16,0,0, - PFD_MAIN_PLANE,0,0, 0, 0 - }; - if ((pixelformat = ChoosePixelFormat(hdc, &pfd)) ==0)return ; - if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE)return ; - pixelformat =::GetPixelFormat(hdc); - ::DescribePixelFormat(hdc, pixelformat, sizeof(pfd), &pfd); - - // - _hglrc = wglCreateContext(hdc); - wglMakeCurrent(hdc, _hglrc); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - RunSiftGPU(); - - wglMakeCurrent(NULL, NULL); - -} - -void GLTestWnd::glResize(int w, int h) -{ - ReShape(w, h); -} - -void GLTestWnd::glPaint(HDC hdc) -{ - wglMakeCurrent(hdc,HGLRC(_hglrc)); - Display(); - SwapBuffers(hdc); -} - -void GLTestWnd::ParseCommandLine(LPSTR cmd) -{ - int argc=0; - char**argv = new char*[256]; - if(*cmd == 0) return; - do - { - while(*cmd ==' ') cmd++; - if(*cmd) - { - argv[argc++] = cmd; - } - while(*cmd && *cmd != ' ') cmd++; - if(*cmd==' ') *cmd++ = 0; - - }while(*cmd && argc <256); - BasicTestWin::ParseSiftParam(argc, argv); -} - -void GLTestWnd::SetDisplaySize(int w, int h) -{ - RECT rc; int dw, dh; - GetClientRect(_hWndMain, &rc); - - dw = w - rc.right; - dh = h - rc.bottom; - GetWindowRect(_hWndMain, &rc); - - MoveWindow(_hWndMain, rc.left, rc.top, rc.right - rc.left + dw, - rc.bottom - rc.top + dh, TRUE); - -} - -void GLTestWnd::SetWindowTitle(char *title) -{ - SetWindowText(_hWndMain, title); -} - -void GLTestWnd::UpdateDisplay() -{ - InvalidateRect(_hWndMain, NULL,0); -} - diff --git a/3rdparty/SiftGPU/src/TestWin/GLTestWnd.h b/3rdparty/SiftGPU/src/TestWin/GLTestWnd.h deleted file mode 100644 index 5eabdad0..00000000 --- a/3rdparty/SiftGPU/src/TestWin/GLTestWnd.h +++ /dev/null @@ -1,61 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: GLTestWnd.h -// Author: Changchang Wu -// Description : interface for the GLTestWnd class. -// Win32-based SiftGPU viewer -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#if !defined(GL_TEST_WND_H) -#define GL_TEST_WND_H - -#if _WIN32 && _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#define WM_MY_IDLE WM_USER+1 - - - - -class BasicTestWin; -class GLTestWnd : public BasicTestWin -{ - HGLRC _hglrc; - HWND _hWndMain; -private: - static LRESULT CALLBACK ___WndProc(HWND, UINT, WPARAM, LPARAM); - inline LRESULT _WndProc(UINT, WPARAM, LPARAM); - void CreateWindowGL(); - static void RegisterWindowClass(); -public: - void UpdateDisplay(); - void SetWindowTitle(char *title); - void SetDisplaySize(int w, int h); - void ParseCommandLine(LPSTR cmd); - void glPaint(HDC ); - void glResize(int w, int h); - void glCreateRC(HDC hdc); - GLTestWnd(LPSTR cmd); - GLTestWnd(int argc, char**argv); - virtual ~GLTestWnd(); - -}; - -#endif // !defined(GL_TEST_WND_H) diff --git a/3rdparty/SiftGPU/src/TestWin/GLTransform.h b/3rdparty/SiftGPU/src/TestWin/GLTransform.h deleted file mode 100644 index 57507d01..00000000 --- a/3rdparty/SiftGPU/src/TestWin/GLTransform.h +++ /dev/null @@ -1,113 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: GLTransform.h -// Author: Changchang Wu -// Description : GLTransform tookit for opengl display -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// -#if !defined(GL_TRANSFORM_H) -#define GL_TRANSFORM_H - -#include -class GlTransform -{ -public: - double cx, cy; - double q[4]; - double t[3]; - double sc, ds; - GlTransform() - { - q[0] = 1.0; - q[1] = q[2] = q[3] =0; - t[0] = t[1] = t[2] =0; - sc = 1.0; - cx = cy = 0; - } - void reset() - { - q[0] = 1.0; - q[1] = q[2] = q[3] =0; - t[0] = t[1] = t[2] =0; - sc = 1.0; - } - void operator=(GlTransform& v) - { - q[0] = v.q[0]; - q[1] = v.q[1]; - q[2] = v.q[2]; - q[3] = v.q[3]; - t[0] = v.t[0]; - t[1] = v.t[1]; - t[2] = v.t[2]; - sc = v.sc; - } - void operator *=(double scale) - { - sc *= scale; - t[0]*= scale; - t[1]*= scale; - t[2]*= scale; - } - void scaleset(double scale) - { - double ds = scale/sc; - t[0]*= ds; - t[1]*= ds; - t[2]*= ds; - sc = scale; - } - void scaleup() - { - double scale; - if(sc < 6) scale = float(int(sc))+1; - else scale = sc * 2.0; - scaleset(scale); - } - void scaledown() - { - double scale; - if(sc >1.0 &&sc < 2.0) scale = 1.0; - else scale = sc*0.5; - scaleset(scale); - } - void translate(int dx, int dy, int dz =0) - { - t[0] += dx; - t[1] += dy; - t[2] += dz; - } - void setcenter(double x, double y) - { - cx = x; - cy = y; - t[0] = t[1] = t[2] = 0; - } - - void transform(double es = 1.0) - { - double s = sc* es; - glTranslated(cx*es, cy*es, 0.0); - glTranslated(t[0] ,t[1] ,t[2]); - glScaled(s,s,s); - glTranslated(-cx, - cy, 0); - } -}; - -#endif - diff --git a/3rdparty/SiftGPU/src/TestWin/MultiThreadSIFT.cpp b/3rdparty/SiftGPU/src/TestWin/MultiThreadSIFT.cpp deleted file mode 100644 index 1f133175..00000000 --- a/3rdparty/SiftGPU/src/TestWin/MultiThreadSIFT.cpp +++ /dev/null @@ -1,258 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: MultiThreadSIFT.cpp -// Author: Changchang Wu -// Description : An example to show how to use SiftGPU in multi-threading -// with each thread using different GPU device. -// The same idea also applies to SiftMatchGPU. -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include -#include -#include -using std::vector; -using std::iostream; -#include - - -#ifdef _WIN32 - #include - //define this to get dll import definition for win32 - #define SIFTGPU_DLL - #ifdef _DEBUG - #pragma comment(lib, "../../lib/siftgpu_d.lib") - #else - #pragma comment(lib, "../../lib/siftgpu.lib") - #endif - #define thread_t HANDLE -#else - #include - #include - #define thread_t pthread_t - pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - - -#include "../SiftGPU/SiftGPU.h" - -class ScopedMutex -{ -#ifdef _WIN32 -private: - HANDLE hmutex; -public: - ScopedMutex(const char* name) { - hmutex = CreateMutex(NULL, FALSE, name); - WaitForSingleObject(hmutex, INFINITE); - } - ~ScopedMutex() - { - ReleaseMutex(hmutex); - CloseHandle(hmutex); - } -#else -public: - ScopedMutex(const char* name) { - pthread_mutex_lock(&global_mutex); - } - ~ScopedMutex() - { - pthread_mutex_unlock(&global_mutex); - } -#endif -}; - - - -class MultiThreadSIFT -{ -protected: - SiftGPU* _sift; - const void * _thread_param; - int _device_id; -private: - void Initialize(int device_id) - { - ScopedMutex mutex("siftgpu_initialize"); - printf("#%d: Initialize MultiThreadSIFT...", device_id); - InitializeSIFT(); - printf("done\n"); - - //The initialization part should be protected by a mutex in - //single-process-multi-thread mode. For now many parameters - //are still global static variables. - } -public: - MultiThreadSIFT(int device_id = 0, const void* thread_param = NULL) - { - _thread_param = thread_param; - _device_id = device_id; - } - virtual ~MultiThreadSIFT() - { - if(_sift) delete _sift; - } - - thread_t RunThread() - { -#ifdef _WIN32 - return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RunMultiThreadSIFT, this, 0, 0); -#else - thread_t threadid; - pthread_create(&threadid, NULL, RunMultiThreadSIFT, this); - return threadid; -#endif - } -#ifdef _WIN32 - static DWORD -#else - static void* -#endif - RunMultiThreadSIFT(void* mts) - { - MultiThreadSIFT* mtsift = (MultiThreadSIFT*) mts; - mtsift->Initialize(mtsift->_device_id); - mtsift->RunTask(); - return 0; - } -public: - //Two Functions to overload for specific task - virtual void RunTask() - { - - } - //set parameters and initizlze SIFT - virtual void InitializeSIFT() - { - //////////////////////////// - char device[2] = {'0' + _device_id, '\0'}; //works for 0-9...use sprintf if you have more than 10 - char * argv[] = {"-fo", "-1", "-v", "0", "-cuda", device}; - //-nogl was previously required, but now default - int argc = sizeof(argv)/sizeof(char*); - - ///////////////////////////////////// - _sift = new SiftGPU; - _sift->ParseParam(argc, argv); - - //create an OpenGL context for computation, and SiftGPU will be initialized automatically - if(_sift->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) exit(0); - } -}; - - -//Multi-threading demo. -//Each thread will load a file, and repeat the processing 100 times. - -class MultiThreadDemo: public MultiThreadSIFT -{ -public: - MultiThreadDemo(int deviceid, const char* filename): MultiThreadSIFT(deviceid, filename) - { - } - virtual void RunTask() - { - printf("#%d, running task\n", _device_id); - time_t t1, t2; - t1 = time(NULL); - for(int i = 0; i < 100; ++i) _sift->RunSIFT(); - t2 = time(NULL); - printf("#%d: %dhz\n", _device_id, int(100/(t2-t1))); - } - virtual void InitializeSIFT() - { - MultiThreadSIFT::InitializeSIFT(); - const char* filename = (const char*) _thread_param; - _sift->RunSIFT(filename); - - ////////////////////////////////////////////////////////////////////// - //WARNING: the image loader (DeviL) used by SiftGPU is not thread-safe. - //This demo will put the file loading part in InitializeSIFT, which - //is protected by a mutex. In your multi-thread application, you should - //load the image data outside SiftGPU, and specify the memory data to - //SiftGPU directly. - ///////////////////////////////////////////////////////////////////// - } -}; - -//Multi-process demo -//Each process will repeat the processing of a file for 100 times. -class MultiProcessDemo: public MultiThreadSIFT -{ -public: - MultiProcessDemo(int deviceid, const char* filename): MultiThreadSIFT(deviceid, filename) - { - } - virtual void RunTask() - { - char* filename = (char*) _thread_param; - time_t t1, t2; - t1 = time(NULL); - for(int i = 0; i < 100; ++i) _sift->RunSIFT(filename); - t2 = time(NULL); - printf("Speed on device %d : %dhz\n", _device_id, int(100/(t2-t1))); - } - virtual void InitializeSIFT() - { - //Although the multi-process demo here uses CUDA, - //if multiple GPUs are mapped to multiple monitors/displayes - //it is possible to use OpenGL (not CUDA)for this. - //Also, the mutex protection is not necessary - char device[2] = {'0' + _device_id, '\0'}; //works for 0-9...use sprintf if you have more than 10 - char * argv[] = {"-fo", "-1", "-v", "0", "-cuda", device}; - int argc = sizeof(argv)/sizeof(char*); - - ///////////////////////////////////// - //create two server with differ socket ports - _sift = CreateRemoteSiftGPU(7777 + _device_id, NULL); - _sift->ParseParam(argc, argv); - - //create an OpenGL context for computation, and SiftGPU will be initialized automatically - if(_sift->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) exit(0); - } -}; - - -int main() -{ - //NOTE that SiftGPU must be compiled with CUDA for this demo - MultiThreadDemo thread1(0, "../data/640-1.jpg"); - MultiThreadDemo thread2(1, "../data/800-1.jpg"); - - - //Use MultiProcessDemo for multi-process mode - //MultiProcessDemo thread1(0, "../data/640-1.jpg"); - //MultiProcessDemo thread2(1, "../data/800-1.jpg"); - - printf("Starting two threads...\n"); - thread_t t1 = thread1.RunThread(); - thread_t t2 = thread2.RunThread(); - -#ifdef _WIN32 - HANDLE handles[2] = {t1, t2}; - WaitForMultipleObjects(2, handles, TRUE, INFINITE); - //////////////////////////////////////////////////////////////// - CloseHandle(t1); - CloseHandle(t2); -#else - pthread_join(t1, NULL); - pthread_join(t2, NULL); -#endif - return 1; -} - diff --git a/3rdparty/SiftGPU/src/TestWin/SimpleSIFT.cpp b/3rdparty/SiftGPU/src/TestWin/SimpleSIFT.cpp deleted file mode 100644 index 882c4280..00000000 --- a/3rdparty/SiftGPU/src/TestWin/SimpleSIFT.cpp +++ /dev/null @@ -1,290 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: SimpleSIFT.cpp -// Author: Changchang Wu -// Description : A simple example shows how to use SiftGPU and SiftMatchGPU -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include -#include -#include -using std::vector; -using std::iostream; - - -//////////////////////////////////////////////////////////////////////////// -#if !defined(SIFTGPU_STATIC) && !defined(SIFTGPU_DLL_RUNTIME) -// SIFTGPU_STATIC comes from compiler -#define SIFTGPU_DLL_RUNTIME -// Load at runtime if the above macro defined -// comment the macro above to use static linking -#endif - -//////////////////////////////////////////////////////////////////////////// -// define REMOTE_SIFTGPU to run computation in multi-process (Or remote) mode -// in order to run on a remote machine, you need to start the server manually -// This mode allows you use Multi-GPUs by creating multiple servers -// #define REMOTE_SIFTGPU -// #define REMOTE_SERVER NULL -// #define REMOTE_SERVER_PORT 7777 - - -/////////////////////////////////////////////////////////////////////////// -//#define DEBUG_SIFTGPU //define this to use the debug version in windows - -#ifdef _WIN32 - #ifdef SIFTGPU_DLL_RUNTIME - #define WIN32_LEAN_AND_MEAN - #include - #define FREE_MYLIB FreeLibrary - #define GET_MYPROC GetProcAddress - #else - //define this to get dll import definition for win32 - #define SIFTGPU_DLL - #ifdef _DEBUG - #pragma comment(lib, "../../lib/siftgpu_d.lib") - #else - #pragma comment(lib, "../../lib/siftgpu.lib") - #endif - #endif -#else - #ifdef SIFTGPU_DLL_RUNTIME - #include - #define FREE_MYLIB dlclose - #define GET_MYPROC dlsym - #endif -#endif - -#include "../SiftGPU/SiftGPU.h" - - -int main() -{ -#ifdef SIFTGPU_DLL_RUNTIME - #ifdef _WIN32 - #ifdef _DEBUG - HMODULE hsiftgpu = LoadLibrary("siftgpu_d.dll"); - #else - HMODULE hsiftgpu = LoadLibrary("siftgpu.dll"); - #endif - #else - void * hsiftgpu = dlopen("libsiftgpu.so", RTLD_LAZY); - #endif - - if(hsiftgpu == NULL) return 0; - - #ifdef REMOTE_SIFTGPU - ComboSiftGPU* (*pCreateRemoteSiftGPU) (int, char*) = NULL; - pCreateRemoteSiftGPU = (ComboSiftGPU* (*) (int, char*)) GET_MYPROC(hsiftgpu, "CreateRemoteSiftGPU"); - ComboSiftGPU * combo = pCreateRemoteSiftGPU(REMOTE_SERVER_PORT, REMOTE_SERVER); - SiftGPU* sift = combo; - SiftMatchGPU* matcher = combo; - #else - SiftGPU* (*pCreateNewSiftGPU)(int) = NULL; - SiftMatchGPU* (*pCreateNewSiftMatchGPU)(int) = NULL; - pCreateNewSiftGPU = (SiftGPU* (*) (int)) GET_MYPROC(hsiftgpu, "CreateNewSiftGPU"); - pCreateNewSiftMatchGPU = (SiftMatchGPU* (*)(int)) GET_MYPROC(hsiftgpu, "CreateNewSiftMatchGPU"); - SiftGPU* sift = pCreateNewSiftGPU(1); - SiftMatchGPU* matcher = pCreateNewSiftMatchGPU(4096); - #endif - -#elif defined(REMOTE_SIFTGPU) - ComboSiftGPU * combo = CreateRemoteSiftGPU(REMOTE_SERVER_PORT, REMOTE_SERVER); - SiftGPU* sift = combo; - SiftMatchGPU* matcher = combo; -#else - //this will use overloaded new operators - SiftGPU *sift = new SiftGPU; - SiftMatchGPU *matcher = new SiftMatchGPU(4096); -#endif - vector descriptors1(1), descriptors2(1); - vector keys1(1), keys2(1); - int num1 = 0, num2 = 0; - - //process parameters - //The following parameters are default in V340 - //-m, up to 2 orientations for each feature (change to single orientation by using -m 1) - //-s enable subpixel subscale (disable by using -s 0) - - - char * argv[] = {"-fo", "-1", "-v", "1"};// - //-fo -1 staring from -1 octave - //-v 1 only print out # feature and overall time - //-loweo add a (.5, .5) offset - //-tc set a soft limit to number of detected features - - //NEW: parameters for GPU-selection - //1. CUDA. Use parameter "-cuda", "[device_id]" - //2. OpenGL. Use "-Display", "display_name" to select monitor/GPU (XLIB/GLUT) - // on windows the display name would be something like \\.\DISPLAY4 - - ////////////////////////////////////////////////////////////////////////////////////// - //You use CUDA for nVidia graphic cards by specifying - //-cuda : cuda implementation (fastest for smaller images) - // CUDA-implementation allows you to create multiple instances for multiple threads - // Checkout src\TestWin\MultiThreadSIFT - ///////////////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////////////////// - ////////////////////////Two Important Parameters/////////////////////////// - // First, texture reallocation happens when image size increases, and too many - // reallocation may lead to allocatoin failure. You should be careful when using - // siftgpu on a set of images with VARYING imag sizes. It is recommended that you - // preset the allocation size to the largest width and largest height by using function - // AllocationPyramid or prameter '-p' (e.g. "-p", "1024x768"). - - // Second, there is a parameter you may not be aware of: the allowed maximum working - // dimension. All the SIFT octaves that needs a larger texture size will be skipped. - // The default prameter is 2560 for the unpacked implementation and 3200 for the packed. - // Those two default parameter is tuned to for 768MB of graphic memory. You should adjust - // it for your own GPU memory. You can also use this to keep/skip the small featuers. - // To change this, call function SetMaxDimension or use parameter "-maxd". - // - // NEW: by default SiftGPU will try to fit the cap of GPU memory, and reduce the working - // dimension so as to not allocate too much. This feature can be disabled by -nomc - ////////////////////////////////////////////////////////////////////////////////////// - - - int argc = sizeof(argv)/sizeof(char*); - sift->ParseParam(argc, argv); - - /////////////////////////////////////////////////////////////////////// - //Only the following parameters can be changed after initialization (by calling ParseParam). - //-dw, -ofix, -ofix-not, -fo, -unn, -maxd, -b - //to change other parameters at runtime, you need to first unload the dynamically loaded libaray - //reload the libarary, then create a new siftgpu instance - - - //Create a context for computation, and SiftGPU will be initialized automatically - //The same context can be used by SiftMatchGPU - if(sift->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) return 0; - - if(sift->RunSIFT("../data/800-1.jpg")) - { - //Call SaveSIFT to save result to file, the format is the same as Lowe's - //sift->SaveSIFT("../data/800-1.sift"); //Note that saving ASCII format is slow - - //get feature count - num1 = sift->GetFeatureNum(); - - //allocate memory - keys1.resize(num1); descriptors1.resize(128*num1); - - //reading back feature vectors is faster than writing files - //if you dont need keys or descriptors, just put NULLs here - sift->GetFeatureVector(&keys1[0], &descriptors1[0]); - //this can be used to write your own sift file. - } - - //You can have at most one OpenGL-based SiftGPU (per process). - //Normally, you should just create one, and reuse on all images. - if(sift->RunSIFT("../data/640-1.jpg")) - { - num2 = sift->GetFeatureNum(); - keys2.resize(num2); descriptors2.resize(128*num2); - sift->GetFeatureVector(&keys2[0], &descriptors2[0]); - } - - //Testing code to check how it works when image size varies - //sift->RunSIFT("../data/256.jpg");sift->SaveSIFT("../data/256.sift.1"); - //sift->RunSIFT("../data/1024.jpg"); //this will result in pyramid reallocation - //sift->RunSIFT("../data/256.jpg"); sift->SaveSIFT("../data/256.sift.2"); - //two sets of features for 256.jpg may have different order due to implementation - - //************************************************************************* - /////compute descriptors for user-specified keypoints (with or without orientations) - - //Method1, set new keypoints for the image you've just processed with siftgpu - //say vector mykeys; - //sift->RunSIFT(mykeys.size(), &mykeys[0]); - //sift->RunSIFT(num2, &keys2[0], 1); sift->SaveSIFT("../data/640-1.sift.2"); - //sift->RunSIFT(num2, &keys2[0], 0); sift->SaveSIFT("../data/640-1.sift.3"); - - //Method2, set keypoints for the next coming image - //The difference of with method 1 is that method 1 skips gaussian filtering - //SiftGPU::SiftKeypoint mykeys[100]; - //for(int i = 0; i < 100; ++i){ - // mykeys[i].s = 1.0f;mykeys[i].o = 0.0f; - // mykeys[i].x = (i%10)*10.0f+50.0f; - // mykeys[i].y = (i/10)*10.0f+50.0f; - //} - //sift->SetKeypointList(100, mykeys, 0); - //sift->RunSIFT("../data/800-1.jpg"); sift->SaveSIFT("../data/800-1.sift.2"); - //### for comparing with method1: - //sift->RunSIFT("../data/800-1.jpg"); - //sift->RunSIFT(100, mykeys, 0); sift->SaveSIFT("../data/800-1.sift.3"); - //********************************************************************************* - - - //**********************GPU SIFT MATCHING********************************* - //**************************select shader language************************* - //SiftMatchGPU will use the same shader lanaguage as SiftGPU by default - //Before initialization, you can choose between glsl, and CUDA(if compiled). - //matcher->SetLanguage(SiftMatchGPU::SIFTMATCH_CUDA); // +i for the (i+1)-th device - - //Verify current OpenGL Context and initialize the Matcher; - //If you don't have an OpenGL Context, call matcher->CreateContextGL instead; - matcher->VerifyContextGL(); //must call once - - //Set descriptors to match, the first argument must be either 0 or 1 - //if you want to use more than 4096 or less than 4096 - //call matcher->SetMaxSift() to change the limit before calling setdescriptor - matcher->SetDescriptors(0, num1, &descriptors1[0]); //image 1 - matcher->SetDescriptors(1, num2, &descriptors2[0]); //image 2 - - //match and get result. - int (*match_buf)[2] = new int[num1][2]; - //use the default thresholds. Check the declaration in SiftGPU.h - int num_match = matcher->GetSiftMatch(num1, match_buf); - std::cout << num_match << " sift matches were found;\n"; - - //enumerate all the feature matches - for(int i = 0; i < num_match; ++i) - { - //How to get the feature matches: - //SiftGPU::SiftKeypoint & key1 = keys1[match_buf[i][0]]; - //SiftGPU::SiftKeypoint & key2 = keys2[match_buf[i][1]]; - //key1 in the first image matches with key2 in the second image - } - - //*****************GPU Guided SIFT MATCHING*************** - //example: define a homography, and use default threshold 32 to search in a 64x64 window - //float h[3][3] = {{0.8f, 0, 0}, {0, 0.8f, 0}, {0, 0, 1.0f}}; - //matcher->SetFeatureLocation(0, &keys1[0]); //SetFeatureLocaiton after SetDescriptors - //matcher->SetFeatureLocation(1, &keys2[0]); - //num_match = matcher->GetGuidedSiftMatch(num1, match_buf, h, NULL); - //std::cout << num_match << " guided sift matches were found;\n"; - //if you can want to use a Fundamental matrix, check the function definition - - // clean up.. - delete[] match_buf; -#ifdef REMOTE_SIFTGPU - delete combo; -#else - delete sift; - delete matcher; -#endif - -#ifdef SIFTGPU_DLL_RUNTIME - FREE_MYLIB(hsiftgpu); -#endif - return 1; -} - diff --git a/3rdparty/SiftGPU/src/TestWin/TestWinGlut.cpp b/3rdparty/SiftGPU/src/TestWin/TestWinGlut.cpp deleted file mode 100644 index 4c6c25b5..00000000 --- a/3rdparty/SiftGPU/src/TestWin/TestWinGlut.cpp +++ /dev/null @@ -1,188 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: TestWinGlut.cpp -// Author: Changchang Wu -// Description : Implementation of TestWinGlut Class -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#include -#ifdef __APPLE__ - #include "GLUT/glut.h" -#else - #include "GL/glut.h" -#endif -#include "BasicTestWin.h" -#include "TestWinGlut.h" - -///main etry - -int main(int argc, char**argv) -{ - // - ////uncomment this if you want to parse glut parameters - glutInit(&argc, argv); - - - //create the glut window - TestWinGlut twg(argc, argv); -// TestWinGlut twg2(0, NULL); - - - //run the glut main loop to display all the TestWinGlut Windows - TestWinGlut::Run(); - - return 0; -} - -////////////////////////////////////////////////////////////////////// -// TestWinGlut Class -////////////////////////////////////////////////////////////////////// - - - -///////////////////////////////////////////////////////////////////// -///Global Variables -////////////////////////////////////////////////////////////////////// -TestWinGlut* TestWinGlut::_win[TestWinGlut::MAX_TEST_WIN_GLUT]; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - - - -TestWinGlut::TestWinGlut(int argc, char**argv) - -{ - //enable console output - SetVerbose(); - ParseSiftParam(argc, argv); - - //create glut window - CreateGLUT(); - - //parse parameters and run sift - RunSiftGPU(); - - -} - -TestWinGlut::~TestWinGlut() -{ - -} - - - -void TestWinGlut::CreateGLUT() -{ - int id; - glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE); - glutInitWindowSize (600,450); - if(_win_x != -1) glutInitWindowPosition(_win_x, _win_y); - id = glutCreateWindow ("SIFT_GPU"); - if(id>0) - { - if(id >=MAX_TEST_WIN_GLUT) exit(0);//should not happen... - - // - glutDisplayFunc (display); - glutKeyboardFunc(keyboard); - glutReshapeFunc (reshape); - glutIdleFunc(idle); - glutMotionFunc(motion); - glutMouseFunc(button); - //save a pointer to the stucture - _win[id] = this; - } - -} - -void TestWinGlut::idle() -{ - int id = glutGetWindow(); - _win[id]->OnIdle(); -} - -void TestWinGlut::keyboard(unsigned char key, int x, int y) -{ - int id = glutGetWindow(); - - _win[id]->KeyInput(key); - glutPostRedisplay(); -} -void TestWinGlut::reshape(int w, int h) -{ - int id = glutGetWindow(); - _win[id]->ReShape(w, h); - glutPostRedisplay(); -} -void TestWinGlut::display() -{ - static int firstcall=1; - int id = glutGetWindow(); - _win[id]->Display(); - glutSwapBuffers(); - if(firstcall ==0) - { - }else - { - //if it is the first display call, redraw - firstcall = 0; - glutPostRedisplay(); - } -} - -void TestWinGlut::Run() -{ - glutMainLoop(); -} - -void TestWinGlut::motion(int x, int y) -{ - int id = glutGetWindow(); - _win[id]->MoveMouse(x, y); -} - -void TestWinGlut::SetWindowTitle(char *title) -{ - glutSetWindowTitle(title); -} - -void TestWinGlut::button(int button, int state,int x, int y) -{ - int id = glutGetWindow(); - if (button == GLUT_LEFT_BUTTON) - { - if(state == GLUT_DOWN) - _win[id]->StartMotion(x, y); - else if (state == GLUT_UP) - _win[id]->EndMotion(); - } -} - -void TestWinGlut::UpdateDisplay() -{ - glutPostRedisplay(); -} - -void TestWinGlut::SetDisplaySize(int w, int h) -{ - glutReshapeWindow(w, h); -} diff --git a/3rdparty/SiftGPU/src/TestWin/TestWinGlut.h b/3rdparty/SiftGPU/src/TestWin/TestWinGlut.h deleted file mode 100644 index 58912d54..00000000 --- a/3rdparty/SiftGPU/src/TestWin/TestWinGlut.h +++ /dev/null @@ -1,62 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: TestWinGlut.h -// Author: Changchang Wu -// Description : interface for the TestWinGlut class. -// GLUT-based SiftGPU viewer -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - -#if !defined(TEST_WIN_GLUT_H) -#define TEST_WIN_GLUT_H - -#if _WIN32 && _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -class BasicTestWin; - -class TestWinGlut : public BasicTestWin -{ - enum - { - MAX_TEST_WIN_GLUT = 100 - }; - static void button(int button, int state,int x, int y); - static void display(); - static void keyboard(unsigned char key, int x, int y); - static void idle(); - void CreateGLUT(); - static void reshape(int w, int h); - - //may also use std::vector - static TestWinGlut * _win[MAX_TEST_WIN_GLUT]; - -public: - void SetDisplaySize(int w, int h); - void UpdateDisplay(); - void SetWindowTitle(char *title); - static void motion(int x, int y); - static void Run(); - TestWinGlut(int argc, char**argv); - virtual ~TestWinGlut(); - - -}; - -#endif // !defined(TEST_WIN_GLUT_H) - diff --git a/3rdparty/SiftGPU/src/TestWin/speed.cpp b/3rdparty/SiftGPU/src/TestWin/speed.cpp deleted file mode 100644 index 9c385bdb..00000000 --- a/3rdparty/SiftGPU/src/TestWin/speed.cpp +++ /dev/null @@ -1,200 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// File: Speed.cpp -// Author: Changchang Wu -// Description : Evaluate the speed of SiftGPU -// -// -// -// Copyright (c) 2007 University of North Carolina at Chapel Hill -// All Rights Reserved -// -// Permission to use, copy, modify and distribute this software and its -// documentation for educational, research and non-profit purposes, without -// fee, and without a written agreement is hereby granted, provided that the -// above copyright notice and the following paragraph appear in all copies. -// -// The University of North Carolina at Chapel Hill make no representations -// about the suitability of this software for any purpose. It is provided -// 'as is' without express or implied warranty. -// -// Please send BUG REPORTS to ccwu@cs.unc.edu -// -//////////////////////////////////////////////////////////////////////////// - - -#include -#include -#include -using std::cout; - -#ifdef _WIN32 - //dll import definition for win32 - #define SIFTGPU_DLL -#endif - -#if defined(_WIN32) -//for windows, the default timing uses timeGetTime, you can define TIMING_BY_CLOCK to use clock() - #if defined(TIMING_BY_CLOCK) - #include - #else - #define WIN32_LEAN_AND_MEAN - #include - #include - #pragma comment(lib, "winmm.lib") - #endif -#else - #include -#endif - - -#include "../SiftGPU/SiftGPU.h" - -//define the marcro bellow to reload image file everytime -//#define INCLUDE_DISK_READING_TIME - -//define the macro below to test speed of multi-process mode -//#define TEST_MULTI_PROCESS_SIFTGPU - - - -#define SIFTGPU_REPEAT 30 - -// you should specify the input image and the sift parameter to speed.exe -// for example: speed.exe -i 600.pgm -fo -1 -// to test CUDA, you first need to recompile SiftGPU with CUDA capability - -int GetMilliSecond(); - -int main(int argc, char * argv[]) -{ -#ifndef TEST_MULTI_PROCESS_SIFTGPU - SiftGPU sift; -#else - ComboSiftGPU* combo = CreateRemoteSiftGPU(); - SiftGPU& sift = (*combo); -#endif - int num; - float timing[10], time_all =0, time_start; - - //Parse parameters - sift.ParseParam(argc - 1, argv + 1); - sift.SetVerbose(0); - - std::cout<<"Initialize and warm up...\n"; - //create an OpenGL context for computation - if(sift.CreateContextGL() ==0) return 0; - - if(sift.RunSIFT()==0) return 0; - - //image is loaded for only once for this experiment -#ifndef TEST_MULTI_PROCESS_SIFTGPU - std::cout<<"Loading image: " << sift._timing[0]*1000 << "ms, " - <<"Tex initialization: "< - -#include "pugixml.hpp" - -/* - * These types add support for BOOST_FOREACH macro to xml_node and xml_document classes (child iteration only). - * Example usage: - * BOOST_FOREACH(xml_node n, doc) {} - */ - -namespace boost -{ - template<> struct range_mutable_iterator - { - typedef pugi::xml_node::iterator type; - }; - - template<> struct range_const_iterator - { - typedef pugi::xml_node::iterator type; - }; - - template<> struct range_mutable_iterator - { - typedef pugi::xml_document::iterator type; - }; - - template<> struct range_const_iterator - { - typedef pugi::xml_document::iterator type; - }; -} - -/* - * These types add support for BOOST_FOREACH macro to xml_node and xml_document classes (child/attribute iteration). - * Example usage: - * BOOST_FOREACH(xml_node n, children(doc)) {} - * BOOST_FOREACH(xml_node n, attributes(doc)) {} - */ - -namespace pugi -{ - inline xml_object_range children(const pugi::xml_node& node) - { - return node.children(); - } - - inline xml_object_range attributes(const pugi::xml_node& node) - { - return node.attributes(); - } -} - -#endif diff --git a/3rdparty/pugixml-1.6/readme.txt b/3rdparty/pugixml-1.6/readme.txt deleted file mode 100644 index faa41d37..00000000 --- a/3rdparty/pugixml-1.6/readme.txt +++ /dev/null @@ -1,52 +0,0 @@ -pugixml 1.6 - an XML processing library - -Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) -Report bugs and download new versions at http://pugixml.org/ - -This is the distribution of pugixml, which is a C++ XML processing library, -which consists of a DOM-like interface with rich traversal/modification -capabilities, an extremely fast XML parser which constructs the DOM tree from -an XML file/buffer, and an XPath 1.0 implementation for complex data-driven -tree queries. Full Unicode support is also available, with Unicode interface -variants and conversions between different Unicode encodings (which happen -automatically during parsing/saving). - -The distribution contains the following folders: - - contrib/ - various contributions to pugixml - - docs/ - documentation - docs/samples - pugixml usage examples - docs/quickstart.html - quick start guide - docs/manual.html - complete manual - - scripts/ - project files for IDE/build systems - - src/ - header and source files - - readme.txt - this file. - -This library is distributed under the MIT License: - -Copyright (c) 2006-2015 Arseny Kapoulkine - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/3rdparty/pugixml-1.6/scripts/CMakeLists.txt b/3rdparty/pugixml-1.6/scripts/CMakeLists.txt deleted file mode 100644 index 094d1ca2..00000000 --- a/3rdparty/pugixml-1.6/scripts/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -project(od_pugixml) - -cmake_minimum_required(VERSION 2.6) - -# Pre-defines standard install locations on *nix systems. -include(GNUInstallDirs) -mark_as_advanced(CLEAR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR) - -set(HEADERS ../src/pugixml.hpp ../src/pugiconfig.hpp) -set(SOURCES ${HEADERS} ../src/pugixml.cpp) - -add_library(pugixml SHARED ${SOURCES}) - -set_target_properties(pugixml PROPERTIES VERSION 1.6 SOVERSION 1) - -install(TARGETS pugixml EXPORT pugixml-config - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) - -install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(EXPORT pugixml-config DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml) diff --git a/3rdparty/pugixml-1.6/scripts/premake4.lua b/3rdparty/pugixml-1.6/scripts/premake4.lua deleted file mode 100644 index f1b89a0a..00000000 --- a/3rdparty/pugixml-1.6/scripts/premake4.lua +++ /dev/null @@ -1,92 +0,0 @@ --- Reset RNG seed to get consistent results across runs (i.e. XCode) -math.randomseed(12345) - -local static = _ARGS[1] == 'static' -local action = premake.action.current() - -if string.startswith(_ACTION, "vs") then - if action then - -- Disable solution generation - function action.onsolution(sln) - sln.vstudio_configs = premake.vstudio_buildconfigs(sln) - end - - -- Rename output file - function action.onproject(prj) - local name = "%%_" .. _ACTION .. (static and "_static" or "") - - if static then - for k, v in pairs(prj.project.__configs) do - v.objectsdir = v.objectsdir .. "Static" - end - end - - if _ACTION == "vs2010" then - premake.generate(prj, name .. ".vcxproj", premake.vs2010_vcxproj) - else - premake.generate(prj, name .. ".vcproj", premake.vs200x_vcproj) - end - end - end -elseif _ACTION == "codeblocks" then - action.onsolution = nil - - function action.onproject(prj) - premake.generate(prj, "%%_" .. _ACTION .. ".cbp", premake.codeblocks_cbp) - end -elseif _ACTION == "codelite" then - action.onsolution = nil - - function action.onproject(prj) - premake.generate(prj, "%%_" .. _ACTION .. ".project", premake.codelite_project) - end -end - -solution "pugixml" - objdir(_ACTION) - targetdir(_ACTION) - -if string.startswith(_ACTION, "vs") then - if _ACTION ~= "vs2002" and _ACTION ~= "vs2003" then - platforms { "x32", "x64" } - - configuration "x32" targetdir(_ACTION .. "/x32") - configuration "x64" targetdir(_ACTION .. "/x64") - end - - configurations { "Debug", "Release" } - - if static then - configuration "Debug" targetsuffix "sd" - configuration "Release" targetsuffix "s" - else - configuration "Debug" targetsuffix "d" - end -else - if _ACTION == "xcode3" then - platforms "universal" - end - - configurations { "Debug", "Release" } - - configuration "Debug" targetsuffix "d" -end - -project "pugixml" - kind "StaticLib" - language "C++" - files { "../src/pugixml.hpp", "../src/pugiconfig.hpp", "../src/pugixml.cpp" } - flags { "NoPCH", "NoMinimalRebuild", "NoEditAndContinue", "Symbols" } - uuid "89A1E353-E2DC-495C-B403-742BE206ACED" - -configuration "Debug" - defines { "_DEBUG" } - -configuration "Release" - defines { "NDEBUG" } - flags { "Optimize" } - -if static then - configuration "*" - flags { "StaticRuntime" } -end diff --git a/3rdparty/pugixml-1.6/scripts/pugixml.xcodeproj/project.pbxproj b/3rdparty/pugixml-1.6/scripts/pugixml.xcodeproj/project.pbxproj deleted file mode 100644 index 7d56bafd..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml.xcodeproj/project.pbxproj +++ /dev/null @@ -1,212 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 45; - objects = { - -/* Begin PBXBuildFile section */ - 0424128F67AB5C730232235E /* pugixml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 47481C4F0E03673E0E780637 /* pugixml.cpp */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 0B66463C5F896E6449051D38 /* pugiconfig.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = "pugiconfig.hpp"; path = "pugiconfig.hpp"; sourceTree = ""; }; - 47481C4F0E03673E0E780637 /* pugixml.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "pugixml.cpp"; path = "pugixml.cpp"; sourceTree = ""; }; - 6C911F0460FC44CD3B1B5624 /* pugixml.hpp */ = {isa = PBXFileReference; lastKnownFileType = text; name = "pugixml.hpp"; path = "pugixml.hpp"; sourceTree = ""; }; - 1DA04ADC64C3566D16C45B6D /* libpugixmld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libpugixmld.a"; path = "libpugixmld.a"; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2BA00212518037166623673F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 19E0517F3CF26ED63AE23641 /* pugixml */ = { - isa = PBXGroup; - children = ( - 578963B4309E714F05E01D71 /* src */, - 219F66186DDF392149043810 /* Products */, - ); - name = "pugixml"; - sourceTree = ""; - }; - 578963B4309E714F05E01D71 /* src */ = { - isa = PBXGroup; - children = ( - 0B66463C5F896E6449051D38 /* pugiconfig.hpp */, - 47481C4F0E03673E0E780637 /* pugixml.cpp */, - 6C911F0460FC44CD3B1B5624 /* pugixml.hpp */, - ); - name = "src"; - path = ../src; - sourceTree = ""; - }; - 219F66186DDF392149043810 /* Products */ = { - isa = PBXGroup; - children = ( - 1DA04ADC64C3566D16C45B6D /* libpugixmld.a */, - ); - name = "Products"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6B55152571905B6C3A6F39D0 /* pugixml */ = { - isa = PBXNativeTarget; - buildConfigurationList = 73BF376C14AA1ECC0AC517ED /* Build configuration list for PBXNativeTarget "pugixml" */; - buildPhases = ( - 6CA66B9B6252229A36E8733C /* Resources */, - 287808486FBF545206A47CC1 /* Sources */, - 2BA00212518037166623673F /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "pugixml"; - productName = "pugixml"; - productReference = 1DA04ADC64C3566D16C45B6D /* libpugixmld.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "pugixml" */; - compatibilityVersion = "Xcode 3.1"; - hasScannedForEncodings = 1; - mainGroup = 19E0517F3CF26ED63AE23641 /* pugixml */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6B55152571905B6C3A6F39D0 /* libpugixmld.a */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6CA66B9B6252229A36E8733C /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 287808486FBF545206A47CC1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 0424128F67AB5C730232235E /* pugixml.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 4FDB54E4253E36FC55CE27E8 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CONFIGURATION_BUILD_DIR = xcode3; - GCC_DYNAMIC_NO_PIC = NO; - GCC_MODEL_TUNING = G5; - INSTALL_PATH = /usr/local/lib; - PRODUCT_NAME = "pugixmld"; - }; - name = "Debug"; - }; - 0A4C28F553990E0405306C15 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CONFIGURATION_BUILD_DIR = xcode3; - GCC_DYNAMIC_NO_PIC = NO; - GCC_MODEL_TUNING = G5; - INSTALL_PATH = /usr/local/lib; - PRODUCT_NAME = "pugixml"; - }; - name = "Release"; - }; - 65DB0F6D27EA20852B6E3BB4 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CONFIGURATION_BUILD_DIR = "$(SYMROOT)"; - CONFIGURATION_TEMP_DIR = "$(OBJROOT)"; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "_DEBUG", - ); - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - OBJROOT = "xcode3/Universal/Debug"; - ONLY_ACTIVE_ARCH = NO; - PREBINDING = NO; - SYMROOT = "xcode3"; - }; - name = "Debug"; - }; - 5314084032B57C1A11945858 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CONFIGURATION_BUILD_DIR = "$(SYMROOT)"; - CONFIGURATION_TEMP_DIR = "$(OBJROOT)"; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = s; - GCC_PREPROCESSOR_DEFINITIONS = ( - "NDEBUG", - ); - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - OBJROOT = "xcode3/Universal/Release"; - ONLY_ACTIVE_ARCH = NO; - PREBINDING = NO; - SYMROOT = "xcode3"; - }; - name = "Release"; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 73BF376C14AA1ECC0AC517ED /* Build configuration list for PBXNativeTarget "libpugixmld.a" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4FDB54E4253E36FC55CE27E8 /* Debug */, - 0A4C28F553990E0405306C15 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = "Debug"; - }; - 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "pugixml" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 65DB0F6D27EA20852B6E3BB4 /* Debug */, - 5314084032B57C1A11945858 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = "Debug"; - }; -/* End XCConfigurationList section */ - - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_airplay.mkf b/3rdparty/pugixml-1.6/scripts/pugixml_airplay.mkf deleted file mode 100644 index 477f54a9..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_airplay.mkf +++ /dev/null @@ -1,13 +0,0 @@ -includepaths -{ -"../src" -} - -files -{ -("../src") -pugiconfig.hpp -pugixml.cpp -pugixml.hpp -} - diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_codeblocks.cbp b/3rdparty/pugixml-1.6/scripts/pugixml_codeblocks.cbp deleted file mode 100644 index e18ccfca..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_codeblocks.cbp +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_codelite.project b/3rdparty/pugixml-1.6/scripts/pugixml_codelite.project deleted file mode 100644 index 637a81da..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_codelite.project +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - None - - - - - - - - - - - - - - - - - - - - - None - - - - - - - - - - - - - diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_vs2005.vcproj b/3rdparty/pugixml-1.6/scripts/pugixml_vs2005.vcproj deleted file mode 100644 index b60f5af8..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_vs2005.vcproj +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_vs2005_static.vcproj b/3rdparty/pugixml-1.6/scripts/pugixml_vs2005_static.vcproj deleted file mode 100644 index 065e0eb4..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_vs2005_static.vcproj +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_vs2008.vcproj b/3rdparty/pugixml-1.6/scripts/pugixml_vs2008.vcproj deleted file mode 100644 index 72186182..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_vs2008.vcproj +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_vs2008_static.vcproj b/3rdparty/pugixml-1.6/scripts/pugixml_vs2008_static.vcproj deleted file mode 100644 index a00e9d1f..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_vs2008_static.vcproj +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_vs2010.vcxproj b/3rdparty/pugixml-1.6/scripts/pugixml_vs2010.vcxproj deleted file mode 100644 index c29b4c57..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_vs2010.vcxproj +++ /dev/null @@ -1,191 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {89A1E353-E2DC-495C-B403-742BE206ACED} - pugixml - Win32Proj - - - - StaticLibrary - MultiByte - true - - - StaticLibrary - MultiByte - true - - - StaticLibrary - MultiByte - true - false - - - StaticLibrary - MultiByte - true - false - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - vs2010\x32\ - vs2010\x32\Debug\ - pugixmld - vs2010\x64\ - vs2010\x64\Debug\ - pugixmld - vs2010\x32\ - vs2010\x32\Release\ - pugixml - vs2010\x64\ - vs2010\x64\Release\ - pugixml - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDebugDLL - true - - Level3 - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - - - $(OutDir)pugixmld.lib - - - Windows - true - $(OutDir)pugixmld.pdb - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDebugDLL - true - - Level3 - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - - - $(OutDir)pugixmld.lib - - - Windows - true - $(OutDir)pugixmld.pdb - - - - - Full - NDEBUG;%(PreprocessorDefinitions) - false - true - MultiThreadedDLL - true - - Level3 - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - - - $(OutDir)pugixml.lib - - - Windows - true - true - true - $(OutDir)pugixml.pdb - - - - - Full - NDEBUG;%(PreprocessorDefinitions) - false - true - MultiThreadedDLL - true - - Level3 - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - - - $(OutDir)pugixml.lib - - - Windows - true - true - true - $(OutDir)pugixml.pdb - - - - - - - - - - - - - - diff --git a/3rdparty/pugixml-1.6/scripts/pugixml_vs2010_static.vcxproj b/3rdparty/pugixml-1.6/scripts/pugixml_vs2010_static.vcxproj deleted file mode 100644 index c1e133ce..00000000 --- a/3rdparty/pugixml-1.6/scripts/pugixml_vs2010_static.vcxproj +++ /dev/null @@ -1,191 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {89A1E353-E2DC-495C-B403-742BE206ACED} - pugixml - Win32Proj - - - - StaticLibrary - MultiByte - true - - - StaticLibrary - MultiByte - true - - - StaticLibrary - MultiByte - true - false - - - StaticLibrary - MultiByte - true - false - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - vs2010\x32\ - vs2010\x32\DebugStatic\ - pugixmlsd - vs2010\x64\ - vs2010\x64\DebugStatic\ - pugixmlsd - vs2010\x32\ - vs2010\x32\ReleaseStatic\ - pugixmls - vs2010\x64\ - vs2010\x64\ReleaseStatic\ - pugixmls - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDebug - true - - Level3 - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - - - $(OutDir)pugixmlsd.lib - - - Windows - true - $(OutDir)pugixmlsd.pdb - - - - - Disabled - _DEBUG;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDebug - true - - Level3 - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - - - $(OutDir)pugixmlsd.lib - - - Windows - true - $(OutDir)pugixmlsd.pdb - - - - - Full - NDEBUG;%(PreprocessorDefinitions) - false - true - MultiThreaded - true - - Level3 - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - - - $(OutDir)pugixmls.lib - - - Windows - true - true - true - $(OutDir)pugixmls.pdb - - - - - Full - NDEBUG;%(PreprocessorDefinitions) - false - true - MultiThreaded - true - - Level3 - ProgramDatabase - - - NDEBUG;%(PreprocessorDefinitions) - - - $(OutDir)pugixmls.lib - - - Windows - true - true - true - $(OutDir)pugixmls.pdb - - - - - - - - - - - - - - diff --git a/3rdparty/pugixml-1.6/src/pugiconfig.hpp b/3rdparty/pugixml-1.6/src/pugiconfig.hpp deleted file mode 100644 index 5ee5131f..00000000 --- a/3rdparty/pugixml-1.6/src/pugiconfig.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * pugixml parser - version 1.6 - * -------------------------------------------------------- - * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ - * - * This library is distributed under the MIT License. See notice at the end - * of this file. - * - * This work is based on the pugxml parser, which is: - * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) - */ - -#ifndef HEADER_PUGICONFIG_HPP -#define HEADER_PUGICONFIG_HPP - -// Uncomment this to enable wchar_t mode -// #define PUGIXML_WCHAR_MODE - -// Uncomment this to disable XPath -// #define PUGIXML_NO_XPATH - -// Uncomment this to disable STL -// #define PUGIXML_NO_STL - -// Uncomment this to disable exceptions -// #define PUGIXML_NO_EXCEPTIONS - -// Set this to control attributes for public classes/functions, i.e.: -// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL -// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL -// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall -// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead - -// Tune these constants to adjust memory-related behavior -// #define PUGIXML_MEMORY_PAGE_SIZE 32768 -// #define PUGIXML_MEMORY_OUTPUT_STACK 10240 -// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 - -// Uncomment this to switch to header-only version -// #define PUGIXML_HEADER_ONLY - -// Uncomment this to enable long long support -// #define PUGIXML_HAS_LONG_LONG - -#endif - -/** - * Copyright (c) 2006-2015 Arseny Kapoulkine - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ diff --git a/3rdparty/pugixml-1.6/src/pugixml.cpp b/3rdparty/pugixml-1.6/src/pugixml.cpp deleted file mode 100644 index 5b77a271..00000000 --- a/3rdparty/pugixml-1.6/src/pugixml.cpp +++ /dev/null @@ -1,11554 +0,0 @@ -/** - * pugixml parser - version 1.6 - * -------------------------------------------------------- - * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ - * - * This library is distributed under the MIT License. See notice at the end - * of this file. - * - * This work is based on the pugxml parser, which is: - * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) - */ - -#ifndef SOURCE_PUGIXML_CPP -#define SOURCE_PUGIXML_CPP - -#include "pugixml.hpp" - -#include -#include -#include -#include - -#ifdef PUGIXML_WCHAR_MODE -# include -#endif - -#ifndef PUGIXML_NO_XPATH -# include -# include -# ifdef PUGIXML_NO_EXCEPTIONS -# include -# endif -#endif - -#ifndef PUGIXML_NO_STL -# include -# include -# include -#endif - -// For placement new -#include - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4127) // conditional expression is constant -# pragma warning(disable: 4324) // structure was padded due to __declspec(align()) -# pragma warning(disable: 4611) // interaction between '_setjmp' and C++ object destruction is non-portable -# pragma warning(disable: 4702) // unreachable code -# pragma warning(disable: 4996) // this function or variable may be unsafe -# pragma warning(disable: 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged -#endif - -#ifdef __INTEL_COMPILER -# pragma warning(disable: 177) // function was declared but never referenced -# pragma warning(disable: 279) // controlling expression is constant -# pragma warning(disable: 1478 1786) // function was declared "deprecated" -# pragma warning(disable: 1684) // conversion from pointer to same-sized integral type -#endif - -#if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY) -# pragma warn -8080 // symbol is declared but never used; disabling this inside push/pop bracket does not make the warning go away -#endif - -#ifdef __BORLANDC__ -# pragma option push -# pragma warn -8008 // condition is always false -# pragma warn -8066 // unreachable code -#endif - -#ifdef __SNC__ -// Using diag_push/diag_pop does not disable the warnings inside templates due to a compiler bug -# pragma diag_suppress=178 // function was declared but never referenced -# pragma diag_suppress=237 // controlling expression is constant -#endif - -// Inlining controls -#if defined(_MSC_VER) && _MSC_VER >= 1300 -# define PUGI__NO_INLINE __declspec(noinline) -#elif defined(__GNUC__) -# define PUGI__NO_INLINE __attribute__((noinline)) -#else -# define PUGI__NO_INLINE -#endif - -// Branch weight controls -#if defined(__GNUC__) -# define PUGI__UNLIKELY(cond) __builtin_expect(cond, 0) -#else -# define PUGI__UNLIKELY(cond) (cond) -#endif - -// Simple static assertion -#define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; } - -// Digital Mars C++ bug workaround for passing char loaded from memory via stack -#ifdef __DMC__ -# define PUGI__DMC_VOLATILE volatile -#else -# define PUGI__DMC_VOLATILE -#endif - -// Borland C++ bug workaround for not defining ::memcpy depending on header include order (can't always use std::memcpy because some compilers don't have it at all) -#if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST) -using std::memcpy; -using std::memmove; -#endif - -// In some environments MSVC is a compiler but the CRT lacks certain MSVC-specific features -#if defined(_MSC_VER) && !defined(__S3E__) -# define PUGI__MSVC_CRT_VERSION _MSC_VER -#endif - -#ifdef PUGIXML_HEADER_ONLY -# define PUGI__NS_BEGIN namespace pugi { namespace impl { -# define PUGI__NS_END } } -# define PUGI__FN inline -# define PUGI__FN_NO_INLINE inline -#else -# if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces -# define PUGI__NS_BEGIN namespace pugi { namespace impl { -# define PUGI__NS_END } } -# else -# define PUGI__NS_BEGIN namespace pugi { namespace impl { namespace { -# define PUGI__NS_END } } } -# endif -# define PUGI__FN -# define PUGI__FN_NO_INLINE PUGI__NO_INLINE -#endif - -// uintptr_t -#if !defined(_MSC_VER) || _MSC_VER >= 1600 -# include -#else -# ifndef _UINTPTR_T_DEFINED -// No native uintptr_t in MSVC6 and in some WinCE versions -typedef size_t uintptr_t; -#define _UINTPTR_T_DEFINED -# endif -PUGI__NS_BEGIN - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -PUGI__NS_END -#endif - -// Memory allocation -PUGI__NS_BEGIN - PUGI__FN void* default_allocate(size_t size) - { - return malloc(size); - } - - PUGI__FN void default_deallocate(void* ptr) - { - free(ptr); - } - - template - struct xml_memory_management_function_storage - { - static allocation_function allocate; - static deallocation_function deallocate; - }; - - // Global allocation functions are stored in class statics so that in header mode linker deduplicates them - // Without a template<> we'll get multiple definitions of the same static - template allocation_function xml_memory_management_function_storage::allocate = default_allocate; - template deallocation_function xml_memory_management_function_storage::deallocate = default_deallocate; - - typedef xml_memory_management_function_storage xml_memory; -PUGI__NS_END - -// String utilities -PUGI__NS_BEGIN - // Get string length - PUGI__FN size_t strlength(const char_t* s) - { - assert(s); - - #ifdef PUGIXML_WCHAR_MODE - return wcslen(s); - #else - return strlen(s); - #endif - } - - // Compare two strings - PUGI__FN bool strequal(const char_t* src, const char_t* dst) - { - assert(src && dst); - - #ifdef PUGIXML_WCHAR_MODE - return wcscmp(src, dst) == 0; - #else - return strcmp(src, dst) == 0; - #endif - } - - // Compare lhs with [rhs_begin, rhs_end) - PUGI__FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count) - { - for (size_t i = 0; i < count; ++i) - if (lhs[i] != rhs[i]) - return false; - - return lhs[count] == 0; - } - - // Get length of wide string, even if CRT lacks wide character support - PUGI__FN size_t strlength_wide(const wchar_t* s) - { - assert(s); - - #ifdef PUGIXML_WCHAR_MODE - return wcslen(s); - #else - const wchar_t* end = s; - while (*end) end++; - return static_cast(end - s); - #endif - } - -#ifdef PUGIXML_WCHAR_MODE - // Convert string to wide string, assuming all symbols are ASCII - PUGI__FN void widen_ascii(wchar_t* dest, const char* source) - { - for (const char* i = source; *i; ++i) *dest++ = *i; - *dest = 0; - } -#endif -PUGI__NS_END - -#if !defined(PUGIXML_NO_STL) || !defined(PUGIXML_NO_XPATH) -// auto_ptr-like buffer holder for exception recovery -PUGI__NS_BEGIN - struct buffer_holder - { - void* data; - void (*deleter)(void*); - - buffer_holder(void* data_, void (*deleter_)(void*)): data(data_), deleter(deleter_) - { - } - - ~buffer_holder() - { - if (data) deleter(data); - } - - void* release() - { - void* result = data; - data = 0; - return result; - } - }; -PUGI__NS_END -#endif - -PUGI__NS_BEGIN - static const size_t xml_memory_page_size = - #ifdef PUGIXML_MEMORY_PAGE_SIZE - PUGIXML_MEMORY_PAGE_SIZE - #else - 32768 - #endif - ; - - static const uintptr_t xml_memory_page_alignment = 64; - static const uintptr_t xml_memory_page_pointer_mask = ~(xml_memory_page_alignment - 1); - static const uintptr_t xml_memory_page_contents_shared_mask = 32; - static const uintptr_t xml_memory_page_name_allocated_mask = 16; - static const uintptr_t xml_memory_page_value_allocated_mask = 8; - static const uintptr_t xml_memory_page_type_mask = 7; - static const uintptr_t xml_memory_page_name_allocated_or_shared_mask = xml_memory_page_name_allocated_mask | xml_memory_page_contents_shared_mask; - static const uintptr_t xml_memory_page_value_allocated_or_shared_mask = xml_memory_page_value_allocated_mask | xml_memory_page_contents_shared_mask; - - #define PUGI__NODETYPE(n) static_cast(((n)->header & impl::xml_memory_page_type_mask) + 1) - - struct xml_allocator; - - struct xml_memory_page - { - static xml_memory_page* construct(void* memory) - { - xml_memory_page* result = static_cast(memory); - - result->allocator = 0; - result->prev = 0; - result->next = 0; - result->busy_size = 0; - result->freed_size = 0; - - return result; - } - - xml_allocator* allocator; - - xml_memory_page* prev; - xml_memory_page* next; - - size_t busy_size; - size_t freed_size; - }; - - struct xml_memory_string_header - { - uint16_t page_offset; // offset from page->data - uint16_t full_size; // 0 if string occupies whole page - }; - - struct xml_allocator - { - xml_allocator(xml_memory_page* root): _root(root), _busy_size(root->busy_size) - { - } - - xml_memory_page* allocate_page(size_t data_size) - { - size_t size = sizeof(xml_memory_page) + data_size; - - // allocate block with some alignment, leaving memory for worst-case padding - void* memory = xml_memory::allocate(size + xml_memory_page_alignment); - if (!memory) return 0; - - // align to next page boundary (note: this guarantees at least 1 usable byte before the page) - char* page_memory = reinterpret_cast((reinterpret_cast(memory) + xml_memory_page_alignment) & ~(xml_memory_page_alignment - 1)); - - // prepare page structure - xml_memory_page* page = xml_memory_page::construct(page_memory); - assert(page); - - page->allocator = _root->allocator; - - // record the offset for freeing the memory block - assert(page_memory > memory && page_memory - static_cast(memory) <= 127); - page_memory[-1] = static_cast(page_memory - static_cast(memory)); - - return page; - } - - static void deallocate_page(xml_memory_page* page) - { - char* page_memory = reinterpret_cast(page); - - xml_memory::deallocate(page_memory - page_memory[-1]); - } - - void* allocate_memory_oob(size_t size, xml_memory_page*& out_page); - - void* allocate_memory(size_t size, xml_memory_page*& out_page) - { - if (_busy_size + size > xml_memory_page_size) return allocate_memory_oob(size, out_page); - - void* buf = reinterpret_cast(_root) + sizeof(xml_memory_page) + _busy_size; - - _busy_size += size; - - out_page = _root; - - return buf; - } - - void deallocate_memory(void* ptr, size_t size, xml_memory_page* page) - { - if (page == _root) page->busy_size = _busy_size; - - assert(ptr >= reinterpret_cast(page) + sizeof(xml_memory_page) && ptr < reinterpret_cast(page) + sizeof(xml_memory_page) + page->busy_size); - (void)!ptr; - - page->freed_size += size; - assert(page->freed_size <= page->busy_size); - - if (page->freed_size == page->busy_size) - { - if (page->next == 0) - { - assert(_root == page); - - // top page freed, just reset sizes - page->busy_size = page->freed_size = 0; - _busy_size = 0; - } - else - { - assert(_root != page); - assert(page->prev); - - // remove from the list - page->prev->next = page->next; - page->next->prev = page->prev; - - // deallocate - deallocate_page(page); - } - } - } - - char_t* allocate_string(size_t length) - { - static const size_t max_encoded_offset = (1 << 16) * sizeof(void*); - - PUGI__STATIC_ASSERT(xml_memory_page_size <= max_encoded_offset); - - // allocate memory for string and header block - size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); - - // round size up to pointer alignment boundary - size_t full_size = (size + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1); - - xml_memory_page* page; - xml_memory_string_header* header = static_cast(allocate_memory(full_size, page)); - - if (!header) return 0; - - // setup header - ptrdiff_t page_offset = reinterpret_cast(header) - reinterpret_cast(page) - sizeof(xml_memory_page); - - assert(page_offset % sizeof(void*) == 0); - assert(page_offset >= 0 && static_cast(page_offset) < max_encoded_offset); - header->page_offset = static_cast(static_cast(page_offset) / sizeof(void*)); - - // full_size == 0 for large strings that occupy the whole page - assert(full_size % sizeof(void*) == 0); - assert(full_size < max_encoded_offset || (page->busy_size == full_size && page_offset == 0)); - header->full_size = static_cast(full_size < max_encoded_offset ? full_size / sizeof(void*) : 0); - - // round-trip through void* to avoid 'cast increases required alignment of target type' warning - // header is guaranteed a pointer-sized alignment, which should be enough for char_t - return static_cast(static_cast(header + 1)); - } - - void deallocate_string(char_t* string) - { - // this function casts pointers through void* to avoid 'cast increases required alignment of target type' warnings - // we're guaranteed the proper (pointer-sized) alignment on the input string if it was allocated via allocate_string - - // get header - xml_memory_string_header* header = static_cast(static_cast(string)) - 1; - assert(header); - - // deallocate - size_t page_offset = sizeof(xml_memory_page) + header->page_offset * sizeof(void*); - xml_memory_page* page = reinterpret_cast(static_cast(reinterpret_cast(header) - page_offset)); - - // if full_size == 0 then this string occupies the whole page - size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size * sizeof(void*); - - deallocate_memory(header, full_size, page); - } - - xml_memory_page* _root; - size_t _busy_size; - }; - - PUGI__FN_NO_INLINE void* xml_allocator::allocate_memory_oob(size_t size, xml_memory_page*& out_page) - { - const size_t large_allocation_threshold = xml_memory_page_size / 4; - - xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size); - out_page = page; - - if (!page) return 0; - - if (size <= large_allocation_threshold) - { - _root->busy_size = _busy_size; - - // insert page at the end of linked list - page->prev = _root; - _root->next = page; - _root = page; - - _busy_size = size; - } - else - { - // insert page before the end of linked list, so that it is deleted as soon as possible - // the last page is not deleted even if it's empty (see deallocate_memory) - assert(_root->prev); - - page->prev = _root->prev; - page->next = _root; - - _root->prev->next = page; - _root->prev = page; - } - - // allocate inside page - page->busy_size = size; - - return reinterpret_cast(page) + sizeof(xml_memory_page); - } -PUGI__NS_END - -namespace pugi -{ - /// A 'name=value' XML attribute structure. - struct xml_attribute_struct - { - /// Default ctor - xml_attribute_struct(impl::xml_memory_page* page): header(reinterpret_cast(page)), name(0), value(0), prev_attribute_c(0), next_attribute(0) - { - } - - uintptr_t header; - - char_t* name; ///< Pointer to attribute name. - char_t* value; ///< Pointer to attribute value. - - xml_attribute_struct* prev_attribute_c; ///< Previous attribute (cyclic list) - xml_attribute_struct* next_attribute; ///< Next attribute - }; - - /// An XML document tree node. - struct xml_node_struct - { - /// Default ctor - /// \param type - node type - xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(reinterpret_cast(page) | (type - 1)), parent(0), name(0), value(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0) - { - } - - uintptr_t header; - - xml_node_struct* parent; ///< Pointer to parent - - char_t* name; ///< Pointer to element name. - char_t* value; ///< Pointer to any associated string data. - - xml_node_struct* first_child; ///< First child - - xml_node_struct* prev_sibling_c; ///< Left brother (cyclic list) - xml_node_struct* next_sibling; ///< Right brother - - xml_attribute_struct* first_attribute; ///< First attribute - }; -} - -PUGI__NS_BEGIN - struct xml_extra_buffer - { - char_t* buffer; - xml_extra_buffer* next; - }; - - struct xml_document_struct: public xml_node_struct, public xml_allocator - { - xml_document_struct(xml_memory_page* page): xml_node_struct(page, node_document), xml_allocator(page), buffer(0), extra_buffers(0) - { - } - - const char_t* buffer; - - xml_extra_buffer* extra_buffers; - }; - - inline xml_allocator& get_allocator(const xml_node_struct* node) - { - assert(node); - - return *reinterpret_cast(node->header & xml_memory_page_pointer_mask)->allocator; - } - - template inline xml_document_struct& get_document(const Object* object) - { - assert(object); - - return *static_cast(reinterpret_cast(object->header & xml_memory_page_pointer_mask)->allocator); - } -PUGI__NS_END - -// Low-level DOM operations -PUGI__NS_BEGIN - inline xml_attribute_struct* allocate_attribute(xml_allocator& alloc) - { - xml_memory_page* page; - void* memory = alloc.allocate_memory(sizeof(xml_attribute_struct), page); - - return new (memory) xml_attribute_struct(page); - } - - inline xml_node_struct* allocate_node(xml_allocator& alloc, xml_node_type type) - { - xml_memory_page* page; - void* memory = alloc.allocate_memory(sizeof(xml_node_struct), page); - - return new (memory) xml_node_struct(page, type); - } - - inline void destroy_attribute(xml_attribute_struct* a, xml_allocator& alloc) - { - uintptr_t header = a->header; - - if (header & impl::xml_memory_page_name_allocated_mask) alloc.deallocate_string(a->name); - if (header & impl::xml_memory_page_value_allocated_mask) alloc.deallocate_string(a->value); - - alloc.deallocate_memory(a, sizeof(xml_attribute_struct), reinterpret_cast(header & xml_memory_page_pointer_mask)); - } - - inline void destroy_node(xml_node_struct* n, xml_allocator& alloc) - { - uintptr_t header = n->header; - - if (header & impl::xml_memory_page_name_allocated_mask) alloc.deallocate_string(n->name); - if (header & impl::xml_memory_page_value_allocated_mask) alloc.deallocate_string(n->value); - - for (xml_attribute_struct* attr = n->first_attribute; attr; ) - { - xml_attribute_struct* next = attr->next_attribute; - - destroy_attribute(attr, alloc); - - attr = next; - } - - for (xml_node_struct* child = n->first_child; child; ) - { - xml_node_struct* next = child->next_sibling; - - destroy_node(child, alloc); - - child = next; - } - - alloc.deallocate_memory(n, sizeof(xml_node_struct), reinterpret_cast(header & xml_memory_page_pointer_mask)); - } - - inline void append_node(xml_node_struct* child, xml_node_struct* node) - { - child->parent = node; - - xml_node_struct* head = node->first_child; - - if (head) - { - xml_node_struct* tail = head->prev_sibling_c; - - tail->next_sibling = child; - child->prev_sibling_c = tail; - head->prev_sibling_c = child; - } - else - { - node->first_child = child; - child->prev_sibling_c = child; - } - } - - inline void prepend_node(xml_node_struct* child, xml_node_struct* node) - { - child->parent = node; - - xml_node_struct* head = node->first_child; - - if (head) - { - child->prev_sibling_c = head->prev_sibling_c; - head->prev_sibling_c = child; - } - else - child->prev_sibling_c = child; - - child->next_sibling = head; - node->first_child = child; - } - - inline void insert_node_after(xml_node_struct* child, xml_node_struct* node) - { - xml_node_struct* parent = node->parent; - - child->parent = parent; - - if (node->next_sibling) - node->next_sibling->prev_sibling_c = child; - else - parent->first_child->prev_sibling_c = child; - - child->next_sibling = node->next_sibling; - child->prev_sibling_c = node; - - node->next_sibling = child; - } - - inline void insert_node_before(xml_node_struct* child, xml_node_struct* node) - { - xml_node_struct* parent = node->parent; - - child->parent = parent; - - if (node->prev_sibling_c->next_sibling) - node->prev_sibling_c->next_sibling = child; - else - parent->first_child = child; - - child->prev_sibling_c = node->prev_sibling_c; - child->next_sibling = node; - - node->prev_sibling_c = child; - } - - inline void remove_node(xml_node_struct* node) - { - xml_node_struct* parent = node->parent; - - if (node->next_sibling) - node->next_sibling->prev_sibling_c = node->prev_sibling_c; - else - parent->first_child->prev_sibling_c = node->prev_sibling_c; - - if (node->prev_sibling_c->next_sibling) - node->prev_sibling_c->next_sibling = node->next_sibling; - else - parent->first_child = node->next_sibling; - - node->parent = 0; - node->prev_sibling_c = 0; - node->next_sibling = 0; - } - - inline void append_attribute(xml_attribute_struct* attr, xml_node_struct* node) - { - xml_attribute_struct* head = node->first_attribute; - - if (head) - { - xml_attribute_struct* tail = head->prev_attribute_c; - - tail->next_attribute = attr; - attr->prev_attribute_c = tail; - head->prev_attribute_c = attr; - } - else - { - node->first_attribute = attr; - attr->prev_attribute_c = attr; - } - } - - inline void prepend_attribute(xml_attribute_struct* attr, xml_node_struct* node) - { - xml_attribute_struct* head = node->first_attribute; - - if (head) - { - attr->prev_attribute_c = head->prev_attribute_c; - head->prev_attribute_c = attr; - } - else - attr->prev_attribute_c = attr; - - attr->next_attribute = head; - node->first_attribute = attr; - } - - inline void insert_attribute_after(xml_attribute_struct* attr, xml_attribute_struct* place, xml_node_struct* node) - { - if (place->next_attribute) - place->next_attribute->prev_attribute_c = attr; - else - node->first_attribute->prev_attribute_c = attr; - - attr->next_attribute = place->next_attribute; - attr->prev_attribute_c = place; - place->next_attribute = attr; - } - - inline void insert_attribute_before(xml_attribute_struct* attr, xml_attribute_struct* place, xml_node_struct* node) - { - if (place->prev_attribute_c->next_attribute) - place->prev_attribute_c->next_attribute = attr; - else - node->first_attribute = attr; - - attr->prev_attribute_c = place->prev_attribute_c; - attr->next_attribute = place; - place->prev_attribute_c = attr; - } - - inline void remove_attribute(xml_attribute_struct* attr, xml_node_struct* node) - { - if (attr->next_attribute) - attr->next_attribute->prev_attribute_c = attr->prev_attribute_c; - else - node->first_attribute->prev_attribute_c = attr->prev_attribute_c; - - if (attr->prev_attribute_c->next_attribute) - attr->prev_attribute_c->next_attribute = attr->next_attribute; - else - node->first_attribute = attr->next_attribute; - - attr->prev_attribute_c = 0; - attr->next_attribute = 0; - } - - PUGI__FN_NO_INLINE xml_node_struct* append_new_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element) - { - xml_node_struct* child = allocate_node(alloc, type); - if (!child) return 0; - - append_node(child, node); - - return child; - } - - PUGI__FN_NO_INLINE xml_attribute_struct* append_new_attribute(xml_node_struct* node, xml_allocator& alloc) - { - xml_attribute_struct* attr = allocate_attribute(alloc); - if (!attr) return 0; - - append_attribute(attr, node); - - return attr; - } -PUGI__NS_END - -// Helper classes for code generation -PUGI__NS_BEGIN - struct opt_false - { - enum { value = 0 }; - }; - - struct opt_true - { - enum { value = 1 }; - }; -PUGI__NS_END - -// Unicode utilities -PUGI__NS_BEGIN - inline uint16_t endian_swap(uint16_t value) - { - return static_cast(((value & 0xff) << 8) | (value >> 8)); - } - - inline uint32_t endian_swap(uint32_t value) - { - return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (value >> 24); - } - - struct utf8_counter - { - typedef size_t value_type; - - static value_type low(value_type result, uint32_t ch) - { - // U+0000..U+007F - if (ch < 0x80) return result + 1; - // U+0080..U+07FF - else if (ch < 0x800) return result + 2; - // U+0800..U+FFFF - else return result + 3; - } - - static value_type high(value_type result, uint32_t) - { - // U+10000..U+10FFFF - return result + 4; - } - }; - - struct utf8_writer - { - typedef uint8_t* value_type; - - static value_type low(value_type result, uint32_t ch) - { - // U+0000..U+007F - if (ch < 0x80) - { - *result = static_cast(ch); - return result + 1; - } - // U+0080..U+07FF - else if (ch < 0x800) - { - result[0] = static_cast(0xC0 | (ch >> 6)); - result[1] = static_cast(0x80 | (ch & 0x3F)); - return result + 2; - } - // U+0800..U+FFFF - else - { - result[0] = static_cast(0xE0 | (ch >> 12)); - result[1] = static_cast(0x80 | ((ch >> 6) & 0x3F)); - result[2] = static_cast(0x80 | (ch & 0x3F)); - return result + 3; - } - } - - static value_type high(value_type result, uint32_t ch) - { - // U+10000..U+10FFFF - result[0] = static_cast(0xF0 | (ch >> 18)); - result[1] = static_cast(0x80 | ((ch >> 12) & 0x3F)); - result[2] = static_cast(0x80 | ((ch >> 6) & 0x3F)); - result[3] = static_cast(0x80 | (ch & 0x3F)); - return result + 4; - } - - static value_type any(value_type result, uint32_t ch) - { - return (ch < 0x10000) ? low(result, ch) : high(result, ch); - } - }; - - struct utf16_counter - { - typedef size_t value_type; - - static value_type low(value_type result, uint32_t) - { - return result + 1; - } - - static value_type high(value_type result, uint32_t) - { - return result + 2; - } - }; - - struct utf16_writer - { - typedef uint16_t* value_type; - - static value_type low(value_type result, uint32_t ch) - { - *result = static_cast(ch); - - return result + 1; - } - - static value_type high(value_type result, uint32_t ch) - { - uint32_t msh = static_cast(ch - 0x10000) >> 10; - uint32_t lsh = static_cast(ch - 0x10000) & 0x3ff; - - result[0] = static_cast(0xD800 + msh); - result[1] = static_cast(0xDC00 + lsh); - - return result + 2; - } - - static value_type any(value_type result, uint32_t ch) - { - return (ch < 0x10000) ? low(result, ch) : high(result, ch); - } - }; - - struct utf32_counter - { - typedef size_t value_type; - - static value_type low(value_type result, uint32_t) - { - return result + 1; - } - - static value_type high(value_type result, uint32_t) - { - return result + 1; - } - }; - - struct utf32_writer - { - typedef uint32_t* value_type; - - static value_type low(value_type result, uint32_t ch) - { - *result = ch; - - return result + 1; - } - - static value_type high(value_type result, uint32_t ch) - { - *result = ch; - - return result + 1; - } - - static value_type any(value_type result, uint32_t ch) - { - *result = ch; - - return result + 1; - } - }; - - struct latin1_writer - { - typedef uint8_t* value_type; - - static value_type low(value_type result, uint32_t ch) - { - *result = static_cast(ch > 255 ? '?' : ch); - - return result + 1; - } - - static value_type high(value_type result, uint32_t ch) - { - (void)ch; - - *result = '?'; - - return result + 1; - } - }; - - template struct wchar_selector; - - template <> struct wchar_selector<2> - { - typedef uint16_t type; - typedef utf16_counter counter; - typedef utf16_writer writer; - }; - - template <> struct wchar_selector<4> - { - typedef uint32_t type; - typedef utf32_counter counter; - typedef utf32_writer writer; - }; - - typedef wchar_selector::counter wchar_counter; - typedef wchar_selector::writer wchar_writer; - - template struct utf_decoder - { - static inline typename Traits::value_type decode_utf8_block(const uint8_t* data, size_t size, typename Traits::value_type result) - { - const uint8_t utf8_byte_mask = 0x3f; - - while (size) - { - uint8_t lead = *data; - - // 0xxxxxxx -> U+0000..U+007F - if (lead < 0x80) - { - result = Traits::low(result, lead); - data += 1; - size -= 1; - - // process aligned single-byte (ascii) blocks - if ((reinterpret_cast(data) & 3) == 0) - { - // round-trip through void* to silence 'cast increases required alignment of target type' warnings - while (size >= 4 && (*static_cast(static_cast(data)) & 0x80808080) == 0) - { - result = Traits::low(result, data[0]); - result = Traits::low(result, data[1]); - result = Traits::low(result, data[2]); - result = Traits::low(result, data[3]); - data += 4; - size -= 4; - } - } - } - // 110xxxxx -> U+0080..U+07FF - else if (static_cast(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80) - { - result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask)); - data += 2; - size -= 2; - } - // 1110xxxx -> U+0800-U+FFFF - else if (static_cast(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80) - { - result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask)); - data += 3; - size -= 3; - } - // 11110xxx -> U+10000..U+10FFFF - else if (static_cast(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80) - { - result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask)); - data += 4; - size -= 4; - } - // 10xxxxxx or 11111xxx -> invalid - else - { - data += 1; - size -= 1; - } - } - - return result; - } - - static inline typename Traits::value_type decode_utf16_block(const uint16_t* data, size_t size, typename Traits::value_type result) - { - const uint16_t* end = data + size; - - while (data < end) - { - unsigned int lead = opt_swap::value ? endian_swap(*data) : *data; - - // U+0000..U+D7FF - if (lead < 0xD800) - { - result = Traits::low(result, lead); - data += 1; - } - // U+E000..U+FFFF - else if (static_cast(lead - 0xE000) < 0x2000) - { - result = Traits::low(result, lead); - data += 1; - } - // surrogate pair lead - else if (static_cast(lead - 0xD800) < 0x400 && data + 1 < end) - { - uint16_t next = opt_swap::value ? endian_swap(data[1]) : data[1]; - - if (static_cast(next - 0xDC00) < 0x400) - { - result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff)); - data += 2; - } - else - { - data += 1; - } - } - else - { - data += 1; - } - } - - return result; - } - - static inline typename Traits::value_type decode_utf32_block(const uint32_t* data, size_t size, typename Traits::value_type result) - { - const uint32_t* end = data + size; - - while (data < end) - { - uint32_t lead = opt_swap::value ? endian_swap(*data) : *data; - - // U+0000..U+FFFF - if (lead < 0x10000) - { - result = Traits::low(result, lead); - data += 1; - } - // U+10000..U+10FFFF - else - { - result = Traits::high(result, lead); - data += 1; - } - } - - return result; - } - - static inline typename Traits::value_type decode_latin1_block(const uint8_t* data, size_t size, typename Traits::value_type result) - { - for (size_t i = 0; i < size; ++i) - { - result = Traits::low(result, data[i]); - } - - return result; - } - - static inline typename Traits::value_type decode_wchar_block_impl(const uint16_t* data, size_t size, typename Traits::value_type result) - { - return decode_utf16_block(data, size, result); - } - - static inline typename Traits::value_type decode_wchar_block_impl(const uint32_t* data, size_t size, typename Traits::value_type result) - { - return decode_utf32_block(data, size, result); - } - - static inline typename Traits::value_type decode_wchar_block(const wchar_t* data, size_t size, typename Traits::value_type result) - { - return decode_wchar_block_impl(reinterpret_cast::type*>(data), size, result); - } - }; - - template PUGI__FN void convert_utf_endian_swap(T* result, const T* data, size_t length) - { - for (size_t i = 0; i < length; ++i) result[i] = endian_swap(data[i]); - } - -#ifdef PUGIXML_WCHAR_MODE - PUGI__FN void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length) - { - for (size_t i = 0; i < length; ++i) result[i] = static_cast(endian_swap(static_cast::type>(data[i]))); - } -#endif -PUGI__NS_END - -PUGI__NS_BEGIN - enum chartype_t - { - ct_parse_pcdata = 1, // \0, &, \r, < - ct_parse_attr = 2, // \0, &, \r, ', " - ct_parse_attr_ws = 4, // \0, &, \r, ', ", \n, tab - ct_space = 8, // \r, \n, space, tab - ct_parse_cdata = 16, // \0, ], >, \r - ct_parse_comment = 32, // \0, -, >, \r - ct_symbol = 64, // Any symbol > 127, a-z, A-Z, 0-9, _, :, -, . - ct_start_symbol = 128 // Any symbol > 127, a-z, A-Z, _, : - }; - - static const unsigned char chartype_table[256] = - { - 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0, // 0-15 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 - 8, 0, 6, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 96, 64, 0, // 32-47 - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 0, 1, 0, 48, 0, // 48-63 - 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 64-79 - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 16, 0, 192, // 80-95 - 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 96-111 - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, // 112-127 - - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 128+ - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192 - }; - - enum chartypex_t - { - ctx_special_pcdata = 1, // Any symbol >= 0 and < 32 (except \t, \r, \n), &, <, > - ctx_special_attr = 2, // Any symbol >= 0 and < 32 (except \t), &, <, >, " - ctx_start_symbol = 4, // Any symbol > 127, a-z, A-Z, _ - ctx_digit = 8, // 0-9 - ctx_symbol = 16 // Any symbol > 127, a-z, A-Z, 0-9, _, -, . - }; - - static const unsigned char chartypex_table[256] = - { - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 2, 3, 3, // 0-15 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 16-31 - 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 16, 16, 0, // 32-47 - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 3, 0, 3, 0, // 48-63 - - 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 64-79 - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 20, // 80-95 - 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 96-111 - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, // 112-127 - - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 128+ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 - }; - -#ifdef PUGIXML_WCHAR_MODE - #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast(c) < 128 ? table[static_cast(c)] : table[128]) & (ct)) -#else - #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast(c)] & (ct)) -#endif - - #define PUGI__IS_CHARTYPE(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartype_table) - #define PUGI__IS_CHARTYPEX(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartypex_table) - - PUGI__FN bool is_little_endian() - { - unsigned int ui = 1; - - return *reinterpret_cast(&ui) == 1; - } - - PUGI__FN xml_encoding get_wchar_encoding() - { - PUGI__STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); - - if (sizeof(wchar_t) == 2) - return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - else - return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - } - - PUGI__FN xml_encoding guess_buffer_encoding(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) - { - // look for BOM in first few bytes - if (d0 == 0 && d1 == 0 && d2 == 0xfe && d3 == 0xff) return encoding_utf32_be; - if (d0 == 0xff && d1 == 0xfe && d2 == 0 && d3 == 0) return encoding_utf32_le; - if (d0 == 0xfe && d1 == 0xff) return encoding_utf16_be; - if (d0 == 0xff && d1 == 0xfe) return encoding_utf16_le; - if (d0 == 0xef && d1 == 0xbb && d2 == 0xbf) return encoding_utf8; - - // look for <, (contents); - - PUGI__DMC_VOLATILE uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3]; - - return guess_buffer_encoding(d0, d1, d2, d3); - } - - PUGI__FN bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) - { - size_t length = size / sizeof(char_t); - - if (is_mutable) - { - out_buffer = static_cast(const_cast(contents)); - out_length = length; - } - else - { - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - if (contents) - memcpy(buffer, contents, length * sizeof(char_t)); - else - assert(length == 0); - - buffer[length] = 0; - - out_buffer = buffer; - out_length = length + 1; - } - - return true; - } - -#ifdef PUGIXML_WCHAR_MODE - PUGI__FN bool need_endian_swap_utf(xml_encoding le, xml_encoding re) - { - return (le == encoding_utf16_be && re == encoding_utf16_le) || (le == encoding_utf16_le && re == encoding_utf16_be) || - (le == encoding_utf32_be && re == encoding_utf32_le) || (le == encoding_utf32_le && re == encoding_utf32_be); - } - - PUGI__FN bool convert_buffer_endian_swap(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) - { - const char_t* data = static_cast(contents); - size_t length = size / sizeof(char_t); - - if (is_mutable) - { - char_t* buffer = const_cast(data); - - convert_wchar_endian_swap(buffer, data, length); - - out_buffer = buffer; - out_length = length; - } - else - { - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - convert_wchar_endian_swap(buffer, data, length); - buffer[length] = 0; - - out_buffer = buffer; - out_length = length + 1; - } - - return true; - } - - PUGI__FN bool convert_buffer_utf8(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) - { - const uint8_t* data = static_cast(contents); - size_t data_length = size; - - // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf8_block(data, data_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert utf8 input to wchar_t - wchar_writer::value_type obegin = reinterpret_cast(buffer); - wchar_writer::value_type oend = utf_decoder::decode_utf8_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint16_t* data = static_cast(contents); - size_t data_length = size / sizeof(uint16_t); - - // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf16_block(data, data_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert utf16 input to wchar_t - wchar_writer::value_type obegin = reinterpret_cast(buffer); - wchar_writer::value_type oend = utf_decoder::decode_utf16_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint32_t* data = static_cast(contents); - size_t data_length = size / sizeof(uint32_t); - - // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf32_block(data, data_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert utf32 input to wchar_t - wchar_writer::value_type obegin = reinterpret_cast(buffer); - wchar_writer::value_type oend = utf_decoder::decode_utf32_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) - { - const uint8_t* data = static_cast(contents); - size_t data_length = size; - - // get length in wchar_t units - size_t length = data_length; - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // convert latin1 input to wchar_t - wchar_writer::value_type obegin = reinterpret_cast(buffer); - wchar_writer::value_type oend = utf_decoder::decode_latin1_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) - { - // get native encoding - xml_encoding wchar_encoding = get_wchar_encoding(); - - // fast path: no conversion required - if (encoding == wchar_encoding) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); - - // only endian-swapping is required - if (need_endian_swap_utf(encoding, wchar_encoding)) return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable); - - // source encoding is utf8 - if (encoding == encoding_utf8) return convert_buffer_utf8(out_buffer, out_length, contents, size); - - // source encoding is utf16 - if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) - { - xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - return (native_encoding == encoding) ? - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true()); - } - - // source encoding is utf32 - if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) - { - xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - return (native_encoding == encoding) ? - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); - } - - // source encoding is latin1 - if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size); - - assert(!"Invalid encoding"); - return false; - } -#else - template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint16_t* data = static_cast(contents); - size_t data_length = size / sizeof(uint16_t); - - // first pass: get length in utf8 units - size_t length = utf_decoder::decode_utf16_block(data, data_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert utf16 input to utf8 - uint8_t* obegin = reinterpret_cast(buffer); - uint8_t* oend = utf_decoder::decode_utf16_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint32_t* data = static_cast(contents); - size_t data_length = size / sizeof(uint32_t); - - // first pass: get length in utf8 units - size_t length = utf_decoder::decode_utf32_block(data, data_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert utf32 input to utf8 - uint8_t* obegin = reinterpret_cast(buffer); - uint8_t* oend = utf_decoder::decode_utf32_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - PUGI__FN size_t get_latin1_7bit_prefix_length(const uint8_t* data, size_t size) - { - for (size_t i = 0; i < size; ++i) - if (data[i] > 127) - return i; - - return size; - } - - PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) - { - const uint8_t* data = static_cast(contents); - size_t data_length = size; - - // get size of prefix that does not need utf8 conversion - size_t prefix_length = get_latin1_7bit_prefix_length(data, data_length); - assert(prefix_length <= data_length); - - const uint8_t* postfix = data + prefix_length; - size_t postfix_length = data_length - prefix_length; - - // if no conversion is needed, just return the original buffer - if (postfix_length == 0) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); - - // first pass: get length in utf8 units - size_t length = prefix_length + utf_decoder::decode_latin1_block(postfix, postfix_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert latin1 input to utf8 - memcpy(buffer, data, prefix_length); - - uint8_t* obegin = reinterpret_cast(buffer); - uint8_t* oend = utf_decoder::decode_latin1_block(postfix, postfix_length, obegin + prefix_length); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) - { - // fast path: no conversion required - if (encoding == encoding_utf8) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); - - // source encoding is utf16 - if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) - { - xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - return (native_encoding == encoding) ? - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true()); - } - - // source encoding is utf32 - if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) - { - xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - return (native_encoding == encoding) ? - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); - } - - // source encoding is latin1 - if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size, is_mutable); - - assert(!"Invalid encoding"); - return false; - } -#endif - - PUGI__FN size_t as_utf8_begin(const wchar_t* str, size_t length) - { - // get length in utf8 characters - return utf_decoder::decode_wchar_block(str, length, 0); - } - - PUGI__FN void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length) - { - // convert to utf8 - uint8_t* begin = reinterpret_cast(buffer); - uint8_t* end = utf_decoder::decode_wchar_block(str, length, begin); - - assert(begin + size == end); - (void)!end; - - // zero-terminate - buffer[size] = 0; - } - -#ifndef PUGIXML_NO_STL - PUGI__FN std::string as_utf8_impl(const wchar_t* str, size_t length) - { - // first pass: get length in utf8 characters - size_t size = as_utf8_begin(str, length); - - // allocate resulting string - std::string result; - result.resize(size); - - // second pass: convert to utf8 - if (size > 0) as_utf8_end(&result[0], size, str, length); - - return result; - } - - PUGI__FN std::basic_string as_wide_impl(const char* str, size_t size) - { - const uint8_t* data = reinterpret_cast(str); - - // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf8_block(data, size, 0); - - // allocate resulting string - std::basic_string result; - result.resize(length); - - // second pass: convert to wchar_t - if (length > 0) - { - wchar_writer::value_type begin = reinterpret_cast(&result[0]); - wchar_writer::value_type end = utf_decoder::decode_utf8_block(data, size, begin); - - assert(begin + length == end); - (void)!end; - } - - return result; - } -#endif - - inline bool strcpy_insitu_allow(size_t length, uintptr_t header, uintptr_t header_mask, char_t* target) - { - // never reuse shared memory - if (header & xml_memory_page_contents_shared_mask) return false; - - size_t target_length = strlength(target); - - // always reuse document buffer memory if possible - if ((header & header_mask) == 0) return target_length >= length; - - // reuse heap memory if waste is not too great - const size_t reuse_threshold = 32; - - return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2); - } - - PUGI__FN bool strcpy_insitu(char_t*& dest, uintptr_t& header, uintptr_t header_mask, const char_t* source) - { - assert(header); - - size_t source_length = strlength(source); - - if (source_length == 0) - { - // empty string and null pointer are equivalent, so just deallocate old memory - xml_allocator* alloc = reinterpret_cast(header & xml_memory_page_pointer_mask)->allocator; - - if (header & header_mask) alloc->deallocate_string(dest); - - // mark the string as not allocated - dest = 0; - header &= ~header_mask; - - return true; - } - else if (dest && strcpy_insitu_allow(source_length, header, header_mask, dest)) - { - // we can reuse old buffer, so just copy the new data (including zero terminator) - memcpy(dest, source, (source_length + 1) * sizeof(char_t)); - - return true; - } - else - { - xml_allocator* alloc = reinterpret_cast(header & xml_memory_page_pointer_mask)->allocator; - - // allocate new buffer - char_t* buf = alloc->allocate_string(source_length + 1); - if (!buf) return false; - - // copy the string (including zero terminator) - memcpy(buf, source, (source_length + 1) * sizeof(char_t)); - - // deallocate old buffer (*after* the above to protect against overlapping memory and/or allocation failures) - if (header & header_mask) alloc->deallocate_string(dest); - - // the string is now allocated, so set the flag - dest = buf; - header |= header_mask; - - return true; - } - } - - struct gap - { - char_t* end; - size_t size; - - gap(): end(0), size(0) - { - } - - // Push new gap, move s count bytes further (skipping the gap). - // Collapse previous gap. - void push(char_t*& s, size_t count) - { - if (end) // there was a gap already; collapse it - { - // Move [old_gap_end, new_gap_start) to [old_gap_start, ...) - assert(s >= end); - memmove(end - size, end, reinterpret_cast(s) - reinterpret_cast(end)); - } - - s += count; // end of current gap - - // "merge" two gaps - end = s; - size += count; - } - - // Collapse all gaps, return past-the-end pointer - char_t* flush(char_t* s) - { - if (end) - { - // Move [old_gap_end, current_pos) to [old_gap_start, ...) - assert(s >= end); - memmove(end - size, end, reinterpret_cast(s) - reinterpret_cast(end)); - - return s - size; - } - else return s; - } - }; - - PUGI__FN char_t* strconv_escape(char_t* s, gap& g) - { - char_t* stre = s + 1; - - switch (*stre) - { - case '#': // &#... - { - unsigned int ucsc = 0; - - if (stre[1] == 'x') // &#x... (hex code) - { - stre += 2; - - char_t ch = *stre; - - if (ch == ';') return stre; - - for (;;) - { - if (static_cast(ch - '0') <= 9) - ucsc = 16 * ucsc + (ch - '0'); - else if (static_cast((ch | ' ') - 'a') <= 5) - ucsc = 16 * ucsc + ((ch | ' ') - 'a' + 10); - else if (ch == ';') - break; - else // cancel - return stre; - - ch = *++stre; - } - - ++stre; - } - else // &#... (dec code) - { - char_t ch = *++stre; - - if (ch == ';') return stre; - - for (;;) - { - if (static_cast(static_cast(ch) - '0') <= 9) - ucsc = 10 * ucsc + (ch - '0'); - else if (ch == ';') - break; - else // cancel - return stre; - - ch = *++stre; - } - - ++stre; - } - - #ifdef PUGIXML_WCHAR_MODE - s = reinterpret_cast(wchar_writer::any(reinterpret_cast(s), ucsc)); - #else - s = reinterpret_cast(utf8_writer::any(reinterpret_cast(s), ucsc)); - #endif - - g.push(s, stre - s); - return stre; - } - - case 'a': // &a - { - ++stre; - - if (*stre == 'm') // &am - { - if (*++stre == 'p' && *++stre == ';') // & - { - *s++ = '&'; - ++stre; - - g.push(s, stre - s); - return stre; - } - } - else if (*stre == 'p') // &ap - { - if (*++stre == 'o' && *++stre == 's' && *++stre == ';') // ' - { - *s++ = '\''; - ++stre; - - g.push(s, stre - s); - return stre; - } - } - break; - } - - case 'g': // &g - { - if (*++stre == 't' && *++stre == ';') // > - { - *s++ = '>'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - - case 'l': // &l - { - if (*++stre == 't' && *++stre == ';') // < - { - *s++ = '<'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - - case 'q': // &q - { - if (*++stre == 'u' && *++stre == 'o' && *++stre == 't' && *++stre == ';') // " - { - *s++ = '"'; - ++stre; - - g.push(s, stre - s); - return stre; - } - break; - } - - default: - break; - } - - return stre; - } - - // Parser utilities - #define PUGI__ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e))) - #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; } - #define PUGI__OPTSET(OPT) ( optmsk & (OPT) ) - #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } - #define PUGI__POPNODE() { cursor = cursor->parent; } - #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; } - #define PUGI__SCANWHILE(X) { while (X) ++s; } - #define PUGI__SCANWHILE_UNROLL(X) { for (;;) { char_t ss = s[0]; if (PUGI__UNLIKELY(!(X))) { break; } ss = s[1]; if (PUGI__UNLIKELY(!(X))) { s += 1; break; } ss = s[2]; if (PUGI__UNLIKELY(!(X))) { s += 2; break; } ss = s[3]; if (PUGI__UNLIKELY(!(X))) { s += 3; break; } s += 4; } } - #define PUGI__ENDSEG() { ch = *s; *s = 0; ++s; } - #define PUGI__THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast(0) - #define PUGI__CHECK_ERROR(err, m) { if (*s == 0) PUGI__THROW_ERROR(err, m); } - - PUGI__FN char_t* strconv_comment(char_t* s, char_t endch) - { - gap g; - - while (true) - { - PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_comment)); - - if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (s[0] == '-' && s[1] == '-' && PUGI__ENDSWITH(s[2], '>')) // comment ends here - { - *g.flush(s) = 0; - - return s + (s[2] == '>' ? 3 : 2); - } - else if (*s == 0) - { - return 0; - } - else ++s; - } - } - - PUGI__FN char_t* strconv_cdata(char_t* s, char_t endch) - { - gap g; - - while (true) - { - PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_cdata)); - - if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')) // CDATA ends here - { - *g.flush(s) = 0; - - return s + 1; - } - else if (*s == 0) - { - return 0; - } - else ++s; - } - } - - typedef char_t* (*strconv_pcdata_t)(char_t*); - - template struct strconv_pcdata_impl - { - static char_t* parse(char_t* s) - { - gap g; - - char_t* begin = s; - - while (true) - { - PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_pcdata)); - - if (*s == '<') // PCDATA ends here - { - char_t* end = g.flush(s); - - if (opt_trim::value) - while (end > begin && PUGI__IS_CHARTYPE(end[-1], ct_space)) - --end; - - *end = 0; - - return s + 1; - } - else if (opt_eol::value && *s == '\r') // Either a single 0x0d or 0x0d 0x0a pair - { - *s++ = '\n'; // replace first one with 0x0a - - if (*s == '\n') g.push(s, 1); - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (*s == 0) - { - char_t* end = g.flush(s); - - if (opt_trim::value) - while (end > begin && PUGI__IS_CHARTYPE(end[-1], ct_space)) - --end; - - *end = 0; - - return s; - } - else ++s; - } - } - }; - - PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask) - { - PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_trim_pcdata == 0x0800); - - switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4)) // get bitmask for flags (eol escapes trim) - { - case 0: return strconv_pcdata_impl::parse; - case 1: return strconv_pcdata_impl::parse; - case 2: return strconv_pcdata_impl::parse; - case 3: return strconv_pcdata_impl::parse; - case 4: return strconv_pcdata_impl::parse; - case 5: return strconv_pcdata_impl::parse; - case 6: return strconv_pcdata_impl::parse; - case 7: return strconv_pcdata_impl::parse; - default: assert(false); return 0; // should not get here - } - } - - typedef char_t* (*strconv_attribute_t)(char_t*, char_t); - - template struct strconv_attribute_impl - { - static char_t* parse_wnorm(char_t* s, char_t end_quote) - { - gap g; - - // trim leading whitespaces - if (PUGI__IS_CHARTYPE(*s, ct_space)) - { - char_t* str = s; - - do ++str; - while (PUGI__IS_CHARTYPE(*str, ct_space)); - - g.push(s, str - s); - } - - while (true) - { - PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr_ws | ct_space)); - - if (*s == end_quote) - { - char_t* str = g.flush(s); - - do *str-- = 0; - while (PUGI__IS_CHARTYPE(*str, ct_space)); - - return s + 1; - } - else if (PUGI__IS_CHARTYPE(*s, ct_space)) - { - *s++ = ' '; - - if (PUGI__IS_CHARTYPE(*s, ct_space)) - { - char_t* str = s + 1; - while (PUGI__IS_CHARTYPE(*str, ct_space)) ++str; - - g.push(s, str - s); - } - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - - static char_t* parse_wconv(char_t* s, char_t end_quote) - { - gap g; - - while (true) - { - PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr_ws)); - - if (*s == end_quote) - { - *g.flush(s) = 0; - - return s + 1; - } - else if (PUGI__IS_CHARTYPE(*s, ct_space)) - { - if (*s == '\r') - { - *s++ = ' '; - - if (*s == '\n') g.push(s, 1); - } - else *s++ = ' '; - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - - static char_t* parse_eol(char_t* s, char_t end_quote) - { - gap g; - - while (true) - { - PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr)); - - if (*s == end_quote) - { - *g.flush(s) = 0; - - return s + 1; - } - else if (*s == '\r') - { - *s++ = '\n'; - - if (*s == '\n') g.push(s, 1); - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - - static char_t* parse_simple(char_t* s, char_t end_quote) - { - gap g; - - while (true) - { - PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr)); - - if (*s == end_quote) - { - *g.flush(s) = 0; - - return s + 1; - } - else if (opt_escape::value && *s == '&') - { - s = strconv_escape(s, g); - } - else if (!*s) - { - return 0; - } - else ++s; - } - } - }; - - PUGI__FN strconv_attribute_t get_strconv_attribute(unsigned int optmask) - { - PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80); - - switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes) - { - case 0: return strconv_attribute_impl::parse_simple; - case 1: return strconv_attribute_impl::parse_simple; - case 2: return strconv_attribute_impl::parse_eol; - case 3: return strconv_attribute_impl::parse_eol; - case 4: return strconv_attribute_impl::parse_wconv; - case 5: return strconv_attribute_impl::parse_wconv; - case 6: return strconv_attribute_impl::parse_wconv; - case 7: return strconv_attribute_impl::parse_wconv; - case 8: return strconv_attribute_impl::parse_wnorm; - case 9: return strconv_attribute_impl::parse_wnorm; - case 10: return strconv_attribute_impl::parse_wnorm; - case 11: return strconv_attribute_impl::parse_wnorm; - case 12: return strconv_attribute_impl::parse_wnorm; - case 13: return strconv_attribute_impl::parse_wnorm; - case 14: return strconv_attribute_impl::parse_wnorm; - case 15: return strconv_attribute_impl::parse_wnorm; - default: assert(false); return 0; // should not get here - } - } - - inline xml_parse_result make_parse_result(xml_parse_status status, ptrdiff_t offset = 0) - { - xml_parse_result result; - result.status = status; - result.offset = offset; - - return result; - } - - struct xml_parser - { - xml_allocator alloc; - char_t* error_offset; - xml_parse_status error_status; - - xml_parser(const xml_allocator& alloc_): alloc(alloc_), error_offset(0), error_status(status_ok) - { - } - - // DOCTYPE consists of nested sections of the following possible types: - // , , "...", '...' - // - // - // First group can not contain nested groups - // Second group can contain nested groups of the same type - // Third group can contain all other groups - char_t* parse_doctype_primitive(char_t* s) - { - if (*s == '"' || *s == '\'') - { - // quoted string - char_t ch = *s++; - PUGI__SCANFOR(*s == ch); - if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); - - s++; - } - else if (s[0] == '<' && s[1] == '?') - { - // - s += 2; - PUGI__SCANFOR(s[0] == '?' && s[1] == '>'); // no need for ENDSWITH because ?> can't terminate proper doctype - if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); - - s += 2; - } - else if (s[0] == '<' && s[1] == '!' && s[2] == '-' && s[3] == '-') - { - s += 4; - PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && s[2] == '>'); // no need for ENDSWITH because --> can't terminate proper doctype - if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); - - s += 3; - } - else PUGI__THROW_ERROR(status_bad_doctype, s); - - return s; - } - - char_t* parse_doctype_ignore(char_t* s) - { - size_t depth = 0; - - assert(s[0] == '<' && s[1] == '!' && s[2] == '['); - s += 3; - - while (*s) - { - if (s[0] == '<' && s[1] == '!' && s[2] == '[') - { - // nested ignore section - s += 3; - depth++; - } - else if (s[0] == ']' && s[1] == ']' && s[2] == '>') - { - // ignore section end - s += 3; - - if (depth == 0) - return s; - - depth--; - } - else s++; - } - - PUGI__THROW_ERROR(status_bad_doctype, s); - } - - char_t* parse_doctype_group(char_t* s, char_t endch) - { - size_t depth = 0; - - assert((s[0] == '<' || s[0] == 0) && s[1] == '!'); - s += 2; - - while (*s) - { - if (s[0] == '<' && s[1] == '!' && s[2] != '-') - { - if (s[2] == '[') - { - // ignore - s = parse_doctype_ignore(s); - if (!s) return s; - } - else - { - // some control group - s += 2; - depth++; - } - } - else if (s[0] == '<' || s[0] == '"' || s[0] == '\'') - { - // unknown tag (forbidden), or some primitive group - s = parse_doctype_primitive(s); - if (!s) return s; - } - else if (*s == '>') - { - if (depth == 0) - return s; - - depth--; - s++; - } - else s++; - } - - if (depth != 0 || endch != '>') PUGI__THROW_ERROR(status_bad_doctype, s); - - return s; - } - - char_t* parse_exclamation(char_t* s, xml_node_struct* cursor, unsigned int optmsk, char_t endch) - { - // parse node contents, starting with exclamation mark - ++s; - - if (*s == '-') // 'value = s; // Save the offset. - } - - if (PUGI__OPTSET(parse_eol) && PUGI__OPTSET(parse_comments)) - { - s = strconv_comment(s, endch); - - if (!s) PUGI__THROW_ERROR(status_bad_comment, cursor->value); - } - else - { - // Scan for terminating '-->'. - PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && PUGI__ENDSWITH(s[2], '>')); - PUGI__CHECK_ERROR(status_bad_comment, s); - - if (PUGI__OPTSET(parse_comments)) - *s = 0; // Zero-terminate this segment at the first terminating '-'. - - s += (s[2] == '>' ? 3 : 2); // Step over the '\0->'. - } - } - else PUGI__THROW_ERROR(status_bad_comment, s); - } - else if (*s == '[') - { - // 'value = s; // Save the offset. - - if (PUGI__OPTSET(parse_eol)) - { - s = strconv_cdata(s, endch); - - if (!s) PUGI__THROW_ERROR(status_bad_cdata, cursor->value); - } - else - { - // Scan for terminating ']]>'. - PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')); - PUGI__CHECK_ERROR(status_bad_cdata, s); - - *s++ = 0; // Zero-terminate this segment. - } - } - else // Flagged for discard, but we still have to scan for the terminator. - { - // Scan for terminating ']]>'. - PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')); - PUGI__CHECK_ERROR(status_bad_cdata, s); - - ++s; - } - - s += (s[1] == '>' ? 2 : 1); // Step over the last ']>'. - } - else PUGI__THROW_ERROR(status_bad_cdata, s); - } - else if (s[0] == 'D' && s[1] == 'O' && s[2] == 'C' && s[3] == 'T' && s[4] == 'Y' && s[5] == 'P' && PUGI__ENDSWITH(s[6], 'E')) - { - s -= 2; - - if (cursor->parent) PUGI__THROW_ERROR(status_bad_doctype, s); - - char_t* mark = s + 9; - - s = parse_doctype_group(s, endch); - if (!s) return s; - - assert((*s == 0 && endch == '>') || *s == '>'); - if (*s) *s++ = 0; - - if (PUGI__OPTSET(parse_doctype)) - { - while (PUGI__IS_CHARTYPE(*mark, ct_space)) ++mark; - - PUGI__PUSHNODE(node_doctype); - - cursor->value = mark; - } - } - else if (*s == 0 && endch == '-') PUGI__THROW_ERROR(status_bad_comment, s); - else if (*s == 0 && endch == '[') PUGI__THROW_ERROR(status_bad_cdata, s); - else PUGI__THROW_ERROR(status_unrecognized_tag, s); - - return s; - } - - char_t* parse_question(char_t* s, xml_node_struct*& ref_cursor, unsigned int optmsk, char_t endch) - { - // load into registers - xml_node_struct* cursor = ref_cursor; - char_t ch = 0; - - // parse node contents, starting with question mark - ++s; - - // read PI target - char_t* target = s; - - if (!PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_pi, s); - - PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); - PUGI__CHECK_ERROR(status_bad_pi, s); - - // determine node type; stricmp / strcasecmp is not portable - bool declaration = (target[0] | ' ') == 'x' && (target[1] | ' ') == 'm' && (target[2] | ' ') == 'l' && target + 3 == s; - - if (declaration ? PUGI__OPTSET(parse_declaration) : PUGI__OPTSET(parse_pi)) - { - if (declaration) - { - // disallow non top-level declarations - if (cursor->parent) PUGI__THROW_ERROR(status_bad_pi, s); - - PUGI__PUSHNODE(node_declaration); - } - else - { - PUGI__PUSHNODE(node_pi); - } - - cursor->name = target; - - PUGI__ENDSEG(); - - // parse value/attributes - if (ch == '?') - { - // empty node - if (!PUGI__ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_pi, s); - s += (*s == '>'); - - PUGI__POPNODE(); - } - else if (PUGI__IS_CHARTYPE(ch, ct_space)) - { - PUGI__SKIPWS(); - - // scan for tag end - char_t* value = s; - - PUGI__SCANFOR(s[0] == '?' && PUGI__ENDSWITH(s[1], '>')); - PUGI__CHECK_ERROR(status_bad_pi, s); - - if (declaration) - { - // replace ending ? with / so that 'element' terminates properly - *s = '/'; - - // we exit from this function with cursor at node_declaration, which is a signal to parse() to go to LOC_ATTRIBUTES - s = value; - } - else - { - // store value and step over > - cursor->value = value; - PUGI__POPNODE(); - - PUGI__ENDSEG(); - - s += (*s == '>'); - } - } - else PUGI__THROW_ERROR(status_bad_pi, s); - } - else - { - // scan for tag end - PUGI__SCANFOR(s[0] == '?' && PUGI__ENDSWITH(s[1], '>')); - PUGI__CHECK_ERROR(status_bad_pi, s); - - s += (s[1] == '>' ? 2 : 1); - } - - // store from registers - ref_cursor = cursor; - - return s; - } - - char_t* parse_tree(char_t* s, xml_node_struct* root, unsigned int optmsk, char_t endch) - { - strconv_attribute_t strconv_attribute = get_strconv_attribute(optmsk); - strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk); - - char_t ch = 0; - xml_node_struct* cursor = root; - char_t* mark = s; - - while (*s != 0) - { - if (*s == '<') - { - ++s; - - LOC_TAG: - if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // '<#...' - { - PUGI__PUSHNODE(node_element); // Append a new node to the tree. - - cursor->name = s; - - PUGI__SCANWHILE_UNROLL(PUGI__IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator. - PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. - - if (ch == '>') - { - // end of tag - } - else if (PUGI__IS_CHARTYPE(ch, ct_space)) - { - LOC_ATTRIBUTES: - while (true) - { - PUGI__SKIPWS(); // Eat any whitespace. - - if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // <... #... - { - xml_attribute_struct* a = append_new_attribute(cursor, alloc); // Make space for this attribute. - if (!a) PUGI__THROW_ERROR(status_out_of_memory, s); - - a->name = s; // Save the offset. - - PUGI__SCANWHILE_UNROLL(PUGI__IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator. - PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. - - if (PUGI__IS_CHARTYPE(ch, ct_space)) - { - PUGI__SKIPWS(); // Eat any whitespace. - - ch = *s; - ++s; - } - - if (ch == '=') // '<... #=...' - { - PUGI__SKIPWS(); // Eat any whitespace. - - if (*s == '"' || *s == '\'') // '<... #="...' - { - ch = *s; // Save quote char to avoid breaking on "''" -or- '""'. - ++s; // Step over the quote. - a->value = s; // Save the offset. - - s = strconv_attribute(s, ch); - - if (!s) PUGI__THROW_ERROR(status_bad_attribute, a->value); - - // After this line the loop continues from the start; - // Whitespaces, / and > are ok, symbols and EOF are wrong, - // everything else will be detected - if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_attribute, s); - } - else PUGI__THROW_ERROR(status_bad_attribute, s); - } - else PUGI__THROW_ERROR(status_bad_attribute, s); - } - else if (*s == '/') - { - ++s; - - if (*s == '>') - { - PUGI__POPNODE(); - s++; - break; - } - else if (*s == 0 && endch == '>') - { - PUGI__POPNODE(); - break; - } - else PUGI__THROW_ERROR(status_bad_start_element, s); - } - else if (*s == '>') - { - ++s; - - break; - } - else if (*s == 0 && endch == '>') - { - break; - } - else PUGI__THROW_ERROR(status_bad_start_element, s); - } - - // !!! - } - else if (ch == '/') // '<#.../' - { - if (!PUGI__ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_start_element, s); - - PUGI__POPNODE(); // Pop. - - s += (*s == '>'); - } - else if (ch == 0) - { - // we stepped over null terminator, backtrack & handle closing tag - --s; - - if (endch != '>') PUGI__THROW_ERROR(status_bad_start_element, s); - } - else PUGI__THROW_ERROR(status_bad_start_element, s); - } - else if (*s == '/') - { - ++s; - - char_t* name = cursor->name; - if (!name) PUGI__THROW_ERROR(status_end_element_mismatch, s); - - while (PUGI__IS_CHARTYPE(*s, ct_symbol)) - { - if (*s++ != *name++) PUGI__THROW_ERROR(status_end_element_mismatch, s); - } - - if (*name) - { - if (*s == 0 && name[0] == endch && name[1] == 0) PUGI__THROW_ERROR(status_bad_end_element, s); - else PUGI__THROW_ERROR(status_end_element_mismatch, s); - } - - PUGI__POPNODE(); // Pop. - - PUGI__SKIPWS(); - - if (*s == 0) - { - if (endch != '>') PUGI__THROW_ERROR(status_bad_end_element, s); - } - else - { - if (*s != '>') PUGI__THROW_ERROR(status_bad_end_element, s); - ++s; - } - } - else if (*s == '?') // 'first_child) continue; - } - } - - if (!PUGI__OPTSET(parse_trim_pcdata)) - s = mark; - - if (cursor->parent || PUGI__OPTSET(parse_fragment)) - { - PUGI__PUSHNODE(node_pcdata); // Append a new node on the tree. - cursor->value = s; // Save the offset. - - s = strconv_pcdata(s); - - PUGI__POPNODE(); // Pop since this is a standalone. - - if (!*s) break; - } - else - { - PUGI__SCANFOR(*s == '<'); // '...<' - if (!*s) break; - - ++s; - } - - // We're after '<' - goto LOC_TAG; - } - } - - // check that last tag is closed - if (cursor != root) PUGI__THROW_ERROR(status_end_element_mismatch, s); - - return s; - } - - #ifdef PUGIXML_WCHAR_MODE - static char_t* parse_skip_bom(char_t* s) - { - unsigned int bom = 0xfeff; - return (s[0] == static_cast(bom)) ? s + 1 : s; - } - #else - static char_t* parse_skip_bom(char_t* s) - { - return (s[0] == '\xef' && s[1] == '\xbb' && s[2] == '\xbf') ? s + 3 : s; - } - #endif - - static bool has_element_node_siblings(xml_node_struct* node) - { - while (node) - { - if (PUGI__NODETYPE(node) == node_element) return true; - - node = node->next_sibling; - } - - return false; - } - - static xml_parse_result parse(char_t* buffer, size_t length, xml_document_struct* xmldoc, xml_node_struct* root, unsigned int optmsk) - { - // allocator object is a part of document object - xml_allocator& alloc_ = *static_cast(xmldoc); - - // early-out for empty documents - if (length == 0) - return make_parse_result(PUGI__OPTSET(parse_fragment) ? status_ok : status_no_document_element); - - // get last child of the root before parsing - xml_node_struct* last_root_child = root->first_child ? root->first_child->prev_sibling_c : 0; - - // create parser on stack - xml_parser parser(alloc_); - - // save last character and make buffer zero-terminated (speeds up parsing) - char_t endch = buffer[length - 1]; - buffer[length - 1] = 0; - - // skip BOM to make sure it does not end up as part of parse output - char_t* buffer_data = parse_skip_bom(buffer); - - // perform actual parsing - parser.parse_tree(buffer_data, root, optmsk, endch); - - // update allocator state - alloc_ = parser.alloc; - - xml_parse_result result = make_parse_result(parser.error_status, parser.error_offset ? parser.error_offset - buffer : 0); - assert(result.offset >= 0 && static_cast(result.offset) <= length); - - if (result) - { - // since we removed last character, we have to handle the only possible false positive (stray <) - if (endch == '<') - return make_parse_result(status_unrecognized_tag, length - 1); - - // check if there are any element nodes parsed - xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling : root->first_child; - - if (!PUGI__OPTSET(parse_fragment) && !has_element_node_siblings(first_root_child_parsed)) - return make_parse_result(status_no_document_element, length - 1); - } - else - { - // roll back offset if it occurs on a null terminator in the source buffer - if (result.offset > 0 && static_cast(result.offset) == length - 1 && endch == 0) - result.offset--; - } - - return result; - } - }; - - // Output facilities - PUGI__FN xml_encoding get_write_native_encoding() - { - #ifdef PUGIXML_WCHAR_MODE - return get_wchar_encoding(); - #else - return encoding_utf8; - #endif - } - - PUGI__FN xml_encoding get_write_encoding(xml_encoding encoding) - { - // replace wchar encoding with utf implementation - if (encoding == encoding_wchar) return get_wchar_encoding(); - - // replace utf16 encoding with utf16 with specific endianness - if (encoding == encoding_utf16) return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - // replace utf32 encoding with utf32 with specific endianness - if (encoding == encoding_utf32) return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - // only do autodetection if no explicit encoding is requested - if (encoding != encoding_auto) return encoding; - - // assume utf8 encoding - return encoding_utf8; - } - -#ifdef PUGIXML_WCHAR_MODE - PUGI__FN size_t get_valid_length(const char_t* data, size_t length) - { - if (length < 1) return 0; - - // discard last character if it's the lead of a surrogate pair - return (sizeof(wchar_t) == 2 && static_cast(static_cast(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length; - } - - PUGI__FN size_t convert_buffer_output(char_t* r_char, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) - { - // only endian-swapping is required - if (need_endian_swap_utf(encoding, get_wchar_encoding())) - { - convert_wchar_endian_swap(r_char, data, length); - - return length * sizeof(char_t); - } - - // convert to utf8 - if (encoding == encoding_utf8) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - return static_cast(end - dest); - } - - // convert to utf16 - if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) - { - uint16_t* dest = r_u16; - - // convert to native utf16 - uint16_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - // swap if necessary - xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint16_t); - } - - // convert to utf32 - if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) - { - uint32_t* dest = r_u32; - - // convert to native utf32 - uint32_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - // swap if necessary - xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint32_t); - } - - // convert to latin1 - if (encoding == encoding_latin1) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - return static_cast(end - dest); - } - - assert(!"Invalid encoding"); - return 0; - } -#else - PUGI__FN size_t get_valid_length(const char_t* data, size_t length) - { - if (length < 5) return 0; - - for (size_t i = 1; i <= 4; ++i) - { - uint8_t ch = static_cast(data[length - i]); - - // either a standalone character or a leading one - if ((ch & 0xc0) != 0x80) return length - i; - } - - // there are four non-leading characters at the end, sequence tail is broken so might as well process the whole chunk - return length; - } - - PUGI__FN size_t convert_buffer_output(char_t* /* r_char */, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) - { - if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) - { - uint16_t* dest = r_u16; - - // convert to native utf16 - uint16_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); - - // swap if necessary - xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint16_t); - } - - if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) - { - uint32_t* dest = r_u32; - - // convert to native utf32 - uint32_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); - - // swap if necessary - xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint32_t); - } - - if (encoding == encoding_latin1) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); - - return static_cast(end - dest); - } - - assert(!"Invalid encoding"); - return 0; - } -#endif - - class xml_buffered_writer - { - xml_buffered_writer(const xml_buffered_writer&); - xml_buffered_writer& operator=(const xml_buffered_writer&); - - public: - xml_buffered_writer(xml_writer& writer_, xml_encoding user_encoding): writer(writer_), bufsize(0), encoding(get_write_encoding(user_encoding)) - { - PUGI__STATIC_ASSERT(bufcapacity >= 8); - } - - ~xml_buffered_writer() - { - flush(); - } - - size_t flush() - { - flush(buffer, bufsize); - bufsize = 0; - return 0; - } - - void flush(const char_t* data, size_t size) - { - if (size == 0) return; - - // fast path, just write data - if (encoding == get_write_native_encoding()) - writer.write(data, size * sizeof(char_t)); - else - { - // convert chunk - size_t result = convert_buffer_output(scratch.data_char, scratch.data_u8, scratch.data_u16, scratch.data_u32, data, size, encoding); - assert(result <= sizeof(scratch)); - - // write data - writer.write(scratch.data_u8, result); - } - } - - void write_direct(const char_t* data, size_t length) - { - // flush the remaining buffer contents - flush(); - - // handle large chunks - if (length > bufcapacity) - { - if (encoding == get_write_native_encoding()) - { - // fast path, can just write data chunk - writer.write(data, length * sizeof(char_t)); - return; - } - - // need to convert in suitable chunks - while (length > bufcapacity) - { - // get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer - // and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary) - size_t chunk_size = get_valid_length(data, bufcapacity); - assert(chunk_size); - - // convert chunk and write - flush(data, chunk_size); - - // iterate - data += chunk_size; - length -= chunk_size; - } - - // small tail is copied below - bufsize = 0; - } - - memcpy(buffer + bufsize, data, length * sizeof(char_t)); - bufsize += length; - } - - void write_buffer(const char_t* data, size_t length) - { - size_t offset = bufsize; - - if (offset + length <= bufcapacity) - { - memcpy(buffer + offset, data, length * sizeof(char_t)); - bufsize = offset + length; - } - else - { - write_direct(data, length); - } - } - - void write_string(const char_t* data) - { - // write the part of the string that fits in the buffer - size_t offset = bufsize; - - while (*data && offset < bufcapacity) - buffer[offset++] = *data++; - - // write the rest - if (offset < bufcapacity) - { - bufsize = offset; - } - else - { - // backtrack a bit if we have split the codepoint - size_t length = offset - bufsize; - size_t extra = length - get_valid_length(data - length, length); - - bufsize = offset - extra; - - write_direct(data - extra, strlength(data) + extra); - } - } - - void write(char_t d0) - { - size_t offset = bufsize; - if (offset > bufcapacity - 1) offset = flush(); - - buffer[offset + 0] = d0; - bufsize = offset + 1; - } - - void write(char_t d0, char_t d1) - { - size_t offset = bufsize; - if (offset > bufcapacity - 2) offset = flush(); - - buffer[offset + 0] = d0; - buffer[offset + 1] = d1; - bufsize = offset + 2; - } - - void write(char_t d0, char_t d1, char_t d2) - { - size_t offset = bufsize; - if (offset > bufcapacity - 3) offset = flush(); - - buffer[offset + 0] = d0; - buffer[offset + 1] = d1; - buffer[offset + 2] = d2; - bufsize = offset + 3; - } - - void write(char_t d0, char_t d1, char_t d2, char_t d3) - { - size_t offset = bufsize; - if (offset > bufcapacity - 4) offset = flush(); - - buffer[offset + 0] = d0; - buffer[offset + 1] = d1; - buffer[offset + 2] = d2; - buffer[offset + 3] = d3; - bufsize = offset + 4; - } - - void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4) - { - size_t offset = bufsize; - if (offset > bufcapacity - 5) offset = flush(); - - buffer[offset + 0] = d0; - buffer[offset + 1] = d1; - buffer[offset + 2] = d2; - buffer[offset + 3] = d3; - buffer[offset + 4] = d4; - bufsize = offset + 5; - } - - void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5) - { - size_t offset = bufsize; - if (offset > bufcapacity - 6) offset = flush(); - - buffer[offset + 0] = d0; - buffer[offset + 1] = d1; - buffer[offset + 2] = d2; - buffer[offset + 3] = d3; - buffer[offset + 4] = d4; - buffer[offset + 5] = d5; - bufsize = offset + 6; - } - - // utf8 maximum expansion: x4 (-> utf32) - // utf16 maximum expansion: x2 (-> utf32) - // utf32 maximum expansion: x1 - enum - { - bufcapacitybytes = - #ifdef PUGIXML_MEMORY_OUTPUT_STACK - PUGIXML_MEMORY_OUTPUT_STACK - #else - 10240 - #endif - , - bufcapacity = bufcapacitybytes / (sizeof(char_t) + 4) - }; - - char_t buffer[bufcapacity]; - - union - { - uint8_t data_u8[4 * bufcapacity]; - uint16_t data_u16[2 * bufcapacity]; - uint32_t data_u32[bufcapacity]; - char_t data_char[bufcapacity]; - } scratch; - - xml_writer& writer; - size_t bufsize; - xml_encoding encoding; - }; - - PUGI__FN void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type) - { - while (*s) - { - const char_t* prev = s; - - // While *s is a usual symbol - PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPEX(ss, type)); - - writer.write_buffer(prev, static_cast(s - prev)); - - switch (*s) - { - case 0: break; - case '&': - writer.write('&', 'a', 'm', 'p', ';'); - ++s; - break; - case '<': - writer.write('&', 'l', 't', ';'); - ++s; - break; - case '>': - writer.write('&', 'g', 't', ';'); - ++s; - break; - case '"': - writer.write('&', 'q', 'u', 'o', 't', ';'); - ++s; - break; - default: // s is not a usual symbol - { - unsigned int ch = static_cast(*s++); - assert(ch < 32); - - writer.write('&', '#', static_cast((ch / 10) + '0'), static_cast((ch % 10) + '0'), ';'); - } - } - } - } - - PUGI__FN void text_output(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags) - { - if (flags & format_no_escapes) - writer.write_string(s); - else - text_output_escaped(writer, s, type); - } - - PUGI__FN void text_output_cdata(xml_buffered_writer& writer, const char_t* s) - { - do - { - writer.write('<', '!', '[', 'C', 'D'); - writer.write('A', 'T', 'A', '['); - - const char_t* prev = s; - - // look for ]]> sequence - we can't output it as is since it terminates CDATA - while (*s && !(s[0] == ']' && s[1] == ']' && s[2] == '>')) ++s; - - // skip ]] if we stopped at ]]>, > will go to the next CDATA section - if (*s) s += 2; - - writer.write_buffer(prev, static_cast(s - prev)); - - writer.write(']', ']', '>'); - } - while (*s); - } - - PUGI__FN void text_output_indent(xml_buffered_writer& writer, const char_t* indent, size_t indent_length, unsigned int depth) - { - switch (indent_length) - { - case 1: - { - for (unsigned int i = 0; i < depth; ++i) - writer.write(indent[0]); - break; - } - - case 2: - { - for (unsigned int i = 0; i < depth; ++i) - writer.write(indent[0], indent[1]); - break; - } - - case 3: - { - for (unsigned int i = 0; i < depth; ++i) - writer.write(indent[0], indent[1], indent[2]); - break; - } - - case 4: - { - for (unsigned int i = 0; i < depth; ++i) - writer.write(indent[0], indent[1], indent[2], indent[3]); - break; - } - - default: - { - for (unsigned int i = 0; i < depth; ++i) - writer.write_buffer(indent, indent_length); - } - } - } - - PUGI__FN void node_output_comment(xml_buffered_writer& writer, const char_t* s) - { - writer.write('<', '!', '-', '-'); - - while (*s) - { - const char_t* prev = s; - - // look for -\0 or -- sequence - we can't output it since -- is illegal in comment body - while (*s && !(s[0] == '-' && (s[1] == '-' || s[1] == 0))) ++s; - - writer.write_buffer(prev, static_cast(s - prev)); - - if (*s) - { - assert(*s == '-'); - - writer.write('-', ' '); - ++s; - } - } - - writer.write('-', '-', '>'); - } - - PUGI__FN void node_output_pi_value(xml_buffered_writer& writer, const char_t* s) - { - while (*s) - { - const char_t* prev = s; - - // look for ?> sequence - we can't output it since ?> terminates PI - while (*s && !(s[0] == '?' && s[1] == '>')) ++s; - - writer.write_buffer(prev, static_cast(s - prev)); - - if (*s) - { - assert(s[0] == '?' && s[1] == '>'); - - writer.write('?', ' ', '>'); - s += 2; - } - } - } - - PUGI__FN void node_output_attributes(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) - { - const char_t* default_name = PUGIXML_TEXT(":anonymous"); - - for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) - { - writer.write(' '); - writer.write_string(a->name ? a->name : default_name); - writer.write('=', '"'); - - if (a->value) - text_output(writer, a->value, ctx_special_attr, flags); - - writer.write('"'); - } - } - - PUGI__FN bool node_output_start(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) - { - const char_t* default_name = PUGIXML_TEXT(":anonymous"); - const char_t* name = node->name ? node->name : default_name; - - writer.write('<'); - writer.write_string(name); - - if (node->first_attribute) - node_output_attributes(writer, node, flags); - - if (!node->first_child) - { - writer.write(' ', '/', '>'); - - return false; - } - else - { - writer.write('>'); - - return true; - } - } - - PUGI__FN void node_output_end(xml_buffered_writer& writer, xml_node_struct* node) - { - const char_t* default_name = PUGIXML_TEXT(":anonymous"); - const char_t* name = node->name ? node->name : default_name; - - writer.write('<', '/'); - writer.write_string(name); - writer.write('>'); - } - - PUGI__FN void node_output_simple(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) - { - const char_t* default_name = PUGIXML_TEXT(":anonymous"); - - switch (PUGI__NODETYPE(node)) - { - case node_pcdata: - text_output(writer, node->value ? node->value : PUGIXML_TEXT(""), ctx_special_pcdata, flags); - break; - - case node_cdata: - text_output_cdata(writer, node->value ? node->value : PUGIXML_TEXT("")); - break; - - case node_comment: - node_output_comment(writer, node->value ? node->value : PUGIXML_TEXT("")); - break; - - case node_pi: - writer.write('<', '?'); - writer.write_string(node->name ? node->name : default_name); - - if (node->value) - { - writer.write(' '); - node_output_pi_value(writer, node->value); - } - - writer.write('?', '>'); - break; - - case node_declaration: - writer.write('<', '?'); - writer.write_string(node->name ? node->name : default_name); - node_output_attributes(writer, node, flags); - writer.write('?', '>'); - break; - - case node_doctype: - writer.write('<', '!', 'D', 'O', 'C'); - writer.write('T', 'Y', 'P', 'E'); - - if (node->value) - { - writer.write(' '); - writer.write_string(node->value); - } - - writer.write('>'); - break; - - default: - assert(!"Invalid node type"); - } - } - - enum indent_flags_t - { - indent_newline = 1, - indent_indent = 2 - }; - - PUGI__FN void node_output(xml_buffered_writer& writer, xml_node_struct* root, const char_t* indent, unsigned int flags, unsigned int depth) - { - size_t indent_length = ((flags & (format_indent | format_raw)) == format_indent) ? strlength(indent) : 0; - unsigned int indent_flags = indent_indent; - - xml_node_struct* node = root; - - do - { - assert(node); - - // begin writing current node - if (PUGI__NODETYPE(node) == node_pcdata || PUGI__NODETYPE(node) == node_cdata) - { - node_output_simple(writer, node, flags); - - indent_flags = 0; - } - else - { - if ((indent_flags & indent_newline) && (flags & format_raw) == 0) - writer.write('\n'); - - if ((indent_flags & indent_indent) && indent_length) - text_output_indent(writer, indent, indent_length, depth); - - if (PUGI__NODETYPE(node) == node_element) - { - indent_flags = indent_newline | indent_indent; - - if (node_output_start(writer, node, flags)) - { - node = node->first_child; - depth++; - continue; - } - } - else if (PUGI__NODETYPE(node) == node_document) - { - indent_flags = indent_indent; - - if (node->first_child) - { - node = node->first_child; - continue; - } - } - else - { - node_output_simple(writer, node, flags); - - indent_flags = indent_newline | indent_indent; - } - } - - // continue to the next node - while (node != root) - { - if (node->next_sibling) - { - node = node->next_sibling; - break; - } - - node = node->parent; - - // write closing node - if (PUGI__NODETYPE(node) == node_element) - { - depth--; - - if ((indent_flags & indent_newline) && (flags & format_raw) == 0) - writer.write('\n'); - - if ((indent_flags & indent_indent) && indent_length) - text_output_indent(writer, indent, indent_length, depth); - - node_output_end(writer, node); - - indent_flags = indent_newline | indent_indent; - } - } - } - while (node != root); - - if ((indent_flags & indent_newline) && (flags & format_raw) == 0) - writer.write('\n'); - } - - PUGI__FN bool has_declaration(xml_node_struct* node) - { - for (xml_node_struct* child = node->first_child; child; child = child->next_sibling) - { - xml_node_type type = PUGI__NODETYPE(child); - - if (type == node_declaration) return true; - if (type == node_element) return false; - } - - return false; - } - - PUGI__FN bool is_attribute_of(xml_attribute_struct* attr, xml_node_struct* node) - { - for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) - if (a == attr) - return true; - - return false; - } - - PUGI__FN bool allow_insert_attribute(xml_node_type parent) - { - return parent == node_element || parent == node_declaration; - } - - PUGI__FN bool allow_insert_child(xml_node_type parent, xml_node_type child) - { - if (parent != node_document && parent != node_element) return false; - if (child == node_document || child == node_null) return false; - if (parent != node_document && (child == node_declaration || child == node_doctype)) return false; - - return true; - } - - PUGI__FN bool allow_move(xml_node parent, xml_node child) - { - // check that child can be a child of parent - if (!allow_insert_child(parent.type(), child.type())) - return false; - - // check that node is not moved between documents - if (parent.root() != child.root()) - return false; - - // check that new parent is not in the child subtree - xml_node cur = parent; - - while (cur) - { - if (cur == child) - return false; - - cur = cur.parent(); - } - - return true; - } - - PUGI__FN void node_copy_string(char_t*& dest, uintptr_t& header, uintptr_t header_mask, char_t* source, uintptr_t& source_header, xml_allocator* alloc) - { - assert(!dest && (header & header_mask) == 0); - - if (source) - { - if (alloc && (source_header & header_mask) == 0) - { - dest = source; - - // since strcpy_insitu can reuse document buffer memory we need to mark both source and dest as shared - header |= xml_memory_page_contents_shared_mask; - source_header |= xml_memory_page_contents_shared_mask; - } - else - strcpy_insitu(dest, header, header_mask, source); - } - } - - PUGI__FN void node_copy_contents(xml_node_struct* dn, xml_node_struct* sn, xml_allocator* shared_alloc) - { - node_copy_string(dn->name, dn->header, xml_memory_page_name_allocated_mask, sn->name, sn->header, shared_alloc); - node_copy_string(dn->value, dn->header, xml_memory_page_value_allocated_mask, sn->value, sn->header, shared_alloc); - - for (xml_attribute_struct* sa = sn->first_attribute; sa; sa = sa->next_attribute) - { - xml_attribute_struct* da = append_new_attribute(dn, get_allocator(dn)); - - if (da) - { - node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc); - node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc); - } - } - } - - PUGI__FN void node_copy_tree(xml_node_struct* dn, xml_node_struct* sn) - { - xml_allocator& alloc = get_allocator(dn); - xml_allocator* shared_alloc = (&alloc == &get_allocator(sn)) ? &alloc : 0; - - node_copy_contents(dn, sn, shared_alloc); - - xml_node_struct* dit = dn; - xml_node_struct* sit = sn->first_child; - - while (sit && sit != sn) - { - if (sit != dn) - { - xml_node_struct* copy = append_new_node(dit, alloc, PUGI__NODETYPE(sit)); - - if (copy) - { - node_copy_contents(copy, sit, shared_alloc); - - if (sit->first_child) - { - dit = copy; - sit = sit->first_child; - continue; - } - } - } - - // continue to the next node - do - { - if (sit->next_sibling) - { - sit = sit->next_sibling; - break; - } - - sit = sit->parent; - dit = dit->parent; - } - while (sit != sn); - } - } - - inline bool is_text_node(xml_node_struct* node) - { - xml_node_type type = PUGI__NODETYPE(node); - - return type == node_pcdata || type == node_cdata; - } - - // get value with conversion functions - PUGI__FN int get_integer_base(const char_t* value) - { - const char_t* s = value; - - while (PUGI__IS_CHARTYPE(*s, ct_space)) - s++; - - if (*s == '-') - s++; - - return (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10; - } - - PUGI__FN int get_value_int(const char_t* value, int def) - { - if (!value) return def; - - int base = get_integer_base(value); - - #ifdef PUGIXML_WCHAR_MODE - return static_cast(wcstol(value, 0, base)); - #else - return static_cast(strtol(value, 0, base)); - #endif - } - - PUGI__FN unsigned int get_value_uint(const char_t* value, unsigned int def) - { - if (!value) return def; - - int base = get_integer_base(value); - - #ifdef PUGIXML_WCHAR_MODE - return static_cast(wcstoul(value, 0, base)); - #else - return static_cast(strtoul(value, 0, base)); - #endif - } - - PUGI__FN double get_value_double(const char_t* value, double def) - { - if (!value) return def; - - #ifdef PUGIXML_WCHAR_MODE - return wcstod(value, 0); - #else - return strtod(value, 0); - #endif - } - - PUGI__FN float get_value_float(const char_t* value, float def) - { - if (!value) return def; - - #ifdef PUGIXML_WCHAR_MODE - return static_cast(wcstod(value, 0)); - #else - return static_cast(strtod(value, 0)); - #endif - } - - PUGI__FN bool get_value_bool(const char_t* value, bool def) - { - if (!value) return def; - - // only look at first char - char_t first = *value; - - // 1*, t* (true), T* (True), y* (yes), Y* (YES) - return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y'); - } - -#ifdef PUGIXML_HAS_LONG_LONG - PUGI__FN long long get_value_llong(const char_t* value, long long def) - { - if (!value) return def; - - int base = get_integer_base(value); - - #ifdef PUGIXML_WCHAR_MODE - #ifdef PUGI__MSVC_CRT_VERSION - return _wcstoi64(value, 0, base); - #else - return wcstoll(value, 0, base); - #endif - #else - #ifdef PUGI__MSVC_CRT_VERSION - return _strtoi64(value, 0, base); - #else - return strtoll(value, 0, base); - #endif - #endif - } - - PUGI__FN unsigned long long get_value_ullong(const char_t* value, unsigned long long def) - { - if (!value) return def; - - int base = get_integer_base(value); - - #ifdef PUGIXML_WCHAR_MODE - #ifdef PUGI__MSVC_CRT_VERSION - return _wcstoui64(value, 0, base); - #else - return wcstoull(value, 0, base); - #endif - #else - #ifdef PUGI__MSVC_CRT_VERSION - return _strtoui64(value, 0, base); - #else - return strtoull(value, 0, base); - #endif - #endif - } -#endif - - // set value with conversion functions - PUGI__FN bool set_value_buffer(char_t*& dest, uintptr_t& header, uintptr_t header_mask, char (&buf)[128]) - { - #ifdef PUGIXML_WCHAR_MODE - char_t wbuf[128]; - impl::widen_ascii(wbuf, buf); - - return strcpy_insitu(dest, header, header_mask, wbuf); - #else - return strcpy_insitu(dest, header, header_mask, buf); - #endif - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, int value) - { - char buf[128]; - sprintf(buf, "%d", value); - - return set_value_buffer(dest, header, header_mask, buf); - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned int value) - { - char buf[128]; - sprintf(buf, "%u", value); - - return set_value_buffer(dest, header, header_mask, buf); - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, float value) - { - char buf[128]; - sprintf(buf, "%.9g", value); - - return set_value_buffer(dest, header, header_mask, buf); - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, double value) - { - char buf[128]; - sprintf(buf, "%.17g", value); - - return set_value_buffer(dest, header, header_mask, buf); - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, bool value) - { - return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); - } - -#ifdef PUGIXML_HAS_LONG_LONG - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, long long value) - { - char buf[128]; - sprintf(buf, "%lld", value); - - return set_value_buffer(dest, header, header_mask, buf); - } - - PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned long long value) - { - char buf[128]; - sprintf(buf, "%llu", value); - - return set_value_buffer(dest, header, header_mask, buf); - } -#endif - - // we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick - PUGI__FN xml_parse_status get_file_size(FILE* file, size_t& out_result) - { - #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) - // there are 64-bit versions of fseek/ftell, let's use them - typedef __int64 length_type; - - _fseeki64(file, 0, SEEK_END); - length_type length = _ftelli64(file); - _fseeki64(file, 0, SEEK_SET); - #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR)) - // there are 64-bit versions of fseek/ftell, let's use them - typedef off64_t length_type; - - fseeko64(file, 0, SEEK_END); - length_type length = ftello64(file); - fseeko64(file, 0, SEEK_SET); - #else - // if this is a 32-bit OS, long is enough; if this is a unix system, long is 64-bit, which is enough; otherwise we can't do anything anyway. - typedef long length_type; - - fseek(file, 0, SEEK_END); - length_type length = ftell(file); - fseek(file, 0, SEEK_SET); - #endif - - // check for I/O errors - if (length < 0) return status_io_error; - - // check for overflow - size_t result = static_cast(length); - - if (static_cast(result) != length) return status_out_of_memory; - - // finalize - out_result = result; - - return status_ok; - } - - PUGI__FN size_t zero_terminate_buffer(void* buffer, size_t size, xml_encoding encoding) - { - // We only need to zero-terminate if encoding conversion does not do it for us - #ifdef PUGIXML_WCHAR_MODE - xml_encoding wchar_encoding = get_wchar_encoding(); - - if (encoding == wchar_encoding || need_endian_swap_utf(encoding, wchar_encoding)) - { - size_t length = size / sizeof(char_t); - - static_cast(buffer)[length] = 0; - return (length + 1) * sizeof(char_t); - } - #else - if (encoding == encoding_utf8) - { - static_cast(buffer)[size] = 0; - return size + 1; - } - #endif - - return size; - } - - PUGI__FN xml_parse_result load_file_impl(xml_document& doc, FILE* file, unsigned int options, xml_encoding encoding) - { - if (!file) return make_parse_result(status_file_not_found); - - // get file size (can result in I/O errors) - size_t size = 0; - xml_parse_status size_status = get_file_size(file, size); - - if (size_status != status_ok) - { - fclose(file); - return make_parse_result(size_status); - } - - size_t max_suffix_size = sizeof(char_t); - - // allocate buffer for the whole file - char* contents = static_cast(xml_memory::allocate(size + max_suffix_size)); - - if (!contents) - { - fclose(file); - return make_parse_result(status_out_of_memory); - } - - // read file in memory - size_t read_size = fread(contents, 1, size, file); - fclose(file); - - if (read_size != size) - { - xml_memory::deallocate(contents); - return make_parse_result(status_io_error); - } - - xml_encoding real_encoding = get_buffer_encoding(encoding, contents, size); - - return doc.load_buffer_inplace_own(contents, zero_terminate_buffer(contents, size, real_encoding), options, real_encoding); - } - -#ifndef PUGIXML_NO_STL - template struct xml_stream_chunk - { - static xml_stream_chunk* create() - { - void* memory = xml_memory::allocate(sizeof(xml_stream_chunk)); - - return new (memory) xml_stream_chunk(); - } - - static void destroy(void* ptr) - { - xml_stream_chunk* chunk = static_cast(ptr); - - // free chunk chain - while (chunk) - { - xml_stream_chunk* next_ = chunk->next; - - xml_memory::deallocate(chunk); - - chunk = next_; - } - } - - xml_stream_chunk(): next(0), size(0) - { - } - - xml_stream_chunk* next; - size_t size; - - T data[xml_memory_page_size / sizeof(T)]; - }; - - template PUGI__FN xml_parse_status load_stream_data_noseek(std::basic_istream& stream, void** out_buffer, size_t* out_size) - { - buffer_holder chunks(0, xml_stream_chunk::destroy); - - // read file to a chunk list - size_t total = 0; - xml_stream_chunk* last = 0; - - while (!stream.eof()) - { - // allocate new chunk - xml_stream_chunk* chunk = xml_stream_chunk::create(); - if (!chunk) return status_out_of_memory; - - // append chunk to list - if (last) last = last->next = chunk; - else chunks.data = last = chunk; - - // read data to chunk - stream.read(chunk->data, static_cast(sizeof(chunk->data) / sizeof(T))); - chunk->size = static_cast(stream.gcount()) * sizeof(T); - - // read may set failbit | eofbit in case gcount() is less than read length, so check for other I/O errors - if (stream.bad() || (!stream.eof() && stream.fail())) return status_io_error; - - // guard against huge files (chunk size is small enough to make this overflow check work) - if (total + chunk->size < total) return status_out_of_memory; - total += chunk->size; - } - - size_t max_suffix_size = sizeof(char_t); - - // copy chunk list to a contiguous buffer - char* buffer = static_cast(xml_memory::allocate(total + max_suffix_size)); - if (!buffer) return status_out_of_memory; - - char* write = buffer; - - for (xml_stream_chunk* chunk = static_cast*>(chunks.data); chunk; chunk = chunk->next) - { - assert(write + chunk->size <= buffer + total); - memcpy(write, chunk->data, chunk->size); - write += chunk->size; - } - - assert(write == buffer + total); - - // return buffer - *out_buffer = buffer; - *out_size = total; - - return status_ok; - } - - template PUGI__FN xml_parse_status load_stream_data_seek(std::basic_istream& stream, void** out_buffer, size_t* out_size) - { - // get length of remaining data in stream - typename std::basic_istream::pos_type pos = stream.tellg(); - stream.seekg(0, std::ios::end); - std::streamoff length = stream.tellg() - pos; - stream.seekg(pos); - - if (stream.fail() || pos < 0) return status_io_error; - - // guard against huge files - size_t read_length = static_cast(length); - - if (static_cast(read_length) != length || length < 0) return status_out_of_memory; - - size_t max_suffix_size = sizeof(char_t); - - // read stream data into memory (guard against stream exceptions with buffer holder) - buffer_holder buffer(xml_memory::allocate(read_length * sizeof(T) + max_suffix_size), xml_memory::deallocate); - if (!buffer.data) return status_out_of_memory; - - stream.read(static_cast(buffer.data), static_cast(read_length)); - - // read may set failbit | eofbit in case gcount() is less than read_length (i.e. line ending conversion), so check for other I/O errors - if (stream.bad() || (!stream.eof() && stream.fail())) return status_io_error; - - // return buffer - size_t actual_length = static_cast(stream.gcount()); - assert(actual_length <= read_length); - - *out_buffer = buffer.release(); - *out_size = actual_length * sizeof(T); - - return status_ok; - } - - template PUGI__FN xml_parse_result load_stream_impl(xml_document& doc, std::basic_istream& stream, unsigned int options, xml_encoding encoding) - { - void* buffer = 0; - size_t size = 0; - xml_parse_status status = status_ok; - - // if stream has an error bit set, bail out (otherwise tellg() can fail and we'll clear error bits) - if (stream.fail()) return make_parse_result(status_io_error); - - // load stream to memory (using seek-based implementation if possible, since it's faster and takes less memory) - if (stream.tellg() < 0) - { - stream.clear(); // clear error flags that could be set by a failing tellg - status = load_stream_data_noseek(stream, &buffer, &size); - } - else - status = load_stream_data_seek(stream, &buffer, &size); - - if (status != status_ok) return make_parse_result(status); - - xml_encoding real_encoding = get_buffer_encoding(encoding, buffer, size); - - return doc.load_buffer_inplace_own(buffer, zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding); - } -#endif - -#if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))) - PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) - { - return _wfopen(path, mode); - } -#else - PUGI__FN char* convert_path_heap(const wchar_t* str) - { - assert(str); - - // first pass: get length in utf8 characters - size_t length = strlength_wide(str); - size_t size = as_utf8_begin(str, length); - - // allocate resulting string - char* result = static_cast(xml_memory::allocate(size + 1)); - if (!result) return 0; - - // second pass: convert to utf8 - as_utf8_end(result, size, str, length); - - return result; - } - - PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) - { - // there is no standard function to open wide paths, so our best bet is to try utf8 path - char* path_utf8 = convert_path_heap(path); - if (!path_utf8) return 0; - - // convert mode to ASCII (we mirror _wfopen interface) - char mode_ascii[4] = {0}; - for (size_t i = 0; mode[i]; ++i) mode_ascii[i] = static_cast(mode[i]); - - // try to open the utf8 path - FILE* result = fopen(path_utf8, mode_ascii); - - // free dummy buffer - xml_memory::deallocate(path_utf8); - - return result; - } -#endif - - PUGI__FN bool save_file_impl(const xml_document& doc, FILE* file, const char_t* indent, unsigned int flags, xml_encoding encoding) - { - if (!file) return false; - - xml_writer_file writer(file); - doc.save(writer, indent, flags, encoding); - - int result = ferror(file); - - fclose(file); - - return result == 0; - } - - PUGI__FN xml_parse_result load_buffer_impl(xml_document_struct* doc, xml_node_struct* root, void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own, char_t** out_buffer) - { - // check input buffer - if (!contents && size) return make_parse_result(status_io_error); - - // get actual encoding - xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size); - - // get private buffer - char_t* buffer = 0; - size_t length = 0; - - if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); - - // delete original buffer if we performed a conversion - if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents); - - // store buffer for offset_debug - doc->buffer = buffer; - - // parse - xml_parse_result res = impl::xml_parser::parse(buffer, length, doc, root, options); - - // remember encoding - res.encoding = buffer_encoding; - - // grab onto buffer if it's our buffer, user is responsible for deallocating contents himself - if (own || buffer != contents) *out_buffer = buffer; - - return res; - } -PUGI__NS_END - -namespace pugi -{ - PUGI__FN xml_writer_file::xml_writer_file(void* file_): file(file_) - { - } - - PUGI__FN void xml_writer_file::write(const void* data, size_t size) - { - size_t result = fwrite(data, 1, size, static_cast(file)); - (void)!result; // unfortunately we can't do proper error handling here - } - -#ifndef PUGIXML_NO_STL - PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(&stream), wide_stream(0) - { - } - - PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream >& stream): narrow_stream(0), wide_stream(&stream) - { - } - - PUGI__FN void xml_writer_stream::write(const void* data, size_t size) - { - if (narrow_stream) - { - assert(!wide_stream); - narrow_stream->write(reinterpret_cast(data), static_cast(size)); - } - else - { - assert(wide_stream); - assert(size % sizeof(wchar_t) == 0); - - wide_stream->write(reinterpret_cast(data), static_cast(size / sizeof(wchar_t))); - } - } -#endif - - PUGI__FN xml_tree_walker::xml_tree_walker(): _depth(0) - { - } - - PUGI__FN xml_tree_walker::~xml_tree_walker() - { - } - - PUGI__FN int xml_tree_walker::depth() const - { - return _depth; - } - - PUGI__FN bool xml_tree_walker::begin(xml_node&) - { - return true; - } - - PUGI__FN bool xml_tree_walker::end(xml_node&) - { - return true; - } - - PUGI__FN xml_attribute::xml_attribute(): _attr(0) - { - } - - PUGI__FN xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr) - { - } - - PUGI__FN static void unspecified_bool_xml_attribute(xml_attribute***) - { - } - - PUGI__FN xml_attribute::operator xml_attribute::unspecified_bool_type() const - { - return _attr ? unspecified_bool_xml_attribute : 0; - } - - PUGI__FN bool xml_attribute::operator!() const - { - return !_attr; - } - - PUGI__FN bool xml_attribute::operator==(const xml_attribute& r) const - { - return (_attr == r._attr); - } - - PUGI__FN bool xml_attribute::operator!=(const xml_attribute& r) const - { - return (_attr != r._attr); - } - - PUGI__FN bool xml_attribute::operator<(const xml_attribute& r) const - { - return (_attr < r._attr); - } - - PUGI__FN bool xml_attribute::operator>(const xml_attribute& r) const - { - return (_attr > r._attr); - } - - PUGI__FN bool xml_attribute::operator<=(const xml_attribute& r) const - { - return (_attr <= r._attr); - } - - PUGI__FN bool xml_attribute::operator>=(const xml_attribute& r) const - { - return (_attr >= r._attr); - } - - PUGI__FN xml_attribute xml_attribute::next_attribute() const - { - return _attr ? xml_attribute(_attr->next_attribute) : xml_attribute(); - } - - PUGI__FN xml_attribute xml_attribute::previous_attribute() const - { - return _attr && _attr->prev_attribute_c->next_attribute ? xml_attribute(_attr->prev_attribute_c) : xml_attribute(); - } - - PUGI__FN const char_t* xml_attribute::as_string(const char_t* def) const - { - return (_attr && _attr->value) ? _attr->value : def; - } - - PUGI__FN int xml_attribute::as_int(int def) const - { - return impl::get_value_int(_attr ? _attr->value : 0, def); - } - - PUGI__FN unsigned int xml_attribute::as_uint(unsigned int def) const - { - return impl::get_value_uint(_attr ? _attr->value : 0, def); - } - - PUGI__FN double xml_attribute::as_double(double def) const - { - return impl::get_value_double(_attr ? _attr->value : 0, def); - } - - PUGI__FN float xml_attribute::as_float(float def) const - { - return impl::get_value_float(_attr ? _attr->value : 0, def); - } - - PUGI__FN bool xml_attribute::as_bool(bool def) const - { - return impl::get_value_bool(_attr ? _attr->value : 0, def); - } - -#ifdef PUGIXML_HAS_LONG_LONG - PUGI__FN long long xml_attribute::as_llong(long long def) const - { - return impl::get_value_llong(_attr ? _attr->value : 0, def); - } - - PUGI__FN unsigned long long xml_attribute::as_ullong(unsigned long long def) const - { - return impl::get_value_ullong(_attr ? _attr->value : 0, def); - } -#endif - - PUGI__FN bool xml_attribute::empty() const - { - return !_attr; - } - - PUGI__FN const char_t* xml_attribute::name() const - { - return (_attr && _attr->name) ? _attr->name : PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* xml_attribute::value() const - { - return (_attr && _attr->value) ? _attr->value : PUGIXML_TEXT(""); - } - - PUGI__FN size_t xml_attribute::hash_value() const - { - return static_cast(reinterpret_cast(_attr) / sizeof(xml_attribute_struct)); - } - - PUGI__FN xml_attribute_struct* xml_attribute::internal_object() const - { - return _attr; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(const char_t* rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(int rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(unsigned int rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(double rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(float rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(bool rhs) - { - set_value(rhs); - return *this; - } - -#ifdef PUGIXML_HAS_LONG_LONG - PUGI__FN xml_attribute& xml_attribute::operator=(long long rhs) - { - set_value(rhs); - return *this; - } - - PUGI__FN xml_attribute& xml_attribute::operator=(unsigned long long rhs) - { - set_value(rhs); - return *this; - } -#endif - - PUGI__FN bool xml_attribute::set_name(const char_t* rhs) - { - if (!_attr) return false; - - return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(const char_t* rhs) - { - if (!_attr) return false; - - return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(int rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(unsigned int rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(double rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(float rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(bool rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - -#ifdef PUGIXML_HAS_LONG_LONG - PUGI__FN bool xml_attribute::set_value(long long rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } - - PUGI__FN bool xml_attribute::set_value(unsigned long long rhs) - { - if (!_attr) return false; - - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); - } -#endif - -#ifdef __BORLANDC__ - PUGI__FN bool operator&&(const xml_attribute& lhs, bool rhs) - { - return (bool)lhs && rhs; - } - - PUGI__FN bool operator||(const xml_attribute& lhs, bool rhs) - { - return (bool)lhs || rhs; - } -#endif - - PUGI__FN xml_node::xml_node(): _root(0) - { - } - - PUGI__FN xml_node::xml_node(xml_node_struct* p): _root(p) - { - } - - PUGI__FN static void unspecified_bool_xml_node(xml_node***) - { - } - - PUGI__FN xml_node::operator xml_node::unspecified_bool_type() const - { - return _root ? unspecified_bool_xml_node : 0; - } - - PUGI__FN bool xml_node::operator!() const - { - return !_root; - } - - PUGI__FN xml_node::iterator xml_node::begin() const - { - return iterator(_root ? _root->first_child : 0, _root); - } - - PUGI__FN xml_node::iterator xml_node::end() const - { - return iterator(0, _root); - } - - PUGI__FN xml_node::attribute_iterator xml_node::attributes_begin() const - { - return attribute_iterator(_root ? _root->first_attribute : 0, _root); - } - - PUGI__FN xml_node::attribute_iterator xml_node::attributes_end() const - { - return attribute_iterator(0, _root); - } - - PUGI__FN xml_object_range xml_node::children() const - { - return xml_object_range(begin(), end()); - } - - PUGI__FN xml_object_range xml_node::children(const char_t* name_) const - { - return xml_object_range(xml_named_node_iterator(child(name_)._root, _root, name_), xml_named_node_iterator(0, _root, name_)); - } - - PUGI__FN xml_object_range xml_node::attributes() const - { - return xml_object_range(attributes_begin(), attributes_end()); - } - - PUGI__FN bool xml_node::operator==(const xml_node& r) const - { - return (_root == r._root); - } - - PUGI__FN bool xml_node::operator!=(const xml_node& r) const - { - return (_root != r._root); - } - - PUGI__FN bool xml_node::operator<(const xml_node& r) const - { - return (_root < r._root); - } - - PUGI__FN bool xml_node::operator>(const xml_node& r) const - { - return (_root > r._root); - } - - PUGI__FN bool xml_node::operator<=(const xml_node& r) const - { - return (_root <= r._root); - } - - PUGI__FN bool xml_node::operator>=(const xml_node& r) const - { - return (_root >= r._root); - } - - PUGI__FN bool xml_node::empty() const - { - return !_root; - } - - PUGI__FN const char_t* xml_node::name() const - { - return (_root && _root->name) ? _root->name : PUGIXML_TEXT(""); - } - - PUGI__FN xml_node_type xml_node::type() const - { - return _root ? PUGI__NODETYPE(_root) : node_null; - } - - PUGI__FN const char_t* xml_node::value() const - { - return (_root && _root->value) ? _root->value : PUGIXML_TEXT(""); - } - - PUGI__FN xml_node xml_node::child(const char_t* name_) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->name && impl::strequal(name_, i->name)) return xml_node(i); - - return xml_node(); - } - - PUGI__FN xml_attribute xml_node::attribute(const char_t* name_) const - { - if (!_root) return xml_attribute(); - - for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) - if (i->name && impl::strequal(name_, i->name)) - return xml_attribute(i); - - return xml_attribute(); - } - - PUGI__FN xml_node xml_node::next_sibling(const char_t* name_) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling) - if (i->name && impl::strequal(name_, i->name)) return xml_node(i); - - return xml_node(); - } - - PUGI__FN xml_node xml_node::next_sibling() const - { - return _root ? xml_node(_root->next_sibling) : xml_node(); - } - - PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c) - if (i->name && impl::strequal(name_, i->name)) return xml_node(i); - - return xml_node(); - } - - PUGI__FN xml_node xml_node::previous_sibling() const - { - if (!_root) return xml_node(); - - if (_root->prev_sibling_c->next_sibling) return xml_node(_root->prev_sibling_c); - else return xml_node(); - } - - PUGI__FN xml_node xml_node::parent() const - { - return _root ? xml_node(_root->parent) : xml_node(); - } - - PUGI__FN xml_node xml_node::root() const - { - return _root ? xml_node(&impl::get_document(_root)) : xml_node(); - } - - PUGI__FN xml_text xml_node::text() const - { - return xml_text(_root); - } - - PUGI__FN const char_t* xml_node::child_value() const - { - if (!_root) return PUGIXML_TEXT(""); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->value && impl::is_text_node(i)) - return i->value; - - return PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* xml_node::child_value(const char_t* name_) const - { - return child(name_).child_value(); - } - - PUGI__FN xml_attribute xml_node::first_attribute() const - { - return _root ? xml_attribute(_root->first_attribute) : xml_attribute(); - } - - PUGI__FN xml_attribute xml_node::last_attribute() const - { - return _root && _root->first_attribute ? xml_attribute(_root->first_attribute->prev_attribute_c) : xml_attribute(); - } - - PUGI__FN xml_node xml_node::first_child() const - { - return _root ? xml_node(_root->first_child) : xml_node(); - } - - PUGI__FN xml_node xml_node::last_child() const - { - return _root && _root->first_child ? xml_node(_root->first_child->prev_sibling_c) : xml_node(); - } - - PUGI__FN bool xml_node::set_name(const char_t* rhs) - { - switch (type()) - { - case node_pi: - case node_declaration: - case node_element: - return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs); - - default: - return false; - } - } - - PUGI__FN bool xml_node::set_value(const char_t* rhs) - { - switch (type()) - { - case node_pi: - case node_cdata: - case node_pcdata: - case node_comment: - case node_doctype: - return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs); - - default: - return false; - } - } - - PUGI__FN xml_attribute xml_node::append_attribute(const char_t* name_) - { - if (!impl::allow_insert_attribute(type())) return xml_attribute(); - - xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); - if (!a) return xml_attribute(); - - impl::append_attribute(a._attr, _root); - - a.set_name(name_); - - return a; - } - - PUGI__FN xml_attribute xml_node::prepend_attribute(const char_t* name_) - { - if (!impl::allow_insert_attribute(type())) return xml_attribute(); - - xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); - if (!a) return xml_attribute(); - - impl::prepend_attribute(a._attr, _root); - - a.set_name(name_); - - return a; - } - - PUGI__FN xml_attribute xml_node::insert_attribute_after(const char_t* name_, const xml_attribute& attr) - { - if (!impl::allow_insert_attribute(type())) return xml_attribute(); - if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); - - xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); - if (!a) return xml_attribute(); - - impl::insert_attribute_after(a._attr, attr._attr, _root); - - a.set_name(name_); - - return a; - } - - PUGI__FN xml_attribute xml_node::insert_attribute_before(const char_t* name_, const xml_attribute& attr) - { - if (!impl::allow_insert_attribute(type())) return xml_attribute(); - if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); - - xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); - if (!a) return xml_attribute(); - - impl::insert_attribute_before(a._attr, attr._attr, _root); - - a.set_name(name_); - - return a; - } - - PUGI__FN xml_attribute xml_node::append_copy(const xml_attribute& proto) - { - if (!proto) return xml_attribute(); - - xml_attribute result = append_attribute(proto.name()); - result.set_value(proto.value()); - - return result; - } - - PUGI__FN xml_attribute xml_node::prepend_copy(const xml_attribute& proto) - { - if (!proto) return xml_attribute(); - - xml_attribute result = prepend_attribute(proto.name()); - result.set_value(proto.value()); - - return result; - } - - PUGI__FN xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr) - { - if (!proto) return xml_attribute(); - - xml_attribute result = insert_attribute_after(proto.name(), attr); - result.set_value(proto.value()); - - return result; - } - - PUGI__FN xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr) - { - if (!proto) return xml_attribute(); - - xml_attribute result = insert_attribute_before(proto.name(), attr); - result.set_value(proto.value()); - - return result; - } - - PUGI__FN xml_node xml_node::append_child(xml_node_type type_) - { - if (!impl::allow_insert_child(type(), type_)) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - impl::append_node(n._root, _root); - - if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); - - return n; - } - - PUGI__FN xml_node xml_node::prepend_child(xml_node_type type_) - { - if (!impl::allow_insert_child(type(), type_)) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - impl::prepend_node(n._root, _root); - - if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); - - return n; - } - - PUGI__FN xml_node xml_node::insert_child_before(xml_node_type type_, const xml_node& node) - { - if (!impl::allow_insert_child(type(), type_)) return xml_node(); - if (!node._root || node._root->parent != _root) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - impl::insert_node_before(n._root, node._root); - - if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); - - return n; - } - - PUGI__FN xml_node xml_node::insert_child_after(xml_node_type type_, const xml_node& node) - { - if (!impl::allow_insert_child(type(), type_)) return xml_node(); - if (!node._root || node._root->parent != _root) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - impl::insert_node_after(n._root, node._root); - - if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); - - return n; - } - - PUGI__FN xml_node xml_node::append_child(const char_t* name_) - { - xml_node result = append_child(node_element); - - result.set_name(name_); - - return result; - } - - PUGI__FN xml_node xml_node::prepend_child(const char_t* name_) - { - xml_node result = prepend_child(node_element); - - result.set_name(name_); - - return result; - } - - PUGI__FN xml_node xml_node::insert_child_after(const char_t* name_, const xml_node& node) - { - xml_node result = insert_child_after(node_element, node); - - result.set_name(name_); - - return result; - } - - PUGI__FN xml_node xml_node::insert_child_before(const char_t* name_, const xml_node& node) - { - xml_node result = insert_child_before(node_element, node); - - result.set_name(name_); - - return result; - } - - PUGI__FN xml_node xml_node::append_copy(const xml_node& proto) - { - xml_node_type type_ = proto.type(); - if (!impl::allow_insert_child(type(), type_)) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - impl::append_node(n._root, _root); - impl::node_copy_tree(n._root, proto._root); - - return n; - } - - PUGI__FN xml_node xml_node::prepend_copy(const xml_node& proto) - { - xml_node_type type_ = proto.type(); - if (!impl::allow_insert_child(type(), type_)) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - impl::prepend_node(n._root, _root); - impl::node_copy_tree(n._root, proto._root); - - return n; - } - - PUGI__FN xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node) - { - xml_node_type type_ = proto.type(); - if (!impl::allow_insert_child(type(), type_)) return xml_node(); - if (!node._root || node._root->parent != _root) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - impl::insert_node_after(n._root, node._root); - impl::node_copy_tree(n._root, proto._root); - - return n; - } - - PUGI__FN xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node) - { - xml_node_type type_ = proto.type(); - if (!impl::allow_insert_child(type(), type_)) return xml_node(); - if (!node._root || node._root->parent != _root) return xml_node(); - - xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); - if (!n) return xml_node(); - - impl::insert_node_before(n._root, node._root); - impl::node_copy_tree(n._root, proto._root); - - return n; - } - - PUGI__FN xml_node xml_node::append_move(const xml_node& moved) - { - if (!impl::allow_move(*this, moved)) return xml_node(); - - // disable document_buffer_order optimization since moving nodes around changes document order without changing buffer pointers - impl::get_document(_root).header |= impl::xml_memory_page_contents_shared_mask; - - impl::remove_node(moved._root); - impl::append_node(moved._root, _root); - - return moved; - } - - PUGI__FN xml_node xml_node::prepend_move(const xml_node& moved) - { - if (!impl::allow_move(*this, moved)) return xml_node(); - - // disable document_buffer_order optimization since moving nodes around changes document order without changing buffer pointers - impl::get_document(_root).header |= impl::xml_memory_page_contents_shared_mask; - - impl::remove_node(moved._root); - impl::prepend_node(moved._root, _root); - - return moved; - } - - PUGI__FN xml_node xml_node::insert_move_after(const xml_node& moved, const xml_node& node) - { - if (!impl::allow_move(*this, moved)) return xml_node(); - if (!node._root || node._root->parent != _root) return xml_node(); - if (moved._root == node._root) return xml_node(); - - // disable document_buffer_order optimization since moving nodes around changes document order without changing buffer pointers - impl::get_document(_root).header |= impl::xml_memory_page_contents_shared_mask; - - impl::remove_node(moved._root); - impl::insert_node_after(moved._root, node._root); - - return moved; - } - - PUGI__FN xml_node xml_node::insert_move_before(const xml_node& moved, const xml_node& node) - { - if (!impl::allow_move(*this, moved)) return xml_node(); - if (!node._root || node._root->parent != _root) return xml_node(); - if (moved._root == node._root) return xml_node(); - - // disable document_buffer_order optimization since moving nodes around changes document order without changing buffer pointers - impl::get_document(_root).header |= impl::xml_memory_page_contents_shared_mask; - - impl::remove_node(moved._root); - impl::insert_node_before(moved._root, node._root); - - return moved; - } - - PUGI__FN bool xml_node::remove_attribute(const char_t* name_) - { - return remove_attribute(attribute(name_)); - } - - PUGI__FN bool xml_node::remove_attribute(const xml_attribute& a) - { - if (!_root || !a._attr) return false; - if (!impl::is_attribute_of(a._attr, _root)) return false; - - impl::remove_attribute(a._attr, _root); - impl::destroy_attribute(a._attr, impl::get_allocator(_root)); - - return true; - } - - PUGI__FN bool xml_node::remove_child(const char_t* name_) - { - return remove_child(child(name_)); - } - - PUGI__FN bool xml_node::remove_child(const xml_node& n) - { - if (!_root || !n._root || n._root->parent != _root) return false; - - impl::remove_node(n._root); - impl::destroy_node(n._root, impl::get_allocator(_root)); - - return true; - } - - PUGI__FN xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) - { - // append_buffer is only valid for elements/documents - if (!impl::allow_insert_child(type(), node_element)) return impl::make_parse_result(status_append_invalid_root); - - // get document node - impl::xml_document_struct* doc = &impl::get_document(_root); - - // disable document_buffer_order optimization since in a document with multiple buffers comparing buffer pointers does not make sense - doc->header |= impl::xml_memory_page_contents_shared_mask; - - // get extra buffer element (we'll store the document fragment buffer there so that we can deallocate it later) - impl::xml_memory_page* page = 0; - impl::xml_extra_buffer* extra = static_cast(doc->allocate_memory(sizeof(impl::xml_extra_buffer), page)); - (void)page; - - if (!extra) return impl::make_parse_result(status_out_of_memory); - - // save name; name of the root has to be NULL before parsing - otherwise closing node mismatches will not be detected at the top level - char_t* rootname = _root->name; - _root->name = 0; - - // parse - char_t* buffer = 0; - xml_parse_result res = impl::load_buffer_impl(doc, _root, const_cast(contents), size, options, encoding, false, false, &buffer); - - // restore name - _root->name = rootname; - - // add extra buffer to the list - extra->buffer = buffer; - extra->next = doc->extra_buffers; - doc->extra_buffers = extra; - - return res; - } - - PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* name_, const char_t* attr_name, const char_t* attr_value) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (i->name && impl::strequal(name_, i->name)) - { - for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) - if (a->name && impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value ? a->value : PUGIXML_TEXT(""))) - return xml_node(i); - } - - return xml_node(); - } - - PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const - { - if (!_root) return xml_node(); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) - if (a->name && impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value ? a->value : PUGIXML_TEXT(""))) - return xml_node(i); - - return xml_node(); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN string_t xml_node::path(char_t delimiter) const - { - xml_node cursor = *this; // Make a copy. - - string_t result = cursor.name(); - - while (cursor.parent()) - { - cursor = cursor.parent(); - - string_t temp = cursor.name(); - temp += delimiter; - temp += result; - result.swap(temp); - } - - return result; - } -#endif - - PUGI__FN xml_node xml_node::first_element_by_path(const char_t* path_, char_t delimiter) const - { - xml_node found = *this; // Current search context. - - if (!_root || !path_ || !path_[0]) return found; - - if (path_[0] == delimiter) - { - // Absolute path; e.g. '/foo/bar' - found = found.root(); - ++path_; - } - - const char_t* path_segment = path_; - - while (*path_segment == delimiter) ++path_segment; - - const char_t* path_segment_end = path_segment; - - while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end; - - if (path_segment == path_segment_end) return found; - - const char_t* next_segment = path_segment_end; - - while (*next_segment == delimiter) ++next_segment; - - if (*path_segment == '.' && path_segment + 1 == path_segment_end) - return found.first_element_by_path(next_segment, delimiter); - else if (*path_segment == '.' && *(path_segment+1) == '.' && path_segment + 2 == path_segment_end) - return found.parent().first_element_by_path(next_segment, delimiter); - else - { - for (xml_node_struct* j = found._root->first_child; j; j = j->next_sibling) - { - if (j->name && impl::strequalrange(j->name, path_segment, static_cast(path_segment_end - path_segment))) - { - xml_node subsearch = xml_node(j).first_element_by_path(next_segment, delimiter); - - if (subsearch) return subsearch; - } - } - - return xml_node(); - } - } - - PUGI__FN bool xml_node::traverse(xml_tree_walker& walker) - { - walker._depth = -1; - - xml_node arg_begin = *this; - if (!walker.begin(arg_begin)) return false; - - xml_node cur = first_child(); - - if (cur) - { - ++walker._depth; - - do - { - xml_node arg_for_each = cur; - if (!walker.for_each(arg_for_each)) - return false; - - if (cur.first_child()) - { - ++walker._depth; - cur = cur.first_child(); - } - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - // Borland C++ workaround - while (!cur.next_sibling() && cur != *this && !cur.parent().empty()) - { - --walker._depth; - cur = cur.parent(); - } - - if (cur != *this) - cur = cur.next_sibling(); - } - } - while (cur && cur != *this); - } - - assert(walker._depth == -1); - - xml_node arg_end = *this; - return walker.end(arg_end); - } - - PUGI__FN size_t xml_node::hash_value() const - { - return static_cast(reinterpret_cast(_root) / sizeof(xml_node_struct)); - } - - PUGI__FN xml_node_struct* xml_node::internal_object() const - { - return _root; - } - - PUGI__FN void xml_node::print(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const - { - if (!_root) return; - - impl::xml_buffered_writer buffered_writer(writer, encoding); - - impl::node_output(buffered_writer, _root, indent, flags, depth); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const - { - xml_writer_stream writer(stream); - - print(writer, indent, flags, encoding, depth); - } - - PUGI__FN void xml_node::print(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, unsigned int depth) const - { - xml_writer_stream writer(stream); - - print(writer, indent, flags, encoding_wchar, depth); - } -#endif - - PUGI__FN ptrdiff_t xml_node::offset_debug() const - { - if (!_root) return -1; - - impl::xml_document_struct& doc = impl::get_document(_root); - - // we can determine the offset reliably only if there is exactly once parse buffer - if (!doc.buffer || doc.extra_buffers) return -1; - - switch (type()) - { - case node_document: - return 0; - - case node_element: - case node_declaration: - case node_pi: - return _root->name && (_root->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0 ? _root->name - doc.buffer : -1; - - case node_pcdata: - case node_cdata: - case node_comment: - case node_doctype: - return _root->value && (_root->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0 ? _root->value - doc.buffer : -1; - - default: - return -1; - } - } - -#ifdef __BORLANDC__ - PUGI__FN bool operator&&(const xml_node& lhs, bool rhs) - { - return (bool)lhs && rhs; - } - - PUGI__FN bool operator||(const xml_node& lhs, bool rhs) - { - return (bool)lhs || rhs; - } -#endif - - PUGI__FN xml_text::xml_text(xml_node_struct* root): _root(root) - { - } - - PUGI__FN xml_node_struct* xml_text::_data() const - { - if (!_root || impl::is_text_node(_root)) return _root; - - for (xml_node_struct* node = _root->first_child; node; node = node->next_sibling) - if (impl::is_text_node(node)) - return node; - - return 0; - } - - PUGI__FN xml_node_struct* xml_text::_data_new() - { - xml_node_struct* d = _data(); - if (d) return d; - - return xml_node(_root).append_child(node_pcdata).internal_object(); - } - - PUGI__FN xml_text::xml_text(): _root(0) - { - } - - PUGI__FN static void unspecified_bool_xml_text(xml_text***) - { - } - - PUGI__FN xml_text::operator xml_text::unspecified_bool_type() const - { - return _data() ? unspecified_bool_xml_text : 0; - } - - PUGI__FN bool xml_text::operator!() const - { - return !_data(); - } - - PUGI__FN bool xml_text::empty() const - { - return _data() == 0; - } - - PUGI__FN const char_t* xml_text::get() const - { - xml_node_struct* d = _data(); - - return (d && d->value) ? d->value : PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* xml_text::as_string(const char_t* def) const - { - xml_node_struct* d = _data(); - - return (d && d->value) ? d->value : def; - } - - PUGI__FN int xml_text::as_int(int def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_int(d ? d->value : 0, def); - } - - PUGI__FN unsigned int xml_text::as_uint(unsigned int def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_uint(d ? d->value : 0, def); - } - - PUGI__FN double xml_text::as_double(double def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_double(d ? d->value : 0, def); - } - - PUGI__FN float xml_text::as_float(float def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_float(d ? d->value : 0, def); - } - - PUGI__FN bool xml_text::as_bool(bool def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_bool(d ? d->value : 0, def); - } - -#ifdef PUGIXML_HAS_LONG_LONG - PUGI__FN long long xml_text::as_llong(long long def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_llong(d ? d->value : 0, def); - } - - PUGI__FN unsigned long long xml_text::as_ullong(unsigned long long def) const - { - xml_node_struct* d = _data(); - - return impl::get_value_ullong(d ? d->value : 0, def); - } -#endif - - PUGI__FN bool xml_text::set(const char_t* rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(int rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(unsigned int rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(float rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(double rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(bool rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - -#ifdef PUGIXML_HAS_LONG_LONG - PUGI__FN bool xml_text::set(long long rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } - - PUGI__FN bool xml_text::set(unsigned long long rhs) - { - xml_node_struct* dn = _data_new(); - - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; - } -#endif - - PUGI__FN xml_text& xml_text::operator=(const char_t* rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(int rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(unsigned int rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(double rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(float rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(bool rhs) - { - set(rhs); - return *this; - } - -#ifdef PUGIXML_HAS_LONG_LONG - PUGI__FN xml_text& xml_text::operator=(long long rhs) - { - set(rhs); - return *this; - } - - PUGI__FN xml_text& xml_text::operator=(unsigned long long rhs) - { - set(rhs); - return *this; - } -#endif - - PUGI__FN xml_node xml_text::data() const - { - return xml_node(_data()); - } - -#ifdef __BORLANDC__ - PUGI__FN bool operator&&(const xml_text& lhs, bool rhs) - { - return (bool)lhs && rhs; - } - - PUGI__FN bool operator||(const xml_text& lhs, bool rhs) - { - return (bool)lhs || rhs; - } -#endif - - PUGI__FN xml_node_iterator::xml_node_iterator() - { - } - - PUGI__FN xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node), _parent(node.parent()) - { - } - - PUGI__FN xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) - { - } - - PUGI__FN bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const - { - return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; - } - - PUGI__FN bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const - { - return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; - } - - PUGI__FN xml_node& xml_node_iterator::operator*() const - { - assert(_wrap._root); - return _wrap; - } - - PUGI__FN xml_node* xml_node_iterator::operator->() const - { - assert(_wrap._root); - return const_cast(&_wrap); // BCC32 workaround - } - - PUGI__FN const xml_node_iterator& xml_node_iterator::operator++() - { - assert(_wrap._root); - _wrap._root = _wrap._root->next_sibling; - return *this; - } - - PUGI__FN xml_node_iterator xml_node_iterator::operator++(int) - { - xml_node_iterator temp = *this; - ++*this; - return temp; - } - - PUGI__FN const xml_node_iterator& xml_node_iterator::operator--() - { - _wrap = _wrap._root ? _wrap.previous_sibling() : _parent.last_child(); - return *this; - } - - PUGI__FN xml_node_iterator xml_node_iterator::operator--(int) - { - xml_node_iterator temp = *this; - --*this; - return temp; - } - - PUGI__FN xml_attribute_iterator::xml_attribute_iterator() - { - } - - PUGI__FN xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent): _wrap(attr), _parent(parent) - { - } - - PUGI__FN xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) - { - } - - PUGI__FN bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const - { - return _wrap._attr == rhs._wrap._attr && _parent._root == rhs._parent._root; - } - - PUGI__FN bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const - { - return _wrap._attr != rhs._wrap._attr || _parent._root != rhs._parent._root; - } - - PUGI__FN xml_attribute& xml_attribute_iterator::operator*() const - { - assert(_wrap._attr); - return _wrap; - } - - PUGI__FN xml_attribute* xml_attribute_iterator::operator->() const - { - assert(_wrap._attr); - return const_cast(&_wrap); // BCC32 workaround - } - - PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator++() - { - assert(_wrap._attr); - _wrap._attr = _wrap._attr->next_attribute; - return *this; - } - - PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator++(int) - { - xml_attribute_iterator temp = *this; - ++*this; - return temp; - } - - PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator--() - { - _wrap = _wrap._attr ? _wrap.previous_attribute() : _parent.last_attribute(); - return *this; - } - - PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator--(int) - { - xml_attribute_iterator temp = *this; - --*this; - return temp; - } - - PUGI__FN xml_named_node_iterator::xml_named_node_iterator(): _name(0) - { - } - - PUGI__FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _wrap(node), _parent(node.parent()), _name(name) - { - } - - PUGI__FN xml_named_node_iterator::xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name): _wrap(ref), _parent(parent), _name(name) - { - } - - PUGI__FN bool xml_named_node_iterator::operator==(const xml_named_node_iterator& rhs) const - { - return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; - } - - PUGI__FN bool xml_named_node_iterator::operator!=(const xml_named_node_iterator& rhs) const - { - return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; - } - - PUGI__FN xml_node& xml_named_node_iterator::operator*() const - { - assert(_wrap._root); - return _wrap; - } - - PUGI__FN xml_node* xml_named_node_iterator::operator->() const - { - assert(_wrap._root); - return const_cast(&_wrap); // BCC32 workaround - } - - PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++() - { - assert(_wrap._root); - _wrap = _wrap.next_sibling(_name); - return *this; - } - - PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator++(int) - { - xml_named_node_iterator temp = *this; - ++*this; - return temp; - } - - PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator--() - { - if (_wrap._root) - _wrap = _wrap.previous_sibling(_name); - else - { - _wrap = _parent.last_child(); - - if (!impl::strequal(_wrap.name(), _name)) - _wrap = _wrap.previous_sibling(_name); - } - - return *this; - } - - PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator--(int) - { - xml_named_node_iterator temp = *this; - --*this; - return temp; - } - - PUGI__FN xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto) - { - } - - PUGI__FN xml_parse_result::operator bool() const - { - return status == status_ok; - } - - PUGI__FN const char* xml_parse_result::description() const - { - switch (status) - { - case status_ok: return "No error"; - - case status_file_not_found: return "File was not found"; - case status_io_error: return "Error reading from file/stream"; - case status_out_of_memory: return "Could not allocate memory"; - case status_internal_error: return "Internal error occurred"; - - case status_unrecognized_tag: return "Could not determine tag type"; - - case status_bad_pi: return "Error parsing document declaration/processing instruction"; - case status_bad_comment: return "Error parsing comment"; - case status_bad_cdata: return "Error parsing CDATA section"; - case status_bad_doctype: return "Error parsing document type declaration"; - case status_bad_pcdata: return "Error parsing PCDATA section"; - case status_bad_start_element: return "Error parsing start element tag"; - case status_bad_attribute: return "Error parsing element attribute"; - case status_bad_end_element: return "Error parsing end element tag"; - case status_end_element_mismatch: return "Start-end tags mismatch"; - - case status_append_invalid_root: return "Unable to append nodes: root is not an element or document"; - - case status_no_document_element: return "No document element found"; - - default: return "Unknown error"; - } - } - - PUGI__FN xml_document::xml_document(): _buffer(0) - { - create(); - } - - PUGI__FN xml_document::~xml_document() - { - destroy(); - } - - PUGI__FN void xml_document::reset() - { - destroy(); - create(); - } - - PUGI__FN void xml_document::reset(const xml_document& proto) - { - reset(); - - for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling()) - append_copy(cur); - } - - PUGI__FN void xml_document::create() - { - assert(!_root); - - // initialize sentinel page - PUGI__STATIC_ASSERT(sizeof(impl::xml_memory_page) + sizeof(impl::xml_document_struct) + impl::xml_memory_page_alignment - sizeof(void*) <= sizeof(_memory)); - - // align upwards to page boundary - void* page_memory = reinterpret_cast((reinterpret_cast(_memory) + (impl::xml_memory_page_alignment - 1)) & ~(impl::xml_memory_page_alignment - 1)); - - // prepare page structure - impl::xml_memory_page* page = impl::xml_memory_page::construct(page_memory); - assert(page); - - page->busy_size = impl::xml_memory_page_size; - - // allocate new root - _root = new (reinterpret_cast(page) + sizeof(impl::xml_memory_page)) impl::xml_document_struct(page); - _root->prev_sibling_c = _root; - - // setup sentinel page - page->allocator = static_cast(_root); - - // verify the document allocation - assert(reinterpret_cast(_root) + sizeof(impl::xml_document_struct) <= _memory + sizeof(_memory)); - } - - PUGI__FN void xml_document::destroy() - { - assert(_root); - - // destroy static storage - if (_buffer) - { - impl::xml_memory::deallocate(_buffer); - _buffer = 0; - } - - // destroy extra buffers (note: no need to destroy linked list nodes, they're allocated using document allocator) - for (impl::xml_extra_buffer* extra = static_cast(_root)->extra_buffers; extra; extra = extra->next) - { - if (extra->buffer) impl::xml_memory::deallocate(extra->buffer); - } - - // destroy dynamic storage, leave sentinel page (it's in static memory) - impl::xml_memory_page* root_page = reinterpret_cast(_root->header & impl::xml_memory_page_pointer_mask); - assert(root_page && !root_page->prev); - assert(reinterpret_cast(root_page) >= _memory && reinterpret_cast(root_page) < _memory + sizeof(_memory)); - - for (impl::xml_memory_page* page = root_page->next; page; ) - { - impl::xml_memory_page* next = page->next; - - impl::xml_allocator::deallocate_page(page); - - page = next; - } - - _root = 0; - } - -#ifndef PUGIXML_NO_STL - PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options, xml_encoding encoding) - { - reset(); - - return impl::load_stream_impl(*this, stream, options, encoding); - } - - PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options) - { - reset(); - - return impl::load_stream_impl(*this, stream, options, encoding_wchar); - } -#endif - - PUGI__FN xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options) - { - // Force native encoding (skip autodetection) - #ifdef PUGIXML_WCHAR_MODE - xml_encoding encoding = encoding_wchar; - #else - xml_encoding encoding = encoding_utf8; - #endif - - return load_buffer(contents, impl::strlength(contents) * sizeof(char_t), options, encoding); - } - - PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) - { - return load_string(contents, options); - } - - PUGI__FN xml_parse_result xml_document::load_file(const char* path_, unsigned int options, xml_encoding encoding) - { - reset(); - - FILE* file = fopen(path_, "rb"); - - return impl::load_file_impl(*this, file, options, encoding); - } - - PUGI__FN xml_parse_result xml_document::load_file(const wchar_t* path_, unsigned int options, xml_encoding encoding) - { - reset(); - - FILE* file = impl::open_file_wide(path_, L"rb"); - - return impl::load_file_impl(*this, file, options, encoding); - } - - PUGI__FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) - { - reset(); - - return impl::load_buffer_impl(static_cast(_root), _root, const_cast(contents), size, options, encoding, false, false, &_buffer); - } - - PUGI__FN xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding) - { - reset(); - - return impl::load_buffer_impl(static_cast(_root), _root, contents, size, options, encoding, true, false, &_buffer); - } - - PUGI__FN xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding) - { - reset(); - - return impl::load_buffer_impl(static_cast(_root), _root, contents, size, options, encoding, true, true, &_buffer); - } - - PUGI__FN void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const - { - impl::xml_buffered_writer buffered_writer(writer, encoding); - - if ((flags & format_write_bom) && encoding != encoding_latin1) - { - // BOM always represents the codepoint U+FEFF, so just write it in native encoding - #ifdef PUGIXML_WCHAR_MODE - unsigned int bom = 0xfeff; - buffered_writer.write(static_cast(bom)); - #else - buffered_writer.write('\xef', '\xbb', '\xbf'); - #endif - } - - if (!(flags & format_no_declaration) && !impl::has_declaration(_root)) - { - buffered_writer.write_string(PUGIXML_TEXT("'); - if (!(flags & format_raw)) buffered_writer.write('\n'); - } - - impl::node_output(buffered_writer, _root, indent, flags, 0); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding) const - { - xml_writer_stream writer(stream); - - save(writer, indent, flags, encoding); - } - - PUGI__FN void xml_document::save(std::basic_ostream >& stream, const char_t* indent, unsigned int flags) const - { - xml_writer_stream writer(stream); - - save(writer, indent, flags, encoding_wchar); - } -#endif - - PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const - { - FILE* file = fopen(path_, (flags & format_save_file_text) ? "w" : "wb"); - return impl::save_file_impl(*this, file, indent, flags, encoding); - } - - PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const - { - FILE* file = impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"); - return impl::save_file_impl(*this, file, indent, flags, encoding); - } - - PUGI__FN xml_node xml_document::document_element() const - { - assert(_root); - - for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) - if (PUGI__NODETYPE(i) == node_element) - return xml_node(i); - - return xml_node(); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str) - { - assert(str); - - return impl::as_utf8_impl(str, impl::strlength_wide(str)); - } - - PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const std::basic_string& str) - { - return impl::as_utf8_impl(str.c_str(), str.size()); - } - - PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const char* str) - { - assert(str); - - return impl::as_wide_impl(str, strlen(str)); - } - - PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const std::string& str) - { - return impl::as_wide_impl(str.c_str(), str.size()); - } -#endif - - PUGI__FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate) - { - impl::xml_memory::allocate = allocate; - impl::xml_memory::deallocate = deallocate; - } - - PUGI__FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function() - { - return impl::xml_memory::allocate; - } - - PUGI__FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function() - { - return impl::xml_memory::deallocate; - } -} - -#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) -namespace std -{ - // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) - PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_node_iterator&) - { - return std::bidirectional_iterator_tag(); - } - - PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_attribute_iterator&) - { - return std::bidirectional_iterator_tag(); - } - - PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_named_node_iterator&) - { - return std::bidirectional_iterator_tag(); - } -} -#endif - -#if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) -namespace std -{ - // Workarounds for (non-standard) iterator category detection - PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_node_iterator&) - { - return std::bidirectional_iterator_tag(); - } - - PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_attribute_iterator&) - { - return std::bidirectional_iterator_tag(); - } - - PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_named_node_iterator&) - { - return std::bidirectional_iterator_tag(); - } -} -#endif - -#ifndef PUGIXML_NO_XPATH -// STL replacements -PUGI__NS_BEGIN - struct equal_to - { - template bool operator()(const T& lhs, const T& rhs) const - { - return lhs == rhs; - } - }; - - struct not_equal_to - { - template bool operator()(const T& lhs, const T& rhs) const - { - return lhs != rhs; - } - }; - - struct less - { - template bool operator()(const T& lhs, const T& rhs) const - { - return lhs < rhs; - } - }; - - struct less_equal - { - template bool operator()(const T& lhs, const T& rhs) const - { - return lhs <= rhs; - } - }; - - template void swap(T& lhs, T& rhs) - { - T temp = lhs; - lhs = rhs; - rhs = temp; - } - - template I min_element(I begin, I end, const Pred& pred) - { - I result = begin; - - for (I it = begin + 1; it != end; ++it) - if (pred(*it, *result)) - result = it; - - return result; - } - - template void reverse(I begin, I end) - { - while (end - begin > 1) swap(*begin++, *--end); - } - - template I unique(I begin, I end) - { - // fast skip head - while (end - begin > 1 && *begin != *(begin + 1)) begin++; - - if (begin == end) return begin; - - // last written element - I write = begin++; - - // merge unique elements - while (begin != end) - { - if (*begin != *write) - *++write = *begin++; - else - begin++; - } - - // past-the-end (write points to live element) - return write + 1; - } - - template void copy_backwards(I begin, I end, I target) - { - while (begin != end) *--target = *--end; - } - - template void insertion_sort(I begin, I end, const Pred& pred, T*) - { - assert(begin != end); - - for (I it = begin + 1; it != end; ++it) - { - T val = *it; - - if (pred(val, *begin)) - { - // move to front - copy_backwards(begin, it, it + 1); - *begin = val; - } - else - { - I hole = it; - - // move hole backwards - while (pred(val, *(hole - 1))) - { - *hole = *(hole - 1); - hole--; - } - - // fill hole with element - *hole = val; - } - } - } - - // std variant for elements with == - template void partition(I begin, I middle, I end, const Pred& pred, I* out_eqbeg, I* out_eqend) - { - I eqbeg = middle, eqend = middle + 1; - - // expand equal range - while (eqbeg != begin && *(eqbeg - 1) == *eqbeg) --eqbeg; - while (eqend != end && *eqend == *eqbeg) ++eqend; - - // process outer elements - I ltend = eqbeg, gtbeg = eqend; - - for (;;) - { - // find the element from the right side that belongs to the left one - for (; gtbeg != end; ++gtbeg) - if (!pred(*eqbeg, *gtbeg)) - { - if (*gtbeg == *eqbeg) swap(*gtbeg, *eqend++); - else break; - } - - // find the element from the left side that belongs to the right one - for (; ltend != begin; --ltend) - if (!pred(*(ltend - 1), *eqbeg)) - { - if (*eqbeg == *(ltend - 1)) swap(*(ltend - 1), *--eqbeg); - else break; - } - - // scanned all elements - if (gtbeg == end && ltend == begin) - { - *out_eqbeg = eqbeg; - *out_eqend = eqend; - return; - } - - // make room for elements by moving equal area - if (gtbeg == end) - { - if (--ltend != --eqbeg) swap(*ltend, *eqbeg); - swap(*eqbeg, *--eqend); - } - else if (ltend == begin) - { - if (eqend != gtbeg) swap(*eqbeg, *eqend); - ++eqend; - swap(*gtbeg++, *eqbeg++); - } - else swap(*gtbeg++, *--ltend); - } - } - - template void median3(I first, I middle, I last, const Pred& pred) - { - if (pred(*middle, *first)) swap(*middle, *first); - if (pred(*last, *middle)) swap(*last, *middle); - if (pred(*middle, *first)) swap(*middle, *first); - } - - template void median(I first, I middle, I last, const Pred& pred) - { - if (last - first <= 40) - { - // median of three for small chunks - median3(first, middle, last, pred); - } - else - { - // median of nine - size_t step = (last - first + 1) / 8; - - median3(first, first + step, first + 2 * step, pred); - median3(middle - step, middle, middle + step, pred); - median3(last - 2 * step, last - step, last, pred); - median3(first + step, middle, last - step, pred); - } - } - - template void sort(I begin, I end, const Pred& pred) - { - // sort large chunks - while (end - begin > 32) - { - // find median element - I middle = begin + (end - begin) / 2; - median(begin, middle, end - 1, pred); - - // partition in three chunks (< = >) - I eqbeg, eqend; - partition(begin, middle, end, pred, &eqbeg, &eqend); - - // loop on larger half - if (eqbeg - begin > end - eqend) - { - sort(eqend, end, pred); - end = eqbeg; - } - else - { - sort(begin, eqbeg, pred); - begin = eqend; - } - } - - // insertion sort small chunk - if (begin != end) insertion_sort(begin, end, pred, &*begin); - } -PUGI__NS_END - -// Allocator used for AST and evaluation stacks -PUGI__NS_BEGIN - struct xpath_memory_block - { - xpath_memory_block* next; - size_t capacity; - - char data[ - #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE - PUGIXML_MEMORY_XPATH_PAGE_SIZE - #else - 4096 - #endif - ]; - }; - - class xpath_allocator - { - xpath_memory_block* _root; - size_t _root_size; - - public: - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf* error_handler; - #endif - - xpath_allocator(xpath_memory_block* root, size_t root_size = 0): _root(root), _root_size(root_size) - { - #ifdef PUGIXML_NO_EXCEPTIONS - error_handler = 0; - #endif - } - - void* allocate_nothrow(size_t size) - { - // align size so that we're able to store pointers in subsequent blocks - size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); - - if (_root_size + size <= _root->capacity) - { - void* buf = _root->data + _root_size; - _root_size += size; - return buf; - } - else - { - // make sure we have at least 1/4th of the page free after allocation to satisfy subsequent allocation requests - size_t block_capacity_base = sizeof(_root->data); - size_t block_capacity_req = size + block_capacity_base / 4; - size_t block_capacity = (block_capacity_base > block_capacity_req) ? block_capacity_base : block_capacity_req; - - size_t block_size = block_capacity + offsetof(xpath_memory_block, data); - - xpath_memory_block* block = static_cast(xml_memory::allocate(block_size)); - if (!block) return 0; - - block->next = _root; - block->capacity = block_capacity; - - _root = block; - _root_size = size; - - return block->data; - } - } - - void* allocate(size_t size) - { - void* result = allocate_nothrow(size); - - if (!result) - { - #ifdef PUGIXML_NO_EXCEPTIONS - assert(error_handler); - longjmp(*error_handler, 1); - #else - throw std::bad_alloc(); - #endif - } - - return result; - } - - void* reallocate(void* ptr, size_t old_size, size_t new_size) - { - // align size so that we're able to store pointers in subsequent blocks - old_size = (old_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); - new_size = (new_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); - - // we can only reallocate the last object - assert(ptr == 0 || static_cast(ptr) + old_size == _root->data + _root_size); - - // adjust root size so that we have not allocated the object at all - bool only_object = (_root_size == old_size); - - if (ptr) _root_size -= old_size; - - // allocate a new version (this will obviously reuse the memory if possible) - void* result = allocate(new_size); - assert(result); - - // we have a new block - if (result != ptr && ptr) - { - // copy old data - assert(new_size >= old_size); - memcpy(result, ptr, old_size); - - // free the previous page if it had no other objects - if (only_object) - { - assert(_root->data == result); - assert(_root->next); - - xpath_memory_block* next = _root->next->next; - - if (next) - { - // deallocate the whole page, unless it was the first one - xml_memory::deallocate(_root->next); - _root->next = next; - } - } - } - - return result; - } - - void revert(const xpath_allocator& state) - { - // free all new pages - xpath_memory_block* cur = _root; - - while (cur != state._root) - { - xpath_memory_block* next = cur->next; - - xml_memory::deallocate(cur); - - cur = next; - } - - // restore state - _root = state._root; - _root_size = state._root_size; - } - - void release() - { - xpath_memory_block* cur = _root; - assert(cur); - - while (cur->next) - { - xpath_memory_block* next = cur->next; - - xml_memory::deallocate(cur); - - cur = next; - } - } - }; - - struct xpath_allocator_capture - { - xpath_allocator_capture(xpath_allocator* alloc): _target(alloc), _state(*alloc) - { - } - - ~xpath_allocator_capture() - { - _target->revert(_state); - } - - xpath_allocator* _target; - xpath_allocator _state; - }; - - struct xpath_stack - { - xpath_allocator* result; - xpath_allocator* temp; - }; - - struct xpath_stack_data - { - xpath_memory_block blocks[2]; - xpath_allocator result; - xpath_allocator temp; - xpath_stack stack; - - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf error_handler; - #endif - - xpath_stack_data(): result(blocks + 0), temp(blocks + 1) - { - blocks[0].next = blocks[1].next = 0; - blocks[0].capacity = blocks[1].capacity = sizeof(blocks[0].data); - - stack.result = &result; - stack.temp = &temp; - - #ifdef PUGIXML_NO_EXCEPTIONS - result.error_handler = temp.error_handler = &error_handler; - #endif - } - - ~xpath_stack_data() - { - result.release(); - temp.release(); - } - }; -PUGI__NS_END - -// String class -PUGI__NS_BEGIN - class xpath_string - { - const char_t* _buffer; - bool _uses_heap; - size_t _length_heap; - - static char_t* duplicate_string(const char_t* string, size_t length, xpath_allocator* alloc) - { - char_t* result = static_cast(alloc->allocate((length + 1) * sizeof(char_t))); - assert(result); - - memcpy(result, string, length * sizeof(char_t)); - result[length] = 0; - - return result; - } - - xpath_string(const char_t* buffer, bool uses_heap_, size_t length_heap): _buffer(buffer), _uses_heap(uses_heap_), _length_heap(length_heap) - { - } - - public: - static xpath_string from_const(const char_t* str) - { - return xpath_string(str, false, 0); - } - - static xpath_string from_heap_preallocated(const char_t* begin, const char_t* end) - { - assert(begin <= end && *end == 0); - - return xpath_string(begin, true, static_cast(end - begin)); - } - - static xpath_string from_heap(const char_t* begin, const char_t* end, xpath_allocator* alloc) - { - assert(begin <= end); - - size_t length = static_cast(end - begin); - - return length == 0 ? xpath_string() : xpath_string(duplicate_string(begin, length, alloc), true, length); - } - - xpath_string(): _buffer(PUGIXML_TEXT("")), _uses_heap(false), _length_heap(0) - { - } - - void append(const xpath_string& o, xpath_allocator* alloc) - { - // skip empty sources - if (!*o._buffer) return; - - // fast append for constant empty target and constant source - if (!*_buffer && !_uses_heap && !o._uses_heap) - { - _buffer = o._buffer; - } - else - { - // need to make heap copy - size_t target_length = length(); - size_t source_length = o.length(); - size_t result_length = target_length + source_length; - - // allocate new buffer - char_t* result = static_cast(alloc->reallocate(_uses_heap ? const_cast(_buffer) : 0, (target_length + 1) * sizeof(char_t), (result_length + 1) * sizeof(char_t))); - assert(result); - - // append first string to the new buffer in case there was no reallocation - if (!_uses_heap) memcpy(result, _buffer, target_length * sizeof(char_t)); - - // append second string to the new buffer - memcpy(result + target_length, o._buffer, source_length * sizeof(char_t)); - result[result_length] = 0; - - // finalize - _buffer = result; - _uses_heap = true; - _length_heap = result_length; - } - } - - const char_t* c_str() const - { - return _buffer; - } - - size_t length() const - { - return _uses_heap ? _length_heap : strlength(_buffer); - } - - char_t* data(xpath_allocator* alloc) - { - // make private heap copy - if (!_uses_heap) - { - size_t length_ = strlength(_buffer); - - _buffer = duplicate_string(_buffer, length_, alloc); - _uses_heap = true; - _length_heap = length_; - } - - return const_cast(_buffer); - } - - bool empty() const - { - return *_buffer == 0; - } - - bool operator==(const xpath_string& o) const - { - return strequal(_buffer, o._buffer); - } - - bool operator!=(const xpath_string& o) const - { - return !strequal(_buffer, o._buffer); - } - - bool uses_heap() const - { - return _uses_heap; - } - }; -PUGI__NS_END - -PUGI__NS_BEGIN - PUGI__FN bool starts_with(const char_t* string, const char_t* pattern) - { - while (*pattern && *string == *pattern) - { - string++; - pattern++; - } - - return *pattern == 0; - } - - PUGI__FN const char_t* find_char(const char_t* s, char_t c) - { - #ifdef PUGIXML_WCHAR_MODE - return wcschr(s, c); - #else - return strchr(s, c); - #endif - } - - PUGI__FN const char_t* find_substring(const char_t* s, const char_t* p) - { - #ifdef PUGIXML_WCHAR_MODE - // MSVC6 wcsstr bug workaround (if s is empty it always returns 0) - return (*p == 0) ? s : wcsstr(s, p); - #else - return strstr(s, p); - #endif - } - - // Converts symbol to lower case, if it is an ASCII one - PUGI__FN char_t tolower_ascii(char_t ch) - { - return static_cast(ch - 'A') < 26 ? static_cast(ch | ' ') : ch; - } - - PUGI__FN xpath_string string_value(const xpath_node& na, xpath_allocator* alloc) - { - if (na.attribute()) - return xpath_string::from_const(na.attribute().value()); - else - { - xml_node n = na.node(); - - switch (n.type()) - { - case node_pcdata: - case node_cdata: - case node_comment: - case node_pi: - return xpath_string::from_const(n.value()); - - case node_document: - case node_element: - { - xpath_string result; - - xml_node cur = n.first_child(); - - while (cur && cur != n) - { - if (cur.type() == node_pcdata || cur.type() == node_cdata) - result.append(xpath_string::from_const(cur.value()), alloc); - - if (cur.first_child()) - cur = cur.first_child(); - else if (cur.next_sibling()) - cur = cur.next_sibling(); - else - { - while (!cur.next_sibling() && cur != n) - cur = cur.parent(); - - if (cur != n) cur = cur.next_sibling(); - } - } - - return result; - } - - default: - return xpath_string(); - } - } - } - - PUGI__FN bool node_is_before_sibling(xml_node_struct* ln, xml_node_struct* rn) - { - assert(ln->parent == rn->parent); - - // there is no common ancestor (the shared parent is null), nodes are from different documents - if (!ln->parent) return ln < rn; - - // determine sibling order - xml_node_struct* ls = ln; - xml_node_struct* rs = rn; - - while (ls && rs) - { - if (ls == rn) return true; - if (rs == ln) return false; - - ls = ls->next_sibling; - rs = rs->next_sibling; - } - - // if rn sibling chain ended ln must be before rn - return !rs; - } - - PUGI__FN bool node_is_before(xml_node_struct* ln, xml_node_struct* rn) - { - // find common ancestor at the same depth, if any - xml_node_struct* lp = ln; - xml_node_struct* rp = rn; - - while (lp && rp && lp->parent != rp->parent) - { - lp = lp->parent; - rp = rp->parent; - } - - // parents are the same! - if (lp && rp) return node_is_before_sibling(lp, rp); - - // nodes are at different depths, need to normalize heights - bool left_higher = !lp; - - while (lp) - { - lp = lp->parent; - ln = ln->parent; - } - - while (rp) - { - rp = rp->parent; - rn = rn->parent; - } - - // one node is the ancestor of the other - if (ln == rn) return left_higher; - - // find common ancestor... again - while (ln->parent != rn->parent) - { - ln = ln->parent; - rn = rn->parent; - } - - return node_is_before_sibling(ln, rn); - } - - PUGI__FN bool node_is_ancestor(xml_node_struct* parent, xml_node_struct* node) - { - while (node && node != parent) node = node->parent; - - return parent && node == parent; - } - - PUGI__FN const void* document_buffer_order(const xpath_node& xnode) - { - xml_node_struct* node = xnode.node().internal_object(); - - if (node) - { - if ((get_document(node).header & xml_memory_page_contents_shared_mask) == 0) - { - if (node->name && (node->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0) return node->name; - if (node->value && (node->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0) return node->value; - } - - return 0; - } - - xml_attribute_struct* attr = xnode.attribute().internal_object(); - - if (attr) - { - if ((get_document(attr).header & xml_memory_page_contents_shared_mask) == 0) - { - if ((attr->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0) return attr->name; - if ((attr->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0) return attr->value; - } - - return 0; - } - - return 0; - } - - struct document_order_comparator - { - bool operator()(const xpath_node& lhs, const xpath_node& rhs) const - { - // optimized document order based check - const void* lo = document_buffer_order(lhs); - const void* ro = document_buffer_order(rhs); - - if (lo && ro) return lo < ro; - - // slow comparison - xml_node ln = lhs.node(), rn = rhs.node(); - - // compare attributes - if (lhs.attribute() && rhs.attribute()) - { - // shared parent - if (lhs.parent() == rhs.parent()) - { - // determine sibling order - for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute()) - if (a == rhs.attribute()) - return true; - - return false; - } - - // compare attribute parents - ln = lhs.parent(); - rn = rhs.parent(); - } - else if (lhs.attribute()) - { - // attributes go after the parent element - if (lhs.parent() == rhs.node()) return false; - - ln = lhs.parent(); - } - else if (rhs.attribute()) - { - // attributes go after the parent element - if (rhs.parent() == lhs.node()) return true; - - rn = rhs.parent(); - } - - if (ln == rn) return false; - - if (!ln || !rn) return ln < rn; - - return node_is_before(ln.internal_object(), rn.internal_object()); - } - }; - - struct duplicate_comparator - { - bool operator()(const xpath_node& lhs, const xpath_node& rhs) const - { - if (lhs.attribute()) return rhs.attribute() ? lhs.attribute() < rhs.attribute() : true; - else return rhs.attribute() ? false : lhs.node() < rhs.node(); - } - }; - - PUGI__FN double gen_nan() - { - #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24)) - union { float f; uint32_t i; } u[sizeof(float) == sizeof(uint32_t) ? 1 : -1]; - u[0].i = 0x7fc00000; - return u[0].f; - #else - // fallback - const volatile double zero = 0.0; - return zero / zero; - #endif - } - - PUGI__FN bool is_nan(double value) - { - #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) - return !!_isnan(value); - #elif defined(fpclassify) && defined(FP_NAN) - return fpclassify(value) == FP_NAN; - #else - // fallback - const volatile double v = value; - return v != v; - #endif - } - - PUGI__FN const char_t* convert_number_to_string_special(double value) - { - #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) - if (_finite(value)) return (value == 0) ? PUGIXML_TEXT("0") : 0; - if (_isnan(value)) return PUGIXML_TEXT("NaN"); - return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); - #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) - switch (fpclassify(value)) - { - case FP_NAN: - return PUGIXML_TEXT("NaN"); - - case FP_INFINITE: - return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); - - case FP_ZERO: - return PUGIXML_TEXT("0"); - - default: - return 0; - } - #else - // fallback - const volatile double v = value; - - if (v == 0) return PUGIXML_TEXT("0"); - if (v != v) return PUGIXML_TEXT("NaN"); - if (v * 2 == v) return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); - return 0; - #endif - } - - PUGI__FN bool convert_number_to_boolean(double value) - { - return (value != 0 && !is_nan(value)); - } - - PUGI__FN void truncate_zeros(char* begin, char* end) - { - while (begin != end && end[-1] == '0') end--; - - *end = 0; - } - - // gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent -#if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) - PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) - { - // get base values - int sign, exponent; - _ecvt_s(buffer, buffer_size, value, DBL_DIG + 1, &exponent, &sign); - - // truncate redundant zeros - truncate_zeros(buffer, buffer + strlen(buffer)); - - // fill results - *out_mantissa = buffer; - *out_exponent = exponent; - } -#else - PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) - { - // get a scientific notation value with IEEE DBL_DIG decimals - sprintf(buffer, "%.*e", DBL_DIG, value); - assert(strlen(buffer) < buffer_size); - (void)!buffer_size; - - // get the exponent (possibly negative) - char* exponent_string = strchr(buffer, 'e'); - assert(exponent_string); - - int exponent = atoi(exponent_string + 1); - - // extract mantissa string: skip sign - char* mantissa = buffer[0] == '-' ? buffer + 1 : buffer; - assert(mantissa[0] != '0' && mantissa[1] == '.'); - - // divide mantissa by 10 to eliminate integer part - mantissa[1] = mantissa[0]; - mantissa++; - exponent++; - - // remove extra mantissa digits and zero-terminate mantissa - truncate_zeros(mantissa, exponent_string); - - // fill results - *out_mantissa = mantissa; - *out_exponent = exponent; - } -#endif - - PUGI__FN xpath_string convert_number_to_string(double value, xpath_allocator* alloc) - { - // try special number conversion - const char_t* special = convert_number_to_string_special(value); - if (special) return xpath_string::from_const(special); - - // get mantissa + exponent form - char mantissa_buffer[32]; - - char* mantissa; - int exponent; - convert_number_to_mantissa_exponent(value, mantissa_buffer, sizeof(mantissa_buffer), &mantissa, &exponent); - - // allocate a buffer of suitable length for the number - size_t result_size = strlen(mantissa_buffer) + (exponent > 0 ? exponent : -exponent) + 4; - char_t* result = static_cast(alloc->allocate(sizeof(char_t) * result_size)); - assert(result); - - // make the number! - char_t* s = result; - - // sign - if (value < 0) *s++ = '-'; - - // integer part - if (exponent <= 0) - { - *s++ = '0'; - } - else - { - while (exponent > 0) - { - assert(*mantissa == 0 || static_cast(static_cast(*mantissa) - '0') <= 9); - *s++ = *mantissa ? *mantissa++ : '0'; - exponent--; - } - } - - // fractional part - if (*mantissa) - { - // decimal point - *s++ = '.'; - - // extra zeroes from negative exponent - while (exponent < 0) - { - *s++ = '0'; - exponent++; - } - - // extra mantissa digits - while (*mantissa) - { - assert(static_cast(*mantissa - '0') <= 9); - *s++ = *mantissa++; - } - } - - // zero-terminate - assert(s < result + result_size); - *s = 0; - - return xpath_string::from_heap_preallocated(result, s); - } - - PUGI__FN bool check_string_to_number_format(const char_t* string) - { - // parse leading whitespace - while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; - - // parse sign - if (*string == '-') ++string; - - if (!*string) return false; - - // if there is no integer part, there should be a decimal part with at least one digit - if (!PUGI__IS_CHARTYPEX(string[0], ctx_digit) && (string[0] != '.' || !PUGI__IS_CHARTYPEX(string[1], ctx_digit))) return false; - - // parse integer part - while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; - - // parse decimal part - if (*string == '.') - { - ++string; - - while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; - } - - // parse trailing whitespace - while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; - - return *string == 0; - } - - PUGI__FN double convert_string_to_number(const char_t* string) - { - // check string format - if (!check_string_to_number_format(string)) return gen_nan(); - - // parse string - #ifdef PUGIXML_WCHAR_MODE - return wcstod(string, 0); - #else - return atof(string); - #endif - } - - PUGI__FN bool convert_string_to_number_scratch(char_t (&buffer)[32], const char_t* begin, const char_t* end, double* out_result) - { - size_t length = static_cast(end - begin); - char_t* scratch = buffer; - - if (length >= sizeof(buffer) / sizeof(buffer[0])) - { - // need to make dummy on-heap copy - scratch = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!scratch) return false; - } - - // copy string to zero-terminated buffer and perform conversion - memcpy(scratch, begin, length * sizeof(char_t)); - scratch[length] = 0; - - *out_result = convert_string_to_number(scratch); - - // free dummy buffer - if (scratch != buffer) xml_memory::deallocate(scratch); - - return true; - } - - PUGI__FN double round_nearest(double value) - { - return floor(value + 0.5); - } - - PUGI__FN double round_nearest_nzero(double value) - { - // same as round_nearest, but returns -0 for [-0.5, -0] - // ceil is used to differentiate between +0 and -0 (we return -0 for [-0.5, -0] and +0 for +0) - return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5); - } - - PUGI__FN const char_t* qualified_name(const xpath_node& node) - { - return node.attribute() ? node.attribute().name() : node.node().name(); - } - - PUGI__FN const char_t* local_name(const xpath_node& node) - { - const char_t* name = qualified_name(node); - const char_t* p = find_char(name, ':'); - - return p ? p + 1 : name; - } - - struct namespace_uri_predicate - { - const char_t* prefix; - size_t prefix_length; - - namespace_uri_predicate(const char_t* name) - { - const char_t* pos = find_char(name, ':'); - - prefix = pos ? name : 0; - prefix_length = pos ? static_cast(pos - name) : 0; - } - - bool operator()(xml_attribute a) const - { - const char_t* name = a.name(); - - if (!starts_with(name, PUGIXML_TEXT("xmlns"))) return false; - - return prefix ? name[5] == ':' && strequalrange(name + 6, prefix, prefix_length) : name[5] == 0; - } - }; - - PUGI__FN const char_t* namespace_uri(xml_node node) - { - namespace_uri_predicate pred = node.name(); - - xml_node p = node; - - while (p) - { - xml_attribute a = p.find_attribute(pred); - - if (a) return a.value(); - - p = p.parent(); - } - - return PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* namespace_uri(xml_attribute attr, xml_node parent) - { - namespace_uri_predicate pred = attr.name(); - - // Default namespace does not apply to attributes - if (!pred.prefix) return PUGIXML_TEXT(""); - - xml_node p = parent; - - while (p) - { - xml_attribute a = p.find_attribute(pred); - - if (a) return a.value(); - - p = p.parent(); - } - - return PUGIXML_TEXT(""); - } - - PUGI__FN const char_t* namespace_uri(const xpath_node& node) - { - return node.attribute() ? namespace_uri(node.attribute(), node.parent()) : namespace_uri(node.node()); - } - - PUGI__FN char_t* normalize_space(char_t* buffer) - { - char_t* write = buffer; - - for (char_t* it = buffer; *it; ) - { - char_t ch = *it++; - - if (PUGI__IS_CHARTYPE(ch, ct_space)) - { - // replace whitespace sequence with single space - while (PUGI__IS_CHARTYPE(*it, ct_space)) it++; - - // avoid leading spaces - if (write != buffer) *write++ = ' '; - } - else *write++ = ch; - } - - // remove trailing space - if (write != buffer && PUGI__IS_CHARTYPE(write[-1], ct_space)) write--; - - // zero-terminate - *write = 0; - - return write; - } - - PUGI__FN char_t* translate(char_t* buffer, const char_t* from, const char_t* to, size_t to_length) - { - char_t* write = buffer; - - while (*buffer) - { - PUGI__DMC_VOLATILE char_t ch = *buffer++; - - const char_t* pos = find_char(from, ch); - - if (!pos) - *write++ = ch; // do not process - else if (static_cast(pos - from) < to_length) - *write++ = to[pos - from]; // replace - } - - // zero-terminate - *write = 0; - - return write; - } - - PUGI__FN unsigned char* translate_table_generate(xpath_allocator* alloc, const char_t* from, const char_t* to) - { - unsigned char table[128] = {0}; - - while (*from) - { - unsigned int fc = static_cast(*from); - unsigned int tc = static_cast(*to); - - if (fc >= 128 || tc >= 128) - return 0; - - // code=128 means "skip character" - if (!table[fc]) - table[fc] = static_cast(tc ? tc : 128); - - from++; - if (tc) to++; - } - - for (int i = 0; i < 128; ++i) - if (!table[i]) - table[i] = static_cast(i); - - void* result = alloc->allocate_nothrow(sizeof(table)); - - if (result) - { - memcpy(result, table, sizeof(table)); - } - - return static_cast(result); - } - - PUGI__FN char_t* translate_table(char_t* buffer, const unsigned char* table) - { - char_t* write = buffer; - - while (*buffer) - { - char_t ch = *buffer++; - unsigned int index = static_cast(ch); - - if (index < 128) - { - unsigned char code = table[index]; - - // code=128 means "skip character" (table size is 128 so 128 can be a special value) - // this code skips these characters without extra branches - *write = static_cast(code); - write += 1 - (code >> 7); - } - else - { - *write++ = ch; - } - } - - // zero-terminate - *write = 0; - - return write; - } - - inline bool is_xpath_attribute(const char_t* name) - { - return !(starts_with(name, PUGIXML_TEXT("xmlns")) && (name[5] == 0 || name[5] == ':')); - } - - struct xpath_variable_boolean: xpath_variable - { - xpath_variable_boolean(): value(false) - { - } - - bool value; - char_t name[1]; - }; - - struct xpath_variable_number: xpath_variable - { - xpath_variable_number(): value(0) - { - } - - double value; - char_t name[1]; - }; - - struct xpath_variable_string: xpath_variable - { - xpath_variable_string(): value(0) - { - } - - ~xpath_variable_string() - { - if (value) xml_memory::deallocate(value); - } - - char_t* value; - char_t name[1]; - }; - - struct xpath_variable_node_set: xpath_variable - { - xpath_node_set value; - char_t name[1]; - }; - - static const xpath_node_set dummy_node_set; - - PUGI__FN unsigned int hash_string(const char_t* str) - { - // Jenkins one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time) - unsigned int result = 0; - - while (*str) - { - result += static_cast(*str++); - result += result << 10; - result ^= result >> 6; - } - - result += result << 3; - result ^= result >> 11; - result += result << 15; - - return result; - } - - template PUGI__FN T* new_xpath_variable(const char_t* name) - { - size_t length = strlength(name); - if (length == 0) return 0; // empty variable names are invalid - - // $$ we can't use offsetof(T, name) because T is non-POD, so we just allocate additional length characters - void* memory = xml_memory::allocate(sizeof(T) + length * sizeof(char_t)); - if (!memory) return 0; - - T* result = new (memory) T(); - - memcpy(result->name, name, (length + 1) * sizeof(char_t)); - - return result; - } - - PUGI__FN xpath_variable* new_xpath_variable(xpath_value_type type, const char_t* name) - { - switch (type) - { - case xpath_type_node_set: - return new_xpath_variable(name); - - case xpath_type_number: - return new_xpath_variable(name); - - case xpath_type_string: - return new_xpath_variable(name); - - case xpath_type_boolean: - return new_xpath_variable(name); - - default: - return 0; - } - } - - template PUGI__FN void delete_xpath_variable(T* var) - { - var->~T(); - xml_memory::deallocate(var); - } - - PUGI__FN void delete_xpath_variable(xpath_value_type type, xpath_variable* var) - { - switch (type) - { - case xpath_type_node_set: - delete_xpath_variable(static_cast(var)); - break; - - case xpath_type_number: - delete_xpath_variable(static_cast(var)); - break; - - case xpath_type_string: - delete_xpath_variable(static_cast(var)); - break; - - case xpath_type_boolean: - delete_xpath_variable(static_cast(var)); - break; - - default: - assert(!"Invalid variable type"); - } - } - - PUGI__FN xpath_variable* get_variable_scratch(char_t (&buffer)[32], xpath_variable_set* set, const char_t* begin, const char_t* end) - { - size_t length = static_cast(end - begin); - char_t* scratch = buffer; - - if (length >= sizeof(buffer) / sizeof(buffer[0])) - { - // need to make dummy on-heap copy - scratch = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!scratch) return 0; - } - - // copy string to zero-terminated buffer and perform lookup - memcpy(scratch, begin, length * sizeof(char_t)); - scratch[length] = 0; - - xpath_variable* result = set->get(scratch); - - // free dummy buffer - if (scratch != buffer) xml_memory::deallocate(scratch); - - return result; - } -PUGI__NS_END - -// Internal node set class -PUGI__NS_BEGIN - PUGI__FN xpath_node_set::type_t xpath_get_order(const xpath_node* begin, const xpath_node* end) - { - if (end - begin < 2) - return xpath_node_set::type_sorted; - - document_order_comparator cmp; - - bool first = cmp(begin[0], begin[1]); - - for (const xpath_node* it = begin + 1; it + 1 < end; ++it) - if (cmp(it[0], it[1]) != first) - return xpath_node_set::type_unsorted; - - return first ? xpath_node_set::type_sorted : xpath_node_set::type_sorted_reverse; - } - - PUGI__FN xpath_node_set::type_t xpath_sort(xpath_node* begin, xpath_node* end, xpath_node_set::type_t type, bool rev) - { - xpath_node_set::type_t order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; - - if (type == xpath_node_set::type_unsorted) - { - xpath_node_set::type_t sorted = xpath_get_order(begin, end); - - if (sorted == xpath_node_set::type_unsorted) - { - sort(begin, end, document_order_comparator()); - - type = xpath_node_set::type_sorted; - } - else - type = sorted; - } - - if (type != order) reverse(begin, end); - - return order; - } - - PUGI__FN xpath_node xpath_first(const xpath_node* begin, const xpath_node* end, xpath_node_set::type_t type) - { - if (begin == end) return xpath_node(); - - switch (type) - { - case xpath_node_set::type_sorted: - return *begin; - - case xpath_node_set::type_sorted_reverse: - return *(end - 1); - - case xpath_node_set::type_unsorted: - return *min_element(begin, end, document_order_comparator()); - - default: - assert(!"Invalid node set type"); - return xpath_node(); - } - } - - class xpath_node_set_raw - { - xpath_node_set::type_t _type; - - xpath_node* _begin; - xpath_node* _end; - xpath_node* _eos; - - public: - xpath_node_set_raw(): _type(xpath_node_set::type_unsorted), _begin(0), _end(0), _eos(0) - { - } - - xpath_node* begin() const - { - return _begin; - } - - xpath_node* end() const - { - return _end; - } - - bool empty() const - { - return _begin == _end; - } - - size_t size() const - { - return static_cast(_end - _begin); - } - - xpath_node first() const - { - return xpath_first(_begin, _end, _type); - } - - void push_back_grow(const xpath_node& node, xpath_allocator* alloc); - - void push_back(const xpath_node& node, xpath_allocator* alloc) - { - if (_end != _eos) - *_end++ = node; - else - push_back_grow(node, alloc); - } - - void append(const xpath_node* begin_, const xpath_node* end_, xpath_allocator* alloc) - { - if (begin_ == end_) return; - - size_t size_ = static_cast(_end - _begin); - size_t capacity = static_cast(_eos - _begin); - size_t count = static_cast(end_ - begin_); - - if (size_ + count > capacity) - { - // reallocate the old array or allocate a new one - xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), (size_ + count) * sizeof(xpath_node))); - assert(data); - - // finalize - _begin = data; - _end = data + size_; - _eos = data + size_ + count; - } - - memcpy(_end, begin_, count * sizeof(xpath_node)); - _end += count; - } - - void sort_do() - { - _type = xpath_sort(_begin, _end, _type, false); - } - - void truncate(xpath_node* pos) - { - assert(_begin <= pos && pos <= _end); - - _end = pos; - } - - void remove_duplicates() - { - if (_type == xpath_node_set::type_unsorted) - sort(_begin, _end, duplicate_comparator()); - - _end = unique(_begin, _end); - } - - xpath_node_set::type_t type() const - { - return _type; - } - - void set_type(xpath_node_set::type_t value) - { - _type = value; - } - }; - - PUGI__FN_NO_INLINE void xpath_node_set_raw::push_back_grow(const xpath_node& node, xpath_allocator* alloc) - { - size_t capacity = static_cast(_eos - _begin); - - // get new capacity (1.5x rule) - size_t new_capacity = capacity + capacity / 2 + 1; - - // reallocate the old array or allocate a new one - xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node))); - assert(data); - - // finalize - _begin = data; - _end = data + capacity; - _eos = data + new_capacity; - - // push - *_end++ = node; - } -PUGI__NS_END - -PUGI__NS_BEGIN - struct xpath_context - { - xpath_node n; - size_t position, size; - - xpath_context(const xpath_node& n_, size_t position_, size_t size_): n(n_), position(position_), size(size_) - { - } - }; - - enum lexeme_t - { - lex_none = 0, - lex_equal, - lex_not_equal, - lex_less, - lex_greater, - lex_less_or_equal, - lex_greater_or_equal, - lex_plus, - lex_minus, - lex_multiply, - lex_union, - lex_var_ref, - lex_open_brace, - lex_close_brace, - lex_quoted_string, - lex_number, - lex_slash, - lex_double_slash, - lex_open_square_brace, - lex_close_square_brace, - lex_string, - lex_comma, - lex_axis_attribute, - lex_dot, - lex_double_dot, - lex_double_colon, - lex_eof - }; - - struct xpath_lexer_string - { - const char_t* begin; - const char_t* end; - - xpath_lexer_string(): begin(0), end(0) - { - } - - bool operator==(const char_t* other) const - { - size_t length = static_cast(end - begin); - - return strequalrange(other, begin, length); - } - }; - - class xpath_lexer - { - const char_t* _cur; - const char_t* _cur_lexeme_pos; - xpath_lexer_string _cur_lexeme_contents; - - lexeme_t _cur_lexeme; - - public: - explicit xpath_lexer(const char_t* query): _cur(query) - { - next(); - } - - const char_t* state() const - { - return _cur; - } - - void next() - { - const char_t* cur = _cur; - - while (PUGI__IS_CHARTYPE(*cur, ct_space)) ++cur; - - // save lexeme position for error reporting - _cur_lexeme_pos = cur; - - switch (*cur) - { - case 0: - _cur_lexeme = lex_eof; - break; - - case '>': - if (*(cur+1) == '=') - { - cur += 2; - _cur_lexeme = lex_greater_or_equal; - } - else - { - cur += 1; - _cur_lexeme = lex_greater; - } - break; - - case '<': - if (*(cur+1) == '=') - { - cur += 2; - _cur_lexeme = lex_less_or_equal; - } - else - { - cur += 1; - _cur_lexeme = lex_less; - } - break; - - case '!': - if (*(cur+1) == '=') - { - cur += 2; - _cur_lexeme = lex_not_equal; - } - else - { - _cur_lexeme = lex_none; - } - break; - - case '=': - cur += 1; - _cur_lexeme = lex_equal; - - break; - - case '+': - cur += 1; - _cur_lexeme = lex_plus; - - break; - - case '-': - cur += 1; - _cur_lexeme = lex_minus; - - break; - - case '*': - cur += 1; - _cur_lexeme = lex_multiply; - - break; - - case '|': - cur += 1; - _cur_lexeme = lex_union; - - break; - - case '$': - cur += 1; - - if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) - { - _cur_lexeme_contents.begin = cur; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - - if (cur[0] == ':' && PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // qname - { - cur++; // : - - while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - } - - _cur_lexeme_contents.end = cur; - - _cur_lexeme = lex_var_ref; - } - else - { - _cur_lexeme = lex_none; - } - - break; - - case '(': - cur += 1; - _cur_lexeme = lex_open_brace; - - break; - - case ')': - cur += 1; - _cur_lexeme = lex_close_brace; - - break; - - case '[': - cur += 1; - _cur_lexeme = lex_open_square_brace; - - break; - - case ']': - cur += 1; - _cur_lexeme = lex_close_square_brace; - - break; - - case ',': - cur += 1; - _cur_lexeme = lex_comma; - - break; - - case '/': - if (*(cur+1) == '/') - { - cur += 2; - _cur_lexeme = lex_double_slash; - } - else - { - cur += 1; - _cur_lexeme = lex_slash; - } - break; - - case '.': - if (*(cur+1) == '.') - { - cur += 2; - _cur_lexeme = lex_double_dot; - } - else if (PUGI__IS_CHARTYPEX(*(cur+1), ctx_digit)) - { - _cur_lexeme_contents.begin = cur; // . - - ++cur; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; - - _cur_lexeme_contents.end = cur; - - _cur_lexeme = lex_number; - } - else - { - cur += 1; - _cur_lexeme = lex_dot; - } - break; - - case '@': - cur += 1; - _cur_lexeme = lex_axis_attribute; - - break; - - case '"': - case '\'': - { - char_t terminator = *cur; - - ++cur; - - _cur_lexeme_contents.begin = cur; - while (*cur && *cur != terminator) cur++; - _cur_lexeme_contents.end = cur; - - if (!*cur) - _cur_lexeme = lex_none; - else - { - cur += 1; - _cur_lexeme = lex_quoted_string; - } - - break; - } - - case ':': - if (*(cur+1) == ':') - { - cur += 2; - _cur_lexeme = lex_double_colon; - } - else - { - _cur_lexeme = lex_none; - } - break; - - default: - if (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) - { - _cur_lexeme_contents.begin = cur; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; - - if (*cur == '.') - { - cur++; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; - } - - _cur_lexeme_contents.end = cur; - - _cur_lexeme = lex_number; - } - else if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) - { - _cur_lexeme_contents.begin = cur; - - while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - - if (cur[0] == ':') - { - if (cur[1] == '*') // namespace test ncname:* - { - cur += 2; // :* - } - else if (PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // namespace test qname - { - cur++; // : - - while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; - } - } - - _cur_lexeme_contents.end = cur; - - _cur_lexeme = lex_string; - } - else - { - _cur_lexeme = lex_none; - } - } - - _cur = cur; - } - - lexeme_t current() const - { - return _cur_lexeme; - } - - const char_t* current_pos() const - { - return _cur_lexeme_pos; - } - - const xpath_lexer_string& contents() const - { - assert(_cur_lexeme == lex_var_ref || _cur_lexeme == lex_number || _cur_lexeme == lex_string || _cur_lexeme == lex_quoted_string); - - return _cur_lexeme_contents; - } - }; - - enum ast_type_t - { - ast_unknown, - ast_op_or, // left or right - ast_op_and, // left and right - ast_op_equal, // left = right - ast_op_not_equal, // left != right - ast_op_less, // left < right - ast_op_greater, // left > right - ast_op_less_or_equal, // left <= right - ast_op_greater_or_equal, // left >= right - ast_op_add, // left + right - ast_op_subtract, // left - right - ast_op_multiply, // left * right - ast_op_divide, // left / right - ast_op_mod, // left % right - ast_op_negate, // left - right - ast_op_union, // left | right - ast_predicate, // apply predicate to set; next points to next predicate - ast_filter, // select * from left where right - ast_string_constant, // string constant - ast_number_constant, // number constant - ast_variable, // variable - ast_func_last, // last() - ast_func_position, // position() - ast_func_count, // count(left) - ast_func_id, // id(left) - ast_func_local_name_0, // local-name() - ast_func_local_name_1, // local-name(left) - ast_func_namespace_uri_0, // namespace-uri() - ast_func_namespace_uri_1, // namespace-uri(left) - ast_func_name_0, // name() - ast_func_name_1, // name(left) - ast_func_string_0, // string() - ast_func_string_1, // string(left) - ast_func_concat, // concat(left, right, siblings) - ast_func_starts_with, // starts_with(left, right) - ast_func_contains, // contains(left, right) - ast_func_substring_before, // substring-before(left, right) - ast_func_substring_after, // substring-after(left, right) - ast_func_substring_2, // substring(left, right) - ast_func_substring_3, // substring(left, right, third) - ast_func_string_length_0, // string-length() - ast_func_string_length_1, // string-length(left) - ast_func_normalize_space_0, // normalize-space() - ast_func_normalize_space_1, // normalize-space(left) - ast_func_translate, // translate(left, right, third) - ast_func_boolean, // boolean(left) - ast_func_not, // not(left) - ast_func_true, // true() - ast_func_false, // false() - ast_func_lang, // lang(left) - ast_func_number_0, // number() - ast_func_number_1, // number(left) - ast_func_sum, // sum(left) - ast_func_floor, // floor(left) - ast_func_ceiling, // ceiling(left) - ast_func_round, // round(left) - ast_step, // process set left with step - ast_step_root, // select root node - - ast_opt_translate_table, // translate(left, right, third) where right/third are constants - ast_opt_compare_attribute // @name = 'string' - }; - - enum axis_t - { - axis_ancestor, - axis_ancestor_or_self, - axis_attribute, - axis_child, - axis_descendant, - axis_descendant_or_self, - axis_following, - axis_following_sibling, - axis_namespace, - axis_parent, - axis_preceding, - axis_preceding_sibling, - axis_self - }; - - enum nodetest_t - { - nodetest_none, - nodetest_name, - nodetest_type_node, - nodetest_type_comment, - nodetest_type_pi, - nodetest_type_text, - nodetest_pi, - nodetest_all, - nodetest_all_in_namespace - }; - - enum predicate_t - { - predicate_default, - predicate_posinv, - predicate_constant, - predicate_constant_one - }; - - enum nodeset_eval_t - { - nodeset_eval_all, - nodeset_eval_any, - nodeset_eval_first - }; - - template struct axis_to_type - { - static const axis_t axis; - }; - - template const axis_t axis_to_type::axis = N; - - class xpath_ast_node - { - private: - // node type - char _type; - char _rettype; - - // for ast_step - char _axis; - - // for ast_step/ast_predicate/ast_filter - char _test; - - // tree node structure - xpath_ast_node* _left; - xpath_ast_node* _right; - xpath_ast_node* _next; - - union - { - // value for ast_string_constant - const char_t* string; - // value for ast_number_constant - double number; - // variable for ast_variable - xpath_variable* variable; - // node test for ast_step (node name/namespace/node type/pi target) - const char_t* nodetest; - // table for ast_opt_translate_table - const unsigned char* table; - } _data; - - xpath_ast_node(const xpath_ast_node&); - xpath_ast_node& operator=(const xpath_ast_node&); - - template static bool compare_eq(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) - { - xpath_value_type lt = lhs->rettype(), rt = rhs->rettype(); - - if (lt != xpath_type_node_set && rt != xpath_type_node_set) - { - if (lt == xpath_type_boolean || rt == xpath_type_boolean) - return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack)); - else if (lt == xpath_type_number || rt == xpath_type_number) - return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack)); - else if (lt == xpath_type_string || rt == xpath_type_string) - { - xpath_allocator_capture cr(stack.result); - - xpath_string ls = lhs->eval_string(c, stack); - xpath_string rs = rhs->eval_string(c, stack); - - return comp(ls, rs); - } - } - else if (lt == xpath_type_node_set && rt == xpath_type_node_set) - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ls = lhs->eval_node_set(c, stack, nodeset_eval_all); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); - - for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture cri(stack.result); - - if (comp(string_value(*li, stack.result), string_value(*ri, stack.result))) - return true; - } - - return false; - } - else - { - if (lt == xpath_type_node_set) - { - swap(lhs, rhs); - swap(lt, rt); - } - - if (lt == xpath_type_boolean) - return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack)); - else if (lt == xpath_type_number) - { - xpath_allocator_capture cr(stack.result); - - double l = lhs->eval_number(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); - - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture cri(stack.result); - - if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) - return true; - } - - return false; - } - else if (lt == xpath_type_string) - { - xpath_allocator_capture cr(stack.result); - - xpath_string l = lhs->eval_string(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); - - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture cri(stack.result); - - if (comp(l, string_value(*ri, stack.result))) - return true; - } - - return false; - } - } - - assert(!"Wrong types"); - return false; - } - - static bool eval_once(xpath_node_set::type_t type, nodeset_eval_t eval) - { - return type == xpath_node_set::type_sorted ? eval != nodeset_eval_all : eval == nodeset_eval_any; - } - - template static bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) - { - xpath_value_type lt = lhs->rettype(), rt = rhs->rettype(); - - if (lt != xpath_type_node_set && rt != xpath_type_node_set) - return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack)); - else if (lt == xpath_type_node_set && rt == xpath_type_node_set) - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ls = lhs->eval_node_set(c, stack, nodeset_eval_all); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); - - for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) - { - xpath_allocator_capture cri(stack.result); - - double l = convert_string_to_number(string_value(*li, stack.result).c_str()); - - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture crii(stack.result); - - if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) - return true; - } - } - - return false; - } - else if (lt != xpath_type_node_set && rt == xpath_type_node_set) - { - xpath_allocator_capture cr(stack.result); - - double l = lhs->eval_number(c, stack); - xpath_node_set_raw rs = rhs->eval_node_set(c, stack, nodeset_eval_all); - - for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri) - { - xpath_allocator_capture cri(stack.result); - - if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str()))) - return true; - } - - return false; - } - else if (lt == xpath_type_node_set && rt != xpath_type_node_set) - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ls = lhs->eval_node_set(c, stack, nodeset_eval_all); - double r = rhs->eval_number(c, stack); - - for (const xpath_node* li = ls.begin(); li != ls.end(); ++li) - { - xpath_allocator_capture cri(stack.result); - - if (comp(convert_string_to_number(string_value(*li, stack.result).c_str()), r)) - return true; - } - - return false; - } - else - { - assert(!"Wrong types"); - return false; - } - } - - static void apply_predicate_boolean(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack, bool once) - { - assert(ns.size() >= first); - assert(expr->rettype() != xpath_type_number); - - size_t i = 1; - size_t size = ns.size() - first; - - xpath_node* last = ns.begin() + first; - - // remove_if... or well, sort of - for (xpath_node* it = last; it != ns.end(); ++it, ++i) - { - xpath_context c(*it, i, size); - - if (expr->eval_boolean(c, stack)) - { - *last++ = *it; - - if (once) break; - } - } - - ns.truncate(last); - } - - static void apply_predicate_number(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack, bool once) - { - assert(ns.size() >= first); - assert(expr->rettype() == xpath_type_number); - - size_t i = 1; - size_t size = ns.size() - first; - - xpath_node* last = ns.begin() + first; - - // remove_if... or well, sort of - for (xpath_node* it = last; it != ns.end(); ++it, ++i) - { - xpath_context c(*it, i, size); - - if (expr->eval_number(c, stack) == i) - { - *last++ = *it; - - if (once) break; - } - } - - ns.truncate(last); - } - - static void apply_predicate_number_const(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack) - { - assert(ns.size() >= first); - assert(expr->rettype() == xpath_type_number); - - size_t size = ns.size() - first; - - xpath_node* last = ns.begin() + first; - - xpath_context c(xpath_node(), 1, size); - - double er = expr->eval_number(c, stack); - - if (er >= 1.0 && er <= size) - { - size_t eri = static_cast(er); - - if (er == eri) - { - xpath_node r = last[eri - 1]; - - *last++ = r; - } - } - - ns.truncate(last); - } - - void apply_predicate(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack, bool once) - { - if (ns.size() == first) return; - - assert(_type == ast_filter || _type == ast_predicate); - - if (_test == predicate_constant || _test == predicate_constant_one) - apply_predicate_number_const(ns, first, _right, stack); - else if (_right->rettype() == xpath_type_number) - apply_predicate_number(ns, first, _right, stack, once); - else - apply_predicate_boolean(ns, first, _right, stack, once); - } - - void apply_predicates(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack, nodeset_eval_t eval) - { - if (ns.size() == first) return; - - bool last_once = eval_once(ns.type(), eval); - - for (xpath_ast_node* pred = _right; pred; pred = pred->_next) - pred->apply_predicate(ns, first, stack, !pred->_next && last_once); - } - - bool step_push(xpath_node_set_raw& ns, xml_attribute_struct* a, xml_node_struct* parent, xpath_allocator* alloc) - { - assert(a); - - const char_t* name = a->name ? a->name : PUGIXML_TEXT(""); - - switch (_test) - { - case nodetest_name: - if (strequal(name, _data.nodetest) && is_xpath_attribute(name)) - { - ns.push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc); - return true; - } - break; - - case nodetest_type_node: - case nodetest_all: - if (is_xpath_attribute(name)) - { - ns.push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc); - return true; - } - break; - - case nodetest_all_in_namespace: - if (starts_with(name, _data.nodetest) && is_xpath_attribute(name)) - { - ns.push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc); - return true; - } - break; - - default: - ; - } - - return false; - } - - bool step_push(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc) - { - assert(n); - - xml_node_type type = PUGI__NODETYPE(n); - - switch (_test) - { - case nodetest_name: - if (type == node_element && n->name && strequal(n->name, _data.nodetest)) - { - ns.push_back(xml_node(n), alloc); - return true; - } - break; - - case nodetest_type_node: - ns.push_back(xml_node(n), alloc); - return true; - - case nodetest_type_comment: - if (type == node_comment) - { - ns.push_back(xml_node(n), alloc); - return true; - } - break; - - case nodetest_type_text: - if (type == node_pcdata || type == node_cdata) - { - ns.push_back(xml_node(n), alloc); - return true; - } - break; - - case nodetest_type_pi: - if (type == node_pi) - { - ns.push_back(xml_node(n), alloc); - return true; - } - break; - - case nodetest_pi: - if (type == node_pi && n->name && strequal(n->name, _data.nodetest)) - { - ns.push_back(xml_node(n), alloc); - return true; - } - break; - - case nodetest_all: - if (type == node_element) - { - ns.push_back(xml_node(n), alloc); - return true; - } - break; - - case nodetest_all_in_namespace: - if (type == node_element && n->name && starts_with(n->name, _data.nodetest)) - { - ns.push_back(xml_node(n), alloc); - return true; - } - break; - - default: - assert(!"Unknown axis"); - } - - return false; - } - - template void step_fill(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc, bool once, T) - { - const axis_t axis = T::axis; - - switch (axis) - { - case axis_attribute: - { - for (xml_attribute_struct* a = n->first_attribute; a; a = a->next_attribute) - if (step_push(ns, a, n, alloc) & once) - return; - - break; - } - - case axis_child: - { - for (xml_node_struct* c = n->first_child; c; c = c->next_sibling) - if (step_push(ns, c, alloc) & once) - return; - - break; - } - - case axis_descendant: - case axis_descendant_or_self: - { - if (axis == axis_descendant_or_self) - if (step_push(ns, n, alloc) & once) - return; - - xml_node_struct* cur = n->first_child; - - while (cur) - { - if (step_push(ns, cur, alloc) & once) - return; - - if (cur->first_child) - cur = cur->first_child; - else - { - while (!cur->next_sibling) - { - cur = cur->parent; - - if (cur == n) return; - } - - cur = cur->next_sibling; - } - } - - break; - } - - case axis_following_sibling: - { - for (xml_node_struct* c = n->next_sibling; c; c = c->next_sibling) - if (step_push(ns, c, alloc) & once) - return; - - break; - } - - case axis_preceding_sibling: - { - for (xml_node_struct* c = n->prev_sibling_c; c->next_sibling; c = c->prev_sibling_c) - if (step_push(ns, c, alloc) & once) - return; - - break; - } - - case axis_following: - { - xml_node_struct* cur = n; - - // exit from this node so that we don't include descendants - while (!cur->next_sibling) - { - cur = cur->parent; - - if (!cur) return; - } - - cur = cur->next_sibling; - - while (cur) - { - if (step_push(ns, cur, alloc) & once) - return; - - if (cur->first_child) - cur = cur->first_child; - else - { - while (!cur->next_sibling) - { - cur = cur->parent; - - if (!cur) return; - } - - cur = cur->next_sibling; - } - } - - break; - } - - case axis_preceding: - { - xml_node_struct* cur = n; - - // exit from this node so that we don't include descendants - while (!cur->prev_sibling_c->next_sibling) - { - cur = cur->parent; - - if (!cur) return; - } - - cur = cur->prev_sibling_c; - - while (cur) - { - if (cur->first_child) - cur = cur->first_child->prev_sibling_c; - else - { - // leaf node, can't be ancestor - if (step_push(ns, cur, alloc) & once) - return; - - while (!cur->prev_sibling_c->next_sibling) - { - cur = cur->parent; - - if (!cur) return; - - if (!node_is_ancestor(cur, n)) - if (step_push(ns, cur, alloc) & once) - return; - } - - cur = cur->prev_sibling_c; - } - } - - break; - } - - case axis_ancestor: - case axis_ancestor_or_self: - { - if (axis == axis_ancestor_or_self) - if (step_push(ns, n, alloc) & once) - return; - - xml_node_struct* cur = n->parent; - - while (cur) - { - if (step_push(ns, cur, alloc) & once) - return; - - cur = cur->parent; - } - - break; - } - - case axis_self: - { - step_push(ns, n, alloc); - - break; - } - - case axis_parent: - { - if (n->parent) - step_push(ns, n->parent, alloc); - - break; - } - - default: - assert(!"Unimplemented axis"); - } - } - - template void step_fill(xpath_node_set_raw& ns, xml_attribute_struct* a, xml_node_struct* p, xpath_allocator* alloc, bool once, T v) - { - const axis_t axis = T::axis; - - switch (axis) - { - case axis_ancestor: - case axis_ancestor_or_self: - { - if (axis == axis_ancestor_or_self && _test == nodetest_type_node) // reject attributes based on principal node type test - if (step_push(ns, a, p, alloc) & once) - return; - - xml_node_struct* cur = p; - - while (cur) - { - if (step_push(ns, cur, alloc) & once) - return; - - cur = cur->parent; - } - - break; - } - - case axis_descendant_or_self: - case axis_self: - { - if (_test == nodetest_type_node) // reject attributes based on principal node type test - step_push(ns, a, p, alloc); - - break; - } - - case axis_following: - { - xml_node_struct* cur = p; - - while (cur) - { - if (cur->first_child) - cur = cur->first_child; - else - { - while (!cur->next_sibling) - { - cur = cur->parent; - - if (!cur) return; - } - - cur = cur->next_sibling; - } - - if (step_push(ns, cur, alloc) & once) - return; - } - - break; - } - - case axis_parent: - { - step_push(ns, p, alloc); - - break; - } - - case axis_preceding: - { - // preceding:: axis does not include attribute nodes and attribute ancestors (they are the same as parent's ancestors), so we can reuse node preceding - step_fill(ns, p, alloc, once, v); - break; - } - - default: - assert(!"Unimplemented axis"); - } - } - - template void step_fill(xpath_node_set_raw& ns, const xpath_node& xn, xpath_allocator* alloc, bool once, T v) - { - const axis_t axis = T::axis; - const bool axis_has_attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); - - if (xn.node()) - step_fill(ns, xn.node().internal_object(), alloc, once, v); - else if (axis_has_attributes && xn.attribute() && xn.parent()) - step_fill(ns, xn.attribute().internal_object(), xn.parent().internal_object(), alloc, once, v); - } - - template xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval, T v) - { - const axis_t axis = T::axis; - const bool axis_reverse = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling); - const xpath_node_set::type_t axis_type = axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; - - bool once = - (axis == axis_attribute && _test == nodetest_name) || - (!_right && eval_once(axis_type, eval)) || - (_right && !_right->_next && _right->_test == predicate_constant_one); - - xpath_node_set_raw ns; - ns.set_type(axis_type); - - if (_left) - { - xpath_node_set_raw s = _left->eval_node_set(c, stack, nodeset_eval_all); - - // self axis preserves the original order - if (axis == axis_self) ns.set_type(s.type()); - - for (const xpath_node* it = s.begin(); it != s.end(); ++it) - { - size_t size = ns.size(); - - // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes - if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); - - step_fill(ns, *it, stack.result, once, v); - if (_right) apply_predicates(ns, size, stack, eval); - } - } - else - { - step_fill(ns, c.n, stack.result, once, v); - if (_right) apply_predicates(ns, 0, stack, eval); - } - - // child, attribute and self axes always generate unique set of nodes - // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice - if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted) - ns.remove_duplicates(); - - return ns; - } - - public: - xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t* value): - _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) - { - assert(type == ast_string_constant); - _data.string = value; - } - - xpath_ast_node(ast_type_t type, xpath_value_type rettype_, double value): - _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) - { - assert(type == ast_number_constant); - _data.number = value; - } - - xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_variable* value): - _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) - { - assert(type == ast_variable); - _data.variable = value; - } - - xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_ast_node* left = 0, xpath_ast_node* right = 0): - _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(left), _right(right), _next(0) - { - } - - xpath_ast_node(ast_type_t type, xpath_ast_node* left, axis_t axis, nodetest_t test, const char_t* contents): - _type(static_cast(type)), _rettype(xpath_type_node_set), _axis(static_cast(axis)), _test(static_cast(test)), _left(left), _right(0), _next(0) - { - assert(type == ast_step); - _data.nodetest = contents; - } - - xpath_ast_node(ast_type_t type, xpath_ast_node* left, xpath_ast_node* right, predicate_t test): - _type(static_cast(type)), _rettype(xpath_type_node_set), _axis(0), _test(static_cast(test)), _left(left), _right(right), _next(0) - { - assert(type == ast_filter || type == ast_predicate); - } - - void set_next(xpath_ast_node* value) - { - _next = value; - } - - void set_right(xpath_ast_node* value) - { - _right = value; - } - - bool eval_boolean(const xpath_context& c, const xpath_stack& stack) - { - switch (_type) - { - case ast_op_or: - return _left->eval_boolean(c, stack) || _right->eval_boolean(c, stack); - - case ast_op_and: - return _left->eval_boolean(c, stack) && _right->eval_boolean(c, stack); - - case ast_op_equal: - return compare_eq(_left, _right, c, stack, equal_to()); - - case ast_op_not_equal: - return compare_eq(_left, _right, c, stack, not_equal_to()); - - case ast_op_less: - return compare_rel(_left, _right, c, stack, less()); - - case ast_op_greater: - return compare_rel(_right, _left, c, stack, less()); - - case ast_op_less_or_equal: - return compare_rel(_left, _right, c, stack, less_equal()); - - case ast_op_greater_or_equal: - return compare_rel(_right, _left, c, stack, less_equal()); - - case ast_func_starts_with: - { - xpath_allocator_capture cr(stack.result); - - xpath_string lr = _left->eval_string(c, stack); - xpath_string rr = _right->eval_string(c, stack); - - return starts_with(lr.c_str(), rr.c_str()); - } - - case ast_func_contains: - { - xpath_allocator_capture cr(stack.result); - - xpath_string lr = _left->eval_string(c, stack); - xpath_string rr = _right->eval_string(c, stack); - - return find_substring(lr.c_str(), rr.c_str()) != 0; - } - - case ast_func_boolean: - return _left->eval_boolean(c, stack); - - case ast_func_not: - return !_left->eval_boolean(c, stack); - - case ast_func_true: - return true; - - case ast_func_false: - return false; - - case ast_func_lang: - { - if (c.n.attribute()) return false; - - xpath_allocator_capture cr(stack.result); - - xpath_string lang = _left->eval_string(c, stack); - - for (xml_node n = c.n.node(); n; n = n.parent()) - { - xml_attribute a = n.attribute(PUGIXML_TEXT("xml:lang")); - - if (a) - { - const char_t* value = a.value(); - - // strnicmp / strncasecmp is not portable - for (const char_t* lit = lang.c_str(); *lit; ++lit) - { - if (tolower_ascii(*lit) != tolower_ascii(*value)) return false; - ++value; - } - - return *value == 0 || *value == '-'; - } - } - - return false; - } - - case ast_opt_compare_attribute: - { - const char_t* value = (_right->_type == ast_string_constant) ? _right->_data.string : _right->_data.variable->get_string(); - - xml_attribute attr = c.n.node().attribute(_left->_data.nodetest); - - return attr && strequal(attr.value(), value) && is_xpath_attribute(attr.name()); - } - - case ast_variable: - { - assert(_rettype == _data.variable->type()); - - if (_rettype == xpath_type_boolean) - return _data.variable->get_boolean(); - - // fallthrough to type conversion - } - - default: - { - switch (_rettype) - { - case xpath_type_number: - return convert_number_to_boolean(eval_number(c, stack)); - - case xpath_type_string: - { - xpath_allocator_capture cr(stack.result); - - return !eval_string(c, stack).empty(); - } - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.result); - - return !eval_node_set(c, stack, nodeset_eval_any).empty(); - } - - default: - assert(!"Wrong expression for return type boolean"); - return false; - } - } - } - } - - double eval_number(const xpath_context& c, const xpath_stack& stack) - { - switch (_type) - { - case ast_op_add: - return _left->eval_number(c, stack) + _right->eval_number(c, stack); - - case ast_op_subtract: - return _left->eval_number(c, stack) - _right->eval_number(c, stack); - - case ast_op_multiply: - return _left->eval_number(c, stack) * _right->eval_number(c, stack); - - case ast_op_divide: - return _left->eval_number(c, stack) / _right->eval_number(c, stack); - - case ast_op_mod: - return fmod(_left->eval_number(c, stack), _right->eval_number(c, stack)); - - case ast_op_negate: - return -_left->eval_number(c, stack); - - case ast_number_constant: - return _data.number; - - case ast_func_last: - return static_cast(c.size); - - case ast_func_position: - return static_cast(c.position); - - case ast_func_count: - { - xpath_allocator_capture cr(stack.result); - - return static_cast(_left->eval_node_set(c, stack, nodeset_eval_all).size()); - } - - case ast_func_string_length_0: - { - xpath_allocator_capture cr(stack.result); - - return static_cast(string_value(c.n, stack.result).length()); - } - - case ast_func_string_length_1: - { - xpath_allocator_capture cr(stack.result); - - return static_cast(_left->eval_string(c, stack).length()); - } - - case ast_func_number_0: - { - xpath_allocator_capture cr(stack.result); - - return convert_string_to_number(string_value(c.n, stack.result).c_str()); - } - - case ast_func_number_1: - return _left->eval_number(c, stack); - - case ast_func_sum: - { - xpath_allocator_capture cr(stack.result); - - double r = 0; - - xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_all); - - for (const xpath_node* it = ns.begin(); it != ns.end(); ++it) - { - xpath_allocator_capture cri(stack.result); - - r += convert_string_to_number(string_value(*it, stack.result).c_str()); - } - - return r; - } - - case ast_func_floor: - { - double r = _left->eval_number(c, stack); - - return r == r ? floor(r) : r; - } - - case ast_func_ceiling: - { - double r = _left->eval_number(c, stack); - - return r == r ? ceil(r) : r; - } - - case ast_func_round: - return round_nearest_nzero(_left->eval_number(c, stack)); - - case ast_variable: - { - assert(_rettype == _data.variable->type()); - - if (_rettype == xpath_type_number) - return _data.variable->get_number(); - - // fallthrough to type conversion - } - - default: - { - switch (_rettype) - { - case xpath_type_boolean: - return eval_boolean(c, stack) ? 1 : 0; - - case xpath_type_string: - { - xpath_allocator_capture cr(stack.result); - - return convert_string_to_number(eval_string(c, stack).c_str()); - } - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.result); - - return convert_string_to_number(eval_string(c, stack).c_str()); - } - - default: - assert(!"Wrong expression for return type number"); - return 0; - } - - } - } - } - - xpath_string eval_string_concat(const xpath_context& c, const xpath_stack& stack) - { - assert(_type == ast_func_concat); - - xpath_allocator_capture ct(stack.temp); - - // count the string number - size_t count = 1; - for (xpath_ast_node* nc = _right; nc; nc = nc->_next) count++; - - // gather all strings - xpath_string static_buffer[4]; - xpath_string* buffer = static_buffer; - - // allocate on-heap for large concats - if (count > sizeof(static_buffer) / sizeof(static_buffer[0])) - { - buffer = static_cast(stack.temp->allocate(count * sizeof(xpath_string))); - assert(buffer); - } - - // evaluate all strings to temporary stack - xpath_stack swapped_stack = {stack.temp, stack.result}; - - buffer[0] = _left->eval_string(c, swapped_stack); - - size_t pos = 1; - for (xpath_ast_node* n = _right; n; n = n->_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack); - assert(pos == count); - - // get total length - size_t length = 0; - for (size_t i = 0; i < count; ++i) length += buffer[i].length(); - - // create final string - char_t* result = static_cast(stack.result->allocate((length + 1) * sizeof(char_t))); - assert(result); - - char_t* ri = result; - - for (size_t j = 0; j < count; ++j) - for (const char_t* bi = buffer[j].c_str(); *bi; ++bi) - *ri++ = *bi; - - *ri = 0; - - return xpath_string::from_heap_preallocated(result, ri); - } - - xpath_string eval_string(const xpath_context& c, const xpath_stack& stack) - { - switch (_type) - { - case ast_string_constant: - return xpath_string::from_const(_data.string); - - case ast_func_local_name_0: - { - xpath_node na = c.n; - - return xpath_string::from_const(local_name(na)); - } - - case ast_func_local_name_1: - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); - xpath_node na = ns.first(); - - return xpath_string::from_const(local_name(na)); - } - - case ast_func_name_0: - { - xpath_node na = c.n; - - return xpath_string::from_const(qualified_name(na)); - } - - case ast_func_name_1: - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); - xpath_node na = ns.first(); - - return xpath_string::from_const(qualified_name(na)); - } - - case ast_func_namespace_uri_0: - { - xpath_node na = c.n; - - return xpath_string::from_const(namespace_uri(na)); - } - - case ast_func_namespace_uri_1: - { - xpath_allocator_capture cr(stack.result); - - xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); - xpath_node na = ns.first(); - - return xpath_string::from_const(namespace_uri(na)); - } - - case ast_func_string_0: - return string_value(c.n, stack.result); - - case ast_func_string_1: - return _left->eval_string(c, stack); - - case ast_func_concat: - return eval_string_concat(c, stack); - - case ast_func_substring_before: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, swapped_stack); - xpath_string p = _right->eval_string(c, swapped_stack); - - const char_t* pos = find_substring(s.c_str(), p.c_str()); - - return pos ? xpath_string::from_heap(s.c_str(), pos, stack.result) : xpath_string(); - } - - case ast_func_substring_after: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, swapped_stack); - xpath_string p = _right->eval_string(c, swapped_stack); - - const char_t* pos = find_substring(s.c_str(), p.c_str()); - if (!pos) return xpath_string(); - - const char_t* rbegin = pos + p.length(); - const char_t* rend = s.c_str() + s.length(); - - return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin); - } - - case ast_func_substring_2: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, swapped_stack); - size_t s_length = s.length(); - - double first = round_nearest(_right->eval_number(c, stack)); - - if (is_nan(first)) return xpath_string(); // NaN - else if (first >= s_length + 1) return xpath_string(); - - size_t pos = first < 1 ? 1 : static_cast(first); - assert(1 <= pos && pos <= s_length + 1); - - const char_t* rbegin = s.c_str() + (pos - 1); - const char_t* rend = s.c_str() + s.length(); - - return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin); - } - - case ast_func_substring_3: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, swapped_stack); - size_t s_length = s.length(); - - double first = round_nearest(_right->eval_number(c, stack)); - double last = first + round_nearest(_right->_next->eval_number(c, stack)); - - if (is_nan(first) || is_nan(last)) return xpath_string(); - else if (first >= s_length + 1) return xpath_string(); - else if (first >= last) return xpath_string(); - else if (last < 1) return xpath_string(); - - size_t pos = first < 1 ? 1 : static_cast(first); - size_t end = last >= s_length + 1 ? s_length + 1 : static_cast(last); - - assert(1 <= pos && pos <= end && end <= s_length + 1); - const char_t* rbegin = s.c_str() + (pos - 1); - const char_t* rend = s.c_str() + (end - 1); - - return (end == s_length + 1 && !s.uses_heap()) ? xpath_string::from_const(rbegin) : xpath_string::from_heap(rbegin, rend, stack.result); - } - - case ast_func_normalize_space_0: - { - xpath_string s = string_value(c.n, stack.result); - - char_t* begin = s.data(stack.result); - char_t* end = normalize_space(begin); - - return xpath_string::from_heap_preallocated(begin, end); - } - - case ast_func_normalize_space_1: - { - xpath_string s = _left->eval_string(c, stack); - - char_t* begin = s.data(stack.result); - char_t* end = normalize_space(begin); - - return xpath_string::from_heap_preallocated(begin, end); - } - - case ast_func_translate: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_string s = _left->eval_string(c, stack); - xpath_string from = _right->eval_string(c, swapped_stack); - xpath_string to = _right->_next->eval_string(c, swapped_stack); - - char_t* begin = s.data(stack.result); - char_t* end = translate(begin, from.c_str(), to.c_str(), to.length()); - - return xpath_string::from_heap_preallocated(begin, end); - } - - case ast_opt_translate_table: - { - xpath_string s = _left->eval_string(c, stack); - - char_t* begin = s.data(stack.result); - char_t* end = translate_table(begin, _data.table); - - return xpath_string::from_heap_preallocated(begin, end); - } - - case ast_variable: - { - assert(_rettype == _data.variable->type()); - - if (_rettype == xpath_type_string) - return xpath_string::from_const(_data.variable->get_string()); - - // fallthrough to type conversion - } - - default: - { - switch (_rettype) - { - case xpath_type_boolean: - return xpath_string::from_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); - - case xpath_type_number: - return convert_number_to_string(eval_number(c, stack), stack.result); - - case xpath_type_node_set: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_node_set_raw ns = eval_node_set(c, swapped_stack, nodeset_eval_first); - return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result); - } - - default: - assert(!"Wrong expression for return type string"); - return xpath_string(); - } - } - } - } - - xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval) - { - switch (_type) - { - case ast_op_union: - { - xpath_allocator_capture cr(stack.temp); - - xpath_stack swapped_stack = {stack.temp, stack.result}; - - xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack, eval); - xpath_node_set_raw rs = _right->eval_node_set(c, stack, eval); - - // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother - rs.set_type(xpath_node_set::type_unsorted); - - rs.append(ls.begin(), ls.end(), stack.result); - rs.remove_duplicates(); - - return rs; - } - - case ast_filter: - { - xpath_node_set_raw set = _left->eval_node_set(c, stack, _test == predicate_constant_one ? nodeset_eval_first : nodeset_eval_all); - - // either expression is a number or it contains position() call; sort by document order - if (_test != predicate_posinv) set.sort_do(); - - bool once = eval_once(set.type(), eval); - - apply_predicate(set, 0, stack, once); - - return set; - } - - case ast_func_id: - return xpath_node_set_raw(); - - case ast_step: - { - switch (_axis) - { - case axis_ancestor: - return step_do(c, stack, eval, axis_to_type()); - - case axis_ancestor_or_self: - return step_do(c, stack, eval, axis_to_type()); - - case axis_attribute: - return step_do(c, stack, eval, axis_to_type()); - - case axis_child: - return step_do(c, stack, eval, axis_to_type()); - - case axis_descendant: - return step_do(c, stack, eval, axis_to_type()); - - case axis_descendant_or_self: - return step_do(c, stack, eval, axis_to_type()); - - case axis_following: - return step_do(c, stack, eval, axis_to_type()); - - case axis_following_sibling: - return step_do(c, stack, eval, axis_to_type()); - - case axis_namespace: - // namespaced axis is not supported - return xpath_node_set_raw(); - - case axis_parent: - return step_do(c, stack, eval, axis_to_type()); - - case axis_preceding: - return step_do(c, stack, eval, axis_to_type()); - - case axis_preceding_sibling: - return step_do(c, stack, eval, axis_to_type()); - - case axis_self: - return step_do(c, stack, eval, axis_to_type()); - - default: - assert(!"Unknown axis"); - return xpath_node_set_raw(); - } - } - - case ast_step_root: - { - assert(!_right); // root step can't have any predicates - - xpath_node_set_raw ns; - - ns.set_type(xpath_node_set::type_sorted); - - if (c.n.node()) ns.push_back(c.n.node().root(), stack.result); - else if (c.n.attribute()) ns.push_back(c.n.parent().root(), stack.result); - - return ns; - } - - case ast_variable: - { - assert(_rettype == _data.variable->type()); - - if (_rettype == xpath_type_node_set) - { - const xpath_node_set& s = _data.variable->get_node_set(); - - xpath_node_set_raw ns; - - ns.set_type(s.type()); - ns.append(s.begin(), s.end(), stack.result); - - return ns; - } - - // fallthrough to type conversion - } - - default: - assert(!"Wrong expression for return type node set"); - return xpath_node_set_raw(); - } - } - - void optimize(xpath_allocator* alloc) - { - if (_left) _left->optimize(alloc); - if (_right) _right->optimize(alloc); - if (_next) _next->optimize(alloc); - - // Rewrite [position()=expr] with [expr] - // Note that this step has to go before classification to recognize [position()=1] - if ((_type == ast_filter || _type == ast_predicate) && - _right->_type == ast_op_equal && _right->_left->_type == ast_func_position && _right->_right->_rettype == xpath_type_number) - { - _right = _right->_right; - } - - // Classify filter/predicate ops to perform various optimizations during evaluation - if (_type == ast_filter || _type == ast_predicate) - { - assert(_test == predicate_default); - - if (_right->_type == ast_number_constant && _right->_data.number == 1.0) - _test = predicate_constant_one; - else if (_right->_rettype == xpath_type_number && (_right->_type == ast_number_constant || _right->_type == ast_variable || _right->_type == ast_func_last)) - _test = predicate_constant; - else if (_right->_rettype != xpath_type_number && _right->is_posinv_expr()) - _test = predicate_posinv; - } - - // Rewrite descendant-or-self::node()/child::foo with descendant::foo - // The former is a full form of //foo, the latter is much faster since it executes the node test immediately - // Do a similar kind of rewrite for self/descendant/descendant-or-self axes - // Note that we only rewrite positionally invariant steps (//foo[1] != /descendant::foo[1]) - if (_type == ast_step && (_axis == axis_child || _axis == axis_self || _axis == axis_descendant || _axis == axis_descendant_or_self) && _left && - _left->_type == ast_step && _left->_axis == axis_descendant_or_self && _left->_test == nodetest_type_node && !_left->_right && - is_posinv_step()) - { - if (_axis == axis_child || _axis == axis_descendant) - _axis = axis_descendant; - else - _axis = axis_descendant_or_self; - - _left = _left->_left; - } - - // Use optimized lookup table implementation for translate() with constant arguments - if (_type == ast_func_translate && _right->_type == ast_string_constant && _right->_next->_type == ast_string_constant) - { - unsigned char* table = translate_table_generate(alloc, _right->_data.string, _right->_next->_data.string); - - if (table) - { - _type = ast_opt_translate_table; - _data.table = table; - } - } - - // Use optimized path for @attr = 'value' or @attr = $value - if (_type == ast_op_equal && - _left->_type == ast_step && _left->_axis == axis_attribute && _left->_test == nodetest_name && !_left->_left && !_left->_right && - (_right->_type == ast_string_constant || (_right->_type == ast_variable && _right->_rettype == xpath_type_string))) - { - _type = ast_opt_compare_attribute; - } - } - - bool is_posinv_expr() const - { - switch (_type) - { - case ast_func_position: - case ast_func_last: - return false; - - case ast_string_constant: - case ast_number_constant: - case ast_variable: - return true; - - case ast_step: - case ast_step_root: - return true; - - case ast_predicate: - case ast_filter: - return true; - - default: - if (_left && !_left->is_posinv_expr()) return false; - - for (xpath_ast_node* n = _right; n; n = n->_next) - if (!n->is_posinv_expr()) return false; - - return true; - } - } - - bool is_posinv_step() const - { - assert(_type == ast_step); - - for (xpath_ast_node* n = _right; n; n = n->_next) - { - assert(n->_type == ast_predicate); - - if (n->_test != predicate_posinv) - return false; - } - - return true; - } - - xpath_value_type rettype() const - { - return static_cast(_rettype); - } - }; - - struct xpath_parser - { - xpath_allocator* _alloc; - xpath_lexer _lexer; - - const char_t* _query; - xpath_variable_set* _variables; - - xpath_parse_result* _result; - - char_t _scratch[32]; - - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf _error_handler; - #endif - - void throw_error(const char* message) - { - _result->error = message; - _result->offset = _lexer.current_pos() - _query; - - #ifdef PUGIXML_NO_EXCEPTIONS - longjmp(_error_handler, 1); - #else - throw xpath_exception(*_result); - #endif - } - - void throw_error_oom() - { - #ifdef PUGIXML_NO_EXCEPTIONS - throw_error("Out of memory"); - #else - throw std::bad_alloc(); - #endif - } - - void* alloc_node() - { - void* result = _alloc->allocate_nothrow(sizeof(xpath_ast_node)); - - if (!result) throw_error_oom(); - - return result; - } - - const char_t* alloc_string(const xpath_lexer_string& value) - { - if (value.begin) - { - size_t length = static_cast(value.end - value.begin); - - char_t* c = static_cast(_alloc->allocate_nothrow((length + 1) * sizeof(char_t))); - if (!c) throw_error_oom(); - assert(c); // workaround for clang static analysis - - memcpy(c, value.begin, length * sizeof(char_t)); - c[length] = 0; - - return c; - } - else return 0; - } - - xpath_ast_node* parse_function_helper(ast_type_t type0, ast_type_t type1, size_t argc, xpath_ast_node* args[2]) - { - assert(argc <= 1); - - if (argc == 1 && args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - - return new (alloc_node()) xpath_ast_node(argc == 0 ? type0 : type1, xpath_type_string, args[0]); - } - - xpath_ast_node* parse_function(const xpath_lexer_string& name, size_t argc, xpath_ast_node* args[2]) - { - switch (name.begin[0]) - { - case 'b': - if (name == PUGIXML_TEXT("boolean") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_boolean, xpath_type_boolean, args[0]); - - break; - - case 'c': - if (name == PUGIXML_TEXT("count") && argc == 1) - { - if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - return new (alloc_node()) xpath_ast_node(ast_func_count, xpath_type_number, args[0]); - } - else if (name == PUGIXML_TEXT("contains") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_contains, xpath_type_boolean, args[0], args[1]); - else if (name == PUGIXML_TEXT("concat") && argc >= 2) - return new (alloc_node()) xpath_ast_node(ast_func_concat, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("ceiling") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_ceiling, xpath_type_number, args[0]); - - break; - - case 'f': - if (name == PUGIXML_TEXT("false") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_false, xpath_type_boolean); - else if (name == PUGIXML_TEXT("floor") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_floor, xpath_type_number, args[0]); - - break; - - case 'i': - if (name == PUGIXML_TEXT("id") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_id, xpath_type_node_set, args[0]); - - break; - - case 'l': - if (name == PUGIXML_TEXT("last") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_last, xpath_type_number); - else if (name == PUGIXML_TEXT("lang") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_lang, xpath_type_boolean, args[0]); - else if (name == PUGIXML_TEXT("local-name") && argc <= 1) - return parse_function_helper(ast_func_local_name_0, ast_func_local_name_1, argc, args); - - break; - - case 'n': - if (name == PUGIXML_TEXT("name") && argc <= 1) - return parse_function_helper(ast_func_name_0, ast_func_name_1, argc, args); - else if (name == PUGIXML_TEXT("namespace-uri") && argc <= 1) - return parse_function_helper(ast_func_namespace_uri_0, ast_func_namespace_uri_1, argc, args); - else if (name == PUGIXML_TEXT("normalize-space") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_normalize_space_0 : ast_func_normalize_space_1, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("not") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_not, xpath_type_boolean, args[0]); - else if (name == PUGIXML_TEXT("number") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_number_0 : ast_func_number_1, xpath_type_number, args[0]); - - break; - - case 'p': - if (name == PUGIXML_TEXT("position") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_position, xpath_type_number); - - break; - - case 'r': - if (name == PUGIXML_TEXT("round") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_round, xpath_type_number, args[0]); - - break; - - case 's': - if (name == PUGIXML_TEXT("string") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_0 : ast_func_string_1, xpath_type_string, args[0]); - else if (name == PUGIXML_TEXT("string-length") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_number, args[0]); - else if (name == PUGIXML_TEXT("starts-with") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_starts_with, xpath_type_boolean, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring-before") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_substring_before, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring-after") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_substring_after, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring") && (argc == 2 || argc == 3)) - return new (alloc_node()) xpath_ast_node(argc == 2 ? ast_func_substring_2 : ast_func_substring_3, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("sum") && argc == 1) - { - if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - return new (alloc_node()) xpath_ast_node(ast_func_sum, xpath_type_number, args[0]); - } - - break; - - case 't': - if (name == PUGIXML_TEXT("translate") && argc == 3) - return new (alloc_node()) xpath_ast_node(ast_func_translate, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("true") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_true, xpath_type_boolean); - - break; - - default: - break; - } - - throw_error("Unrecognized function or wrong parameter count"); - - return 0; - } - - axis_t parse_axis_name(const xpath_lexer_string& name, bool& specified) - { - specified = true; - - switch (name.begin[0]) - { - case 'a': - if (name == PUGIXML_TEXT("ancestor")) - return axis_ancestor; - else if (name == PUGIXML_TEXT("ancestor-or-self")) - return axis_ancestor_or_self; - else if (name == PUGIXML_TEXT("attribute")) - return axis_attribute; - - break; - - case 'c': - if (name == PUGIXML_TEXT("child")) - return axis_child; - - break; - - case 'd': - if (name == PUGIXML_TEXT("descendant")) - return axis_descendant; - else if (name == PUGIXML_TEXT("descendant-or-self")) - return axis_descendant_or_self; - - break; - - case 'f': - if (name == PUGIXML_TEXT("following")) - return axis_following; - else if (name == PUGIXML_TEXT("following-sibling")) - return axis_following_sibling; - - break; - - case 'n': - if (name == PUGIXML_TEXT("namespace")) - return axis_namespace; - - break; - - case 'p': - if (name == PUGIXML_TEXT("parent")) - return axis_parent; - else if (name == PUGIXML_TEXT("preceding")) - return axis_preceding; - else if (name == PUGIXML_TEXT("preceding-sibling")) - return axis_preceding_sibling; - - break; - - case 's': - if (name == PUGIXML_TEXT("self")) - return axis_self; - - break; - - default: - break; - } - - specified = false; - return axis_child; - } - - nodetest_t parse_node_test_type(const xpath_lexer_string& name) - { - switch (name.begin[0]) - { - case 'c': - if (name == PUGIXML_TEXT("comment")) - return nodetest_type_comment; - - break; - - case 'n': - if (name == PUGIXML_TEXT("node")) - return nodetest_type_node; - - break; - - case 'p': - if (name == PUGIXML_TEXT("processing-instruction")) - return nodetest_type_pi; - - break; - - case 't': - if (name == PUGIXML_TEXT("text")) - return nodetest_type_text; - - break; - - default: - break; - } - - return nodetest_none; - } - - // PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall - xpath_ast_node* parse_primary_expression() - { - switch (_lexer.current()) - { - case lex_var_ref: - { - xpath_lexer_string name = _lexer.contents(); - - if (!_variables) - throw_error("Unknown variable: variable set is not provided"); - - xpath_variable* var = get_variable_scratch(_scratch, _variables, name.begin, name.end); - - if (!var) - throw_error("Unknown variable: variable set does not contain the given name"); - - _lexer.next(); - - return new (alloc_node()) xpath_ast_node(ast_variable, var->type(), var); - } - - case lex_open_brace: - { - _lexer.next(); - - xpath_ast_node* n = parse_expression(); - - if (_lexer.current() != lex_close_brace) - throw_error("Unmatched braces"); - - _lexer.next(); - - return n; - } - - case lex_quoted_string: - { - const char_t* value = alloc_string(_lexer.contents()); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_string_constant, xpath_type_string, value); - _lexer.next(); - - return n; - } - - case lex_number: - { - double value = 0; - - if (!convert_string_to_number_scratch(_scratch, _lexer.contents().begin, _lexer.contents().end, &value)) - throw_error_oom(); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_number_constant, xpath_type_number, value); - _lexer.next(); - - return n; - } - - case lex_string: - { - xpath_ast_node* args[2] = {0}; - size_t argc = 0; - - xpath_lexer_string function = _lexer.contents(); - _lexer.next(); - - xpath_ast_node* last_arg = 0; - - if (_lexer.current() != lex_open_brace) - throw_error("Unrecognized function call"); - _lexer.next(); - - if (_lexer.current() != lex_close_brace) - args[argc++] = parse_expression(); - - while (_lexer.current() != lex_close_brace) - { - if (_lexer.current() != lex_comma) - throw_error("No comma between function arguments"); - _lexer.next(); - - xpath_ast_node* n = parse_expression(); - - if (argc < 2) args[argc] = n; - else last_arg->set_next(n); - - argc++; - last_arg = n; - } - - _lexer.next(); - - return parse_function(function, argc, args); - } - - default: - throw_error("Unrecognizable primary expression"); - - return 0; - } - } - - // FilterExpr ::= PrimaryExpr | FilterExpr Predicate - // Predicate ::= '[' PredicateExpr ']' - // PredicateExpr ::= Expr - xpath_ast_node* parse_filter_expression() - { - xpath_ast_node* n = parse_primary_expression(); - - while (_lexer.current() == lex_open_square_brace) - { - _lexer.next(); - - xpath_ast_node* expr = parse_expression(); - - if (n->rettype() != xpath_type_node_set) throw_error("Predicate has to be applied to node set"); - - n = new (alloc_node()) xpath_ast_node(ast_filter, n, expr, predicate_default); - - if (_lexer.current() != lex_close_square_brace) - throw_error("Unmatched square brace"); - - _lexer.next(); - } - - return n; - } - - // Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep - // AxisSpecifier ::= AxisName '::' | '@'? - // NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' - // NameTest ::= '*' | NCName ':' '*' | QName - // AbbreviatedStep ::= '.' | '..' - xpath_ast_node* parse_step(xpath_ast_node* set) - { - if (set && set->rettype() != xpath_type_node_set) - throw_error("Step has to be applied to node set"); - - bool axis_specified = false; - axis_t axis = axis_child; // implied child axis - - if (_lexer.current() == lex_axis_attribute) - { - axis = axis_attribute; - axis_specified = true; - - _lexer.next(); - } - else if (_lexer.current() == lex_dot) - { - _lexer.next(); - - return new (alloc_node()) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0); - } - else if (_lexer.current() == lex_double_dot) - { - _lexer.next(); - - return new (alloc_node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0); - } - - nodetest_t nt_type = nodetest_none; - xpath_lexer_string nt_name; - - if (_lexer.current() == lex_string) - { - // node name test - nt_name = _lexer.contents(); - _lexer.next(); - - // was it an axis name? - if (_lexer.current() == lex_double_colon) - { - // parse axis name - if (axis_specified) throw_error("Two axis specifiers in one step"); - - axis = parse_axis_name(nt_name, axis_specified); - - if (!axis_specified) throw_error("Unknown axis"); - - // read actual node test - _lexer.next(); - - if (_lexer.current() == lex_multiply) - { - nt_type = nodetest_all; - nt_name = xpath_lexer_string(); - _lexer.next(); - } - else if (_lexer.current() == lex_string) - { - nt_name = _lexer.contents(); - _lexer.next(); - } - else throw_error("Unrecognized node test"); - } - - if (nt_type == nodetest_none) - { - // node type test or processing-instruction - if (_lexer.current() == lex_open_brace) - { - _lexer.next(); - - if (_lexer.current() == lex_close_brace) - { - _lexer.next(); - - nt_type = parse_node_test_type(nt_name); - - if (nt_type == nodetest_none) throw_error("Unrecognized node type"); - - nt_name = xpath_lexer_string(); - } - else if (nt_name == PUGIXML_TEXT("processing-instruction")) - { - if (_lexer.current() != lex_quoted_string) - throw_error("Only literals are allowed as arguments to processing-instruction()"); - - nt_type = nodetest_pi; - nt_name = _lexer.contents(); - _lexer.next(); - - if (_lexer.current() != lex_close_brace) - throw_error("Unmatched brace near processing-instruction()"); - _lexer.next(); - } - else - throw_error("Unmatched brace near node type test"); - - } - // QName or NCName:* - else - { - if (nt_name.end - nt_name.begin > 2 && nt_name.end[-2] == ':' && nt_name.end[-1] == '*') // NCName:* - { - nt_name.end--; // erase * - - nt_type = nodetest_all_in_namespace; - } - else nt_type = nodetest_name; - } - } - } - else if (_lexer.current() == lex_multiply) - { - nt_type = nodetest_all; - _lexer.next(); - } - else throw_error("Unrecognized node test"); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step, set, axis, nt_type, alloc_string(nt_name)); - - xpath_ast_node* last = 0; - - while (_lexer.current() == lex_open_square_brace) - { - _lexer.next(); - - xpath_ast_node* expr = parse_expression(); - - xpath_ast_node* pred = new (alloc_node()) xpath_ast_node(ast_predicate, 0, expr, predicate_default); - - if (_lexer.current() != lex_close_square_brace) - throw_error("Unmatched square brace"); - _lexer.next(); - - if (last) last->set_next(pred); - else n->set_right(pred); - - last = pred; - } - - return n; - } - - // RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step - xpath_ast_node* parse_relative_location_path(xpath_ast_node* set) - { - xpath_ast_node* n = parse_step(set); - - while (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) - { - lexeme_t l = _lexer.current(); - _lexer.next(); - - if (l == lex_double_slash) - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); - - n = parse_step(n); - } - - return n; - } - - // LocationPath ::= RelativeLocationPath | AbsoluteLocationPath - // AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath - xpath_ast_node* parse_location_path() - { - if (_lexer.current() == lex_slash) - { - _lexer.next(); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set); - - // relative location path can start from axis_attribute, dot, double_dot, multiply and string lexemes; any other lexeme means standalone root path - lexeme_t l = _lexer.current(); - - if (l == lex_string || l == lex_axis_attribute || l == lex_dot || l == lex_double_dot || l == lex_multiply) - return parse_relative_location_path(n); - else - return n; - } - else if (_lexer.current() == lex_double_slash) - { - _lexer.next(); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set); - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); - - return parse_relative_location_path(n); - } - - // else clause moved outside of if because of bogus warning 'control may reach end of non-void function being inlined' in gcc 4.0.1 - return parse_relative_location_path(0); - } - - // PathExpr ::= LocationPath - // | FilterExpr - // | FilterExpr '/' RelativeLocationPath - // | FilterExpr '//' RelativeLocationPath - // UnionExpr ::= PathExpr | UnionExpr '|' PathExpr - // UnaryExpr ::= UnionExpr | '-' UnaryExpr - xpath_ast_node* parse_path_or_unary_expression() - { - // Clarification. - // PathExpr begins with either LocationPath or FilterExpr. - // FilterExpr begins with PrimaryExpr - // PrimaryExpr begins with '$' in case of it being a variable reference, - // '(' in case of it being an expression, string literal, number constant or - // function call. - - if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace || - _lexer.current() == lex_quoted_string || _lexer.current() == lex_number || - _lexer.current() == lex_string) - { - if (_lexer.current() == lex_string) - { - // This is either a function call, or not - if not, we shall proceed with location path - const char_t* state = _lexer.state(); - - while (PUGI__IS_CHARTYPE(*state, ct_space)) ++state; - - if (*state != '(') return parse_location_path(); - - // This looks like a function call; however this still can be a node-test. Check it. - if (parse_node_test_type(_lexer.contents()) != nodetest_none) return parse_location_path(); - } - - xpath_ast_node* n = parse_filter_expression(); - - if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) - { - lexeme_t l = _lexer.current(); - _lexer.next(); - - if (l == lex_double_slash) - { - if (n->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set"); - - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); - } - - // select from location path - return parse_relative_location_path(n); - } - - return n; - } - else if (_lexer.current() == lex_minus) - { - _lexer.next(); - - // precedence 7+ - only parses union expressions - xpath_ast_node* expr = parse_expression_rec(parse_path_or_unary_expression(), 7); - - return new (alloc_node()) xpath_ast_node(ast_op_negate, xpath_type_number, expr); - } - else - return parse_location_path(); - } - - struct binary_op_t - { - ast_type_t asttype; - xpath_value_type rettype; - int precedence; - - binary_op_t(): asttype(ast_unknown), rettype(xpath_type_none), precedence(0) - { - } - - binary_op_t(ast_type_t asttype_, xpath_value_type rettype_, int precedence_): asttype(asttype_), rettype(rettype_), precedence(precedence_) - { - } - - static binary_op_t parse(xpath_lexer& lexer) - { - switch (lexer.current()) - { - case lex_string: - if (lexer.contents() == PUGIXML_TEXT("or")) - return binary_op_t(ast_op_or, xpath_type_boolean, 1); - else if (lexer.contents() == PUGIXML_TEXT("and")) - return binary_op_t(ast_op_and, xpath_type_boolean, 2); - else if (lexer.contents() == PUGIXML_TEXT("div")) - return binary_op_t(ast_op_divide, xpath_type_number, 6); - else if (lexer.contents() == PUGIXML_TEXT("mod")) - return binary_op_t(ast_op_mod, xpath_type_number, 6); - else - return binary_op_t(); - - case lex_equal: - return binary_op_t(ast_op_equal, xpath_type_boolean, 3); - - case lex_not_equal: - return binary_op_t(ast_op_not_equal, xpath_type_boolean, 3); - - case lex_less: - return binary_op_t(ast_op_less, xpath_type_boolean, 4); - - case lex_greater: - return binary_op_t(ast_op_greater, xpath_type_boolean, 4); - - case lex_less_or_equal: - return binary_op_t(ast_op_less_or_equal, xpath_type_boolean, 4); - - case lex_greater_or_equal: - return binary_op_t(ast_op_greater_or_equal, xpath_type_boolean, 4); - - case lex_plus: - return binary_op_t(ast_op_add, xpath_type_number, 5); - - case lex_minus: - return binary_op_t(ast_op_subtract, xpath_type_number, 5); - - case lex_multiply: - return binary_op_t(ast_op_multiply, xpath_type_number, 6); - - case lex_union: - return binary_op_t(ast_op_union, xpath_type_node_set, 7); - - default: - return binary_op_t(); - } - } - }; - - xpath_ast_node* parse_expression_rec(xpath_ast_node* lhs, int limit) - { - binary_op_t op = binary_op_t::parse(_lexer); - - while (op.asttype != ast_unknown && op.precedence >= limit) - { - _lexer.next(); - - xpath_ast_node* rhs = parse_path_or_unary_expression(); - - binary_op_t nextop = binary_op_t::parse(_lexer); - - while (nextop.asttype != ast_unknown && nextop.precedence > op.precedence) - { - rhs = parse_expression_rec(rhs, nextop.precedence); - - nextop = binary_op_t::parse(_lexer); - } - - if (op.asttype == ast_op_union && (lhs->rettype() != xpath_type_node_set || rhs->rettype() != xpath_type_node_set)) - throw_error("Union operator has to be applied to node sets"); - - lhs = new (alloc_node()) xpath_ast_node(op.asttype, op.rettype, lhs, rhs); - - op = binary_op_t::parse(_lexer); - } - - return lhs; - } - - // Expr ::= OrExpr - // OrExpr ::= AndExpr | OrExpr 'or' AndExpr - // AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr - // EqualityExpr ::= RelationalExpr - // | EqualityExpr '=' RelationalExpr - // | EqualityExpr '!=' RelationalExpr - // RelationalExpr ::= AdditiveExpr - // | RelationalExpr '<' AdditiveExpr - // | RelationalExpr '>' AdditiveExpr - // | RelationalExpr '<=' AdditiveExpr - // | RelationalExpr '>=' AdditiveExpr - // AdditiveExpr ::= MultiplicativeExpr - // | AdditiveExpr '+' MultiplicativeExpr - // | AdditiveExpr '-' MultiplicativeExpr - // MultiplicativeExpr ::= UnaryExpr - // | MultiplicativeExpr '*' UnaryExpr - // | MultiplicativeExpr 'div' UnaryExpr - // | MultiplicativeExpr 'mod' UnaryExpr - xpath_ast_node* parse_expression() - { - return parse_expression_rec(parse_path_or_unary_expression(), 0); - } - - xpath_parser(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result) - { - } - - xpath_ast_node* parse() - { - xpath_ast_node* result = parse_expression(); - - if (_lexer.current() != lex_eof) - { - // there are still unparsed tokens left, error - throw_error("Incorrect query"); - } - - return result; - } - - static xpath_ast_node* parse(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result) - { - xpath_parser parser(query, variables, alloc, result); - - #ifdef PUGIXML_NO_EXCEPTIONS - int error = setjmp(parser._error_handler); - - return (error == 0) ? parser.parse() : 0; - #else - return parser.parse(); - #endif - } - }; - - struct xpath_query_impl - { - static xpath_query_impl* create() - { - void* memory = xml_memory::allocate(sizeof(xpath_query_impl)); - - return new (memory) xpath_query_impl(); - } - - static void destroy(void* ptr) - { - if (!ptr) return; - - // free all allocated pages - static_cast(ptr)->alloc.release(); - - // free allocator memory (with the first page) - xml_memory::deallocate(ptr); - } - - xpath_query_impl(): root(0), alloc(&block) - { - block.next = 0; - block.capacity = sizeof(block.data); - } - - xpath_ast_node* root; - xpath_allocator alloc; - xpath_memory_block block; - }; - - PUGI__FN xpath_string evaluate_string_impl(xpath_query_impl* impl, const xpath_node& n, xpath_stack_data& sd) - { - if (!impl) return xpath_string(); - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return xpath_string(); - #endif - - xpath_context c(n, 1, 1); - - return impl->root->eval_string(c, sd.stack); - } - - PUGI__FN impl::xpath_ast_node* evaluate_node_set_prepare(xpath_query_impl* impl) - { - if (!impl) return 0; - - if (impl->root->rettype() != xpath_type_node_set) - { - #ifdef PUGIXML_NO_EXCEPTIONS - return 0; - #else - xpath_parse_result res; - res.error = "Expression does not evaluate to node set"; - - throw xpath_exception(res); - #endif - } - - return impl->root; - } -PUGI__NS_END - -namespace pugi -{ -#ifndef PUGIXML_NO_EXCEPTIONS - PUGI__FN xpath_exception::xpath_exception(const xpath_parse_result& result_): _result(result_) - { - assert(_result.error); - } - - PUGI__FN const char* xpath_exception::what() const throw() - { - return _result.error; - } - - PUGI__FN const xpath_parse_result& xpath_exception::result() const - { - return _result; - } -#endif - - PUGI__FN xpath_node::xpath_node() - { - } - - PUGI__FN xpath_node::xpath_node(const xml_node& node_): _node(node_) - { - } - - PUGI__FN xpath_node::xpath_node(const xml_attribute& attribute_, const xml_node& parent_): _node(attribute_ ? parent_ : xml_node()), _attribute(attribute_) - { - } - - PUGI__FN xml_node xpath_node::node() const - { - return _attribute ? xml_node() : _node; - } - - PUGI__FN xml_attribute xpath_node::attribute() const - { - return _attribute; - } - - PUGI__FN xml_node xpath_node::parent() const - { - return _attribute ? _node : _node.parent(); - } - - PUGI__FN static void unspecified_bool_xpath_node(xpath_node***) - { - } - - PUGI__FN xpath_node::operator xpath_node::unspecified_bool_type() const - { - return (_node || _attribute) ? unspecified_bool_xpath_node : 0; - } - - PUGI__FN bool xpath_node::operator!() const - { - return !(_node || _attribute); - } - - PUGI__FN bool xpath_node::operator==(const xpath_node& n) const - { - return _node == n._node && _attribute == n._attribute; - } - - PUGI__FN bool xpath_node::operator!=(const xpath_node& n) const - { - return _node != n._node || _attribute != n._attribute; - } - -#ifdef __BORLANDC__ - PUGI__FN bool operator&&(const xpath_node& lhs, bool rhs) - { - return (bool)lhs && rhs; - } - - PUGI__FN bool operator||(const xpath_node& lhs, bool rhs) - { - return (bool)lhs || rhs; - } -#endif - - PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_) - { - assert(begin_ <= end_); - - size_t size_ = static_cast(end_ - begin_); - - if (size_ <= 1) - { - // deallocate old buffer - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); - - // use internal buffer - if (begin_ != end_) _storage = *begin_; - - _begin = &_storage; - _end = &_storage + size_; - } - else - { - // make heap copy - xpath_node* storage = static_cast(impl::xml_memory::allocate(size_ * sizeof(xpath_node))); - - if (!storage) - { - #ifdef PUGIXML_NO_EXCEPTIONS - return; - #else - throw std::bad_alloc(); - #endif - } - - memcpy(storage, begin_, size_ * sizeof(xpath_node)); - - // deallocate old buffer - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); - - // finalize - _begin = storage; - _end = storage + size_; - } - } - - PUGI__FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(&_storage), _end(&_storage) - { - } - - PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_), _begin(&_storage), _end(&_storage) - { - _assign(begin_, end_); - } - - PUGI__FN xpath_node_set::~xpath_node_set() - { - if (_begin != &_storage) impl::xml_memory::deallocate(_begin); - } - - PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(ns._type), _begin(&_storage), _end(&_storage) - { - _assign(ns._begin, ns._end); - } - - PUGI__FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns) - { - if (this == &ns) return *this; - - _type = ns._type; - _assign(ns._begin, ns._end); - - return *this; - } - - PUGI__FN xpath_node_set::type_t xpath_node_set::type() const - { - return _type; - } - - PUGI__FN size_t xpath_node_set::size() const - { - return _end - _begin; - } - - PUGI__FN bool xpath_node_set::empty() const - { - return _begin == _end; - } - - PUGI__FN const xpath_node& xpath_node_set::operator[](size_t index) const - { - assert(index < size()); - return _begin[index]; - } - - PUGI__FN xpath_node_set::const_iterator xpath_node_set::begin() const - { - return _begin; - } - - PUGI__FN xpath_node_set::const_iterator xpath_node_set::end() const - { - return _end; - } - - PUGI__FN void xpath_node_set::sort(bool reverse) - { - _type = impl::xpath_sort(_begin, _end, _type, reverse); - } - - PUGI__FN xpath_node xpath_node_set::first() const - { - return impl::xpath_first(_begin, _end, _type); - } - - PUGI__FN xpath_parse_result::xpath_parse_result(): error("Internal error"), offset(0) - { - } - - PUGI__FN xpath_parse_result::operator bool() const - { - return error == 0; - } - - PUGI__FN const char* xpath_parse_result::description() const - { - return error ? error : "No error"; - } - - PUGI__FN xpath_variable::xpath_variable(): _type(xpath_type_none), _next(0) - { - } - - PUGI__FN const char_t* xpath_variable::name() const - { - switch (_type) - { - case xpath_type_node_set: - return static_cast(this)->name; - - case xpath_type_number: - return static_cast(this)->name; - - case xpath_type_string: - return static_cast(this)->name; - - case xpath_type_boolean: - return static_cast(this)->name; - - default: - assert(!"Invalid variable type"); - return 0; - } - } - - PUGI__FN xpath_value_type xpath_variable::type() const - { - return _type; - } - - PUGI__FN bool xpath_variable::get_boolean() const - { - return (_type == xpath_type_boolean) ? static_cast(this)->value : false; - } - - PUGI__FN double xpath_variable::get_number() const - { - return (_type == xpath_type_number) ? static_cast(this)->value : impl::gen_nan(); - } - - PUGI__FN const char_t* xpath_variable::get_string() const - { - const char_t* value = (_type == xpath_type_string) ? static_cast(this)->value : 0; - return value ? value : PUGIXML_TEXT(""); - } - - PUGI__FN const xpath_node_set& xpath_variable::get_node_set() const - { - return (_type == xpath_type_node_set) ? static_cast(this)->value : impl::dummy_node_set; - } - - PUGI__FN bool xpath_variable::set(bool value) - { - if (_type != xpath_type_boolean) return false; - - static_cast(this)->value = value; - return true; - } - - PUGI__FN bool xpath_variable::set(double value) - { - if (_type != xpath_type_number) return false; - - static_cast(this)->value = value; - return true; - } - - PUGI__FN bool xpath_variable::set(const char_t* value) - { - if (_type != xpath_type_string) return false; - - impl::xpath_variable_string* var = static_cast(this); - - // duplicate string - size_t size = (impl::strlength(value) + 1) * sizeof(char_t); - - char_t* copy = static_cast(impl::xml_memory::allocate(size)); - if (!copy) return false; - - memcpy(copy, value, size); - - // replace old string - if (var->value) impl::xml_memory::deallocate(var->value); - var->value = copy; - - return true; - } - - PUGI__FN bool xpath_variable::set(const xpath_node_set& value) - { - if (_type != xpath_type_node_set) return false; - - static_cast(this)->value = value; - return true; - } - - PUGI__FN xpath_variable_set::xpath_variable_set() - { - for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) _data[i] = 0; - } - - PUGI__FN xpath_variable_set::~xpath_variable_set() - { - for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) - { - xpath_variable* var = _data[i]; - - while (var) - { - xpath_variable* next = var->_next; - - impl::delete_xpath_variable(var->_type, var); - - var = next; - } - } - } - - PUGI__FN xpath_variable* xpath_variable_set::find(const char_t* name) const - { - const size_t hash_size = sizeof(_data) / sizeof(_data[0]); - size_t hash = impl::hash_string(name) % hash_size; - - // look for existing variable - for (xpath_variable* var = _data[hash]; var; var = var->_next) - if (impl::strequal(var->name(), name)) - return var; - - return 0; - } - - PUGI__FN xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type) - { - const size_t hash_size = sizeof(_data) / sizeof(_data[0]); - size_t hash = impl::hash_string(name) % hash_size; - - // look for existing variable - for (xpath_variable* var = _data[hash]; var; var = var->_next) - if (impl::strequal(var->name(), name)) - return var->type() == type ? var : 0; - - // add new variable - xpath_variable* result = impl::new_xpath_variable(type, name); - - if (result) - { - result->_type = type; - result->_next = _data[hash]; - - _data[hash] = result; - } - - return result; - } - - PUGI__FN bool xpath_variable_set::set(const char_t* name, bool value) - { - xpath_variable* var = add(name, xpath_type_boolean); - return var ? var->set(value) : false; - } - - PUGI__FN bool xpath_variable_set::set(const char_t* name, double value) - { - xpath_variable* var = add(name, xpath_type_number); - return var ? var->set(value) : false; - } - - PUGI__FN bool xpath_variable_set::set(const char_t* name, const char_t* value) - { - xpath_variable* var = add(name, xpath_type_string); - return var ? var->set(value) : false; - } - - PUGI__FN bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value) - { - xpath_variable* var = add(name, xpath_type_node_set); - return var ? var->set(value) : false; - } - - PUGI__FN xpath_variable* xpath_variable_set::get(const char_t* name) - { - return find(name); - } - - PUGI__FN const xpath_variable* xpath_variable_set::get(const char_t* name) const - { - return find(name); - } - - PUGI__FN xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0) - { - impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create(); - - if (!qimpl) - { - #ifdef PUGIXML_NO_EXCEPTIONS - _result.error = "Out of memory"; - #else - throw std::bad_alloc(); - #endif - } - else - { - impl::buffer_holder impl_holder(qimpl, impl::xpath_query_impl::destroy); - - qimpl->root = impl::xpath_parser::parse(query, variables, &qimpl->alloc, &_result); - - if (qimpl->root) - { - qimpl->root->optimize(&qimpl->alloc); - - _impl = static_cast(impl_holder.release()); - _result.error = 0; - } - } - } - - PUGI__FN xpath_query::~xpath_query() - { - impl::xpath_query_impl::destroy(_impl); - } - - PUGI__FN xpath_value_type xpath_query::return_type() const - { - if (!_impl) return xpath_type_none; - - return static_cast(_impl)->root->rettype(); - } - - PUGI__FN bool xpath_query::evaluate_boolean(const xpath_node& n) const - { - if (!_impl) return false; - - impl::xpath_context c(n, 1, 1); - impl::xpath_stack_data sd; - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return false; - #endif - - return static_cast(_impl)->root->eval_boolean(c, sd.stack); - } - - PUGI__FN double xpath_query::evaluate_number(const xpath_node& n) const - { - if (!_impl) return impl::gen_nan(); - - impl::xpath_context c(n, 1, 1); - impl::xpath_stack_data sd; - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return impl::gen_nan(); - #endif - - return static_cast(_impl)->root->eval_number(c, sd.stack); - } - -#ifndef PUGIXML_NO_STL - PUGI__FN string_t xpath_query::evaluate_string(const xpath_node& n) const - { - impl::xpath_stack_data sd; - - impl::xpath_string r = impl::evaluate_string_impl(static_cast(_impl), n, sd); - - return string_t(r.c_str(), r.length()); - } -#endif - - PUGI__FN size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const - { - impl::xpath_stack_data sd; - - impl::xpath_string r = impl::evaluate_string_impl(static_cast(_impl), n, sd); - - size_t full_size = r.length() + 1; - - if (capacity > 0) - { - size_t size = (full_size < capacity) ? full_size : capacity; - assert(size > 0); - - memcpy(buffer, r.c_str(), (size - 1) * sizeof(char_t)); - buffer[size - 1] = 0; - } - - return full_size; - } - - PUGI__FN xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const - { - impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast(_impl)); - if (!root) return xpath_node_set(); - - impl::xpath_context c(n, 1, 1); - impl::xpath_stack_data sd; - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return xpath_node_set(); - #endif - - impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack, impl::nodeset_eval_all); - - return xpath_node_set(r.begin(), r.end(), r.type()); - } - - PUGI__FN xpath_node xpath_query::evaluate_node(const xpath_node& n) const - { - impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast(_impl)); - if (!root) return xpath_node(); - - impl::xpath_context c(n, 1, 1); - impl::xpath_stack_data sd; - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return xpath_node(); - #endif - - impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack, impl::nodeset_eval_first); - - return r.first(); - } - - PUGI__FN const xpath_parse_result& xpath_query::result() const - { - return _result; - } - - PUGI__FN static void unspecified_bool_xpath_query(xpath_query***) - { - } - - PUGI__FN xpath_query::operator xpath_query::unspecified_bool_type() const - { - return _impl ? unspecified_bool_xpath_query : 0; - } - - PUGI__FN bool xpath_query::operator!() const - { - return !_impl; - } - - PUGI__FN xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables) const - { - xpath_query q(query, variables); - return select_node(q); - } - - PUGI__FN xpath_node xml_node::select_node(const xpath_query& query) const - { - return query.evaluate_node(*this); - } - - PUGI__FN xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const - { - xpath_query q(query, variables); - return select_nodes(q); - } - - PUGI__FN xpath_node_set xml_node::select_nodes(const xpath_query& query) const - { - return query.evaluate_node_set(*this); - } - - PUGI__FN xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const - { - xpath_query q(query, variables); - return select_single_node(q); - } - - PUGI__FN xpath_node xml_node::select_single_node(const xpath_query& query) const - { - return query.evaluate_node(*this); - } -} - -#endif - -#ifdef __BORLANDC__ -# pragma option pop -#endif - -// Intel C++ does not properly keep warning state for function templates, -// so popping warning state at the end of translation unit leads to warnings in the middle. -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) -# pragma warning(pop) -#endif - -// Undefine all local macros (makes sure we're not leaking macros in header-only mode) -#undef PUGI__NO_INLINE -#undef PUGI__UNLIKELY -#undef PUGI__STATIC_ASSERT -#undef PUGI__DMC_VOLATILE -#undef PUGI__MSVC_CRT_VERSION -#undef PUGI__NS_BEGIN -#undef PUGI__NS_END -#undef PUGI__FN -#undef PUGI__FN_NO_INLINE -#undef PUGI__NODETYPE -#undef PUGI__IS_CHARTYPE_IMPL -#undef PUGI__IS_CHARTYPE -#undef PUGI__IS_CHARTYPEX -#undef PUGI__ENDSWITH -#undef PUGI__SKIPWS -#undef PUGI__OPTSET -#undef PUGI__PUSHNODE -#undef PUGI__POPNODE -#undef PUGI__SCANFOR -#undef PUGI__SCANWHILE -#undef PUGI__SCANWHILE_UNROLL -#undef PUGI__ENDSEG -#undef PUGI__THROW_ERROR -#undef PUGI__CHECK_ERROR - -#endif - -/** - * Copyright (c) 2006-2015 Arseny Kapoulkine - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ diff --git a/3rdparty/pugixml-1.6/src/pugixml.hpp b/3rdparty/pugixml-1.6/src/pugixml.hpp deleted file mode 100644 index d59f8640..00000000 --- a/3rdparty/pugixml-1.6/src/pugixml.hpp +++ /dev/null @@ -1,1366 +0,0 @@ -/** - * pugixml parser - version 1.6 - * -------------------------------------------------------- - * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) - * Report bugs and download new versions at http://pugixml.org/ - * - * This library is distributed under the MIT License. See notice at the end - * of this file. - * - * This work is based on the pugxml parser, which is: - * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) - */ - -#ifndef PUGIXML_VERSION -// Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons -# define PUGIXML_VERSION 160 -#endif - -// Include user configuration file (this can define various configuration macros) -#include "pugiconfig.hpp" - -#ifndef HEADER_PUGIXML_HPP -#define HEADER_PUGIXML_HPP - -// Include stddef.h for size_t and ptrdiff_t -#include - -// Include exception header for XPath -#if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS) -# include -#endif - -// Include STL headers -#ifndef PUGIXML_NO_STL -# include -# include -# include -#endif - -// Macro for deprecated features -#ifndef PUGIXML_DEPRECATED -# if defined(__GNUC__) -# define PUGIXML_DEPRECATED __attribute__((deprecated)) -# elif defined(_MSC_VER) && _MSC_VER >= 1300 -# define PUGIXML_DEPRECATED __declspec(deprecated) -# else -# define PUGIXML_DEPRECATED -# endif -#endif - -// If no API is defined, assume default -#ifndef PUGIXML_API -# define PUGIXML_API -#endif - -// If no API for classes is defined, assume default -#ifndef PUGIXML_CLASS -# define PUGIXML_CLASS PUGIXML_API -#endif - -// If no API for functions is defined, assume default -#ifndef PUGIXML_FUNCTION -# define PUGIXML_FUNCTION PUGIXML_API -#endif - -// If the platform is known to have long long support, enable long long functions -#ifndef PUGIXML_HAS_LONG_LONG -# if defined(__cplusplus) && __cplusplus >= 201103 -# define PUGIXML_HAS_LONG_LONG -# elif defined(_MSC_VER) && _MSC_VER >= 1400 -# define PUGIXML_HAS_LONG_LONG -# endif -#endif - -// Character interface macros -#ifdef PUGIXML_WCHAR_MODE -# define PUGIXML_TEXT(t) L ## t -# define PUGIXML_CHAR wchar_t -#else -# define PUGIXML_TEXT(t) t -# define PUGIXML_CHAR char -#endif - -namespace pugi -{ - // Character type used for all internal storage and operations; depends on PUGIXML_WCHAR_MODE - typedef PUGIXML_CHAR char_t; - -#ifndef PUGIXML_NO_STL - // String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE - typedef std::basic_string, std::allocator > string_t; -#endif -} - -// The PugiXML namespace -namespace pugi -{ - // Tree node types - enum xml_node_type - { - node_null, // Empty (null) node handle - node_document, // A document tree's absolute root - node_element, // Element tag, i.e. '' - node_pcdata, // Plain character data, i.e. 'text' - node_cdata, // Character data, i.e. '' - node_comment, // Comment tag, i.e. '' - node_pi, // Processing instruction, i.e. '' - node_declaration, // Document declaration, i.e. '' - node_doctype // Document type declaration, i.e. '' - }; - - // Parsing options - - // Minimal parsing mode (equivalent to turning all other flags off). - // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed. - const unsigned int parse_minimal = 0x0000; - - // This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default. - const unsigned int parse_pi = 0x0001; - - // This flag determines if comments (node_comment) are added to the DOM tree. This flag is off by default. - const unsigned int parse_comments = 0x0002; - - // This flag determines if CDATA sections (node_cdata) are added to the DOM tree. This flag is on by default. - const unsigned int parse_cdata = 0x0004; - - // This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree. - // This flag is off by default; turning it on usually results in slower parsing and more memory consumption. - const unsigned int parse_ws_pcdata = 0x0008; - - // This flag determines if character and entity references are expanded during parsing. This flag is on by default. - const unsigned int parse_escapes = 0x0010; - - // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default. - const unsigned int parse_eol = 0x0020; - - // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. - const unsigned int parse_wconv_attribute = 0x0040; - - // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. - const unsigned int parse_wnorm_attribute = 0x0080; - - // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. - const unsigned int parse_declaration = 0x0100; - - // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default. - const unsigned int parse_doctype = 0x0200; - - // This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only - // of whitespace is added to the DOM tree. - // This flag is off by default; turning it on may result in slower parsing and more memory consumption. - const unsigned int parse_ws_pcdata_single = 0x0400; - - // This flag determines if leading and trailing whitespace is to be removed from plain character data. This flag is off by default. - const unsigned int parse_trim_pcdata = 0x0800; - - // This flag determines if plain character data that does not have a parent node is added to the DOM tree, and if an empty document - // is a valid document. This flag is off by default. - const unsigned int parse_fragment = 0x1000; - - // The default parsing mode. - // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, - // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. - const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol; - - // The full parsing mode. - // Nodes of all types are added to the DOM tree, character/reference entities are expanded, - // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. - const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype; - - // These flags determine the encoding of input data for XML document - enum xml_encoding - { - encoding_auto, // Auto-detect input encoding using BOM or < / class xml_object_range - { - public: - typedef It const_iterator; - typedef It iterator; - - xml_object_range(It b, It e): _begin(b), _end(e) - { - } - - It begin() const { return _begin; } - It end() const { return _end; } - - private: - It _begin, _end; - }; - - // Writer interface for node printing (see xml_node::print) - class PUGIXML_CLASS xml_writer - { - public: - virtual ~xml_writer() {} - - // Write memory chunk into stream/file/whatever - virtual void write(const void* data, size_t size) = 0; - }; - - // xml_writer implementation for FILE* - class PUGIXML_CLASS xml_writer_file: public xml_writer - { - public: - // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio - xml_writer_file(void* file); - - virtual void write(const void* data, size_t size); - - private: - void* file; - }; - - #ifndef PUGIXML_NO_STL - // xml_writer implementation for streams - class PUGIXML_CLASS xml_writer_stream: public xml_writer - { - public: - // Construct writer from an output stream object - xml_writer_stream(std::basic_ostream >& stream); - xml_writer_stream(std::basic_ostream >& stream); - - virtual void write(const void* data, size_t size); - - private: - std::basic_ostream >* narrow_stream; - std::basic_ostream >* wide_stream; - }; - #endif - - // A light-weight handle for manipulating attributes in DOM tree - class PUGIXML_CLASS xml_attribute - { - friend class xml_attribute_iterator; - friend class xml_node; - - private: - xml_attribute_struct* _attr; - - typedef void (*unspecified_bool_type)(xml_attribute***); - - public: - // Default constructor. Constructs an empty attribute. - xml_attribute(); - - // Constructs attribute from internal pointer - explicit xml_attribute(xml_attribute_struct* attr); - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - - // Comparison operators (compares wrapped attribute pointers) - bool operator==(const xml_attribute& r) const; - bool operator!=(const xml_attribute& r) const; - bool operator<(const xml_attribute& r) const; - bool operator>(const xml_attribute& r) const; - bool operator<=(const xml_attribute& r) const; - bool operator>=(const xml_attribute& r) const; - - // Check if attribute is empty - bool empty() const; - - // Get attribute name/value, or "" if attribute is empty - const char_t* name() const; - const char_t* value() const; - - // Get attribute value, or the default value if attribute is empty - const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; - - // Get attribute value as a number, or the default value if conversion did not succeed or attribute is empty - int as_int(int def = 0) const; - unsigned int as_uint(unsigned int def = 0) const; - double as_double(double def = 0) const; - float as_float(float def = 0) const; - - #ifdef PUGIXML_HAS_LONG_LONG - long long as_llong(long long def = 0) const; - unsigned long long as_ullong(unsigned long long def = 0) const; - #endif - - // Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty - bool as_bool(bool def = false) const; - - // Set attribute name/value (returns false if attribute is empty or there is not enough memory) - bool set_name(const char_t* rhs); - bool set_value(const char_t* rhs); - - // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") - bool set_value(int rhs); - bool set_value(unsigned int rhs); - bool set_value(double rhs); - bool set_value(float rhs); - bool set_value(bool rhs); - - #ifdef PUGIXML_HAS_LONG_LONG - bool set_value(long long rhs); - bool set_value(unsigned long long rhs); - #endif - - // Set attribute value (equivalent to set_value without error checking) - xml_attribute& operator=(const char_t* rhs); - xml_attribute& operator=(int rhs); - xml_attribute& operator=(unsigned int rhs); - xml_attribute& operator=(double rhs); - xml_attribute& operator=(float rhs); - xml_attribute& operator=(bool rhs); - - #ifdef PUGIXML_HAS_LONG_LONG - xml_attribute& operator=(long long rhs); - xml_attribute& operator=(unsigned long long rhs); - #endif - - // Get next/previous attribute in the attribute list of the parent node - xml_attribute next_attribute() const; - xml_attribute previous_attribute() const; - - // Get hash value (unique for handles to the same object) - size_t hash_value() const; - - // Get internal pointer - xml_attribute_struct* internal_object() const; - }; - -#ifdef __BORLANDC__ - // Borland C++ workaround - bool PUGIXML_FUNCTION operator&&(const xml_attribute& lhs, bool rhs); - bool PUGIXML_FUNCTION operator||(const xml_attribute& lhs, bool rhs); -#endif - - // A light-weight handle for manipulating nodes in DOM tree - class PUGIXML_CLASS xml_node - { - friend class xml_attribute_iterator; - friend class xml_node_iterator; - friend class xml_named_node_iterator; - - protected: - xml_node_struct* _root; - - typedef void (*unspecified_bool_type)(xml_node***); - - public: - // Default constructor. Constructs an empty node. - xml_node(); - - // Constructs node from internal pointer - explicit xml_node(xml_node_struct* p); - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - - // Comparison operators (compares wrapped node pointers) - bool operator==(const xml_node& r) const; - bool operator!=(const xml_node& r) const; - bool operator<(const xml_node& r) const; - bool operator>(const xml_node& r) const; - bool operator<=(const xml_node& r) const; - bool operator>=(const xml_node& r) const; - - // Check if node is empty. - bool empty() const; - - // Get node type - xml_node_type type() const; - - // Get node name, or "" if node is empty or it has no name - const char_t* name() const; - - // Get node value, or "" if node is empty or it has no value - // Note: For text node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. - const char_t* value() const; - - // Get attribute list - xml_attribute first_attribute() const; - xml_attribute last_attribute() const; - - // Get children list - xml_node first_child() const; - xml_node last_child() const; - - // Get next/previous sibling in the children list of the parent node - xml_node next_sibling() const; - xml_node previous_sibling() const; - - // Get parent node - xml_node parent() const; - - // Get root of DOM tree this node belongs to - xml_node root() const; - - // Get text object for the current node - xml_text text() const; - - // Get child, attribute or next/previous sibling with the specified name - xml_node child(const char_t* name) const; - xml_attribute attribute(const char_t* name) const; - xml_node next_sibling(const char_t* name) const; - xml_node previous_sibling(const char_t* name) const; - - // Get child value of current node; that is, value of the first child node of type PCDATA/CDATA - const char_t* child_value() const; - - // Get child value of child with specified name. Equivalent to child(name).child_value(). - const char_t* child_value(const char_t* name) const; - - // Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value) - bool set_name(const char_t* rhs); - bool set_value(const char_t* rhs); - - // Add attribute with specified name. Returns added attribute, or empty attribute on errors. - xml_attribute append_attribute(const char_t* name); - xml_attribute prepend_attribute(const char_t* name); - xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr); - xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr); - - // Add a copy of the specified attribute. Returns added attribute, or empty attribute on errors. - xml_attribute append_copy(const xml_attribute& proto); - xml_attribute prepend_copy(const xml_attribute& proto); - xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr); - xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr); - - // Add child node with specified type. Returns added node, or empty node on errors. - xml_node append_child(xml_node_type type = node_element); - xml_node prepend_child(xml_node_type type = node_element); - xml_node insert_child_after(xml_node_type type, const xml_node& node); - xml_node insert_child_before(xml_node_type type, const xml_node& node); - - // Add child element with specified name. Returns added node, or empty node on errors. - xml_node append_child(const char_t* name); - xml_node prepend_child(const char_t* name); - xml_node insert_child_after(const char_t* name, const xml_node& node); - xml_node insert_child_before(const char_t* name, const xml_node& node); - - // Add a copy of the specified node as a child. Returns added node, or empty node on errors. - xml_node append_copy(const xml_node& proto); - xml_node prepend_copy(const xml_node& proto); - xml_node insert_copy_after(const xml_node& proto, const xml_node& node); - xml_node insert_copy_before(const xml_node& proto, const xml_node& node); - - // Move the specified node to become a child of this node. Returns moved node, or empty node on errors. - xml_node append_move(const xml_node& moved); - xml_node prepend_move(const xml_node& moved); - xml_node insert_move_after(const xml_node& moved, const xml_node& node); - xml_node insert_move_before(const xml_node& moved, const xml_node& node); - - // Remove specified attribute - bool remove_attribute(const xml_attribute& a); - bool remove_attribute(const char_t* name); - - // Remove specified child - bool remove_child(const xml_node& n); - bool remove_child(const char_t* name); - - // Parses buffer as an XML document fragment and appends all nodes as children of the current node. - // Copies/converts the buffer, so it may be deleted or changed after the function returns. - // Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory. - xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Find attribute using predicate. Returns first attribute for which predicate returned true. - template xml_attribute find_attribute(Predicate pred) const - { - if (!_root) return xml_attribute(); - - for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute()) - if (pred(attrib)) - return attrib; - - return xml_attribute(); - } - - // Find child node using predicate. Returns first child for which predicate returned true. - template xml_node find_child(Predicate pred) const - { - if (!_root) return xml_node(); - - for (xml_node node = first_child(); node; node = node.next_sibling()) - if (pred(node)) - return node; - - return xml_node(); - } - - // Find node from subtree using predicate. Returns first node from subtree (depth-first), for which predicate returned true. - template xml_node find_node(Predicate pred) const - { - if (!_root) return xml_node(); - - xml_node cur = first_child(); - - while (cur._root && cur._root != _root) - { - if (pred(cur)) return cur; - - if (cur.first_child()) cur = cur.first_child(); - else if (cur.next_sibling()) cur = cur.next_sibling(); - else - { - while (!cur.next_sibling() && cur._root != _root) cur = cur.parent(); - - if (cur._root != _root) cur = cur.next_sibling(); - } - } - - return xml_node(); - } - - // Find child node by attribute name/value - xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const; - xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const; - - #ifndef PUGIXML_NO_STL - // Get the absolute node path from root as a text string. - string_t path(char_t delimiter = '/') const; - #endif - - // Search for a node by path consisting of node names and . or .. elements. - xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const; - - // Recursively traverse subtree with xml_tree_walker - bool traverse(xml_tree_walker& walker); - - #ifndef PUGIXML_NO_XPATH - // Select single node by evaluating XPath query. Returns first node from the resulting node set. - xpath_node select_node(const char_t* query, xpath_variable_set* variables = 0) const; - xpath_node select_node(const xpath_query& query) const; - - // Select node set by evaluating XPath query - xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const; - xpath_node_set select_nodes(const xpath_query& query) const; - - // (deprecated: use select_node instead) Select single node by evaluating XPath query. - xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; - xpath_node select_single_node(const xpath_query& query) const; - - #endif - - // Print subtree using a writer object - void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; - - #ifndef PUGIXML_NO_STL - // Print subtree to stream - void print(std::basic_ostream >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; - void print(std::basic_ostream >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const; - #endif - - // Child nodes iterators - typedef xml_node_iterator iterator; - - iterator begin() const; - iterator end() const; - - // Attribute iterators - typedef xml_attribute_iterator attribute_iterator; - - attribute_iterator attributes_begin() const; - attribute_iterator attributes_end() const; - - // Range-based for support - xml_object_range children() const; - xml_object_range children(const char_t* name) const; - xml_object_range attributes() const; - - // Get node offset in parsed file/string (in char_t units) for debugging purposes - ptrdiff_t offset_debug() const; - - // Get hash value (unique for handles to the same object) - size_t hash_value() const; - - // Get internal pointer - xml_node_struct* internal_object() const; - }; - -#ifdef __BORLANDC__ - // Borland C++ workaround - bool PUGIXML_FUNCTION operator&&(const xml_node& lhs, bool rhs); - bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs); -#endif - - // A helper for working with text inside PCDATA nodes - class PUGIXML_CLASS xml_text - { - friend class xml_node; - - xml_node_struct* _root; - - typedef void (*unspecified_bool_type)(xml_text***); - - explicit xml_text(xml_node_struct* root); - - xml_node_struct* _data_new(); - xml_node_struct* _data() const; - - public: - // Default constructor. Constructs an empty object. - xml_text(); - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - - // Check if text object is empty - bool empty() const; - - // Get text, or "" if object is empty - const char_t* get() const; - - // Get text, or the default value if object is empty - const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; - - // Get text as a number, or the default value if conversion did not succeed or object is empty - int as_int(int def = 0) const; - unsigned int as_uint(unsigned int def = 0) const; - double as_double(double def = 0) const; - float as_float(float def = 0) const; - - #ifdef PUGIXML_HAS_LONG_LONG - long long as_llong(long long def = 0) const; - unsigned long long as_ullong(unsigned long long def = 0) const; - #endif - - // Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty - bool as_bool(bool def = false) const; - - // Set text (returns false if object is empty or there is not enough memory) - bool set(const char_t* rhs); - - // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") - bool set(int rhs); - bool set(unsigned int rhs); - bool set(double rhs); - bool set(float rhs); - bool set(bool rhs); - - #ifdef PUGIXML_HAS_LONG_LONG - bool set(long long rhs); - bool set(unsigned long long rhs); - #endif - - // Set text (equivalent to set without error checking) - xml_text& operator=(const char_t* rhs); - xml_text& operator=(int rhs); - xml_text& operator=(unsigned int rhs); - xml_text& operator=(double rhs); - xml_text& operator=(float rhs); - xml_text& operator=(bool rhs); - - #ifdef PUGIXML_HAS_LONG_LONG - xml_text& operator=(long long rhs); - xml_text& operator=(unsigned long long rhs); - #endif - - // Get the data node (node_pcdata or node_cdata) for this object - xml_node data() const; - }; - -#ifdef __BORLANDC__ - // Borland C++ workaround - bool PUGIXML_FUNCTION operator&&(const xml_text& lhs, bool rhs); - bool PUGIXML_FUNCTION operator||(const xml_text& lhs, bool rhs); -#endif - - // Child node iterator (a bidirectional iterator over a collection of xml_node) - class PUGIXML_CLASS xml_node_iterator - { - friend class xml_node; - - private: - mutable xml_node _wrap; - xml_node _parent; - - xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent); - - public: - // Iterator traits - typedef ptrdiff_t difference_type; - typedef xml_node value_type; - typedef xml_node* pointer; - typedef xml_node& reference; - - #ifndef PUGIXML_NO_STL - typedef std::bidirectional_iterator_tag iterator_category; - #endif - - // Default constructor - xml_node_iterator(); - - // Construct an iterator which points to the specified node - xml_node_iterator(const xml_node& node); - - // Iterator operators - bool operator==(const xml_node_iterator& rhs) const; - bool operator!=(const xml_node_iterator& rhs) const; - - xml_node& operator*() const; - xml_node* operator->() const; - - const xml_node_iterator& operator++(); - xml_node_iterator operator++(int); - - const xml_node_iterator& operator--(); - xml_node_iterator operator--(int); - }; - - // Attribute iterator (a bidirectional iterator over a collection of xml_attribute) - class PUGIXML_CLASS xml_attribute_iterator - { - friend class xml_node; - - private: - mutable xml_attribute _wrap; - xml_node _parent; - - xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent); - - public: - // Iterator traits - typedef ptrdiff_t difference_type; - typedef xml_attribute value_type; - typedef xml_attribute* pointer; - typedef xml_attribute& reference; - - #ifndef PUGIXML_NO_STL - typedef std::bidirectional_iterator_tag iterator_category; - #endif - - // Default constructor - xml_attribute_iterator(); - - // Construct an iterator which points to the specified attribute - xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent); - - // Iterator operators - bool operator==(const xml_attribute_iterator& rhs) const; - bool operator!=(const xml_attribute_iterator& rhs) const; - - xml_attribute& operator*() const; - xml_attribute* operator->() const; - - const xml_attribute_iterator& operator++(); - xml_attribute_iterator operator++(int); - - const xml_attribute_iterator& operator--(); - xml_attribute_iterator operator--(int); - }; - - // Named node range helper - class PUGIXML_CLASS xml_named_node_iterator - { - friend class xml_node; - - public: - // Iterator traits - typedef ptrdiff_t difference_type; - typedef xml_node value_type; - typedef xml_node* pointer; - typedef xml_node& reference; - - #ifndef PUGIXML_NO_STL - typedef std::bidirectional_iterator_tag iterator_category; - #endif - - // Default constructor - xml_named_node_iterator(); - - // Construct an iterator which points to the specified node - xml_named_node_iterator(const xml_node& node, const char_t* name); - - // Iterator operators - bool operator==(const xml_named_node_iterator& rhs) const; - bool operator!=(const xml_named_node_iterator& rhs) const; - - xml_node& operator*() const; - xml_node* operator->() const; - - const xml_named_node_iterator& operator++(); - xml_named_node_iterator operator++(int); - - const xml_named_node_iterator& operator--(); - xml_named_node_iterator operator--(int); - - private: - mutable xml_node _wrap; - xml_node _parent; - const char_t* _name; - - xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name); - }; - - // Abstract tree walker class (see xml_node::traverse) - class PUGIXML_CLASS xml_tree_walker - { - friend class xml_node; - - private: - int _depth; - - protected: - // Get current traversal depth - int depth() const; - - public: - xml_tree_walker(); - virtual ~xml_tree_walker(); - - // Callback that is called when traversal begins - virtual bool begin(xml_node& node); - - // Callback that is called for each node traversed - virtual bool for_each(xml_node& node) = 0; - - // Callback that is called when traversal ends - virtual bool end(xml_node& node); - }; - - // Parsing status, returned as part of xml_parse_result object - enum xml_parse_status - { - status_ok = 0, // No error - - status_file_not_found, // File was not found during load_file() - status_io_error, // Error reading from file/stream - status_out_of_memory, // Could not allocate memory - status_internal_error, // Internal error occurred - - status_unrecognized_tag, // Parser could not determine tag type - - status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction - status_bad_comment, // Parsing error occurred while parsing comment - status_bad_cdata, // Parsing error occurred while parsing CDATA section - status_bad_doctype, // Parsing error occurred while parsing document type declaration - status_bad_pcdata, // Parsing error occurred while parsing PCDATA section - status_bad_start_element, // Parsing error occurred while parsing start element tag - status_bad_attribute, // Parsing error occurred while parsing element attribute - status_bad_end_element, // Parsing error occurred while parsing end element tag - status_end_element_mismatch,// There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) - - status_append_invalid_root, // Unable to append nodes since root type is not node_element or node_document (exclusive to xml_node::append_buffer) - - status_no_document_element // Parsing resulted in a document without element nodes - }; - - // Parsing result - struct PUGIXML_CLASS xml_parse_result - { - // Parsing status (see xml_parse_status) - xml_parse_status status; - - // Last parsed offset (in char_t units from start of input data) - ptrdiff_t offset; - - // Source document encoding - xml_encoding encoding; - - // Default constructor, initializes object to failed state - xml_parse_result(); - - // Cast to bool operator - operator bool() const; - - // Get error description - const char* description() const; - }; - - // Document class (DOM tree root) - class PUGIXML_CLASS xml_document: public xml_node - { - private: - char_t* _buffer; - - char _memory[192]; - - // Non-copyable semantics - xml_document(const xml_document&); - const xml_document& operator=(const xml_document&); - - void create(); - void destroy(); - - public: - // Default constructor, makes empty document - xml_document(); - - // Destructor, invalidates all node/attribute handles to this document - ~xml_document(); - - // Removes all nodes, leaving the empty document - void reset(); - - // Removes all nodes, then copies the entire contents of the specified document - void reset(const xml_document& proto); - - #ifndef PUGIXML_NO_STL - // Load document from stream. - xml_parse_result load(std::basic_istream >& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - xml_parse_result load(std::basic_istream >& stream, unsigned int options = parse_default); - #endif - - // (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied. - xml_parse_result load(const char_t* contents, unsigned int options = parse_default); - - // Load document from zero-terminated string. No encoding conversions are applied. - xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default); - - // Load document from file - xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Load document from buffer. Copies/converts the buffer, so it may be deleted or changed after the function returns. - xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). - // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed. - xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). - // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore). - xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); - - // Save XML document to writer (semantics is slightly different from xml_node::print, see documentation for details). - void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - - #ifndef PUGIXML_NO_STL - // Save XML document to stream (semantics is slightly different from xml_node::print, see documentation for details). - void save(std::basic_ostream >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - void save(std::basic_ostream >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const; - #endif - - // Save XML to file - bool save_file(const char* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; - - // Get document element - xml_node document_element() const; - }; - -#ifndef PUGIXML_NO_XPATH - // XPath query return type - enum xpath_value_type - { - xpath_type_none, // Unknown type (query failed to compile) - xpath_type_node_set, // Node set (xpath_node_set) - xpath_type_number, // Number - xpath_type_string, // String - xpath_type_boolean // Boolean - }; - - // XPath parsing result - struct PUGIXML_CLASS xpath_parse_result - { - // Error message (0 if no error) - const char* error; - - // Last parsed offset (in char_t units from string start) - ptrdiff_t offset; - - // Default constructor, initializes object to failed state - xpath_parse_result(); - - // Cast to bool operator - operator bool() const; - - // Get error description - const char* description() const; - }; - - // A single XPath variable - class PUGIXML_CLASS xpath_variable - { - friend class xpath_variable_set; - - protected: - xpath_value_type _type; - xpath_variable* _next; - - xpath_variable(); - - // Non-copyable semantics - xpath_variable(const xpath_variable&); - xpath_variable& operator=(const xpath_variable&); - - public: - // Get variable name - const char_t* name() const; - - // Get variable type - xpath_value_type type() const; - - // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error - bool get_boolean() const; - double get_number() const; - const char_t* get_string() const; - const xpath_node_set& get_node_set() const; - - // Set variable value; no type conversion is performed, false is returned on type mismatch error - bool set(bool value); - bool set(double value); - bool set(const char_t* value); - bool set(const xpath_node_set& value); - }; - - // A set of XPath variables - class PUGIXML_CLASS xpath_variable_set - { - private: - xpath_variable* _data[64]; - - // Non-copyable semantics - xpath_variable_set(const xpath_variable_set&); - xpath_variable_set& operator=(const xpath_variable_set&); - - xpath_variable* find(const char_t* name) const; - - public: - // Default constructor/destructor - xpath_variable_set(); - ~xpath_variable_set(); - - // Add a new variable or get the existing one, if the types match - xpath_variable* add(const char_t* name, xpath_value_type type); - - // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch - bool set(const char_t* name, bool value); - bool set(const char_t* name, double value); - bool set(const char_t* name, const char_t* value); - bool set(const char_t* name, const xpath_node_set& value); - - // Get existing variable by name - xpath_variable* get(const char_t* name); - const xpath_variable* get(const char_t* name) const; - }; - - // A compiled XPath query object - class PUGIXML_CLASS xpath_query - { - private: - void* _impl; - xpath_parse_result _result; - - typedef void (*unspecified_bool_type)(xpath_query***); - - // Non-copyable semantics - xpath_query(const xpath_query&); - xpath_query& operator=(const xpath_query&); - - public: - // Construct a compiled object from XPath expression. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. - explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0); - - // Destructor - ~xpath_query(); - - // Get query expression return type - xpath_value_type return_type() const; - - // Evaluate expression as boolean value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - bool evaluate_boolean(const xpath_node& n) const; - - // Evaluate expression as double value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - double evaluate_number(const xpath_node& n) const; - - #ifndef PUGIXML_NO_STL - // Evaluate expression as string value in the specified context; performs type conversion if necessary. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - string_t evaluate_string(const xpath_node& n) const; - #endif - - // Evaluate expression as string value in the specified context; performs type conversion if necessary. - // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). - // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. - // If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead. - size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const; - - // Evaluate expression as node set in the specified context. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. - // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead. - xpath_node_set evaluate_node_set(const xpath_node& n) const; - - // Evaluate expression as node set in the specified context. - // Return first node in document order, or empty node if node set is empty. - // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. - // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node instead. - xpath_node evaluate_node(const xpath_node& n) const; - - // Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode) - const xpath_parse_result& result() const; - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - }; - - #ifndef PUGIXML_NO_EXCEPTIONS - // XPath exception class - class PUGIXML_CLASS xpath_exception: public std::exception - { - private: - xpath_parse_result _result; - - public: - // Construct exception from parse result - explicit xpath_exception(const xpath_parse_result& result); - - // Get error message - virtual const char* what() const throw(); - - // Get parse result - const xpath_parse_result& result() const; - }; - #endif - - // XPath node class (either xml_node or xml_attribute) - class PUGIXML_CLASS xpath_node - { - private: - xml_node _node; - xml_attribute _attribute; - - typedef void (*unspecified_bool_type)(xpath_node***); - - public: - // Default constructor; constructs empty XPath node - xpath_node(); - - // Construct XPath node from XML node/attribute - xpath_node(const xml_node& node); - xpath_node(const xml_attribute& attribute, const xml_node& parent); - - // Get node/attribute, if any - xml_node node() const; - xml_attribute attribute() const; - - // Get parent of contained node/attribute - xml_node parent() const; - - // Safe bool conversion operator - operator unspecified_bool_type() const; - - // Borland C++ workaround - bool operator!() const; - - // Comparison operators - bool operator==(const xpath_node& n) const; - bool operator!=(const xpath_node& n) const; - }; - -#ifdef __BORLANDC__ - // Borland C++ workaround - bool PUGIXML_FUNCTION operator&&(const xpath_node& lhs, bool rhs); - bool PUGIXML_FUNCTION operator||(const xpath_node& lhs, bool rhs); -#endif - - // A fixed-size collection of XPath nodes - class PUGIXML_CLASS xpath_node_set - { - public: - // Collection type - enum type_t - { - type_unsorted, // Not ordered - type_sorted, // Sorted by document order (ascending) - type_sorted_reverse // Sorted by document order (descending) - }; - - // Constant iterator type - typedef const xpath_node* const_iterator; - - // We define non-constant iterator to be the same as constant iterator so that various generic algorithms (i.e. boost foreach) work - typedef const xpath_node* iterator; - - // Default constructor. Constructs empty set. - xpath_node_set(); - - // Constructs a set from iterator range; data is not checked for duplicates and is not sorted according to provided type, so be careful - xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted); - - // Destructor - ~xpath_node_set(); - - // Copy constructor/assignment operator - xpath_node_set(const xpath_node_set& ns); - xpath_node_set& operator=(const xpath_node_set& ns); - - // Get collection type - type_t type() const; - - // Get collection size - size_t size() const; - - // Indexing operator - const xpath_node& operator[](size_t index) const; - - // Collection iterators - const_iterator begin() const; - const_iterator end() const; - - // Sort the collection in ascending/descending order by document order - void sort(bool reverse = false); - - // Get first node in the collection by document order - xpath_node first() const; - - // Check if collection is empty - bool empty() const; - - private: - type_t _type; - - xpath_node _storage; - - xpath_node* _begin; - xpath_node* _end; - - void _assign(const_iterator begin, const_iterator end); - }; -#endif - -#ifndef PUGIXML_NO_STL - // Convert wide string to UTF8 - std::basic_string, std::allocator > PUGIXML_FUNCTION as_utf8(const wchar_t* str); - std::basic_string, std::allocator > PUGIXML_FUNCTION as_utf8(const std::basic_string, std::allocator >& str); - - // Convert UTF8 to wide string - std::basic_string, std::allocator > PUGIXML_FUNCTION as_wide(const char* str); - std::basic_string, std::allocator > PUGIXML_FUNCTION as_wide(const std::basic_string, std::allocator >& str); -#endif - - // Memory allocation function interface; returns pointer to allocated memory or NULL on failure - typedef void* (*allocation_function)(size_t size); - - // Memory deallocation function interface - typedef void (*deallocation_function)(void* ptr); - - // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. - void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); - - // Get current memory management functions - allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); - deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); -} - -#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) -namespace std -{ - // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) - std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&); - std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&); - std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&); -} -#endif - -#if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) -namespace std -{ - // Workarounds for (non-standard) iterator category detection - std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&); - std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&); - std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&); -} -#endif - -#endif - -// Make sure implementation is included in header-only mode -// Use macro expansion in #include to work around QMake (QTBUG-11923) -#if defined(PUGIXML_HEADER_ONLY) && !defined(PUGIXML_SOURCE) -# define PUGIXML_SOURCE "pugixml.cpp" -# include PUGIXML_SOURCE -#endif - -/** - * Copyright (c) 2006-2015 Arseny Kapoulkine - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ diff --git a/3rdparty/pugixml_build/CMakeLists.txt b/3rdparty/pugixml_build/CMakeLists.txt new file mode 100644 index 00000000..72973bfb --- /dev/null +++ b/3rdparty/pugixml_build/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 2.8) +Project(pugixml CXX) + +add_library(pugixml SHARED ${CMAKE_SOURCE_DIR}/3rdparty/pugixml/src/pugixml.cpp) diff --git a/3rdparty/svmlight b/3rdparty/svmlight new file mode 160000 index 00000000..64ecc2c9 --- /dev/null +++ b/3rdparty/svmlight @@ -0,0 +1 @@ +Subproject commit 64ecc2c9914b667e480d77d5c41b4c796942571d diff --git a/3rdparty/svmlight/CMakeLists.txt b/3rdparty/svmlight/CMakeLists.txt deleted file mode 100644 index 5000e2a0..00000000 --- a/3rdparty/svmlight/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_library(od_svmlight SHARED svm_classify.c svm_common.c svm_hideo.c svm_learn.c) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94902837..0f8fe1eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,57 +1,40 @@ cmake_minimum_required(VERSION 2.8) project(OpenDetection) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ") - -# init variables for convinience +# Initialize variables set(OD_SOURCE_DIR ${OpenDetection_SOURCE_DIR}) set(OD_BINARY_DIR ${OpenDetection_BINARY_DIR}) - -# init directories before doing all the searches and includes -set(OD_CMAKE_DIR "${OpenDetection_SOURCE_DIR}/cmake" "${OpenDetection_SOURCE_DIR}/cmake/modules") -set(CMAKE_MODULE_PATH ${OD_CMAKE_DIR} ${CMAKE_MODULE_PATH}) - - - - -# include bunch of stuffs and set the appropriate variables - -# 1. Version -include(od_version) -set(OD_VERSION "${OD_MAJOR_VERSION}.${OD_MINOR_VERSION}") -set(OD_VERSION_DETAILED "${OD_MAJOR_VERSION}.${OD_MINOR_VERSION}.${OD_BUILD_VERSION}") -# generate config files -configure_file ( - "${OD_SOURCE_DIR}/ODConfig.h.in" - "${OD_BINARY_DIR}/generated/ODConfig.h" - ) - -# 3. set up different macros and configurations -include(od_targets) -include(od_mandatory_dependency) - -# 2. collect config options and set appropriate variables which will be used in the next hierarchy -option(WITH_DOCUMENTATION "Build the OD documentation" ON) -option(WITH_GPU "Build GPU components of the project" ON) -option(WITH_SVMLIGHT "Build SVM Light" ON) - -# 3. add all the modules -set(OD_MODULES_NAMES common doc detectors examples 3rdparty) -set(OD_MODULES_DIRS ${OD_MODULES_NAMES}) - -foreach(subdir ${OD_MODULES_DIRS}) - add_subdirectory("${OD_SOURCE_DIR}/${subdir}") +set(OD_CMAKE_DIR ${OD_SOURCE_DIR}/cmake) +set(CMAKE_MODULE_PATH ${OD_CMAKE_DIR}/modules) +set(CMAKE_3RDPARTY_DIR ${OD_SOURCE_DIR}/3rdparty) +set(CMAKE_OD_GENERATED_DIR ${OD_BINARY_DIR}/generated) + +# Initialize versioning +include(${OD_CMAKE_DIR}/Version.cmake) +set(OD_VERSION ${OD_MAJOR_VERSION}.${OD_MINOR_VERSION}) +set(OD_VERSION_DETAILED ${OD_MAJOR_VERSION}.${OD_MINOR_VERSION}.${OD_BUILD_VERSION}) + +# Set up macros and configurations +include(${OD_CMAKE_DIR}/Options.cmake) +include(${OD_CMAKE_DIR}/Targets.cmake) +include(${OD_CMAKE_DIR}/Dependency.cmake) +include(${OD_CMAKE_DIR}/Macros.cmake) +include(${OD_CMAKE_DIR}/Deb.cmake) +include(${OD_CMAKE_DIR}/Uninstall.cmake) + +# Prepare configuration files +configure_file(${OD_CMAKE_DIR}/Version.h.in ${CMAKE_OD_GENERATED_DIR}/version.h) +install(FILES ${CMAKE_OD_GENERATED_DIR}/version.h DESTINATION ${OD_INSTALL_INCLUDE_DIR}) + +# Set modules +set(OD_MODULES_NAMES 3rdparty common gpu/common detectors gpu/detectors doc examples) + +# Add modules +foreach(subdir ${OD_MODULES_NAMES}) + add_subdirectory(${OD_SOURCE_DIR}/${subdir}) endforeach(subdir) - - - - -#include folders -include_directories("${OD_BINARY_DIR}/generated") - - - - -set(SOURCE_FILES opendetection.cpp) -add_executable(opendetection ${SOURCE_FILES}) \ No newline at end of file +# Install the FindPackage configuration file +get_property(OD_INSTALLED_LIBRARIES GLOBAL PROPERTY OD_INSTALLED_LIBRARIES) +configure_file(${OD_CMAKE_DIR}/Config.cmake.in ${OD_BINARY_DIR}/Config.cmake) +install(FILES ${OD_BINARY_DIR}/Config.cmake DESTINATION ${OD_CMAKE_INSTALL_DIR}) diff --git a/README.md b/README.md index 9451c452..fd7f7f58 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ OpenDetection ============= OpenDetection is a standalone open source project for object detection and recognition in images and 3D point clouds. +To clone the dependencies (SiftGPU and pugixml) clone with --recursive flag or pull submodules with ``git submodule init && git submodule update && git submodule foreach git pull origin master`` . Website - http://opendetection.com or http://krips89.github.io/opendetection_docs diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 00000000..0d10f43a --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,14 @@ + +set(OD_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/${OD_INSTALL_INCLUDE_DIR}) +set(OD_LIBRARY_PATH ${CMAKE_INSTALL_PREFIX}/${OD_INSTALL_LIBRARY_DIR}) +set(OD_LIBRARIES ${OD_INSTALLED_LIBRARIES}) + +if(WIN32) + if(MSVC) + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} /SUBSYSTEM:WINDOWS /DNOMINMAX") + elseif(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows -std=c++11") + endif() +elseif(UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +endif() \ No newline at end of file diff --git a/cmake/Deb.cmake b/cmake/Deb.cmake new file mode 100644 index 00000000..af1d8e48 --- /dev/null +++ b/cmake/Deb.cmake @@ -0,0 +1,12 @@ +set(CPACK_GENERATOR "DEB") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Giacomo Dabisias") +set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Opendetection library installation package") +set(CPACK_DEBIAN_PACKAGE_VERSION {OD_MAJOR_VERSION}.${OD_MINOR_VERSION}.${OD_BUILD_VERSION}) + +# Set the correct architecture for the deb +execute_process(COMMAND dpkg --print-architecture COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE) +if(ARCHITECTURE) + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${ARCHITECTURE}) +endif() + +include(CPack) \ No newline at end of file diff --git a/cmake/Dependency.cmake b/cmake/Dependency.cmake new file mode 100644 index 00000000..e796db9f --- /dev/null +++ b/cmake/Dependency.cmake @@ -0,0 +1,26 @@ +find_package(PCL REQUIRED) +find_package(OpenCV 3 REQUIRED) +find_package(VTK REQUIRED) +find_package(Boost 1.40 COMPONENTS program_options REQUIRED) + +if(0) +if(WITH_CAFFE) + find_package(Caffe REQUIRED) + if(Caffe_FOUND) + add_definitions(${Caffe_DEFINITIONS}) + if(WITH_GPU) + find_package(CUDA REQUIRED) + endif() + if(WITH_GTKMM) + find_package(PkgConfig) + pkg_check_modules(GTKMM gtkmm-3.0) + endif() + else() + message("Caffe not found!") + endif() +endif() +endif(0) + +# Needed by od_common. There is a circular dependency between od_common and od_gpu_common include dirs. +include_directories(GPU_COMMON_INCLUDE_DIRS ${OD_SOURCE_DIR}/gpu/common/include) +include_directories(GPU_DETECTORS_INCLUDE_DIRS ${OD_SOURCE_DIR}/gpu/detectors/include) \ No newline at end of file diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake new file mode 100644 index 00000000..73de7d22 --- /dev/null +++ b/cmake/Macros.cmake @@ -0,0 +1,56 @@ +# global installation type +set(OD_LIB_TYPE SHARED) + +macro(OD_ADD_LIBRARY _name ) + + set(lib_name "od_${_name}") + + set(options) + set(oneValueArgs) + set(multiValueArgs SRCS LINK_WITH) + cmake_parse_arguments(OD_ADD_LIBRARY "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + add_library(${lib_name} ${OD_LIB_TYPE} ${OD_ADD_LIBRARY_SRCS}) + + target_link_libraries(${lib_name} ${OD_ADD_LIBRARY_LINK_WITH}) + + # target properties + set_target_properties(${lib_name} PROPERTIES + VERSION ${OD_VERSION} + SOVERSION ${OD_MAJOR_VERSION}.${OD_MINOR_VERSION} + ) + + # Install library + install(TARGETS ${lib_name} + RUNTIME DESTINATION ${OD_INSTALL_RUNTIME_DIR} COMPONENT ${lib_name} + LIBRARY DESTINATION ${OD_INSTALL_LIBRARY_DIR} COMPONENT ${lib_name} + ARCHIVE DESTINATION ${OD_INSTALL_ARCHIVE_DIR} COMPONENT ${lib_name}) + + set_property(GLOBAL APPEND PROPERTY OD_INSTALLED_LIBRARIES ${lib_name}) + +endmacro(OD_ADD_LIBRARY) + +macro(OD_ADD_EXAMPLE _name) + set(options) + set(oneValueArgs) + set(multiValueArgs FILES LINK_WITH INCLUDE) + cmake_parse_arguments(OD_ADD_EXAMPLE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + include_directories("${OD_SOURCE_DIR}" ${OD_ADD_EXAMPLE_INCLUDE}) + add_executable(${_name} ${OD_ADD_EXAMPLE_FILES}) + target_link_libraries(${_name} ${OD_ADD_EXAMPLE_LINK_WITH}) +endmacro(OD_ADD_EXAMPLE) + +MACRO(SUBDIR_LIST retval curdir return_relative) + file(GLOB sub-dir RELATIVE ${curdir} *) + set(list_of_dirs "") + foreach(dir ${sub-dir}) + if(IS_DIRECTORY ${curdir}/${dir}) + if (${return_relative}) + set(list_of_dirs ${list_of_dirs} ${dir}) + else() + set(list_of_dirs ${list_of_dirs} ${curdir}/${dir}) + endif() + endif() + endforeach() + set(${retval} ${list_of_dirs}) +endmacro() diff --git a/cmake/Options.cmake b/cmake/Options.cmake new file mode 100644 index 00000000..0d954038 --- /dev/null +++ b/cmake/Options.cmake @@ -0,0 +1,50 @@ +# Set correct flags depending on the OS and compiler +if(WIN32) + if(MSVC) + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} /SUBSYSTEM:WINDOWS /DNOMINMAX") + elseif(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows -std=c++11") + endif() +elseif(UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +endif() + +if(WITH_WARNINGS) + if(WIN32) + if(MSVC) + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} /WALL") + elseif(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + endif() + elseif(UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + endif() +endif() + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) +endif(NOT CMAKE_BUILD_TYPE) + +# Optional parameters +option(WITH_WARNINGS "Add build warnings" OFF) +option(WITH_DOCUMENTATION "Build the OD documentation" ON) +option(WITH_GPU "Build GPU modules" ON) +option(WITH_EXAMPLES "Build examples" OFF) +option(WITH_SVMLIGHT "Build with svmlight support" ON) +option(WITH_STD_SHARED_PTR "use std::shared_ptr instead of boost::shared_ptr" OFF) +#option(WITH_CAFFE "build caffe support" OFF) +#option(WITH_GTKMM "build gtkmm support" OFF) + +option(BUILD_GLOBAL_2D_DETECTION "build global 2D detection" ON) +option(BUILD_GLOBAL_3D_DETECTION "build global 3D detection" ON) +option(BUILD_LOCAL_2D_DETECTION "build local 2D detection" ON) +option(BUILD_MISC_DETECTION "build miscellaneous detection" ON) + +if(WITH_STD_SHARED_PTR) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWITH_STD_SHARED_PTR") +endif() + +if(WITH_GPU) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWITH_GPU") +endif() + diff --git a/cmake/Targets.cmake b/cmake/Targets.cmake new file mode 100644 index 00000000..677a9776 --- /dev/null +++ b/cmake/Targets.cmake @@ -0,0 +1,42 @@ +# installation structure +if(NOT OD_INSTALL_RUNTIME_DIR) + set(OD_INSTALL_RUNTIME_DIR bin) +endif() + +if(NOT OD_INSTALL_LIBRARY_DIR) + set(OD_INSTALL_LIBRARY_DIR lib) +endif() + +if(NOT OD_INSTALL_ARCHIVE_DIR) + set(OD_INSTALL_ARCHIVE_DIR lib) +endif() + +if(NOT OD_INSTALL_INCLUDE_DIR) + set(OD_INSTALL_INCLUDE_DIR include/od-${OD_VERSION}) +endif() + +if(NOT OD_INSTALL_DATA_DIR) + set(OD_INSTALL_DATA_DIR share/od-${OD_VERSION}) +endif() + +if(NOT OD_INSTALL_DOC_DIR) + set(OD_INSTALL_DOC_DIR share/doc/od-${OD_VERSION}) +endif() + +if(NOT OD_CMAKE_INSTALL_DIR) + set(OD_CMAKE_INSTALL_DIR lib/cmake/OD) +endif() + +if(NOT OD_INSTALL_PACKAGE_DIR) + set(OD_INSTALL_PACKAGE_DIR lib/cmake/od-${OD_VERSION}) +endif() + +if(NOT OD_INSTALL_DOXYGEN_DIR) + set(OD_INSTALL_DOXYGEN_DIR ${OD_INSTALL_DOC_DIR}/doxygen) +endif() + +if(NOT OD_INSTALLED_LIBRARIES) + set_property(GLOBAL PROPERTY OD_INSTALLED_LIBRARIES "") +endif() + + diff --git a/cmake/Uninstall.cmake b/cmake/Uninstall.cmake new file mode 100644 index 00000000..8937476d --- /dev/null +++ b/cmake/Uninstall.cmake @@ -0,0 +1,3 @@ +# uninstall target +configure_file("${OD_CMAKE_DIR}/Uninstall.cmake.in" "${OD_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) +add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) \ No newline at end of file diff --git a/cmake/Uninstall.cmake.in b/cmake/Uninstall.cmake.in new file mode 100644 index 00000000..2037e365 --- /dev/null +++ b/cmake/Uninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) diff --git a/cmake/od_version.cmake b/cmake/Version.cmake similarity index 76% rename from cmake/od_version.cmake rename to cmake/Version.cmake index 243635fb..818060e4 100644 --- a/cmake/od_version.cmake +++ b/cmake/Version.cmake @@ -1,4 +1,5 @@ # OD version number components. set(OD_MAJOR_VERSION 1) set(OD_MINOR_VERSION 0) -set(OD_BUILD_VERSION 0) \ No newline at end of file +set(OD_BUILD_VERSION 0) + diff --git a/ODConfig.h.in b/cmake/Version.h.in similarity index 100% rename from ODConfig.h.in rename to cmake/Version.h.in diff --git a/cmake/modules/FindEigen.cmake b/cmake/modules/FindEigen.cmake deleted file mode 100644 index 5819a5c7..00000000 --- a/cmake/modules/FindEigen.cmake +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################### -# Find Eigen3 -# -# This sets the following variables: -# EIGEN_FOUND - True if Eigen was found. -# EIGEN_INCLUDE_DIRS - Directories containing the Eigen include files. -# EIGEN_DEFINITIONS - Compiler flags for Eigen. -# EIGEN_VERSION - Package version - -find_package(PkgConfig QUIET) -pkg_check_modules(PC_EIGEN eigen3) -set(EIGEN_DEFINITIONS ${PC_EIGEN_CFLAGS_OTHER}) - -if(CMAKE_SYSTEM_NAME STREQUAL Linux) - set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr /usr/local) -endif(CMAKE_SYSTEM_NAME STREQUAL Linux) -if(APPLE) - list(APPEND CMAKE_INCLUDE_PATH /opt/local) - set(CMAKE_FIND_FRAMEWORK NEVER) -endif() - -find_path(EIGEN_INCLUDE_DIR Eigen/Core - HINTS ${PC_EIGEN_INCLUDEDIR} ${PC_EIGEN_INCLUDE_DIRS} "${EIGEN_ROOT}" "$ENV{EIGEN_ROOT}" - PATHS "$ENV{PROGRAMFILES}/Eigen" "$ENV{PROGRAMW6432}/Eigen" - "$ENV{PROGRAMFILES}/Eigen 3.0.0" "$ENV{PROGRAMW6432}/Eigen 3.0.0" - PATH_SUFFIXES eigen3 include/eigen3 include) - -if(EIGEN_INCLUDE_DIR) - file(READ "${EIGEN_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen_version_header) - - string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}") - set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}") - set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}") - set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}") - set(EIGEN_VERSION ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}) -endif(EIGEN_INCLUDE_DIR) - -set(EIGEN_INCLUDE_DIRS ${EIGEN_INCLUDE_DIR}) -set(CMAKE_FIND_FRAMEWORK) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Eigen DEFAULT_MSG EIGEN_INCLUDE_DIR) - -mark_as_advanced(EIGEN_INCLUDE_DIR) - -if(EIGEN_FOUND) - message(STATUS "Eigen found (include: ${EIGEN_INCLUDE_DIRS}, version: ${EIGEN_VERSION})") -endif(EIGEN_FOUND) diff --git a/cmake/modules/FindGLEW.cmake b/cmake/modules/FindGLEW.cmake deleted file mode 100644 index 722da208..00000000 --- a/cmake/modules/FindGLEW.cmake +++ /dev/null @@ -1,17 +0,0 @@ -# Find the GLEW library -# -# Defines: -# -# GLEW_FOUND - system has GLEW -# GLEW_INCLUDE_DIRS - the GLEW include directories -# GLEW_LIBRARY - The GLEW library -# -find_path(GLEW_INCLUDE_DIR GL/glew.h) -find_library(GLEW_LIBRARY NAMES GLEW glew32) - -set(GLEW_INCLUDE_DIRS "${GLEW_INCLUDE_DIR}") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_INCLUDE_DIR GLEW_LIBRARY) - -mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY) diff --git a/cmake/modules/FindSphinx.cmake b/cmake/modules/FindSphinx.cmake deleted file mode 100644 index 33bd40b1..00000000 --- a/cmake/modules/FindSphinx.cmake +++ /dev/null @@ -1,26 +0,0 @@ -############################################################################### -# Find Sphinx -# -# This sets the following variables: -# SPHINX_FOUND - True if Sphinx was found. -# SPHINX_EXECUTABLE - Sphinx-build executable - -find_package(PkgConfig QUIET) -pkg_check_modules(PC_SPHINX sphinx-build) - -find_package(PythonInterp) - -if(PYTHONINTERP_FOUND) - get_filename_component(PYTHON_DIR "${PYTHON_EXECUTABLE}" PATH) -endif(PYTHONINTERP_FOUND) - -find_program(SPHINX_EXECUTABLE NAMES sphinx-build - HINTS ${PC_SPHINX_EXECUTABLE} $ENV{SPHINX_DIR} ${PYTHON_DIR}/Scripts - PATH_SUFFIXES bin - DOC "Sphinx documentation generator" -) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Sphinx DEFAULT_MSG SPHINX_EXECUTABLE) - -mark_as_advanced(SPHINX_EXECUTABLE) diff --git a/cmake/od_mandatory_dependency.cmake b/cmake/od_mandatory_dependency.cmake deleted file mode 100644 index 94f5f621..00000000 --- a/cmake/od_mandatory_dependency.cmake +++ /dev/null @@ -1,8 +0,0 @@ -find_package(PCL REQUIRED) -find_package(OpenCV REQUIRED) -find_package(VTK REQUIRED) -find_package(Eigen REQUIRED) -find_package(Boost 1.40 COMPONENTS program_options REQUIRED ) - - -include_directories("${OD_SOURCE_DIR}" ${EIGEN_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${PCL_INCLUDE_DIRS} ${OD_SOURCE_DIR}/3rdparty/SiftGPU/src/SiftGPU) \ No newline at end of file diff --git a/cmake/od_targets.cmake b/cmake/od_targets.cmake deleted file mode 100644 index 73ed2b0a..00000000 --- a/cmake/od_targets.cmake +++ /dev/null @@ -1,147 +0,0 @@ - -# installation structure -if(NOT OD_INSTALL_RUNTIME_DIR) - set(OD_INSTALL_RUNTIME_DIR bin) -endif() -if(NOT OD_INSTALL_LIBRARY_DIR) - set(OD_INSTALL_LIBRARY_DIR lib) -endif() -if(NOT OD_INSTALL_ARCHIVE_DIR) - set(OD_INSTALL_ARCHIVE_DIR lib) -endif() -if(NOT OD_INSTALL_INCLUDE_DIR) - set(OD_INSTALL_INCLUDE_DIR include/od-${OD_VERSION}/od) -endif() -if(NOT OD_INSTALL_DATA_DIR) - set(OD_INSTALL_DATA_DIR share/od-${OD_VERSION}) -endif() -if(NOT OD_INSTALL_DOC_DIR) - set(OD_INSTALL_DOC_DIR share/doc/od-${OD_VERSION}) -endif() -if(NOT OD_INSTALL_PACKAGE_DIR) - set(OD_INSTALL_PACKAGE_DIR "lib/cmake/od-${OD_VERSION}") -endif() -if(NOT OD_INSTALL_DOXYGEN_DIR) - set(OD_INSTALL_DOXYGEN_DIR ${OD_INSTALL_DOC_DIR}/doxygen) -endif() - -# global installation type -set(OD_LIB_TYPE SHARED) - -# usefull functions called -macro(OD_ADD_LIBRARY1 _name _srcs _incs _impl_incs) - - set(lib_name "od_${_name}") - - message(input to od_add_library: ${OD_LIB_TYPE} ${_srcs} ${_incs} ${_impl_incs}) - add_library(${lib_name} ${OD_LIB_TYPE} ${_srcs} ${_incs} ${_impl_incs}) - - # allways link libs: - target_link_libraries(${lib_name} ${Boost_LIBRARIES}) - - # target properties - set_target_properties(${lib_name} PROPERTIES - VERSION ${OD_VERSION} - SOVERSION ${OD_MAJOR_VERSION}.${OD_MINOR_VERSION} - ) - - # Install library - install(TARGETS ${lib_name} - RUNTIME DESTINATION ${OD_INSTALL_RUNTIME_DIR} COMPONENT ${lib_name} - LIBRARY DESTINATION ${OD_INSTALL_LIBRARY_DIR} COMPONENT ${lib_name} - ARCHIVE DESTINATION ${OD_INSTALL_ARCHIVE_DIR} COMPONENT ${lib_name}) - - #install includes - install(FILES ${_incs} ${_impl_incs} - DESTINATION ${OD_INSTALL_INCLUDE_DIR}/${_name} - COMPONENT ${lib_name}) - -endmacro(OD_ADD_LIBRARY1) - -macro(OD_ADD_LIBRARY_ALL _name ) - - set(lib_name "od_${_name}") - - set(options) - set(oneValueArgs) - set(multiValueArgs SRCS INCS) - cmake_parse_arguments(OD_ADD_LIBRARY_ALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - - #message(input to od_add_library: ${OD_LIB_TYPE} ${OD_ADD_LIBRARY_ALL_SRCS} ${OD_ADD_LIBRARY_ALL_INCS}) - - add_library(${lib_name} ${OD_LIB_TYPE} ${OD_ADD_LIBRARY_ALL_SRCS} ${OD_ADD_LIBRARY_ALL_INCS}) - - # allways link libs: - target_link_libraries(${lib_name} ${Boost_LIBRARIES}) - - # target properties - set_target_properties(${lib_name} PROPERTIES - VERSION ${OD_VERSION} - SOVERSION ${OD_MAJOR_VERSION}.${OD_MINOR_VERSION} - ) - - - # Install library - install(TARGETS ${lib_name} - RUNTIME DESTINATION ${OD_INSTALL_RUNTIME_DIR} COMPONENT ${lib_name} - LIBRARY DESTINATION ${OD_INSTALL_LIBRARY_DIR} COMPONENT ${lib_name} - ARCHIVE DESTINATION ${OD_INSTALL_ARCHIVE_DIR} COMPONENT ${lib_name}) - - message(${_name}) - message("includes to od_add_library: " ${OD_ADD_LIBRARY_ALL_INCS}) - message("include dir: " ${OD_INSTALL_INCLUDE_DIR}) - message("include dir: " ${OD_INSTALL_DOXYGEN_DIR}) - #install includes - install(FILES ${_OD_ADD_LIBRARY_ALL_INCS} - DESTINATION ${OD_INSTALL_INCLUDE_DIR}/${_name} - COMPONENT ${lib_name}) - -endmacro(OD_ADD_LIBRARY_ALL) - -macro(OD_ADD_LIBRARY _name) - - set(lib_name "od_${_name}") - - include_directories("${OD_SOURCE_DIR}") - - #message(input to od_add_library: ${OD_LIB_TYPE} ${ARGN}) - add_library(${lib_name} ${OD_LIB_TYPE} ${ARGN}) - - - # allways link libs: - target_link_libraries(${lib_name} ${Boost_LIBRARIES}) - - # target properties - set_target_properties(${lib_name} PROPERTIES - VERSION ${OD_VERSION} - SOVERSION ${OD_MAJOR_VERSION}.${OD_MINOR_VERSION} - ) - - # Install library - install(TARGETS ${lib_name} - RUNTIME DESTINATION ${OD_INSTALL_RUNTIME_DIR} COMPONENT ${lib_name} - LIBRARY DESTINATION ${OD_INSTALL_LIBRARY_DIR} COMPONENT ${lib_name} - ARCHIVE DESTINATION ${OD_INSTALL_ARCHIVE_DIR} COMPONENT ${lib_name}) - -endmacro(OD_ADD_LIBRARY) - - -macro(OD_ADD_EXAMPLE _name) - set(options) - set(oneValueArgs) - set(multiValueArgs FILES LINK_WITH) - cmake_parse_arguments(OD_ADD_EXAMPLE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - include_directories("${OD_SOURCE_DIR}") - add_executable(${_name} ${OD_ADD_EXAMPLE_FILES}) - target_link_libraries(${_name} ${OD_ADD_EXAMPLE_LINK_WITH}) -endmacro(OD_ADD_EXAMPLE) - - -macro(OD_ADD_INCLUDES _name) - #install includes - install(FILES ${ARGN} - DESTINATION ${OD_INSTALL_INCLUDE_DIR}/${_name} - COMPONENT ${lib_name}) - -endmacro(OD_ADD_INCLUDES) - diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 54a9a43a..c59be1e9 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,56 +1,42 @@ set(SUBSYS_NAME common) set(LIB_NAME od_${SUBSYS_NAME}) set(SUBSYS_DESC "The core module of OpenDetection having the pipeline logic") -set(SUBSYS_DEPS ${OpenCV_LIBS} ${PCL_LIBRARIES}) +set(SUBSYS_DEPS ${OpenCV_LIBS} ${PCL_LIBRARIES} GLEW) -if(WITH_GPU) - set(SUBSYS_DEPS ${SUBSYS_DEPS} siftgpu) -endif() +set(COMMON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(COMMON_IMPL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/impl) -set(build TRUE) +set(COMMON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE) +set(COMMON_IMPL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/impl PARENT_SCOPE) +if(WITH_GPU) + set(SUBSYS_DEPS ${SUBSYS_DEPS} od_gpu_common) + include_directories(${GPU_COMMON_INCLUDE_DIR}) +endif() -if(build) - - set(submodules - pipeline +set(SOURCES + "src/pipeline/ObjectDetector.cpp" + "src/pipeline/Scene.cpp" + "src/pipeline/Detection.cpp" + "src/utils/Utils.cpp" + "src/utils/FeatureDetector2D.cpp" + "src/utils/Viewer.cpp" + "src/utils/FeatureDetector.cpp" + "src/utils/FeatureDetectorInterface.cpp" ) - set(incs - "pipeline/ObjectDetector.h" - "pipeline/ODAlgorithmBase.h" - - "pipeline/ODScene.h" - "pipeline/ODDetection.h" - - "pipeline/ODTrainer.h" - "pipeline/ODDetector.h" - - "utils/ODFrameGenerator.h" - "utils/utils.h" - "utils/ODFeatureDetector2D.h" - - "bindings/svmlight.h" - ) - - set(impl_incs - ) - - set(srcs - "pipeline/ObjectDetector.cpp" - "pipeline/ODScene.cpp" - "utils/utils.cpp" - "utils/ODFeatureDetector2D.cpp" - ) - - OD_ADD_LIBRARY_ALL("${SUBSYS_NAME}" SRCS ${srcs} INCS ${incs} ${impl_incs}) - install(FILES ${incs} DESTINATION ${OD_INSTALL_INCLUDE_DIR}/${SUBSYS_NAME} COMPONENT ${LIB_NAME}) - - if(SUBSYS_DEPS) - target_link_libraries("${LIB_NAME}" ${SUBSYS_DEPS}) - endif(SUBSYS_DEPS) +if(WITH_SVMLIGHT) + set(SOURCES ${SOURCES} "src/bindings/Svmlight.cpp") + include_directories(${CMAKE_3RDPARTY_DIR}/svmlight/) + set(SUBSYS_DEPS ${SUBSYS_DEPS} svmlight) +endif() - #PCL_MAKE_PKGCONFIG("${LIB_NAME}" "${SUBSYS_NAME}" "${SUBSYS_DESC}" "${SUBSYS_DEPS}" "" "" "" "") +include_directories(${OpenCV_INCLUDE_DIRS}) +include_directories(${COMMON_INCLUDE_DIR}) +include_directories(${COMMON_IMPL_DIR}) +include_directories(${PCL_INCLUDE_DIRS}s) +OD_ADD_LIBRARY(${SUBSYS_NAME} SRCS ${SOURCES} LINK_WITH ${SUBSYS_DEPS}) +install(DIRECTORY ${COMMON_INCLUDE_DIR}/od DESTINATION ${OD_INSTALL_INCLUDE_DIR} COMPONENT ${LIB_NAME}) +install(DIRECTORY ${COMMON_IMPL_DIR}/od DESTINATION ${OD_INSTALL_INCLUDE_DIR} COMPONENT ${LIB_NAME}) -endif(build) \ No newline at end of file diff --git a/common/bindings/svmlight.h b/common/bindings/svmlight.h deleted file mode 100644 index b57277c0..00000000 --- a/common/bindings/svmlight.h +++ /dev/null @@ -1,204 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. - - - Original code under the following Apache License 2.0: - Changes - None - - ---------- - This software is licensed under the Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html) Please find the Apache license 2.0 statement in the respective file alongside this software. - -Copyright 2015 Jan Hendriks - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - ---------- - */ - -/** - * @file: svmlight.h - * @author: Jan Hendriks (dahoc3150 [at] gmail.com) - * @date: Created on 11. Mai 2011 - * @brief: Wrapper interface for SVMlight, - * @see http://www.cs.cornell.edu/people/tj/svm_light/ for SVMlight details and terms of use - * - */ - -#ifndef SVMLIGHT_H -#define SVMLIGHT_H - -#include -#include -// svmlight related -// namespace required for avoiding collisions of declarations (e.g. LINEAR being declared in flann, svmlight and libsvm) -namespace svmlight { - extern "C" { - #include "3rdparty/svmlight/svm_common.h" - #include "3rdparty/svmlight/svm_learn.h" - } -} - -using namespace svmlight; - -class SVMlight { -private: - DOC** docs; // training examples - long totwords, totdoc, i; // support vector stuff - double* target; - double* alpha_in; - KERNEL_CACHE* kernel_cache; - MODEL* model; // SVM model - - SVMlight() { - // Init variables - alpha_in = NULL; - kernel_cache = NULL; // Cache not needed with linear kernel - model = (MODEL *) my_malloc(sizeof (MODEL)); - learn_parm = new LEARN_PARM; - kernel_parm = new KERNEL_PARM; - // Init parameters - verbosity = 1; // Show some messages -v 1 - learn_parm->alphafile[0] = ' '; // NULL; // Important, otherwise files with strange/invalid names appear in the working directory - // learn_parm->alphafile = NULL; // Important, otherwise files with strange/invalid names appear in the working directory - learn_parm->biased_hyperplane = 1; - learn_parm->sharedslack = 0; // 1 - learn_parm->skip_final_opt_check = 0; - learn_parm->svm_maxqpsize = 10; - learn_parm->svm_newvarsinqp = 0; - learn_parm->svm_iter_to_shrink = 2; // 2 is for linear; - learn_parm->kernel_cache_size = 40; - learn_parm->maxiter = 100000; - learn_parm->svm_costratio = 1.0; - learn_parm->svm_costratio_unlab = 1.0; - learn_parm->svm_unlabbound = 1E-5; - learn_parm->eps = 0.1; - learn_parm->transduction_posratio = -1.0; - learn_parm->epsilon_crit = 0.001; - learn_parm->epsilon_a = 1E-15; - learn_parm->compute_loo = 0; - learn_parm->rho = 1.0; - learn_parm->xa_depth = 0; - // The HOG paper uses a soft classifier (C = 0.01), set to 0.0 to get the default calculation - learn_parm->svm_c = 0.01; // -c 0.01 - learn_parm->type = REGRESSION; - learn_parm->remove_inconsistent = 0; // -i 0 - Important - kernel_parm->rbf_gamma = 1.0; - kernel_parm->coef_lin = 1; - kernel_parm->coef_const = 1; - kernel_parm->kernel_type = LINEAR; // -t 0 - kernel_parm->poly_degree = 3; - } - - virtual ~SVMlight() { - // Cleanup area - // Free the memory used for the cache - if (kernel_cache) - kernel_cache_cleanup(kernel_cache); - free(alpha_in); - free_model(model, 0); - for (i = 0; i < totdoc; i++) - free_example(docs[i], 1); - free(docs); - free(target); - } - -public: - LEARN_PARM* learn_parm; - KERNEL_PARM* kernel_parm; - - static SVMlight* getInstance(); - - inline void saveModelToFile(const std::string _modelFileName) { - write_model(const_cast(_modelFileName.c_str()), model); - } - - void loadModelFromFile(const std::string _modelFileName) { - this->model = read_model(const_cast(_modelFileName.c_str())); - } - - // read in a problem (in svmlight format) - void read_problem(char* filename) { - // Reads and parses the specified file - read_documents(filename, &docs, &target, &totwords, &totdoc); - } - - // Calls the actual machine learning algorithm - void train() { - svm_learn_regression(docs, target, totdoc, totwords, learn_parm, kernel_parm, &kernel_cache, model); - } - - /** - * Generates a single detecting feature vector (vec1) from the trained support vectors, for use e.g. with the HOG algorithm - * vec1 = sum_1_n (alpha_y*x_i). (vec1 is a 1 x n column vector. n = feature vector length) - * @param singleDetectorVector resulting single detector vector for use in openCV HOG - * @param singleDetectorVectorIndices dummy vector for this implementation - */ - void getSingleDetectingVector(std::vector& singleDetectorVector, std::vector& singleDetectorVectorIndices) { - // Now we use the trained svm to retrieve the single detector vector - DOC** supveclist = model->supvec; - printf("Calculating single descriptor vector out of support vectors (may take some time)\n"); - // Retrieve single detecting vector (v1) from returned ones by calculating vec1 = sum_1_n (alpha_y*x_i). (vec1 is a n x1 column vector. n = feature vector length) - singleDetectorVector.clear(); - singleDetectorVector.resize(model->totwords, 0.); - printf("Resulting vector size %lu\n", singleDetectorVector.size()); - - // Walk over every support vector - for (long ssv = 1; ssv < model->sv_num; ++ssv) { // Don't know what's inside model->supvec[0] ?! - // Get a single support vector - DOC* singleSupportVector = supveclist[ssv]; // Get next support vector - SVECTOR* singleSupportVectorValues = singleSupportVector->fvec; - WORD singleSupportVectorComponent; - // Walk through components of the support vector and populate our detector vector - for (unsigned long singleFeature = 0; singleFeature < model->totwords; ++singleFeature) { - singleSupportVectorComponent = singleSupportVectorValues->words[singleFeature]; - singleDetectorVector.at(singleSupportVectorComponent.wnum-1) += (singleSupportVectorComponent.weight * model->alpha[ssv]); - } - } - } - - /** - * Return model detection threshold / bias - * @return detection threshold / bias - */ - float getThreshold() const { - return model->b; - } - - const char* getSVMName() const { - return "SVMlight"; - } - -}; - -/// Singleton -SVMlight* SVMlight::getInstance() { - static SVMlight theInstance; - return &theInstance; -} - -#endif /* SVMLIGHT_H */ diff --git a/common/impl/od/common/utils/FrameGenerator.hpp b/common/impl/od/common/utils/FrameGenerator.hpp new file mode 100644 index 00000000..e69de29b diff --git a/common/impl/od/common/utils/Scene.hpp b/common/impl/od/common/utils/Scene.hpp new file mode 100644 index 00000000..b162923d --- /dev/null +++ b/common/impl/od/common/utils/Scene.hpp @@ -0,0 +1,43 @@ +#pragma once + + +template +ScenePointCloud::ScenePointCloud(const shared_ptr > point_cloud) +{ + point_cloud_ = point_cloud; +} + +template +ScenePointCloud::ScenePointCloud(const std::string & point_cloud_file): + point_cloud_(new pcl::PointCloud()) +{ + if(pcl::io::loadPCDFile (point_cloud_file, *point_cloud_ ) == -1) + { + std::cout << "ERROR: Couldn't read the file "<< point_cloud_file << std::endl; + } + path_ = point_cloud_file; +} + +template +shared_ptr > ScenePointCloud::getPointCloud() const +{ + return point_cloud_; +} + +template +shared_ptr > ScenePointCloud::getPointCloudRef() const +{ + return point_cloud_; +} + +template +void ScenePointCloud::setPointCloud(const shared_ptr > point_cloud) +{ + point_cloud_ = point_cloud; +} + +template +void * ScenePointCloud::getData() +{ + return (void *)point_cloud_.get(); +} \ No newline at end of file diff --git a/common/impl/od/common/utils/Viewer.hpp b/common/impl/od/common/utils/Viewer.hpp new file mode 100644 index 00000000..ff4d2fa9 --- /dev/null +++ b/common/impl/od/common/utils/Viewer.hpp @@ -0,0 +1,115 @@ +#pragma once +#include "od/common/utils/Viewer.h" + +namespace od { + + template + void Viewer::render(shared_ptr > to_display, const std::string & cloud_name, bool colored) + { + if(status_ != POINTCLOUD){ + std::cout << "Switching viewer to PointCloud mode" << std::endl; + if(status_ == CVMAT){ + cv::destroyWindow(mat_window_name_.c_str()); + } + } + + status_ = POINTCLOUD; + + if(!viewer_ ){ +#ifndef WITH_BSTD_SHARED_PTR + viewer_ = shared_ptr(new pcl::visualization::PCLVisualizer(cloud_name)); +#else + viewer_ = make_shared(cloud_name); +#endif + viewer_->setBackgroundColor(0, 0, 0); + } + + clouds_.push_back(cloud_name); + + if(colored) + { + pcl::visualization::PointCloudColorHandlerRGBField rgb(to_display); + viewer_->addPointCloud(to_display, rgb, cloud_name); + }else{ + viewer_->addPointCloud(to_display, cloud_name); + } + } + + template + void Viewer::render(shared_ptr > to_display, + pcl::visualization::PointCloudColorHandlerRandom & random_handler, const std::string & cloud_name) + { + if(status_ != POINTCLOUD){ + std::cout << "Switching viewer to PointCloud mode" << std::endl; + if(status_ == CVMAT){ + cv::destroyWindow(mat_window_name_.c_str()); + } + } + + status_ = POINTCLOUD; + + if(!viewer_ ){ +#ifndef WITH_BOOST_SHARED_PTR + viewer_ = shared_ptr(new pcl::visualization::PCLVisualizer(cloud_name)); +#else + viewer_ = make_shared(cloud_name); +#endif + viewer_->setBackgroundColor(0, 0, 0); + } + + clouds_.push_back(cloud_name); + + viewer_->addPointCloud(to_display, random_handler, cloud_name); + + } + + template + void Viewer::render(shared_ptr > to_display, const std::string & cloud_name, bool colored) + { + render(to_display->getPointCloud(), cloud_name, colored); + } + + template + void Viewer::render(const ScenePointCloud & to_display, const std::string & cloud_name, bool colored) + { + render(to_display.getPointCloud(), cloud_name, colored); + } + + template + void Viewer::update(shared_ptr > to_display, const std::string & cloud_name, bool colored) + { + if(status_ != POINTCLOUD){ + std::cout << "No PointCloud to render! use render(shared_ptr>) first!" << std::endl; + return; + } + + + if(!viewer_ || std::find(clouds_.begin(), clouds_.end(), cloud_name) != clouds_.end()){ + std::cout << "No cloud " << cloud_name + << " present. Please first use render(shared_ptr >, const std::string & ) to add the cloud" + << std::endl; + return; + } + + if(colored) + { + pcl::visualization::PointCloudColorHandlerRGBField rgb(to_display); + viewer_->updatePointCloud(to_display, rgb, cloud_name); + }else{ + viewer_->updatePointCloud(to_display, cloud_name); + } + } + + template + void Viewer::update(shared_ptr > to_display, const std::string & cloud_name, bool colored) + { + update(to_display->getPointCloud(), cloud_name, colored); + } + + template + void Viewer::update(const ScenePointCloud & to_display, const std::string & cloud_name, bool colored) + { + update(to_display.getPointCloud(), cloud_name, colored); + } + +} \ No newline at end of file diff --git a/common/include/od/common/bindings/Svmlight.h b/common/include/od/common/bindings/Svmlight.h new file mode 100644 index 00000000..0ce8bf32 --- /dev/null +++ b/common/include/od/common/bindings/Svmlight.h @@ -0,0 +1,109 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. + + + Original code under the following Apache License 2.0: + Changes - None + + ---------- + This software is licensed under the Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html) Please find the Apache license 2.0 statement in the respective file alongside this software. + +Copyright 2015 Jan Hendriks + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + ---------- + */ + +/** + * @author: Jan Hendriks (dahoc3150 [at] gmail.com) + * @date: Created on 11. Mai 2011 + * @brief: Wrapper interface for SVMlight, + * @see http://www.cs.cornell.edu/people/tj/svm_light/ for SVMlight details and terms of use + * + */ +#pragma once +#include +#include +#include + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +namespace svmlight { + extern "C" { + #include "svm_common.h" + #include "svm_learn.h" + } +} +#endif + +class SVMlight { +private: + + svmlight::DOC ** docs_; // training examples + long totwords_, totdoc_; // support vector stuff + double * target_; + double * alpha_in_; + svmlight::KERNEL_CACHE * kernel_cache_; + svmlight::MODEL * model_; // SVM model + + SVMlight(); + virtual ~SVMlight(); + +public: + + svmlight::LEARN_PARM learn_parm_; + svmlight::KERNEL_PARM kernel_parm_; + + static SVMlight * getInstance(); + + void saveModelToFile(const std::string model_file_name); + + void loadModelFromFile(const std::string model_file_name); + + // read in a problem (in svmlight format) + void read_problem(char * filename); + + // Calls the actual machine learning algorithm + void train(); + + /** + * Generates a single detecting feature vector (vec1) from the trained support vectors, for use e.g. with the HOG algorithm + * vec1 = sum_1_n (alpha_y*x_i). (vec1 is a 1 x n column vector. n = feature vector length) + * @param single_detector_vector resulting single detector vector for use in openCV HOG + */ + void getSingleDetectingVector(std::vector & single_detector_vector); + + /** + * Return model detection threshold / bias + * @return detection threshold / bias + */ + float getThreshold() const; + + std::string getSVMName() const; +}; + diff --git a/common/include/od/common/pipeline/Detection.h b/common/include/od/common/pipeline/Detection.h new file mode 100644 index 00000000..c01a56e9 --- /dev/null +++ b/common/include/od/common/pipeline/Detection.h @@ -0,0 +1,354 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/ +// +// Created by sarkar on 12.06.15. +// +#pragma once +#include "od/common/utils/Utils.h" +#include "od/common/pipeline/Scene.h" +#include "od/common/utils/Shared_pointers.h" + +#include +#include +#include + +namespace od +{ + + /** \brief The base class of all the detection. + * + * This is the base class of all the detection classes containing the detection information. All the Detectors return a collection of this class (in the form of Detections). + * Supports three modes: recognition (with type RECOGNITION) and classification (with type CLASSIFICATION) and detection (with type DETECTION). Along with the type, Detector sets an ID to identify what class or what instance of recognition is detected/recognied. + * + * \author Kripasindhu Sarkar + * + */ + namespace detection { + _DEFINE_ENUM_WITH_STRING_CONVERSIONS(DetectionType, (RECOGNITION)(CLASSIFICATION)(DETECTION)(DETECTION_NULL)) + } + + + class Detection + { + public: + + + + virtual ~Detection(){} + + /** \brief Constructor of the Detection class. + \param type The detection type. + \param id The detection identifier. + \param confidence The detection confidence. + */ + Detection(const detection::DetectionType & type = detection::DETECTION_NULL, const std::string & id = std::string(""), double confidence = 1.0); + + /** \brief Prints type and id of the detection. + */ + void printSelf(); + + /** \brief Get the type of the detection. This can be _RECOGNITION, _CLASSIFICATION, _DETECTION, _DETECTION_NULL. + \return The type of the detection. + */ + const detection::DetectionType & getType() const; + + /** \brief Set the type of the detection. This can be _RECOGNITION, _CLASSIFICATION, _DETECTION, _DETECTION_NULL. + \param type The type of the detection. + */ + void setType(const detection::DetectionType & type); + + /** \brief Get the id of the detection. + \return The id of the detection. + */ + const std::string & getId() const; + + /** \brief Set the id of the detection. + \param id The id of the detection. + */ + void setId(const std::string & id); + + /** \brief Get the confidence of the detection. Detector can use this to provide confidence amnong several detections. + \return The confidence level of the detection. + */ + double getConfidence() const; + + /** \brief Set the confidence of the detection. Detector can use this to provide confidence amnong several detections. + \param confidence The confidence level of the detection. + */ + void setConfidence(double confidence); + + private: + + detection::DetectionType type_; + std::string id_; + double confidence_; + + }; + + /** \brief Detection for 2D with 2D location information + * + * \author Kripasindhu Sarkar + * + */ + class Detection2D : public virtual Detection + { + public: + + virtual ~Detection2D(){} + + /** \brief Constructor of the Detection2D class. + \param type The detection type. + \param id The detection identifier. + \param confidence The detection confidence. + */ + Detection2D(const detection::DetectionType & type = detection::DETECTION_NULL, const std::string & id = std::string(""), double confidence = 1.0); + + /** \brief Get the 2D location of the detection. + \return The 2D vector of the detection position. + */ + const Eigen::Vector3d & getLocation() const; + + /** \brief Set the 2D location of the detection. + \param location The 2D location of the detection. + */ + void setLocation(const Eigen::Vector3d & location); + + /** \brief Get the bounding box of the detection. + \return The bounding box if the detection in the frame. + */ + const cv::Rect & getBoundingBox() const; + + /** \brief Set the bounding box of the detection. + \param bounding_box The bounding box of the detection. + */ + void setBoundingBox(const cv::Rect & bounding_box); + + /** \brief Get the image template concerning the detection. + \return Image template concerning the detection. + */ + const cv::Mat & getMetainfoImage() const; + + /** \brief Set the image template concerning the detection. + \param metainfo_image The image template concerning the detection. + */ + void setMetainfoImage(const cv::Mat & metainfo_image); + + Eigen::Vector3d location_2d_; + cv::Rect bounding_box_2d_; + cv::Mat metainfo_image_; + + }; + + /** \brief Detection in 3D with 3D location information. + * + * \author Kripasindhu Sarkar + * + */ + class Detection3D : public virtual Detection + { + public: + + virtual ~Detection3D(){} + + /** \brief Constructor of the Detection3D class. + \param type The detection type. + \param id The detection identifier. + \param confidence The detection confidence. + */ + Detection3D(const detection::DetectionType & type = detection::DETECTION_NULL, const std::string & id = std::string(""), double confidence = 1.0); + + + /** \brief Get the 3D location of the detection. + \return The 3D vector of the detection position. + */ + const Eigen::Vector4d & getLocation() const; + + /** \brief Set the 3D location of the detection. + \param location 3D location of the detection. + */ + void setLocation(const Eigen::Vector4d & location); + + /** \brief Set the 3D location of the detection. + \param location The 3D location of the detection. + */ + void setLocation(const cv::Mat & location); + + /** \brief Returns the pose of the detection. + \return The detection orientation. + */ + const Eigen::Matrix3Xd & getPose() const; + + /** \brief Set the 3D pose of the detection. + \param pose The 3D pose of the detection. + */ + void setPose(const Eigen::Matrix3Xd & pose); + + /** \brief Set the 3D location of the detection. + \param pose_cv The 3D pose of the detection. + */ + void setPose(const cv::Mat & pose_cv); + + /** \brief Get the scale of the detection. + \return Scale of the detection. + */ + double getScale() const; + + /** \brief Set the scale of the detection. + \param scale scale of the detection. + */ + void setScale(double scale); + + const cv::Mat & getMetainfoImage() const; + void setMetainfoImage(const cv::Mat & metainfo_image); + + const shared_ptr > & getMetainfoCluster() const; + void setMetainfoCluster(const shared_ptr > & metainfo_cluster); + + void printSelf(); + + Eigen::Vector4d location_3d_; + Eigen::Matrix3Xd orientation_; + double scale_; + cv::Mat metainfo_image_; + shared_ptr> metainfo_cluster_; + + }; + + /** \brief Detection in 2D with complete information. + * + * \author Kripasindhu Sarkar + * + */ + class DetectionComplete: public Detection2D, public Detection3D + { + }; + + /** \brief The container class for Detections + * + * \author Kripasindhu Sarkar + * + */ + class Detections + { + public: + + Detections(unsigned int n = 0); + + virtual ~Detections(); + + unsigned int size() const; + + void push_back(shared_ptr detection); + + void append(shared_ptr detections); + + shared_ptr operator[](unsigned int i); + shared_ptr at(unsigned int i); + + const cv::Mat & getMetainfoImage() const; + void setMetainfoImage(const cv::Mat & metainfo_image_); + + const shared_ptr > & getMetainfoCluster() const; + void setMetainfoCluster(const shared_ptr > & metainfo_cluster); + + protected: + + std::vector> detections_; + cv::Mat metainfo_image_; + shared_ptr > metainfo_cluster_; + + }; + + + + +/** \brief The container class for Detection2D returned by Detector2D + * + * \author Kripasindhu Sarkar + * + */ + class Detections2D: public Detections + { + public: + + /** \brief Draws rectangles over the input image using the bounding box information present in all the 2D detections. This is a quick function to render and verify the detections made. + */ + SceneImage renderMetainfo(SceneImage & input); + SceneImage renderMetainfo(shared_ptr input); + + shared_ptr operator[](unsigned int i); + shared_ptr at(unsigned int i); + + }; + + /** \brief The container class for Detection3D returned by Detector3D + * + * \author Kripasindhu Sarkar + * + */ + class Detections3D: public Detections + { + public: + + /*SceneImage renderMetainfo(SceneImage input) + { + //picking up random colors for different detection algorithm, if exist + std::map color_map; + for(int i = 0; i < detections_.size(); i++) + { + if(color_map.find(detections_[i]->getId()) == color_map.end()) + color_map[detections_[i]->getId()] = CV_RGB(rand()%255, rand()%255, rand()%255); + } + + cv::Mat image = input.getCVImage().clone(); + for(int i = 0; i < detections_.size(); i++) + { + Detections3D * detection = dynamic_cast(detections_[i]); + cv::rectangle(image, detection->bounding_box_2d_, color_map[detections_[i]->getId()], 2); + } + return SceneImage(image); + }*/ + + + shared_ptr operator[](unsigned int i); + shared_ptr at(unsigned int i); + }; + + /** \brief The container class for DetectionComplete returned by Detector2DComplete + * + * \author Kripasindhu Sarkar + * + */ + class DetectionsComplete: public Detections + { + public: + + shared_ptr operator[](unsigned int i); + shared_ptr at(unsigned int i); + }; + +} diff --git a/common/pipeline/ODDetector.h b/common/include/od/common/pipeline/Detector.h similarity index 62% rename from common/pipeline/ODDetector.h rename to common/include/od/common/pipeline/Detector.h index 5ff482cc..16a1e436 100644 --- a/common/pipeline/ODDetector.h +++ b/common/include/od/common/pipeline/Detector.h @@ -18,7 +18,7 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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 @@ -27,16 +27,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Created by sarkar on 08.06.15. // - -#ifndef OPENDETECTION_ODDETECTOR_H -#define OPENDETECTION_ODDETECTOR_H - -#include "ObjectDetector.h" -#include "ODScene.h" -#include "ODDetection.h" -#include "ObjectDetector.h" -#include "ODAlgorithmBase.h" -#include +#pragma once +#include "od/common/pipeline/Scene.h" +#include "od/common/pipeline/ObjectDetector.h" +#include "od/common/utils/Shared_pointers.h" namespace od { @@ -48,110 +42,107 @@ namespace od * \author Kripasindhu Sarkar * */ - class ODDetector: public ODDetectorCommon + class Detector: public DetectorCommon { public: - ODDetector(std::string const &training_data_location_) : ODDetectorCommon(training_data_location_) - { } + Detector(const std::string & training_data_location) : DetectorCommon(training_data_location) {} + Detector() {} - virtual ODDetections* detect(ODScene *scene){} - virtual ODDetections* detectOmni(ODScene *scene){} + virtual shared_ptr detect(shared_ptr scene) = 0; + virtual shared_ptr detectOmni(shared_ptr scene) = 0; - bool metainfo_; + bool meta_info_; }; /** \brief The detector of 2D scene. * - * This class takes a 2D scene (ODSceneImage) as input and performs detection on them. All the 2D detectors should derive from this class and implement the detect and detectOmni functions. + * This class takes a 2D scene (SceneImage) as input and performs detection on them. All the 2D detectors should derive from this class and implement the detect and detectOmni functions. * * \author Kripasindhu Sarkar * */ - class ODDetector2D: public ODDetector + class Detector2D: public Detector { public: - ODDetector2D(std::string const &trained_data_location_) : ODDetector(trained_data_location_) - { } + Detector2D(const std::string & trained_data_location) : Detector(trained_data_location) {} + Detector2D() {} - ODDetections* detect(ODScene *scene) + shared_ptr detect(shared_ptr scene) { - return detect(dynamic_cast(scene)); + return detect(dynamic_pointer_cast(scene)); } /** \brief Function for performing detection on a segmented scene. * The purpose of this function is to perform detection on a segmented scene or an 'object candidate'. i.e. the entire scene is considered as an 'object' or an detection. It is possible for a scene to trigger multiple detections. * \param[in] scene An instance of 2D scene - * \return [out] detections A number of detections as an ODDetections instance. + * \return [out] detections A number of detections as an Detections instance. */ - virtual ODDetections* detect(ODSceneImage *scene) = 0; + virtual shared_ptr detect(shared_ptr scene) = 0; /** \brief Function for performing detection on an entire scene. * The purpose of this function is to detect an object in an entire scene. Thus, other than the type of detection we also have information about the location of the detection w.r.t. the scene. * \param[in] scene An instance of 2D scene - * \return [out] detections A number of detections as an ODDetections2D instance containing information about the detection and its 2D location. + * \return [out] detections A number of detections as an Detections2D instance containing information about the detection and its 2D location. */ - virtual ODDetections2D* detectOmni(ODSceneImage *scene) = 0; + virtual shared_ptr detectOmni(shared_ptr scene) = 0; }; /** \brief The detector of 3D scene. * - * This class takes a 2D scene (ODSceneImage) as input and performs detection on them. All the 3D detectors should derive from this class and implement the detect and detectOmni functions. + * This class takes a 2D scene (SceneImage) as input and performs detection on them. All the 3D detectors should derive from this class and implement the detect and detectOmni functions. * * \author Kripasindhu Sarkar * */ - template - class ODDetector3D: public ODDetector + template + class Detector3D: public Detector { public: - ODDetector3D(std::string const &trained_data_location_) : ODDetector(trained_data_location_) - { } + Detector3D(const std::string & trained_data_location) : Detector(trained_data_location) {} /** \brief Function for performing detection on a segmented scene. * The purpose of this function is to perform detection on a segmented scene or an 'object candidate'. i.e. the entire scene is considered as an 'object' or an detection. It is possible for a scene to trigger multiple detections. * \param[in] scene An instance of 3D scene - * \return A number of detections as an ODDetections instance. + * \return A number of detections as an Detections instance. */ - virtual ODDetections* detect(ODScenePointCloud *scene) = 0; + virtual shared_ptr detect(shared_ptr > scene) = 0; /** \brief Function for performing detection on an entire scene. * The purpose of this function is to detect an object in an entire scene. Thus, other than the type of detection we also have information about the location of the detection w.r.t. the scene. * \param[in] scene An instance of 3D scene - * \return A number of detections as an ODDetections3D instance containing information about the detection and its 3D pose. + * \return A number of detections as an Detections3D instance containing information about the detection and its 3D pose. */ - virtual ODDetections3D* detectOmni(ODScenePointCloud *scene) = 0; + virtual shared_ptr detectOmni(shared_ptr > scene) = 0; }; /** \brief The detector of 2D scene performing a 'complete detection'. * - * This class takes a 2D scene (ODSceneImage) as input and performs complete detection on them. That is, other than finding the bounding box or location of the object in the image it + * This class takes a 2D scene (SceneImage) as input and performs complete detection on them. That is, other than finding the bounding box or location of the object in the image it * finds out the 3D location and orientation (in other words translation and rotation) of the object in the actual 3D scene as well. * * \author Kripasindhu Sarkar * */ - class ODDetector2DComplete: public ODDetector + class Detector2DComplete: public Detector { public: - ODDetector2DComplete(std::string const &trained_data_location_) : ODDetector(trained_data_location_) - { } + Detector2DComplete(const std::string & trained_data_location) : Detector(trained_data_location) {} /** \brief Function for performing detection on a segmented scene. * The purpose of this function is to perform detection on a segmented scene or an 'object candidate'. i.e. the entire scene is considered as an 'object' or an detection. It is possible for a scene to trigger multiple detections. * \param[in] scene An instance of 2D scene - * \return A number of detections as an ODDetections instance. + * \return A number of detections as an Detections instance. */ - virtual ODDetections* detect(ODSceneImage *scene) = 0; + virtual shared_ptr detect(shared_ptr scene) = 0; /** \brief Function for performing detection on an entire scene. * The purpose of this function is to detect an object in an entire scene. Thus, other than the type of detection we also have information about the location of the detection w.r.t. the scene. * \param[in] scene An instance of 2D scene - * \return A number of detections as an ODDetections3D instance containing information about the detection and its pose in 3D. + * \return A number of detections as an Detections3D instance containing information about the detection and its pose in 3D. */ - virtual ODDetections3D* detectOmni(ODSceneImage *scene) = 0; + virtual shared_ptr detectOmni(shared_ptr scene) = 0; }; } -#endif //OPENDETECTION_ODDETECTOR_H diff --git a/common/pipeline/ObjectDetector.h b/common/include/od/common/pipeline/ObjectDetector.h similarity index 56% rename from common/pipeline/ObjectDetector.h rename to common/include/od/common/pipeline/ObjectDetector.h index 29bd9174..8089a3c1 100644 --- a/common/pipeline/ObjectDetector.h +++ b/common/include/od/common/pipeline/ObjectDetector.h @@ -18,7 +18,7 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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 @@ -27,21 +27,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Created by sarkar on 03.06.15. // - -#ifndef OPENDETECTION_OBJECTDETECTOR_H -#define OPENDETECTION_OBJECTDETECTOR_H - +#pragma once #include #include -#include "ODDetection.h" - +#include "od/common/pipeline/Detection.h" +#include "od/common/pipeline/Scene.h" namespace od { - class ODScene; - class ODDetection; - enum DetectionMethod { PC_GLOBAL_FEATUREMATCHING, PC_LOCAL_CORRESPONDENCE_GROUPING, @@ -57,78 +51,51 @@ namespace od * */ - class ODDetectorCommon + class DetectorCommon { public: - ODDetectorCommon( std::string const &trained_data_location_="") : trained_data_location_(trained_data_location_) - { - std::string clasname = typeid(this).name(); - TRAINED_DATA_ID_ = clasname; - std::transform(clasname.begin(), clasname.end(), clasname.begin(), ::toupper); - TRAINED_LOCATION_DENTIFIER_ = clasname; - } + DetectorCommon(const std::string & trained_data_location); + DetectorCommon() {} virtual void init() = 0; /** \brief Gets/Sets the directory containing the data for training. The trainer uses the data from directory for training. Detectors can use this location to get additional information in its detection algirhtms as well. */ - std::string getTrainingInputLocation() const - { - return training_input_location_; - } + std::string getTrainingInputLocation() const; /** \brief Gets/Sets the directory containing the data for training. The trainer uses the data from directory for training. Detectors can use this location to get additional information in its detection algirhtms as well. */ - void setTrainingInputLocation(std::string training_input_location_) - { - this->training_input_location_ = training_input_location_; - } + void setTrainingInputLocation(const std::string & training_input_location); /** \brief Gets/Sets the base directory for trained data. This should be same for all Trainers and Detectors and can be considered as the 'database' of trained data. Trainers uses one of its * subdirectories based on its type to store algo specific trained data. The corresponding Detector would use the same directory to fetch the trained data for online detection. */ - std::string getTrainedDataLocation() const - { - return trained_data_location_; - } + std::string getTrainedDataLocation() const; /** \brief The base directory for trained data. This should be same for all Trainers and Detectors and can be considered as the 'database' of trained data. Trainers uses one of its * subdirectories based on its type to store algo specific trained data. The corresponding Detector would use the same directory to fetch the trained data for online detection. */ - virtual void setTrainedDataLocation(std::string trained_data_location_) - { - this->trained_data_location_ = trained_data_location_; - } + virtual void setTrainedDataLocation(const std::string & trained_data_location); /** \brief Gets the specific directory for a Trainer or a Detector inside trained_data_location_. */ - std::string getSpecificTrainingDataLocation() - { - return trained_data_location_ + "/" + "TD_" + TRAINED_LOCATION_DENTIFIER_; - } - - std::string getSpecificTrainingData() - { - return getSpecificTrainingDataLocation() + "/" + TRAINED_DATA_ID_; - } - - std::string const &getTrainedDataID() const - { - return TRAINED_DATA_ID_; - } - - void setTrainedDataID(std::string const &trainedDataID) - { - ODDetectorCommon::TRAINED_DATA_ID_ = trainedDataID; - } + std::string getSpecificTrainingDataLocation(); + + std::string getSpecificTrainingData(); + + const std::string & getTrainedDataID() const; + + void setTrainedDataID(const std::string & trainedDataID); protected: + std::string training_input_location_, trained_data_location_; - std::string TRAINED_DATA_ID_, TRAINED_LOCATION_DENTIFIER_; + std::string trained_data_id_, trained_location_identifier_; + }; /** \brief This is the main class for object detection and recognition. @@ -140,54 +107,20 @@ namespace od class ObjectDetector { public: + const DetectionMethod & getMethod() const; - ObjectDetector() - { } + void setDetectionMethod(const DetectionMethod & detection_method); - DetectionMethod const &getMethod() const - { - return method_; - } + bool getAlwaysTrain() const; + void setAlwaysTrain(bool always_train); - void setDetectionMethod(DetectionMethod const &detection_method_) - { - this->method_ = detection_method_; - } + std::string getTrainingInputLocation() const; + void setTrainingInputLocation(const std::string & training_input_location); - bool getAlwaysTrain() const - { - return always_train_; - } + std::string getTrainingDataLocation() const; + void setTrainingDataLocation(const std::string & training_data_location); - void setAlwaysTrain(bool always_train_) - { - this->always_train_ = always_train_; - } - - std::string getTrainingInputLocation() const - { - return training_input_location_; - } - - void setTrainingInputLocation(std::string training_input_location_) - { - this->training_input_location_ = training_input_location_; - } - - std::string getTrainingDataLocation() const - { - return training_data_location_; - } - - void setTrainingDataLocation(std::string training_data_location_) - { - this->training_data_location_ = training_data_location_; - } - - std::string getSpecificTrainingDataLocation() - { - return training_data_location_ + "/" + "TD_" + TRAINED_DATA_IDENTIFIER_; - } + std::string getSpecificTrainingDataLocation(); virtual void init() = 0; @@ -196,21 +129,18 @@ namespace od virtual int train() = 0; + virtual int detect(shared_ptr scene, const std::vector > & detections) = 0; - virtual int detect(ODScene *scene, std::vector detections) {} - - virtual ODDetection* detect(ODScene *scene) {} - virtual ODDetections* detectOmni(ODScene *scene) {} + virtual shared_ptr detect(shared_ptr scene) = 0; + virtual shared_ptr detectOmni(shared_ptr scene) = 0; protected: + DetectionMethod method_; bool always_train_; bool trained_; std::string training_input_location_, training_data_location_; - - std::string TRAINED_DATA_EXT_, TRAINED_DATA_IDENTIFIER_; + std::string trained_data_ext_, trained_data_identifier_; }; } - -#endif //OPENDETECTION_OBJECTDETECTOR_H diff --git a/common/include/od/common/pipeline/Scene.h b/common/include/od/common/pipeline/Scene.h new file mode 100644 index 00000000..f6257f03 --- /dev/null +++ b/common/include/od/common/pipeline/Scene.h @@ -0,0 +1,169 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/ +// +// Created by sarkar on 10.06.15. +// + +#pragma once +#include +#include +#include +#include +#include +#include "od/common/utils/Shared_pointers.h" + +namespace od +{ + /** \brief Base class for Scenes. This contains information about the scenes. Scenes can be image scenes or point cloud scenes + * + * \author Kripasindhu Sarkar + * + */ + class Scene + { + public: + + virtual void * getData() = 0; + + const std::string & getPath() const; + + protected: + + std::string path_; + + }; + + /** \brief Class for Image Scene. + * + * \author Kripasindhu Sarkar + * + */ + class SceneImage : public Scene + { + public: + + SceneImage(const cv::Mat & cvimage); + SceneImage(const std::string & path); + + const std::vector & getKeypoints() const; + void setKeypoints(const std::vector & keypoints_); + + const cv::Mat & getDescriptors() const; + void setDescriptors(const cv::Mat & descriptors_); + + cv::Mat getCVImage() const; + + void * getData(); + + protected: + + cv::Mat cvimage_; + std::vector keypoints_; + cv::Mat descriptors_; + bool is_trained_; + + }; + + + /** \brief Class for 3D scene containing point cloud. + * + * \author Kripasindhu Sarkar + * + */ + template + class ScenePointCloud : public Scene + { + + public: + + ScenePointCloud(const shared_ptr > point_cloud); + ScenePointCloud(const std::string & point_cloud_file); + ScenePointCloud(): point_cloud_(new pcl::PointCloud()){} + + shared_ptr > getPointCloud() const; + shared_ptr > getPointCloudRef() const; + void setPointCloud(const shared_ptr > point_cloud_); + + void * getData(); + + protected: + + shared_ptr > point_cloud_; + + }; + + #ifndef DOXYGEN_SHOULD_SKIP_THIS + + extern template + ScenePointCloud::ScenePointCloud(const shared_ptr > point_cloud); + extern template + ScenePointCloud::ScenePointCloud(const shared_ptr > point_cloud); + extern template + ScenePointCloud::ScenePointCloud(const shared_ptr > point_cloud); + + extern template + ScenePointCloud::ScenePointCloud(const std::string & point_cloud_file); + extern template + ScenePointCloud::ScenePointCloud(const std::string & point_cloud_file); + extern template + ScenePointCloud::ScenePointCloud(const std::string & point_cloud_file); + + extern template + shared_ptr > ScenePointCloud::getPointCloud() const; + extern template + shared_ptr > ScenePointCloud::getPointCloud() const; + extern template + shared_ptr > ScenePointCloud::getPointCloud() const; + + extern template + shared_ptr > ScenePointCloud::getPointCloudRef() const; + extern template + shared_ptr > ScenePointCloud::getPointCloudRef() const; + extern template + shared_ptr > ScenePointCloud::getPointCloudRef() const; + + extern template + void ScenePointCloud::setPointCloud(const shared_ptr > point_cloud); + extern template + void ScenePointCloud::setPointCloud(const shared_ptr > point_cloud); + extern template + void ScenePointCloud::setPointCloud(const shared_ptr > point_cloud); + + extern template + void * ScenePointCloud::getData(); + extern template + void * ScenePointCloud::getData(); + extern template + void * ScenePointCloud::getData(); + + #include "od/common/utils/Scene.hpp" + + #endif + + +} + diff --git a/common/pipeline/ODTrainer.h b/common/include/od/common/pipeline/Trainer.h similarity index 77% rename from common/pipeline/ODTrainer.h rename to common/include/od/common/pipeline/Trainer.h index e3fa2c32..6a0b13d7 100644 --- a/common/pipeline/ODTrainer.h +++ b/common/include/od/common/pipeline/Trainer.h @@ -18,7 +18,7 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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 @@ -27,19 +27,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Created by sarkar on 08.06.15. // - -#ifndef OPENDETECTION_TRAINER_H -#define OPENDETECTION_TRAINER_H - -#include +#pragma once #include -#include - -#include "ODAlgorithmBase.h" -#include "ObjectDetector.h" - - -namespace bf = boost::filesystem; +#include "od/common/pipeline/ObjectDetector.h" namespace od { @@ -48,11 +38,12 @@ namespace od * \author Kripasindhu Sarkar * */ - class ODTrainer: public ODDetectorCommon + class Trainer: public DetectorCommon { public: - ODTrainer(std::string const &training_input_location ="", std::string const &training_data_location="") : ODDetectorCommon(training_data_location) + Trainer(const std::string & training_input_location = std::string(""), const std::string & training_data_location = std::string("")) : + DetectorCommon(training_data_location) { training_input_location_ = training_data_location; } @@ -62,4 +53,3 @@ namespace od }; } -#endif //OPENDETECTION_TRAINER_H diff --git a/common/include/od/common/utils/FeatureDetector.h b/common/include/od/common/utils/FeatureDetector.h new file mode 100644 index 00000000..ad6ee32c --- /dev/null +++ b/common/include/od/common/utils/FeatureDetector.h @@ -0,0 +1,31 @@ +#pragma once +#include "od/common/utils/Shared_pointers.h" +#include "od/common/utils/FeatureDetectorInterface.h" +#include "od/common/utils/FeatureDetector2D.h" + + + +namespace od +{ + + class FeatureDetector + { + + public: + + FeatureDetector(FeatureType type); + FeatureDetector(const std::string & type); + + void computeKeypointsAndDescriptors(const cv::Mat & image, cv::Mat & descriptors, std::vector & keypoints); + + void computeAndSave(const cv::Mat & image, const std::string & path); + + private: + + FeatureType mode_; + bool gpu_; + shared_ptr feature_detector_; + + }; + +} \ No newline at end of file diff --git a/common/include/od/common/utils/FeatureDetector2D.h b/common/include/od/common/utils/FeatureDetector2D.h new file mode 100644 index 00000000..4dd583ab --- /dev/null +++ b/common/include/od/common/utils/FeatureDetector2D.h @@ -0,0 +1,26 @@ +// +// Created by sarkar on 20.04.15. +// +#pragma once +#include "od/common/utils/FeatureDetectorInterface.h" +#include + + +namespace od +{ + + class FeatureDetector2D: public FeatureDetectorIterface + { + + public: + + FeatureDetector2D(FeatureType type); + + void computeKeypointsAndDescriptors(const cv::Mat & image, cv::Mat & descriptors, std::vector & keypoints); + + void computeAndSave(const cv::Mat & image, const std::string & path); + + }; + +} + diff --git a/common/include/od/common/utils/FeatureDetectorInterface.h b/common/include/od/common/utils/FeatureDetectorInterface.h new file mode 100644 index 00000000..c3ea8211 --- /dev/null +++ b/common/include/od/common/utils/FeatureDetectorInterface.h @@ -0,0 +1,36 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace od +{ + + enum FeatureType + { + SIFT, SURF, ORB, SIFT_GPU, ORB_GPU + }; + + extern std::map od_enum_map; + + FeatureType string2FeatureType(const std::string & name); + + class FeatureDetectorIterface + { + + public: + + virtual void computeKeypointsAndDescriptors(const cv::Mat & image, cv::Mat & descriptors, std::vector & keypoints) = 0; + + virtual void computeAndSave(const cv::Mat & image, const std::string & path) = 0; + + protected: + + FeatureType mode_; + cv::Ptr feature_detector_; + + }; + +} \ No newline at end of file diff --git a/common/include/od/common/utils/FrameGenerator.h b/common/include/od/common/utils/FrameGenerator.h new file mode 100644 index 00000000..3dda333e --- /dev/null +++ b/common/include/od/common/utils/FrameGenerator.h @@ -0,0 +1,281 @@ +#pragma once +#include "od/common/pipeline/Detection.h" +#include "od/common/pipeline/Scene.h" +#include +#include +#include +#include + +namespace od +{ + enum GeneratorType + { + GENERATOR_TYPE_FILE_LIST, GENERATOR_TYPE_DEVICE, GENERATOR_TYPE_CONTAINER + }; + + + /** \brief The FrameGenerator class for capturing and reading Scenes conveniently. + * Templated with two parameters - SceneType identifying a Scene class, and TYPE identifying the type of input. After the instantiation with a correct TYPE, use the function + * getNextFrame() to get an instance of next scene of SceneType. getNextFrame() returns valid scenes until all scenes matched are exhausted - the time when 'isValid()' is false. + * + * \tparam SceneT One of the Scene classes - SceneImage or ScenePointCloud + * \tparam TYPE TYPE can be GENERATOR_TYPE_FILE_LIST which means you provide the list of scene files to be returned by the FrameGenerator in the constructor (for eg. \/home/username/pics/\*.jpg) + * Or it can be GENERATOR_TYPE_DEVICE which picks up the webcam or the kinect based on the SceneType. + * \author Kripasindhu Sarkar + * + */ + template + class FrameGenerator + { + public: + + FrameGenerator(const std::string & input = std::string("")); + FrameGenerator(int input = 0){} + + shared_ptr getNextFrame(); + + bool isValid(); + + protected: + + std::vector file_list_; + std::string video_read_path_; + unsigned int curr_image_; + cv::VideoCapture inputCapture_; + bool exhausted_; + + }; + + + template + class FrameGenerator + { + public: + FrameGenerator(const std::string & input = std::string("")) + { + file_list_ = od_glob(input); + curr_image_ = -1; + exhausted_ = false; + } + + shared_ptr getNextFrame() + { + if(exhausted_) + { + cout << "Files Exhausted!"; + return nullptr; + } + + curr_image_++; + if(curr_image_ == file_list_.size() - 1) + exhausted_ = true; + + cout << "Frame: " << file_list_[curr_image_] << endl; +#ifndef WITH_BOOST_SHARED_PTR + return shared_ptr(new SceneT(file_list_[curr_image_])); +#else + return make_shared(file_list_[curr_image_]); +#endif + } + + bool isValid() + { + return !exhausted_; + } + + std::string currentFile() + { + return file_list_[curr_image_]; + } + + private: + + std::vector file_list_; + bool exhausted_; + int curr_image_; + + }; + +/* + template class TContainer, class TObject> + class FrameGenerator + { + public: + + explicit FrameGenerator(TContainer> & container) :container_(container) + { + curr_image_ = -1; + exhausted_ = false; + } + + shared_ptr getNextFrame() + { + if(exhausted_) + { + cout << "Files Exhausted!"; + return nullptr; + } + + curr_image_++; + if(curr_image_ == file_list_.size() - 1) + exhausted_ = true; + + } + + bool isValid() + { + return !exhausted_; + } + + private: + + TContainer> & container_; + bool exhausted_; + int curr_image_; + + }; +*/ + + + template<> + class FrameGenerator + { + public: + + FrameGenerator(const std::string & input = std::string("")) + { + std::cout << "Opening :" << input << std::endl; + input_capture_.open(input); + if(!input_capture_.isOpened()) + {std::cout << "FATAL: Cannot open video capture!" << std::endl;} + } + + FrameGenerator(int input = 0) + { + std::cout << "Opening cam :" << input << std::endl; + input_capture_.open(input); + if(!input_capture_.isOpened()) + {std::cout << "FATAL: Cannot open video capture!" << std::endl;} + } + + shared_ptr getNextFrame() + { + cv::Mat frame; + input_capture_.read(frame); + return make_shared(frame); + } + + bool isValid() + { + return input_capture_.isOpened(); + } + + cv::VideoCapture input_capture_; + }; + + /* + template<> + class FrameGenerator , GENERATOR_TYPE_DEVICE> + { + public: + + + FrameGenerator(std::string input = "") + { + + camera_ = new OpenNIFrameSource::OpenNIFrameSource(input); + + keyboard_cb = boost::bind (&OpenNIFrameSource::OpenNIFrameSource::onKeyboardEvent, camera_, _1); + } + + boost::function const &getKeyboard_cb() const + { + return keyboard_cb; + } + + ScenePointCloud * getNextFrame() + { + OpenNIFrameSource::PointCloudPtr frame = camera_->snap(); + + return new ScenePointCloud(frame); + } + bool isValid() {return camera_->isActive();} + + OpenNIFrameSource::OpenNIFrameSource *camera_; + boost::function keyboard_cb; + }; +*/ + + + template + class FrameGenerator, GENERATOR_TYPE_DEVICE> + { + public: + + typedef pcl::PointCloud PointCloud; + typedef typename pcl::PointCloud::Ptr PointCloudPtr; + typedef typename pcl::PointCloud::ConstPtr PointCloudConstPtr; + + /* A simple class for capturing data from an OpenNI camera */ + FrameGenerator(const std::string & input = std::string("")) : grabber_(input), most_recent_frame_(), frame_counter_(0), active_(true) + { + boost::function frame_cb = boost::bind(&FrameGenerator , GENERATOR_TYPE_DEVICE>::onNewFrame, this, _1); + grabber_.registerCallback(frame_cb); + grabber_.start (); + boost::this_thread::sleep(boost::posix_time::seconds(5)); + } + + ~FrameGenerator() + { + grabber_.stop (); + } + + shared_ptr> getNextFrame() + { + OpenNIFrameSource::PointCloudPtr frame = snap(); + + return make_shared>(frame); + } + + bool isValid() + { + return isActive(); + } + + const PointCloudPtr snap () + { + return most_recent_frame_; + } + + bool isActive () + { + return active_; + } + void onKeyboardEvent(const pcl::visualization::KeyboardEvent & event) + { + // When the spacebar is pressed, trigger a frame capture + mutex_.lock (); + if (event.keyDown () && event.getKeySym () == "e") + { + active_ = false; + } + mutex_.unlock (); + } + + protected: + + void onNewFrame(const PointCloudConstPtr & cloud) + { + mutex_.lock (); + ++frame_counter_; + most_recent_frame_ = make_shared(*cloud); // Make a copy of the frame + mutex_.unlock (); + } + + pcl::OpenNIGrabber grabber_; + PointCloudPtr most_recent_frame_; + unsigned int frame_counter_; + boost::mutex mutex_; + bool active_; + }; +} diff --git a/common/include/od/common/utils/Shared_pointers.h b/common/include/od/common/utils/Shared_pointers.h new file mode 100644 index 00000000..b66242b1 --- /dev/null +++ b/common/include/od/common/utils/Shared_pointers.h @@ -0,0 +1,16 @@ +#pragma once +#ifdef WITH_STD_SHARED_PTR + #include + using std::shared_ptr; + using std::make_shared; + using std::static_pointer_cast; + using std::dynamic_pointer_cast; +#else + #include + #include + #include + using boost::shared_ptr; + using boost::make_shared; + using boost::static_pointer_cast; + using boost::dynamic_pointer_cast; +#endif \ No newline at end of file diff --git a/common/include/od/common/utils/Utils.h b/common/include/od/common/utils/Utils.h new file mode 100644 index 00000000..e7ff573f --- /dev/null +++ b/common/include/od/common/utils/Utils.h @@ -0,0 +1,77 @@ +// +// Created by sarkar on 09.06.15. +// + +#pragma once +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE(r, data, elem) \ + case elem : return BOOST_PP_STRINGIZE(elem); + +#define _DEFINE_ENUM_WITH_STRING_CONVERSIONS(name, enumerators) \ + enum name { \ + BOOST_PP_SEQ_ENUM(enumerators) \ + }; \ + \ + inline const char * enumToString(name v) \ + { \ + switch (v) \ + { \ + BOOST_PP_SEQ_FOR_EACH( \ + X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE, \ + name, \ + enumerators \ + ) \ + default: return "[Unknown " BOOST_PP_STRINGIZE(name) "]"; \ + } \ + } + + +namespace od +{ + + //TO REMOVE AND SUBSTITUTE USING BOOST FILESYSTEM + std::vector od_glob(const std::string & pat); + + void normL2(cv::Mat &descriptors); + + /** + * @brief Makes composite image from the given images. Equal number of rows and columns are preferred. Therefore, number of rows = sqrt(number of input images) + * + * @param imgs Vector of Images. + * @param cellSize Size of individual images to be placed inside the composite images. images from `imgs` will be resized to this size before appending. + * @param messages Messages to be put on the top left of each image in `imgs`. Note `message.size()` should be equal to `imgs.size()`. + * @return new composite image. + */ + cv::Mat makeCanvasMultiImages(const std::vector & imgs, const cv::Size & cellSize, const std::vector & messages); + + cv::Scalar getHashedColor(const std::string & name, int offset = 100); + + std::string getTexfileinObj(const std::string & objfilename); + + namespace fileutils { + + std::string getFirstFile(const std::string & base_path, const std::string & extension); + + void getFilesInDirectoryRec(const std::string & base_path, const std::string & extension, std::vector & files); + void getFilesInDirectoryRec(const std::string & base_path, const std::vector & extensions, std::vector & files); + + void getFilesInDirectoryInternal(const boost::filesystem::path & dir, const std::string & rel_path_so_far, std::vector & relative_paths, const std::vector & exts); + void getFilesInDirectoryInternal(const boost::filesystem::path & dir, const std::string & rel_path_so_far, std::vector & relative_paths, const std::string & ext); + + void getFilesInDirectory(const boost::filesystem::path & dir, const std::string & rel_path_so_far, std::vector & relative_paths, const std::string & ext); + void createTrainingDir(const std::string & training_dir); + + //TO REMOVE + void getArgvArgc(std::string const & commandline, char ***argv, int & argc); + } +} diff --git a/common/include/od/common/utils/Viewer.h b/common/include/od/common/utils/Viewer.h new file mode 100644 index 00000000..b2989c09 --- /dev/null +++ b/common/include/od/common/utils/Viewer.h @@ -0,0 +1,143 @@ +#pragma once +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "od/common/utils/Shared_pointers.h" +#include "od/common/pipeline/Scene.h" + + +namespace od { + + /** \brief The viewer class. + * + * This class is used to visualize all types handled by the OpenDetection Library. For now it is possible to display cv::Mat and pcl::PointCloud >. + * + * \author Giacomo Dabisias + * + */ + class Viewer { + + enum odViewType { + UNDEFINED, + POINTCLOUD, + CVMAT + }; + + public: + + Viewer(); + + template + void render(shared_ptr > to_display, const std::string & cloud_name, bool colored = true); + + template + void render(shared_ptr > to_display, const std::string & cloud_name, bool colored = true); + + template + void render(const ScenePointCloud & to_display, const std::string & cloud_name, bool colored = true); + + template + void render(shared_ptr > to_display, + pcl::visualization::PointCloudColorHandlerRandom & random_handler, const std::string & cloud_name); + + void render(const cv::Mat & to_display, const std::string & window_name); + void render(shared_ptr to_display, const std::string & window_name); + void render(const SceneImage & to_display, const std::string & window_name); + + void initCVWindow(const std::string & window_name); + void initPCLWindow(const std::string & window_name); + + template + void update(shared_ptr > to_display, const std::string & cloud_name, bool colored = true); + + template + void update(shared_ptr > to_display, const std::string & cloud_name, bool colored = true); + + template + void update(const ScenePointCloud & to_display, const std::string & cloud_name, bool colored = true); + + void update(const cv::Mat & to_display, const std::string & window_name); + void update(const SceneImage & to_display, const std::string & window_name); + void update(shared_ptr to_display, const std::string & window_name); + + void setBackGround(const cv::Scalar & color); + void setBackGround(unsigned int r, unsigned int g, unsigned int b); + + void registerCallback(void(*callback)(const pcl::visualization::KeyboardEvent &, void *), void * data = nullptr); + void registerCallback(const std::string & window_name, CvMouseCallback on_mouse, void * data = nullptr); + + void spin(); + bool toStop(); + + void addText(const std::string & text, pcl::PointXYZ pos, double textScale, cv::Scalar color); + void addText(const std::string & text, cv::Point3f pos, double textScale, cv::Scalar color); + + void removeText(const std::string & text); + + void remove(const std::string & name); + void removeAll(); + + void removeShape(const std::string & text); + void removeAllShapes(); + + unsigned int wait(unsigned int time) const; + + shared_ptr getViewer(); + + private: + + odViewType status_; + shared_ptr viewer_; + std::string mat_window_name_, pcl_window_name_; + std::vector clouds_; + shared_ptr mat_; + + }; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + extern template void Viewer::render(shared_ptr >, const std::string &, bool); + extern template void Viewer::render(shared_ptr >, const std::string &, bool); + extern template void Viewer::render(shared_ptr >, const std::string &, bool); + + extern template void Viewer::render(shared_ptr > to_display, + pcl::visualization::PointCloudColorHandlerRandom & random_handler, const std::string & cloud_name); + extern template void Viewer::render(shared_ptr > to_display, + pcl::visualization::PointCloudColorHandlerRandom & random_handler, const std::string & cloud_name); + extern template void Viewer::render(shared_ptr > to_display, + pcl::visualization::PointCloudColorHandlerRandom & random_handler, const std::string & cloud_name); + + extern template void Viewer::render(shared_ptr >, const std::string &, bool); + extern template void Viewer::render(shared_ptr >, const std::string &, bool); + extern template void Viewer::render(shared_ptr >, const std::string &, bool); + + extern template void Viewer::render(const ScenePointCloud &, const std::string &, bool); + extern template void Viewer::render(const ScenePointCloud &, const std::string &, bool); + extern template void Viewer::render(const ScenePointCloud &, const std::string &, bool); + + extern template void Viewer::update(shared_ptr >, const std::string &, bool); + extern template void Viewer::update(shared_ptr >, const std::string &, bool); + extern template void Viewer::update(shared_ptr >, const std::string &, bool); + + extern template void Viewer::update(shared_ptr >, const std::string &, bool); + extern template void Viewer::update(shared_ptr >, const std::string &, bool); + extern template void Viewer::update(shared_ptr >, const std::string &, bool); + + extern template void Viewer::update(const ScenePointCloud &, const std::string &, bool); + extern template void Viewer::update(const ScenePointCloud &, const std::string &, bool); + extern template void Viewer::update(const ScenePointCloud &, const std::string &, bool); + +#endif +} + +#include "od/common/utils/Viewer.hpp" diff --git a/common/pipeline/ODDetection.h b/common/pipeline/ODDetection.h deleted file mode 100644 index ccf1e7a4..00000000 --- a/common/pipeline/ODDetection.h +++ /dev/null @@ -1,419 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 12.06.15. -// - -#ifndef OPENDETECTION_ODDETECTION_H -#define OPENDETECTION_ODDETECTION_H - -#include "iostream" -#include "common/utils/utils.h" -#include "ODScene.h" -#include -#include - - -#include -#include -#include - -namespace od -{ - - /** \brief The base class of all the detection. - * - * This is the base class of all the detection classes containing the detection information. All the ODDetector s return a collection of this class (in the form of ODDetections). - * Supports two modes: recognition (with type OD_DETECTION_RECOG) and classification (with type OD_DETECTION_CLASS). Along with the type, ODDetector sets an ID to identify what class or what instance of recognition is detected/recognied. - * - * \author Kripasindhu Sarkar - * - */ - class ODDetection - { - public: - - - OD_DEFINE_ENUM_WITH_STRING_CONVERSIONS(DetectionType, (OD_DETECTION_RECOG)(OD_DETECTION_CLASS)(OD_DETECTION_NULL)) - - virtual ~ODDetection() - { } - - ODDetection(DetectionType const &type_ = OD_DETECTION_NULL, std::string const &id_ = "", double confidence_ = 1) : type_(type_), id_(id_), - confidence_(confidence_) - { } - - void printSelf() - { - std::cout << "--Detection-- \nType: " << enumToString(type_) << std::endl; - std::cout << "ID: " << id_ << std::endl; - } - - DetectionType const &getType() const - { - return type_; - } - - void setType(DetectionType const &type_) - { - ODDetection::type_ = type_; - } - - std::string const &getId() const - { - return id_; - } - - void setId(std::string const &id_) - { - ODDetection::id_ = id_; - } - - - /** \brief Get/Set the confidence of the detection. ODDetector can use this to provide confidence amnong several detections. - */ - double getConfidence() const - { - return confidence_; - } - - /** \brief Get/Set the confidence of the detection. ODDetector can use this to provide confidence amnong several detections. - */ - void setConfidence(double confidence_) - { - ODDetection::confidence_ = confidence_; - } - - private: - DetectionType type_; - std::string id_; - double confidence_; - }; - - /** \brief Detection for 2D with 2D location information - * - * \author Kripasindhu Sarkar - * - */ - class ODDetection2D : public virtual ODDetection - { - public: - - virtual ~ODDetection2D() - { } - - ODDetection2D(DetectionType const &type_ = OD_DETECTION_NULL, std::string const &id_ = "", double confidence_ = 1) : ODDetection(type_, id_, confidence_) - { - location_2d_ = Eigen::Vector3d::UnitZ(); - } - - Eigen::Vector3d const &getLocation() const - { - return location_2d_; - } - - void setLocation(Eigen::Vector3d const &location_) - { - ODDetection2D::location_2d_ = location_; - } - - cv::Rect const &getBoundingBox() const - { - return bounding_box_2d_; - } - - void setBoundingBox(cv::Rect const &bounding_box_) - { - ODDetection2D::bounding_box_2d_ = bounding_box_; - } - - cv::Mat const &getMetainfoImage() const - { - return metainfo_image_; - } - - void setMetainfoImage(cv::Mat const &metainfo_image_) - { - ODDetection2D::metainfo_image_ = metainfo_image_; - } - - - Eigen::Vector3d location_2d_; - cv::Rect bounding_box_2d_; - cv::Mat metainfo_image_; - }; - - /** \brief Detection in 3D with 3D location information. - * - * \author Kripasindhu Sarkar - * - */ - class ODDetection3D : public virtual ODDetection - { - public: - virtual ~ODDetection3D() - { } - - Eigen::Vector4d const &getLocation() const - { - return location_3d_; - } - - void setLocation(Eigen::Vector4d const &location_) - { - ODDetection3D::location_3d_ = location_; - } - void setLocation(cv::Mat const &location_) - { - cv::cv2eigen(location_, this->location_3d_); - } - - Eigen::Matrix3Xd const &getPose() const - { - return orientation_; - } - - void setPose(Eigen::Matrix3Xd const &pose_) - { - ODDetection3D::orientation_ = pose_; - } - void setPose(cv::Mat const & pose_cv) - { - this->orientation_ = Eigen::Map(pose_cv.clone().ptr()); - } - - double getScale() const - { - return scale_; - } - - void setScale(double scale) - { - ODDetection3D::scale_ = scale; - } - - cv::Mat const &getMetainfoImage() const - { - return metainfo_image_; - } - - void setMetainfoImage(cv::Mat const &metainfo_image) - { - ODDetection3D::metainfo_image_ = metainfo_image; - } - - typename pcl::PointCloud::Ptr const &getMetainfoCluster() const - { - return metainfo_cluster_; - } - - void setMetainfoCluster(typename pcl::PointCloud::Ptr const &metainfo_cluster_) - { - ODDetection3D::metainfo_cluster_ = metainfo_cluster_; - } - - ODDetection3D(DetectionType const &type_ = OD_DETECTION_NULL, std::string const &id_ = "", double confidence_ = 1) : ODDetection(type_, id_, confidence_) - { - location_3d_ = Eigen::Vector4d::UnitW(); - orientation_.setIdentity(); - scale_ = 1; - } - - void printSelf() - { - ODDetection::printSelf(); - std::cout << "Location: " << location_3d_ << std::endl; - std::cout << "Pose: " << orientation_ << std::endl; - std::cout << "Scale: " << scale_ << std::endl; - } - - Eigen::Vector4d location_3d_; - Eigen::Matrix3Xd orientation_; - double scale_; - cv::Mat metainfo_image_; - typename pcl::PointCloud::Ptr metainfo_cluster_; - }; - - /** \brief Detection in 2D with complete information. - * - * \author Kripasindhu Sarkar - * - */ - class ODDetectionComplete: public ODDetection2D, public ODDetection3D - { - }; - - /** \brief The container class for ODDetection - * - * \author Kripasindhu Sarkar - * - */ - class ODDetections - { - public: - - ODDetections (int n = 0): detections_(n) - { - } - - virtual ~ODDetections() - { - for (int i = 0; i < this->size(); i++) - delete detections_[i]; - detections_.resize(0); - } - - int size() { return detections_.size(); } - - void push_back(ODDetection* detection) - { - detections_.push_back(detection); - } - - void append(ODDetections* detections) - { - detections_.insert(detections_.end(), detections->detections_.begin(), detections->detections_.end()); - //note the meta information of the appended detections are lost here. - } - - ODDetection * operator[](int i) { return detections_[i]; } - ODDetection * at(int i) { return (*this)[i]; } - - cv::Mat const &getMetainfoImage() const - { - return metainfo_image_; - } - - void setMetainfoImage(cv::Mat const &metainfo_image_) - { - this->metainfo_image_ = metainfo_image_.clone(); - } - - typename pcl::PointCloud::Ptr const &getMetainfoCluster() const - { - return metainfo_cluster_; - } - - void setMetainfoCluster(typename pcl::PointCloud::Ptr const &metainfo_cluster_) - { - this->metainfo_cluster_ = metainfo_cluster_; - } - - protected: - std::vector detections_; - cv::Mat metainfo_image_; - typename pcl::PointCloud::Ptr metainfo_cluster_; - }; - - - - -/** \brief The container class for ODDetection2D returned by ODDetector2D - * - * \author Kripasindhu Sarkar - * - */ - class ODDetections2D: public ODDetections - { - public: - - /** \brief Draws rectangles over the input image using the bounding box information present in all the 2D detections. This is a quick function to render and verify the detections made. - */ - ODSceneImage renderMetainfo(ODSceneImage input) - { - - //picking up random colors for different detection algorithm, if exist - /*std::map color_map; - for(int i = 0; i < detections_.size(); i++) - { - if(color_map.find(detections_[i]->getId()) == color_map.end()) - color_map[detections_[i]->getId()] = CV_RGB(rand()%255, rand()%255, rand()%255); - }*/ - - cv::Mat image = input.getCVImage().clone(); - for(int i = 0; i < detections_.size(); i++) - { - ODDetection2D * detection = dynamic_cast(detections_[i]); - cv::rectangle(image, detection->bounding_box_2d_, getHashedColor(detections_[i]->getId(), 100), 2); - } - return ODSceneImage(image); - } - - - ODDetection2D * operator[](int i) { return dynamic_cast(detections_[i]); } - ODDetection2D * at(int i) { return dynamic_cast(detections_[i]); } - - }; - - /** \brief The container class for ODDetection3D returned by ODDetector3D - * - * \author Kripasindhu Sarkar - * - */ - class ODDetections3D: public ODDetections - { - public: - - /*ODSceneImage renderMetainfo(ODSceneImage input) - { - //picking up random colors for different detection algorithm, if exist - std::map color_map; - for(int i = 0; i < detections_.size(); i++) - { - if(color_map.find(detections_[i]->getId()) == color_map.end()) - color_map[detections_[i]->getId()] = CV_RGB(rand()%255, rand()%255, rand()%255); - } - - cv::Mat image = input.getCVImage().clone(); - for(int i = 0; i < detections_.size(); i++) - { - ODDetections3D * detection = dynamic_cast(detections_[i]); - cv::rectangle(image, detection->bounding_box_2d_, color_map[detections_[i]->getId()], 2); - } - return ODSceneImage(image); - }*/ - - - ODDetection3D * operator[](int i) { return dynamic_cast(detections_[i]); } - ODDetection3D * at(int i) { return dynamic_cast(detections_[i]); } - }; - - /** \brief The container class for ODDetectionComplete returned by ODDetector2DComplete - * - * \author Kripasindhu Sarkar - * - */ - class ODDetectionsComplete: public ODDetections - { - public: - - ODDetectionComplete * operator[](int i) { return dynamic_cast(detections_[i]); } - ODDetectionComplete * at(int i) { return dynamic_cast (detections_[i]); } - }; - -} -#endif //OPENDETECTION_ODDETECTION_H diff --git a/common/pipeline/ODDetector.cpp b/common/pipeline/ODDetector.cpp deleted file mode 100644 index 6aaa81d2..00000000 --- a/common/pipeline/ODDetector.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 13.08.15. -// - diff --git a/common/pipeline/ODScene.cpp b/common/pipeline/ODScene.cpp deleted file mode 100644 index 9fb6709a..00000000 --- a/common/pipeline/ODScene.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 10.06.15. -// - -#include "ODScene.h" diff --git a/common/pipeline/ODScene.h b/common/pipeline/ODScene.h deleted file mode 100644 index 547e7f12..00000000 --- a/common/pipeline/ODScene.h +++ /dev/null @@ -1,175 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 10.06.15. -// - -#ifndef OPENDETECTION_SCENE_H -#define OPENDETECTION_SCENE_H - -//#include -#include -#include -#include -#include -#include -#include - -namespace od -{ - /** \brief Base class for Scenes. This contains information about the scenes. Scenes can be image scenes or point cloud scenes - * - * \author Kripasindhu Sarkar - * - */ - class ODScene - { - public: - - virtual void *getData() = 0; - - std::string const &getPath() const - { - return path_; - } - - protected: - std::string path_; - }; - - /** \brief Class for Image Scene. - * - * \author Kripasindhu Sarkar - * - */ - class ODSceneImage : public ODScene - { - public: - - std::vector const &getKeypoints() const - { - return keypoints_; - } - - void setKeypoints(std::vector const &keypoints_) - { - ODSceneImage::keypoints_ = keypoints_; - } - - cv::Mat const &getDescriptors() const - { - return descriptors_; - } - - void setDescriptors(cv::Mat const &descriptors_) - { - ODSceneImage::descriptors_ = descriptors_; - is_trained_ = true; - } - - ODSceneImage(cv::Mat const &cvimage):is_trained_(false) - { - this->cvimage_ = cvimage.clone(); - } - - ODSceneImage(std::string const &path):is_trained_(false) - { - this->cvimage_ = cv::imread(path); - this->path_ = path; - } - - cv::Mat getCVImage() - { - return cvimage_; - } - - void *getData() - { - return &cvimage_; - } - - protected: - cv::Mat cvimage_; - - std::vector keypoints_; - cv::Mat descriptors_; - bool is_trained_; - - }; - - - /** \brief Class for 3D scene containing point cloud. - * - * \author Kripasindhu Sarkar - * - */ - template - class ODScenePointCloud : public ODScene - { - - public: - typedef typename pcl::PointCloud::Ptr PointCloudPtr; - - ODScenePointCloud(PointCloudPtr const &point_cloud) - { - point_cloud_ = point_cloud; - } - - ODScenePointCloud(std::string point_cloud_file): point_cloud_(new pcl::PointCloud()) - { - if (pcl::io::loadPCDFile (point_cloud_file, *point_cloud_ ) == -1) - { - std::cout<<"ERROR: Couldn't read the file "<< point_cloud_file <path_ = point_cloud_file; - } - - ODScenePointCloud(): point_cloud_(new pcl::PointCloud()) - {} - - PointCloudPtr const &getPointCloud() const - { - return point_cloud_; - } - - PointCloudPtr &getPointCloudRef() const - { - return point_cloud_; - } - - void setPointCloud(PointCloudPtr const &point_cloud_) - { - ODScenePointCloud::point_cloud_ = point_cloud_; - } - - void * getData() { return (void *)point_cloud_.get(); } - protected: - PointCloudPtr point_cloud_; - }; -} - -#endif //OPENDETECTION_SCENE_H diff --git a/common/pipeline/ObjectDetector.cpp b/common/pipeline/ObjectDetector.cpp deleted file mode 100644 index b5627401..00000000 --- a/common/pipeline/ObjectDetector.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 03.06.15. -// - -#include "ObjectDetector.h" diff --git a/common/src/bindings/Svmlight.cpp b/common/src/bindings/Svmlight.cpp new file mode 100644 index 00000000..ccb01c29 --- /dev/null +++ b/common/src/bindings/Svmlight.cpp @@ -0,0 +1,157 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. + + + Original code under the following Apache License 2.0: + Changes - None + + ---------- + This software is licensed under the Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html) Please find the Apache license 2.0 statement in the respective file alongside this software. + +Copyright 2015 Jan Hendriks + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + ---------- + */ + +/** + * @file: svmlight.h + * @author: Jan Hendriks (dahoc3150 [at] gmail.com) + * @date: Created on 11. Mai 2011 + * @brief: Wrapper interface for SVMlight, + * @see http://www.cs.cornell.edu/people/tj/svm_light/ for SVMlight details and terms of use + * + */ + +#include "od/common/bindings/Svmlight.h" + +SVMlight::SVMlight(){ + // Init variables + alpha_in_ = NULL; + kernel_cache_ = NULL; // Cache not needed with linear kernel + model_ = static_cast(svmlight::my_malloc(sizeof(svmlight::MODEL))); + // Init parameters + svmlight::verbosity = 1; // Show some messages -v 1 + learn_parm_.alphafile[0] = ' '; // NULL; // Important, otherwise files with strange/invalid names appear in the working directory + // learn_parm_->alphafile = NULL; // Important, otherwise files with strange/invalid names appear in the working directory + learn_parm_.biased_hyperplane = 1; + learn_parm_.sharedslack = 0; // 1 + learn_parm_.skip_final_opt_check = 0; + learn_parm_.svm_maxqpsize = 10; + learn_parm_.svm_newvarsinqp = 0; + learn_parm_.svm_iter_to_shrink = 2; // 2 is for linear; + learn_parm_.kernel_cache_size = 40; + learn_parm_.maxiter = 100000; + learn_parm_.svm_costratio = 1.0; + learn_parm_.svm_costratio_unlab = 1.0; + learn_parm_.svm_unlabbound = 1E-5; + learn_parm_.eps = 0.1; + learn_parm_.transduction_posratio = -1.0; + learn_parm_.epsilon_crit = 0.001; + learn_parm_.epsilon_a = 1E-15; + learn_parm_.compute_loo = 0; + learn_parm_.rho = 1.0; + learn_parm_.xa_depth = 0; + // The HOG paper uses a soft classifier (C = 0.01), set to 0.0 to get the default calculation + learn_parm_.svm_c = 0.01; // -c 0.01 + learn_parm_.type = svmlight::REGRESSION; + learn_parm_.remove_inconsistent = 0; // -i 0 - Important + kernel_parm_.rbf_gamma = 1.0; + kernel_parm_.coef_lin = 1; + kernel_parm_.coef_const = 1; + kernel_parm_.kernel_type = LINEAR; // -t 0 + kernel_parm_.poly_degree = 3; +} + +SVMlight::~SVMlight() { + // Cleanup area + // Free the memory used for the cache + if(kernel_cache_) + svmlight::kernel_cache_cleanup(kernel_cache_); + free(alpha_in_); + free_model(model_, 0); + for(long i = 0; i < totdoc_; ++i) + free_example(docs_[i], 1); + free(docs_); + free(target_); +} + +void SVMlight::saveModelToFile(const std::string model_file_name) { + write_model(const_cast(model_file_name.c_str()), model_); +} + +void SVMlight::loadModelFromFile(const std::string model_file_name) { + model_ = svmlight::read_model(const_cast(model_file_name.c_str())); +} + +void SVMlight::read_problem(char * file_name) { + read_documents(file_name, &docs_, &target_, &totwords_, &totdoc_); +} + +void SVMlight::train() { + svm_learn_regression(docs_, target_, totdoc_, totwords_, &learn_parm_, &kernel_parm_, &kernel_cache_, model_); +} + +void SVMlight::getSingleDetectingVector(std::vector & single_detector_vector) { + // Now we use the trained svm to retrieve the single detector vector + svmlight::DOC ** supveclist = model_->supvec; + std::cout << "Calculating single descriptor vector out of support vectors (may take some time)" << std::endl; + // Retrieve single detecting vector (v1) from returned ones by calculating vec1 = sum_1_n (alpha_y*x_i). (vec1 is a n x1 column vector. n = feature vector length) + single_detector_vector.clear(); + single_detector_vector.resize(model_->totwords, 0.); + std::cout << "Resulting vector size " << single_detector_vector.size() << std::endl; + + // Walk over every support vector + for(long ssv = 1; ssv < model_->sv_num; ++ssv) { // Don't know what's inside model->supvec[0] ?! + // Get a single support vector + svmlight::DOC * singleSupportVector = supveclist[ssv]; // Get next support vector + svmlight::SVECTOR * singleSupportVectorValues = singleSupportVector->fvec; + svmlight::WORD singleSupportVectorComponent; + // Walk through components of the support vector and populate our detector vector + for(long singleFeature = 0; singleFeature < model_->totwords; ++singleFeature) { + singleSupportVectorComponent = singleSupportVectorValues->words[singleFeature]; + single_detector_vector.at(singleSupportVectorComponent.wnum-1) += (singleSupportVectorComponent.weight * model_->alpha[ssv]); + } + } +} + +float SVMlight::getThreshold() const { + return model_->b; +} + +std::string SVMlight::getSVMName() const { + return std::string("SVMlight"); +} + + +/// Singleton +SVMlight * SVMlight::getInstance() { + static SVMlight theInstance; + return &theInstance; +} diff --git a/common/src/pipeline/Detection.cpp b/common/src/pipeline/Detection.cpp new file mode 100644 index 00000000..6f06108d --- /dev/null +++ b/common/src/pipeline/Detection.cpp @@ -0,0 +1,290 @@ +#include "od/common/pipeline/Detection.h" + +namespace od +{ + + Detection::Detection(const detection::DetectionType & type, const std::string & id, double confidence) : + type_(type), id_(id), confidence_(confidence) {} + + void Detection::printSelf() + { + std::cout << "--Detection-- \nType: " << enumToString(type_) << std::endl; + std::cout << "ID: " << id_ << std::endl; + } + + const detection::DetectionType & Detection::getType() const + { + return type_; + } + + void Detection::setType(const detection::DetectionType & type) + { + type_ = type; + } + + const std::string & Detection::getId() const + { + return id_; + } + + void Detection::setId(const std::string & id) + { + id_ = id_; + } + + double Detection::getConfidence() const + { + return confidence_; + } + + + void Detection::setConfidence(double confidence) + { + confidence_ = confidence; + } + + + + + Detection2D::Detection2D(const detection::DetectionType & type, const std::string & id , double confidence) : Detection(type, id, confidence) + { + location_2d_ = Eigen::Vector3d::UnitZ(); + } + + const Eigen::Vector3d & Detection2D::getLocation() const + { + return location_2d_; + } + + void Detection2D::setLocation(const Eigen::Vector3d & location) + { + location_2d_ = location; + } + + const cv::Rect & Detection2D::getBoundingBox() const + { + return bounding_box_2d_; + } + + void Detection2D::setBoundingBox(const cv::Rect & bounding_box) + { + bounding_box_2d_ = bounding_box; + } + + const cv::Mat & Detection2D::getMetainfoImage() const + { + return metainfo_image_; + } + + void Detection2D::setMetainfoImage(const cv::Mat & metainfo_image) + { + metainfo_image_ = metainfo_image; + } + + + + Detection3D::Detection3D(const detection::DetectionType & type, const std::string & id, double confidence) : Detection(type, id, confidence) + { + location_3d_ = Eigen::Vector4d::UnitW(); + orientation_.setIdentity(); + scale_ = 1; + } + + const Eigen::Vector4d & Detection3D::getLocation() const + { + return location_3d_; + } + + void Detection3D::setLocation(const Eigen::Vector4d & location) + { + location_3d_ = location; + } + void Detection3D::setLocation(const cv::Mat & location) + { + cv::cv2eigen(location, location_3d_); + } + + const Eigen::Matrix3Xd & Detection3D::getPose() const + { + return orientation_; + } + + void Detection3D::setPose(const Eigen::Matrix3Xd & pose) + { + orientation_ = pose; + } + //TO why clone? + void Detection3D::setPose(const cv::Mat & pose_cv) + { + orientation_ = Eigen::Map(pose_cv.clone().ptr()); + } + + double Detection3D::getScale() const + { + return scale_; + } + + void Detection3D::setScale(double scale) + { + Detection3D::scale_ = scale; + } + + const cv::Mat & Detection3D::getMetainfoImage() const + { + return metainfo_image_; + } + + void Detection3D::setMetainfoImage(const cv::Mat & metainfo_image) + { + metainfo_image_ = metainfo_image; + } + + const pcl::PointCloud::Ptr & Detection3D::getMetainfoCluster() const + { + return metainfo_cluster_; + } + + void Detection3D::setMetainfoCluster(const pcl::PointCloud::Ptr & metainfo_cluster) + { + metainfo_cluster_ = metainfo_cluster; + } + + void Detection3D::printSelf() + { + Detection::printSelf(); + std::cout << "Location: " << location_3d_ << std::endl; + std::cout << "Pose: " << orientation_ << std::endl; + std::cout << "Scale: " << scale_ << std::endl; + } + + + Detections::Detections(unsigned int n): detections_(n) {} + + Detections::~Detections() + { + detections_.resize(0); + } + + unsigned int Detections::size() const + { + return detections_.size(); + } + + void Detections::push_back(shared_ptr detection) + { + detections_.push_back(detection); + } + + void Detections::append(shared_ptr detections) + { + detections_.insert(detections_.end(), detections->detections_.begin(), detections->detections_.end()); + } + + shared_ptr Detections::operator[](unsigned int i) + { + return detections_[i]; + } + + shared_ptr Detections::at(unsigned int i) + { + return detections_[i]; + } + + const cv::Mat & Detections::getMetainfoImage() const + { + return metainfo_image_; + } + + void Detections::setMetainfoImage(const cv::Mat & metainfo_image) + { + metainfo_image_ = metainfo_image.clone(); + } + + const pcl::PointCloud::Ptr & Detections::getMetainfoCluster() const + { + return metainfo_cluster_; + } + + void Detections::setMetainfoCluster(const pcl::PointCloud::Ptr & metainfo_cluster) + { + metainfo_cluster_ = metainfo_cluster; + } + + + SceneImage Detections2D::renderMetainfo(SceneImage & input) + { + + //picking up random colors for different detection algorithm, if exist + /*std::map color_map; + for(int i = 0; i < detections_.size(); i++) + { + if(color_map.find(detections_[i]->getId()) == color_map.end()) + color_map[detections_[i]->getId()] = CV_RGB(rand()%255, rand()%255, rand()%255); + }*/ + + cv::Mat image = input.getCVImage(); + for(size_t i = 0; i < detections_.size(); ++i) + { + shared_ptr detection = dynamic_pointer_cast(detections_[i]); + if(detection) + cv::rectangle(image, detection->bounding_box_2d_, getHashedColor(detections_[i]->getId(), 100), 2); + } + return SceneImage(image); + } + + SceneImage Detections2D::renderMetainfo(shared_ptr input) + { + + //picking up random colors for different detection algorithm, if exist + /*std::map color_map; + for(int i = 0; i < detections_.size(); i++) + { + if(color_map.find(detections_[i]->getId()) == color_map.end()) + color_map[detections_[i]->getId()] = CV_RGB(rand()%255, rand()%255, rand()%255); + }*/ + + cv::Mat image = input->getCVImage().clone(); + for(size_t i = 0; i < detections_.size(); ++i) + { + shared_ptr detection = dynamic_pointer_cast(detections_[i]); + if(detection) + cv::rectangle(image, detection->bounding_box_2d_, getHashedColor(detections_[i]->getId(), 100), 2); + } + return SceneImage(image); + } + + + shared_ptr Detections2D::operator[](unsigned int i) + { + return dynamic_pointer_cast(detections_[i]); + } + + shared_ptr Detections2D::at(unsigned int i) + { + return dynamic_pointer_cast(detections_[i]); + } + + + shared_ptr Detections3D::operator[](unsigned int i) + { + return dynamic_pointer_cast(detections_[i]); + } + + shared_ptr Detections3D::at(unsigned int i) + { + return dynamic_pointer_cast(detections_[i]); + } + + + shared_ptr DetectionsComplete::operator[](unsigned int i) + { + return dynamic_pointer_cast(detections_[i]); + } + + shared_ptr DetectionsComplete::at(unsigned int i) + { + return dynamic_pointer_cast(detections_[i]); + } + + +} \ No newline at end of file diff --git a/common/src/pipeline/ObjectDetector.cpp b/common/src/pipeline/ObjectDetector.cpp new file mode 100644 index 00000000..37094315 --- /dev/null +++ b/common/src/pipeline/ObjectDetector.cpp @@ -0,0 +1,129 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/ +// +// Created by sarkar on 03.06.15. +// + +#include "od/common/pipeline/ObjectDetector.h" + +namespace od { + + DetectorCommon::DetectorCommon(const std::string & trained_data_location) : trained_data_location_(trained_data_location) + { + std::string classname = typeid(this).name(); + trained_data_id_ = classname; + std::transform(classname.begin(), classname.end(), classname.begin(), ::toupper); + trained_location_identifier_ = classname; + } + + std::string DetectorCommon::getTrainingInputLocation() const + { + return training_input_location_; + } + + void DetectorCommon::setTrainingInputLocation(const std::string & training_input_location) + { + training_input_location_ = training_input_location; + } + + std::string DetectorCommon::getTrainedDataLocation() const + { + return trained_data_location_; + } + + void DetectorCommon::setTrainedDataLocation(const std::string & trained_data_location) + { + trained_data_location_ = trained_data_location; + } + + std::string DetectorCommon::getSpecificTrainingDataLocation() + { + return trained_data_location_ + "/" + "TD_" + trained_location_identifier_; + } + + std::string DetectorCommon::getSpecificTrainingData() + { + return getSpecificTrainingDataLocation() + "/" + trained_data_id_; + } + + const std::string & DetectorCommon::getTrainedDataID() const + { + return trained_data_id_; + } + + void DetectorCommon::setTrainedDataID(const std::string & trainedDataID) + { + trained_data_id_ = trainedDataID; + } + + + const DetectionMethod & ObjectDetector::getMethod() const + { + return method_; + } + + void ObjectDetector::setDetectionMethod(const DetectionMethod & detection_method) + { + method_ = detection_method; + } + + bool ObjectDetector::getAlwaysTrain() const + { + return always_train_; + } + + void ObjectDetector::setAlwaysTrain(bool always_train) + { + always_train_ = always_train; + } + + std::string ObjectDetector::getTrainingInputLocation() const + { + return training_input_location_; + } + + void ObjectDetector::setTrainingInputLocation(const std::string & training_input_location) + { + training_input_location_ = training_input_location; + } + + std::string ObjectDetector::getTrainingDataLocation() const + { + return training_data_location_; + } + + void ObjectDetector::setTrainingDataLocation(const std::string & training_data_location) + { + training_data_location_ = training_data_location; + } + + std::string ObjectDetector::getSpecificTrainingDataLocation() + { + return training_data_location_ + "/" + "TD_" + trained_data_identifier_; + } + +} \ No newline at end of file diff --git a/common/src/pipeline/Scene.cpp b/common/src/pipeline/Scene.cpp new file mode 100644 index 00000000..2bb6d886 --- /dev/null +++ b/common/src/pipeline/Scene.cpp @@ -0,0 +1,127 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/ +// +// Created by sarkar on 10.06.15. +// + +#include "od/common/pipeline/Scene.h" + +namespace od { + + std::string const & Scene::getPath() const + { + return path_; + } + + + SceneImage::SceneImage(const cv::Mat & cvimage): is_trained_(false) + { + cvimage_ = cvimage.clone(); + } + + SceneImage::SceneImage(const std::string & path): is_trained_(false) + { + cvimage_ = cv::imread(path); + path_ = path; + } + + const std::vector & SceneImage::getKeypoints() const + { + return keypoints_; + } + + void SceneImage::setKeypoints(const std::vector & keypoints) + { + keypoints_ = keypoints; + } + + const cv::Mat & SceneImage::getDescriptors() const + { + return descriptors_; + } + + void SceneImage::setDescriptors(const cv::Mat & descriptors) + { + descriptors_ = descriptors; + is_trained_ = true; + } + + cv::Mat SceneImage::getCVImage() const + { + return cvimage_; + } + + void * SceneImage::getData() + { + return &cvimage_; + } + + + template + ScenePointCloud::ScenePointCloud(const shared_ptr > point_cloud); + template + ScenePointCloud::ScenePointCloud(const shared_ptr > point_cloud); + template + ScenePointCloud::ScenePointCloud(const shared_ptr > point_cloud); + + template + ScenePointCloud::ScenePointCloud(const std::string & point_cloud_file); + template + ScenePointCloud::ScenePointCloud(const std::string & point_cloud_file); + template + ScenePointCloud::ScenePointCloud(const std::string & point_cloud_file); + + template + shared_ptr > ScenePointCloud::getPointCloud() const; + template + shared_ptr > ScenePointCloud::getPointCloud() const; + template + shared_ptr > ScenePointCloud::getPointCloud() const; + + template + shared_ptr > ScenePointCloud::getPointCloudRef() const; + template + shared_ptr > ScenePointCloud::getPointCloudRef() const; + template + shared_ptr > ScenePointCloud::getPointCloudRef() const; + + template + void ScenePointCloud::setPointCloud(const shared_ptr > point_cloud); + template + void ScenePointCloud::setPointCloud(const shared_ptr > point_cloud); + template + void ScenePointCloud::setPointCloud(const shared_ptr > point_cloud); + + template + void * ScenePointCloud::getData(); + template + void * ScenePointCloud::getData(); + template + void * ScenePointCloud::getData(); + + +} \ No newline at end of file diff --git a/common/src/utils/FeatureDetector.cpp b/common/src/utils/FeatureDetector.cpp new file mode 100644 index 00000000..179d403f --- /dev/null +++ b/common/src/utils/FeatureDetector.cpp @@ -0,0 +1,51 @@ +#include "od/common/utils/FeatureDetector.h" + +namespace od +{ + + FeatureDetector::FeatureDetector(FeatureType type) + { + + mode_ = type; + + switch(mode_) + { + case(SIFT) : + case(ORB) : + case(SURF) : + feature_detector_ = make_shared(mode_); + gpu_ = false; + break; + case(SIFT_GPU): + case(ORB_GPU): +#if WIHT_GPU + feature_detector_ = make_shared(mode_); + gpu_ = true; +#else + std::cout << "FATAL ERROR, gpu type is not compile. Recompile with WITH_GPU to enable GPU support." << std::endl; + exit(-1); +#endif + default : + std::cout << "FATAL ERROR, type is not defined" << std::endl; + exit(-1); + break; + + } + } + + FeatureDetector::FeatureDetector(const std::string & type) + { + FeatureDetector(string2FeatureType(type)); + } + + void FeatureDetector::computeKeypointsAndDescriptors(const cv::Mat & image, cv::Mat & descriptors, std::vector & keypoints) + { + feature_detector_->computeKeypointsAndDescriptors(image, descriptors,keypoints); + } + + void FeatureDetector::computeAndSave(const cv::Mat & image, const std::string & path) + { + feature_detector_->computeAndSave(image, path); + } + +} \ No newline at end of file diff --git a/common/src/utils/FeatureDetector2D.cpp b/common/src/utils/FeatureDetector2D.cpp new file mode 100644 index 00000000..94965760 --- /dev/null +++ b/common/src/utils/FeatureDetector2D.cpp @@ -0,0 +1,55 @@ +// +// Created by sarkar on 20.04.15. +// + +#include "od/common/utils/FeatureDetector2D.h" + +namespace od +{ + + FeatureDetector2D::FeatureDetector2D(FeatureType type) + { + + mode_ = type; + + switch(type) + { + case(SIFT) : + feature_detector_ = cv::xfeatures2d::SIFT::create(); + break; + + case(ORB) : + feature_detector_ = cv::ORB::create(); + break; + + case(SURF) : + feature_detector_ = cv::xfeatures2d::SURF::create(); + break; + + case(ORB_GPU) : + case(SIFT_GPU) : + default : + std::cout << "FATAL ERROR, type is not defined" << std::endl; + exit(-1); + break; + + } + } + + void FeatureDetector2D::computeKeypointsAndDescriptors(const cv::Mat & image, cv::Mat & descriptors, std::vector & keypoints) + { + + feature_detector_->detect(image, keypoints); + feature_detector_->compute(image, keypoints, descriptors); + } + + + void FeatureDetector2D::computeAndSave(const cv::Mat & image, const std::string & path) + { + cv::Mat descriptors; + std::vector keypoints; + + //TO implementation + + } +} diff --git a/common/src/utils/FeatureDetectorInterface.cpp b/common/src/utils/FeatureDetectorInterface.cpp new file mode 100644 index 00000000..b1d562c2 --- /dev/null +++ b/common/src/utils/FeatureDetectorInterface.cpp @@ -0,0 +1,13 @@ +#include "od/common/utils/FeatureDetectorInterface.h" + +namespace od +{ + + std::map od_enum_map = {{"SIFT", SIFT}, {"SURF", SURF}, {"ORB", ORB}, {"SIFT_GPU", SIFT_GPU}, {"ORB_GPU", ORB_GPU}}; + + FeatureType string2FeatureType(const std::string & name) + { + return od_enum_map[name]; + } + +} \ No newline at end of file diff --git a/common/src/utils/FrameGenerator.cpp b/common/src/utils/FrameGenerator.cpp new file mode 100644 index 00000000..e69de29b diff --git a/common/src/utils/Utils.cpp b/common/src/utils/Utils.cpp new file mode 100644 index 00000000..d412f6fc --- /dev/null +++ b/common/src/utils/Utils.cpp @@ -0,0 +1,330 @@ +// +// Created by sarkar on 19.06.15. +// +#include "od/common/utils/Utils.h" + + +namespace od +{ + +#ifdef WIN32 + +std::vector od_glob(const std::string & pat) + { + HANDLE hFind; + WIN32_FIND_DATA data; + std::vector ret; + + hFind = FindFirstFile(pat.c_str(), &data); + if (hFind != INVALID_HANDLE_VALUE) { + do { + ret.push_back(data.cFileName); + } while (FindNextFile(hFind, &data)); + FindClose(hFind); + } + + return ret; + } +#else + std::vector od_glob(const std::string & pat) + { + glob_t glob_result; + glob(pat.c_str(), GLOB_TILDE, nullptr, &glob_result); + std::vector ret; + for(size_t i = 0; i < glob_result.gl_pathc; ++i) { + ret.push_back(std::string(glob_result.gl_pathv[i])); + } + globfree(&glob_result); + return ret; + } +#endif + + + void normL2(cv::Mat & descriptors) + { + for(int r = 0; r < descriptors.rows; r++) + { + float norm = 0; + for(int c = 0; c < descriptors.cols; c++) + norm += (descriptors.at(r, c)*descriptors.at(r, c)); + + norm = 1.0/sqrt(norm); + + for(int c = 0; c < descriptors.cols; c++) + descriptors.at(r, c) *= norm; + } + } + + void drawTextTopLeft(cv::Mat & image, const std::string & text, const cv::Scalar & color) + { + cv::putText(image, text, cv::Point(25,50), cv::FONT_HERSHEY_SIMPLEX, 0.75, color, 2, 16); + } + + cv::Mat makeCanvasMultiImages(const std::vector & imgs, const cv::Size & cell_size, const std::vector & messages) + { + + bool printmssg = false; + if(messages.size() == imgs.size()) + printmssg = true; + + const float n_imgs = imgs.size(); + const unsigned int imgs_in_row = ceil(sqrt(n_imgs)); + const unsigned int imgs_in_col = ceil(n_imgs/imgs_in_row); + + const unsigned int cell_width = cell_size.width; + const unsigned int cell_height = cell_size.height; + + const int resultImgW = cell_width * imgs_in_row; + const int resultImgH = cell_height * imgs_in_col; + + cv::Mat result_img = cv::Mat::zeros(resultImgH, resultImgW, CV_8UC3); + unsigned int ind = 0; + cv::Mat tmp; + for(size_t i = 0; i < imgs_in_col; i++) + { + for(size_t j = 0; j < imgs_in_row; j++) + { + if(ind < imgs.size()) + { + const int cell_row = i*cell_height; + const int cell_col = j*cell_width; + + resize(imgs[ind], tmp, cell_size); + + if(printmssg) + drawTextTopLeft(tmp, messages[ind], cv::Scalar(0, 255, 255)); + + tmp.copyTo(result_img(cv::Range(cell_row, cell_row+cell_height), cv::Range(cell_col, cell_col+cell_width))); + } + ind++; + } + } + + return result_img; + } + + std::string getTexfileinObj(const std::string & objfilename) + { + + std::string input_dir(boost::filesystem::path(objfilename).parent_path().string()); + + std::ifstream input(objfilename); + std::string line; + while(getline(input, line)) + { + std::istringstream iss(line); + std::string tok1; + iss >> tok1; + if(tok1.compare(std::string("mtllib")) == 0) + { + std::string tok2; + + iss >> tok2; + std::string linemtl; + + std::ifstream inputmtl((input_dir + "/" + tok2)); + while(getline(inputmtl, linemtl)) + { + std::istringstream issmtl(linemtl); + issmtl >> tok1; + if(tok1.compare(std::string("map_Kd")) == 0) + { + issmtl >> tok2; + return input_dir + std::string("/") + tok2; + } + } + } + } + return std::string(""); + } + + cv::Scalar getHashedColor(const std::string & name, int offset) + { + boost::hash string_hash; + const int hashed = string_hash(name); + + return CV_RGB((hashed + offset) % 255, (hashed + 2*offset) % 255, (hashed + 3*offset) % 255); + } + + + namespace fileutils { + + std::string getFirstFile(const std::string & base_path, const std::string & extension) + { + std::vector files; + fileutils::getFilesInDirectoryInternal(base_path, "", files, extension); + if(files.size() == 0) + { + std::cout << "No file with extension " << extension << " present!" << std::endl; + std::cout << "Returning empty string" << std::endl; + return std::string(""); + } + return files[0]; + } + + void getFilesInDirectoryRec(const std::string & base_path, const std::string & extension, std::vector & files) + { + fileutils::getFilesInDirectoryInternal(base_path, "", files, extension); + } + + void getFilesInDirectoryRec(const std::string & base_path, const std::vector & extensions, std::vector & files) + { + fileutils::getFilesInDirectoryInternal(base_path, "", files, extensions); + } + + void getFilesInDirectoryInternal(const boost::filesystem::path & dir, const std::string & rel_path_so_far, std::vector & relative_paths, const std::vector & exts) + { + boost::filesystem::directory_iterator end_itr; + for(boost::filesystem::directory_iterator itr(dir); itr != end_itr; ++itr) { + //check if its a directory, then get models in it + if(boost::filesystem::is_directory(*itr)) { +#if BOOST_FILESYSTEM_VERSION == 3 + std::string so_far = rel_path_so_far + (itr->path().filename()).string() + std::string("/"); +#else + std::string so_far = rel_path_so_far + (itr->path ()).filename () + std::string("/"); +#endif + + boost::filesystem::path curr_path = itr->path(); + getFilesInDirectoryInternal(curr_path, so_far, relative_paths, exts); + } else { + //check that it is a ply file and then add, otherwise ignore.. + std::vector strs; +#if BOOST_FILESYSTEM_VERSION == 3 + std::string file = (itr->path().filename()).string(); +#else + std::string file = (itr->path ()).filename (); +#endif + + boost::split(strs, file, boost::is_any_of(".")); + std::string extension = strs[strs.size() - 1]; + + bool flagfound = false; + for (size_t exti = 0; exti < exts.size(); ++exti) + if(file.rfind(exts[exti]) != std::string::npos) + { flagfound = true; + break; + } + + if(flagfound == true) + { +#if BOOST_FILESYSTEM_VERSION == 3 + std::string path = rel_path_so_far + (itr->path().filename()).string(); +#else + std::string path = rel_path_so_far + (itr->path ()).filename (); +#endif + std::string fullpath = rel_path_so_far + itr->path().string(); + relative_paths.push_back(fullpath); + } + } + } + } + + void getFilesInDirectoryInternal(const boost::filesystem::path & dir, const std::string & rel_path_so_far, std::vector & relative_paths, const std::string & ext) + { + boost::filesystem::directory_iterator end_itr; + for(boost::filesystem::directory_iterator itr(dir); itr != end_itr; ++itr) { + //check if its a directory, then get models in it + if(boost::filesystem::is_directory(*itr)) { +#if BOOST_FILESYSTEM_VERSION == 3 + std::string so_far = rel_path_so_far + (itr->path().filename()).string() + std::string("/"); +#else + std::string so_far = rel_path_so_far + (itr->path ()).filename () + std::string("/"); +#endif + + boost::filesystem::path curr_path = itr->path(); + getFilesInDirectoryInternal(curr_path, so_far, relative_paths, ext); + } else { + //check that it is a ply file and then add, otherwise ignore.. + std::vector strs; +#if BOOST_FILESYSTEM_VERSION == 3 + std::string file = (itr->path().filename()).string(); +#else + std::string file = (itr->path ()).filename (); +#endif + + boost::split(strs, file, boost::is_any_of(".")); + std::string extension = strs[strs.size() - 1]; + + if( file.rfind(ext) != std::string::npos ) + { +#if BOOST_FILESYSTEM_VERSION == 3 + std::string path = rel_path_so_far + (itr->path().filename()).string(); +#else + std::string path = rel_path_so_far + (itr->path ()).filename (); +#endif + std::string fullpath = rel_path_so_far + itr->path().string(); + relative_paths.push_back(fullpath); + } + } + } + } + + void getFilesInDirectory(const boost::filesystem::path & dir, const std::string & rel_path_so_far, std::vector & relative_paths, const std::string & ext) + { + boost::filesystem::directory_iterator end_itr; + for(boost::filesystem::directory_iterator itr(dir); itr != end_itr; ++itr) { + //check if its a directory, then get models in it + if(boost::filesystem::is_directory(*itr)) { +#if BOOST_FILESYSTEM_VERSION == 3 + std::string so_far = rel_path_so_far + (itr->path().filename()).string() + std::string("/"); +#else + std::string so_far = rel_path_so_far + (itr->path ()).filename () + std::string("/"); +#endif + + boost::filesystem::path curr_path = itr->path(); + getFilesInDirectoryInternal(curr_path, so_far, relative_paths, ext); + } else { + //check that it is a ply file and then add, otherwise ignore.. + std::vector strs; +#if BOOST_FILESYSTEM_VERSION == 3 + std::string file = (itr->path().filename()).string(); +#else + std::string file = (itr->path ()).filename (); +#endif + + boost::split(strs, file, boost::is_any_of(".")); + std::string extension = strs[strs.size() - 1]; + + if( file.rfind(ext) != std::string::npos ) + { +#if BOOST_FILESYSTEM_VERSION == 3 + std::string path = rel_path_so_far + (itr->path().filename()).string(); +#else + std::string path = rel_path_so_far + (itr->path ()).filename (); +#endif + std::string fullpath = rel_path_so_far + itr->path().string(); + relative_paths.push_back(path); + } + } + } + } + + void createTrainingDir(const std::string & training_dir) + { + if(!boost::filesystem::exists(training_dir)) + boost::filesystem::create_directory(training_dir); + } + + void getArgvArgc(const std::string & commandline, char *** argv, int & argc) + { + enum + { + kMaxArgs = 64 + }; + + argc = 0; + *argv = new char *[kMaxArgs]; + (*argv)[argc++] = (char *) "program"; + + char *p; + p = strtok((char *) commandline.c_str(), " "); + while(p && argc < kMaxArgs) { + (*argv)[argc++] = p; + p = strtok(0, " "); + } + } + // fileutil namespace + } + //od namespace +} + diff --git a/common/src/utils/Viewer.cpp b/common/src/utils/Viewer.cpp new file mode 100644 index 00000000..e3c8ae1d --- /dev/null +++ b/common/src/utils/Viewer.cpp @@ -0,0 +1,323 @@ +#include "od/common/utils/Viewer.h" +#if(WIN32) + #include +#endif + +namespace od { + + Viewer::Viewer() : status_(UNDEFINED) {} + + void Viewer::render(const cv::Mat & to_display, const std::string & window_name) + { + if(status_ != CVMAT){ + std::cout << "Switching viewer to cv::Mat mode" << std::endl; + if(status_ == POINTCLOUD){ + //BUGGED IN PCL, its not closing https://github.com/PointCloudLibrary/pcl/issues/172 + //viewer_->close(); + //Alternative solution +#if(WIN32) + HWND hWnd = (HWND)viewer3d->getRenderWindow()->GetGenericWindowId(); + viewer_.reset(); + DestroyWindow(hWnd); +#else + auto p = viewer_->getRenderWindow(); + viewer_.reset(); + p->Finalize(); +#endif + } + } + status_ = CVMAT; + mat_window_name_ = window_name; + mat_ = make_shared(to_display); + //cvStartWindowThread(); + cvNamedWindow(mat_window_name_.c_str(), CV_WINDOW_AUTOSIZE); + } + + void Viewer::render(const SceneImage & to_display, const std::string & window_name) + { + render(to_display.getCVImage(), window_name); + } + + void Viewer::render(shared_ptr to_display, const std::string & window_name) + { + render(to_display->getCVImage(), window_name); + } + + void Viewer::initCVWindow(const std::string & window_name) + { + if(status_ != CVMAT){ + std::cout << "Switching viewer to cv::Mat mode" << std::endl; + if(status_ == POINTCLOUD){ + //BUGGED IN PCL, its not closing https://github.com/PointCloudLibrary/pcl/issues/172 + //viewer_->close(); + //Alternative solution +#if(WIN32) + HWND hWnd = (HWND)viewer3d->getRenderWindow()->GetGenericWindowId(); + viewer_.reset(); + DestroyWindow(hWnd); +#else + auto p = viewer_->getRenderWindow(); + viewer_.reset(); + p->Finalize(); +#endif + } + } + status_ = CVMAT; + mat_window_name_ = window_name; + mat_ = make_shared(); + //cvStartWindowThread(); + cvNamedWindow(mat_window_name_.c_str(), CV_WINDOW_AUTOSIZE); + } + + void Viewer::initPCLWindow(const std::string & window_name) + { + if(status_ != POINTCLOUD){ + std::cout << "Switching viewer to PointCloud mode" << std::endl; + if(status_ == CVMAT){ + cv::destroyWindow(mat_window_name_.c_str()); + } + } + + status_ = POINTCLOUD; + + if(!viewer_ || pcl_window_name_ != window_name) + { +#ifndef WITH_BOOST_SHARED_PTR + viewer_ = shared_ptr(new pcl::visualization::PCLVisualizer(window_name)); +#else + viewer_ = make_shared(window_name); +#endif + viewer_->setBackgroundColor(0, 0, 0); + } + + pcl_window_name_ = window_name; + } + + void Viewer::update(const cv::Mat & to_display, const std::string & window_name) + { + if(status_ != CVMAT) + { + std::cout << "No cv::Mat to render! use render(const cv::Mat &) first!" << std::endl; + return; + } + if(window_name != mat_window_name_) + { + render(to_display, window_name); + return; + } + + mat_ = make_shared(to_display); + + } + + void Viewer::update(const SceneImage & to_display, const std::string & window_name) + { + update(to_display.getCVImage(), window_name); + } + void Viewer::update(shared_ptr to_display, const std::string & window_name) + { + update(to_display->getCVImage(), window_name); + } + + void Viewer::setBackGround(const cv::Scalar & color) + { + switch(status_){ + case POINTCLOUD : + viewer_->setBackgroundColor(color[2], color[1], color[0]); + break; + case CVMAT : + *mat_ = color; + break; + case UNDEFINED : + std::cout << "Render an element first before adding a backgroud!" << std::endl; + break; + } + + } + + bool Viewer::toStop() + { + + switch(status_){ + case POINTCLOUD : + return(viewer_->wasStopped()); + break; + case CVMAT : + return (cv::waitKey(50) == 27 || cv::waitKey(50) == 'q'); + break; + case UNDEFINED : + break; + } + return false; + + } + + void Viewer::setBackGround(unsigned int r, unsigned int g, unsigned int b) + { + setBackGround(cv::Scalar(b, g, r)); + } + + void Viewer::spin() + { + switch(status_){ + case POINTCLOUD : + if(viewer_) + viewer_->spinOnce(); + break; + case CVMAT : + cv::imshow(mat_window_name_, *mat_); + cv::waitKey(10); + break; + case UNDEFINED : + std::cout << "Nothing to render!" << std::endl; + break; + } + } + + unsigned int Viewer::wait(unsigned int time) const + { + return cv::waitKey(time); + } + + void Viewer::addText(const std::string & text, pcl::PointXYZ pos, double textScale, cv::Scalar color) + { + if(status_ == CVMAT) + { + cv::putText(*mat_, text, cv::Point(pos.x, pos.y), cv::FONT_HERSHEY_SIMPLEX, textScale, color); + } + else if(status_ == POINTCLOUD) + { + viewer_->addText3D(text, pos, textScale, color[2], color[1], color[0]); + + } + } + + void Viewer::addText(const std::string & text, cv::Point3f pos, double textScale, cv::Scalar color) + { + if(status_ == CVMAT) + { + cv::putText(*mat_, text, cv::Point(pos.x, pos.y), cv::FONT_HERSHEY_SIMPLEX, textScale, color); + } + else if(status_ == POINTCLOUD) + { + viewer_->addText3D(text, pcl::PointXYZ(pos.x, pos.y, pos.z), textScale, color[2], color[1], color[0]); + + } + } + + void Viewer::remove(const std::string & text) + { + if(status_ == CVMAT) + { + if(text != mat_window_name_) + { + std::cout << "no window " << text << " to remove" << std::endl; + return; + } + cv::destroyWindow(mat_window_name_.c_str()); + mat_window_name_ = std::string(); + } + else if(status_ == POINTCLOUD) + { + if(std::remove(clouds_.begin(), clouds_.end(), text) == clouds_.end()) + { + std::cout << "no cloud " << text << " to remove" << std::endl; + return; + } + viewer_->removePointCloud(text); + } + } + + void Viewer::removeAll() + { + if(status_ == CVMAT) + { + remove(mat_window_name_); + } + else if(status_ == POINTCLOUD) + { + viewer_->removeAllPointClouds(); + clouds_.clear(); + } + } + + void Viewer::removeAllShapes() + { + if(status_ == CVMAT) + { + std::cout << "Not in pcl mode!" << std::endl; + } + else if(status_ == POINTCLOUD) + { + viewer_->removeAllShapes(); + } + + } + + + void Viewer::removeText(const std::string & text) + { + if(status_ == CVMAT) + { + std::cout << "Not in pcl mode!" << std::endl; + } + else if(status_ == POINTCLOUD) + { + viewer_->removeText3D(text); + } + + } + + void Viewer::removeShape(const std::string & text) + { + if(status_ == CVMAT) + { + std::cout << "Not in pcl mode!" << std::endl; + } + else if(status_ == POINTCLOUD) + { + viewer_->removeShape(text); + } + + } + + shared_ptr Viewer::getViewer() + { + return viewer_; + } + + + + // Explicit template function instantiation + template void Viewer::render(shared_ptr >, const std::string &, bool); + template void Viewer::render(shared_ptr >, const std::string &, bool); + template void Viewer::render(shared_ptr >, const std::string &, bool); + + template void Viewer::render(shared_ptr > to_display, + pcl::visualization::PointCloudColorHandlerRandom & random_handler, const std::string & cloud_name); + template void Viewer::render(shared_ptr > to_display, + pcl::visualization::PointCloudColorHandlerRandom & random_handler, const std::string & cloud_name); + template void Viewer::render(shared_ptr > to_display, + pcl::visualization::PointCloudColorHandlerRandom & random_handler, const std::string & cloud_name); + + template void Viewer::render(shared_ptr >, const std::string &, bool); + template void Viewer::render(shared_ptr >, const std::string &, bool); + template void Viewer::render(shared_ptr >, const std::string &, bool); + + template void Viewer::render(const ScenePointCloud &, const std::string &, bool); + template void Viewer::render(const ScenePointCloud &, const std::string &, bool); + template void Viewer::render(const ScenePointCloud &, const std::string &, bool); + + template void Viewer::update(shared_ptr >, const std::string &, bool); + template void Viewer::update(shared_ptr >, const std::string &, bool); + template void Viewer::update(shared_ptr >, const std::string &, bool); + + template void Viewer::update(shared_ptr >, const std::string &, bool); + template void Viewer::update(shared_ptr >, const std::string &, bool); + template void Viewer::update(shared_ptr >, const std::string &, bool); + + template void Viewer::update(const ScenePointCloud &, const std::string &, bool); + template void Viewer::update(const ScenePointCloud &, const std::string &, bool); + template void Viewer::update(const ScenePointCloud &, const std::string &, bool); + +} \ No newline at end of file diff --git a/common/utils/ODFeatureDetector2D.cpp b/common/utils/ODFeatureDetector2D.cpp deleted file mode 100644 index 33ed6df1..00000000 --- a/common/utils/ODFeatureDetector2D.cpp +++ /dev/null @@ -1,198 +0,0 @@ -// -// Created by sarkar on 20.04.15. -// - -#include -#include "ODFeatureDetector2D.h" - -using namespace std; -namespace od -{ - - ODFeatureDetector2D::ODFeatureDetector2D(string type, bool use_gpu) - { - mode_ = SIFT; //by default it is SIFT - - if(use_gpu) { - - - //##########GPU VERSION - - - if(type == "ORB") { - mode_ = ORB_GPU; - feature_detector_ = cv::cuda::ORB::create(); - } else if(type == "SIFT") { - mode_ = SIFT_GPU; - sift_gpu_ = new SiftGPU; - //char * argv[] = {(char *)"-fo", (char *)"-1", (char *)"-v", (char *)"1", (char *)"-cuda", (char *)"0"}; - char *argv[] = {(char *) "-fo", (char *) "-1", (char *) "-v", (char *) "1"}; - int argc = sizeof(argv) / sizeof(char *); - sift_gpu_->ParseParam(argc, argv); - if(sift_gpu_->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) - cout << "FATAL ERROR cannot create SIFTGPU context"; - } - } else { - - //########CPU VERSIONS - - - if(type == "SIFT") { - mode_ = SIFT; - feature_detector_ = cv::xfeatures2d::SIFT::create(); - } else if(type == "ORB") { - mode_ = ORB; - feature_detector_ = cv::ORB::create(); - } else if(type == "SURF") { - mode_ = SURF; - feature_detector_ = cv::xfeatures2d::SURF::create(); - } - } - } - - void ODFeatureDetector2D::computeKeypointsAndDescriptors(cv::Mat const &image, cv::Mat &descriptors, vector &keypoints) - { - if(mode_ == SIFT_GPU) { - findSiftGPUDescriptors1(image, descriptors, keypoints); - } else { - feature_detector_->detect(image, keypoints); - feature_detector_->compute(image, keypoints, descriptors); - } - //viewImage(image, keypoints); - } - - void CVMatToSiftGPU(const cv::Mat &image, unsigned char *siftImage, cv::Mat &grey) - { - siftImage = (unsigned char *) malloc(image.rows * image.cols); - cv::Mat tmp; - cv::cvtColor(image, grey, cv::COLOR_BGR2GRAY); - - memcpy(siftImage, grey.data, image.rows * image.cols); - - -// tmp2.convertTo(tmp, CV_8U); -// //viewImage(tmp); -// -// for (int y = 0; y < tmp.rows; ++y) { -// for (int x = 0; x < tmp.cols; ++x) { -// siftImage[y * tmp.cols + x] = tmp.at (y, x); -// } -// } - return; - } - - void ODFeatureDetector2D::findSiftGPUDescriptors1(cv::Mat const &image, cv::Mat &descriptors, vector &keypoints) - { - unsigned char *data = image.data; - cv::Mat greyimage; - if(image.type() != CV_8U) { - cv::cvtColor(image, greyimage, cv::COLOR_BGR2GRAY); - data = greyimage.data; - } - sift_gpu_->RunSIFT(image.cols, image.rows, data, GL_LUMINANCE, GL_UNSIGNED_BYTE); - - int nFeat = sift_gpu_->GetFeatureNum();//get feature count - //allocate memory for readback - vector keys(nFeat); - //read back keypoints and normalized descritpros - //specify NULL if you don’t need keypoints or descriptors - vector imageDescriptors(128 * nFeat); - sift_gpu_->GetFeatureVector(&keys[0], &imageDescriptors[0]); - - sift_gpu_->SaveSIFT("2.sift"); - - //to opencv format - keypoints.clear(); - descriptors.create(0, 128, CV_32FC1); - for(int i = 0; i < nFeat; ++i) { - cv::KeyPoint key(keys[i].x, keys[i].y, keys[i].s, keys[i].o); - keypoints.push_back(key); - cv::Mat descriptor(1, 128, CV_32FC1); - - for(int x = 0; x < 128; x++) - descriptor.at(x) = floor(0.5 + (512.0f * imageDescriptors[(i * 128) + x])); - - descriptors.push_back(descriptor); - } - - - //viewImage(image, keypoints); - - } - - void ODFeatureDetector2D::findSiftGPUDescriptors(cv::Mat const &image, cv::Mat &descriptors, vector &keypoints) - { - unsigned char *data = image.data; - cv::Mat greyimage; - if(image.type() != CV_8U) { - cv::Mat tmp; - cv::cvtColor(image, tmp, cv::COLOR_BGR2GRAY); - data = tmp.data; - } - sift_gpu_->RunSIFT(image.cols, image.rows, data, GL_LUMINANCE, GL_UNSIGNED_BYTE); - - int nFeat = sift_gpu_->GetFeatureNum();//get feature count - //allocate memory for readback - vector keys(nFeat); - //read back keypoints and normalized descritpros - //specify NULL if you don’t need keypoints or descriptors - vector imageDescriptors(128 * nFeat); - sift_gpu_->GetFeatureVector(&keys[0], &imageDescriptors[0]); - - sift_gpu_->SaveSIFT("2.sift"); - - //to opencv format - keypoints.clear(); - cv::Mat descriptormat = cv::Mat(1, nFeat, CV_32F, &imageDescriptors[0]); - descriptormat.copyTo(descriptors); - - for(int i = 0; i < nFeat; ++i) { - cv::KeyPoint key(keys[i].x, keys[i].y, keys[i].s, keys[i].o); - keypoints.push_back(key); - } - - - //viewImage(image, keypoints); - - } - - void ODFeatureDetector2D::findSiftGPUDescriptors(char const *image_name, cv::Mat &descriptors, vector &keypoints) - { - sift_gpu_->RunSIFT(image_name); - - int nFeat = sift_gpu_->GetFeatureNum();//get feature count - //allocate memory for readback - vector keys(nFeat); - //read back keypoints and normalized descritpros - //specify NULL if you don’t need keypoints or descriptors - vector imageDescriptors(128 * nFeat); - sift_gpu_->GetFeatureVector(&keys[0], &imageDescriptors[0]); - - sift_gpu_->SaveSIFT("1.sift"); - - //to opencv format - keypoints.clear(); - descriptors.create(0, 128, CV_32FC1); - for(int i = 0; i < nFeat; ++i) { - cv::KeyPoint key(keys[i].x, keys[i].y, keys[i].s, keys[i].o); - keypoints.push_back(key); - cv::Mat descriptor(1, 128, CV_32FC1); - for(int x = 0; x < 128; x++) descriptor.at(x) = floor(0.5 + 512.0f * imageDescriptors[(i << 7) + x]); - descriptors.push_back(descriptor); - } - cv::Mat image = cv::imread(image_name); - } - - void ODFeatureDetector2D::computeAndSave(cv::Mat const &image, std::string const path) - { - cv::Mat descriptors; - vector keypoints; - if(mode_ == SIFT_GPU) { - findSiftGPUDescriptors1(image, descriptors, keypoints); - sift_gpu_->SaveSIFT(path.c_str()); - } else { - //DO NOTHING! IMPLEMENT LATER - - } - } -} diff --git a/common/utils/ODFeatureDetector2D.h b/common/utils/ODFeatureDetector2D.h deleted file mode 100644 index 24535a47..00000000 --- a/common/utils/ODFeatureDetector2D.h +++ /dev/null @@ -1,78 +0,0 @@ -// -// Created by sarkar on 20.04.15. -// - -#ifndef OBJECT_DETECTION_FEATUREDETECTOR_H -#define OBJECT_DETECTION_FEATUREDETECTOR_H - -#include - -#include -#include -#include -#include -#include "SiftGPU.h" - -#include - -namespace od -{ - - class ODFeatureDetector2D - { - - public: - ODFeatureDetector2D(std::string feature_type, bool use_gpu); - - enum FeatureType - { - SIFT, SURF, ORB, SIFT_GPU, ORB_GPU, - }; - - int mode_; - - ODFeatureDetector2D(FeatureType type) - { - - mode_ = type; - - if(type == SIFT) { - feature_detector_ = cv::xfeatures2d::SIFT::create(); - } else if(type == ORB) { - feature_detector_ = cv::ORB::create(); - } else if(type == SURF) { - feature_detector_ = cv::xfeatures2d::SURF::create(); - } else if(type == ORB_GPU) { - feature_detector_ = cv::cuda::ORB::create(); - } else if(type == SIFT_GPU) { - sift_gpu_ = new SiftGPU; - //char * argv[] = {(char *)"-fo", (char *)"-1", (char *)"-v", (char *)"1"}; - char *argv[] = {(char *) "-fo", (char *) "-1", (char *) "-v", (char *) "3", (char *) "-cuda"}; - int argc = sizeof(argv) / sizeof(char *); - sift_gpu_->ParseParam(argc, argv); - if(sift_gpu_->CreateContextGL() != SiftGPU::SIFTGPU_FULL_SUPPORTED) - std::cout << "FATAL ERROR cannot create SIFTGPU context"; - } - } - - //always return Opencv type keypoints - void computeKeypointsAndDescriptors(cv::Mat const &image, cv::Mat &descriptors, std::vector &keypoints); - - void findSiftGPUDescriptors(char const *image_name, cv::Mat &descriptors, std::vector &keypoints); - - void findSiftGPUDescriptors(cv::Mat const &image, cv::Mat &descriptors, std::vector &keypoints); - - void computeAndSave(cv::Mat const &image, std::string const path); - - private: - - cv::Ptr feature_detector_; - cv::Ptr sift_gpu_; - - - void findSiftGPUDescriptors1(cv::Mat const &image, cv::Mat &descriptors, std::vector &keypoints); - }; - -} - -#endif //OBJECT_DETECTION_FEATUREDETECTOR_H diff --git a/common/utils/ODFrameGenerator.h b/common/utils/ODFrameGenerator.h deleted file mode 100644 index fd675b77..00000000 --- a/common/utils/ODFrameGenerator.h +++ /dev/null @@ -1,221 +0,0 @@ -// -// Created by sarkar on 19.06.15. -// - -#ifndef OPENDETECTION_ODFRAMEGENERATOR_H -#define OPENDETECTION_ODFRAMEGENERATOR_H - -#include "common/pipeline/ODDetection.h" -#include "common/pipeline/ODScene.h" -#include -#include -#include - -namespace od -{ - enum GeneratorType - { - GENERATOR_TYPE_FILE_LIST, GENERATOR_TYPE_DEVICE - }; - - - - /** \brief The FrameGenerator class for capturing and reading Scenes conveniently. - * Templated with two parameters - SceneType identifying a Scene class, and TYPE identifying the type of input. After the instantiation with a correct TYPE, use the function - * getNextFrame() to get an instance of next scene of SceneType. getNextFrame() returns valid scenes until all scenes matched are exhausted - the time when 'isValid()' is false. - * - * \tparam SceneT One of the Scene classes - ODSceneImage or ODScenePointCloud - * \tparam TYPE TYPE can be GENERATOR_TYPE_FILE_LIST which means you provide the list of scene files to be returned by the FrameGenerator in the constructor (for eg. \/home/username/pics/*.jpg) - * Or it can be GENERATOR_TYPE_DEVICE which picks up the webcam or the kinect based on the SceneType. - * \author Kripasindhu Sarkar - * - */ - template - class ODFrameGenerator - { - public: - - ODFrameGenerator(std::string input = ""); - ODFrameGenerator(int input = 0){} - - SceneT * getNextFrame(); - - bool isValid(); - - protected: - int cameraID_; - std::vector file_list_; - std::string video_read_path_; - int curr_image_; - cv::VideoCapture inputCapture_; - bool exhausted_; - }; - - - template - class ODFrameGenerator - { - public: - ODFrameGenerator(std::string const input = "") - { - file_list_ = myglob(input); - curr_image_ = -1; - exhausted_ = false; - } - - SceneT * getNextFrame() - { - if (exhausted_) - { - cout << "Files Exhausted!"; - return NULL; - } - curr_image_++; - if(curr_image_ == file_list_.size() - 1) - exhausted_ = true; - - cout << "Frame: " << file_list_[curr_image_] << endl; - return new SceneT(file_list_[curr_image_]); - } - bool isValid() {return !exhausted_;} - std::string currentFile() - { - return file_list_[curr_image_]; - } - std::vector file_list_; - bool exhausted_; - int curr_image_; - }; - - template<> - class ODFrameGenerator - { - public: - ODFrameGenerator(std::string input = "") - { - input_capture_.open(input); - if (!input_capture_.isOpened()) { cout << "FATAL: Cannot open video capture!";} - } - - ODFrameGenerator(int input = 0) - { - input_capture_.open(input); - if (!input_capture_.isOpened()) { cout << "FATAL: Cannot open video capture!";} - } - - ODSceneImage * getNextFrame() - { - cv::Mat frame; input_capture_.read(frame); - return new ODSceneImage(frame); - } - bool isValid() {return input_capture_.isOpened();} - - cv::VideoCapture input_capture_; - }; - - /* - template<> - class ODFrameGenerator , GENERATOR_TYPE_DEVICE> - { - public: - - - ODFrameGenerator(std::string input = "") - { - - camera_ = new OpenNIFrameSource::OpenNIFrameSource(input); - - keyboard_cb = boost::bind (&OpenNIFrameSource::OpenNIFrameSource::onKeyboardEvent, camera_, _1); - } - - boost::function const &getKeyboard_cb() const - { - return keyboard_cb; - } - - ODScenePointCloud * getNextFrame() - { - OpenNIFrameSource::PointCloudPtr frame = camera_->snap(); - - return new ODScenePointCloud(frame); - } - bool isValid() {return camera_->isActive();} - - OpenNIFrameSource::OpenNIFrameSource *camera_; - boost::function keyboard_cb; - }; -*/ - - - template<> - class ODFrameGenerator , GENERATOR_TYPE_DEVICE> - { - public: - typedef pcl::PointXYZRGBA PointT; - typedef pcl::PointCloud PointCloud; - typedef pcl::PointCloud::Ptr PointCloudPtr; - typedef pcl::PointCloud::ConstPtr PointCloudConstPtr; - - /* A simple class for capturing data from an OpenNI camera */ - ODFrameGenerator(std::string input = "") : grabber_(input), most_recent_frame_(), frame_counter_(0), active_(true) - { - boost::function frame_cb = boost::bind (&ODFrameGenerator , GENERATOR_TYPE_DEVICE>::onNewFrame, this, _1); - grabber_.registerCallback (frame_cb); - grabber_.start (); - boost::this_thread::sleep (boost::posix_time::seconds(5)); - } - - ~ODFrameGenerator() - { - // Stop the grabber when shutting down - grabber_.stop (); - } - - ODScenePointCloud * getNextFrame() - { - OpenNIFrameSource::PointCloudPtr frame = snap(); - - return new ODScenePointCloud(frame); - } - - bool isValid() {return isActive();} - - const PointCloudPtr snap () - { - return (most_recent_frame_); - } - - bool isActive () - { - return active_; - } - void onKeyboardEvent (const pcl::visualization::KeyboardEvent & event) - { - // When the spacebar is pressed, trigger a frame capture - mutex_.lock (); - if (event.keyDown () && event.getKeySym () == "e") - { - active_ = false; - } - mutex_.unlock (); - } - - protected: - void onNewFrame (const PointCloudConstPtr &cloud) - { - mutex_.lock (); - ++frame_counter_; - most_recent_frame_ = boost::make_shared < PointCloud > (*cloud); // Make a copy of the frame - mutex_.unlock (); - } - - pcl::OpenNIGrabber grabber_; - PointCloudPtr most_recent_frame_; - int frame_counter_; - boost::mutex mutex_; - bool active_; - }; - -} -// -#endif //OPENDETECTION_ODFRAMEGENERATOR_H diff --git a/common/utils/utils.cpp b/common/utils/utils.cpp deleted file mode 100644 index f00f1b68..00000000 --- a/common/utils/utils.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// -// Created by sarkar on 19.06.15. -// -#include "utils.h" -#include "opencv2/imgproc/imgproc.hpp" -#include - -using namespace std; -using namespace cv; - -namespace od -{ - - - std::vector myglob(const std::string &pat) - { - using namespace std; - glob_t glob_result; - glob(pat.c_str(), GLOB_TILDE, NULL, &glob_result); - vector ret; - for(unsigned int i = 0; i < glob_result.gl_pathc; ++i) { - ret.push_back(string(glob_result.gl_pathv[i])); - } - globfree(&glob_result); - return ret; - } - - void normL2(cv::Mat &descriptors) - { - for (int r = 0; r < descriptors.rows; r++) - { - float norm=0; - for (int c = 0; c < descriptors.cols; c++) norm+=(descriptors.at(r, c)*descriptors.at(r, c)); - norm = 1.0/sqrt(norm); - for (int c = 0; c < descriptors.cols; c++) descriptors.at(r, c)*=norm; - } - } - - cv::Mat makeCanvasMultiImage(std::vector& vecMat, int windowHeight, int nRows) - { - int N = vecMat.size(); - nRows = nRows > N ? N : nRows; - int edgeThickness = 10; - int imagesPerRow = ceil(double(N) / nRows); - int resizeHeight = floor(2.0 * ((floor(double(windowHeight - edgeThickness) / nRows)) / 2.0)) - edgeThickness; - int maxRowLength = 0; - - std::vector resizeWidth; - for (int i = 0; i < N;) { - int thisRowLen = 0; - for (int k = 0; k < imagesPerRow; k++) { - double aspectRatio = double(vecMat[i].cols) / vecMat[i].rows; - int temp = int( ceil(resizeHeight * aspectRatio)); - resizeWidth.push_back(temp); - thisRowLen += temp; - if (++i == N) break; - } - if ((thisRowLen + edgeThickness * (imagesPerRow + 1)) > maxRowLength) { - maxRowLength = thisRowLen + edgeThickness * (imagesPerRow + 1); - } - } - int windowWidth = maxRowLength; - cv::Mat canvasImage(windowHeight, windowWidth, CV_8UC3, cv::Scalar(0, 0, 0)); - - for (int k = 0, i = 0; i < nRows; i++) { - int y = i * resizeHeight + (i + 1) * edgeThickness; - int x_end = edgeThickness; - for (int j = 0; j < imagesPerRow && k < N; k++, j++) { - int x = x_end; - cv::Rect roi(x, y, resizeWidth[k], resizeHeight); - cv::Size s = canvasImage(roi).size(); - // change the number of channels to three - cv::Mat target_ROI(s, CV_8UC3); - if (vecMat[k].channels() != canvasImage.channels()) { - if (vecMat[k].channels() == 1) { - cv::cvtColor(vecMat[k], target_ROI, CV_GRAY2BGR); - } - } - cv::resize(target_ROI, target_ROI, s); - if (target_ROI.type() != canvasImage.type()) { - target_ROI.convertTo(target_ROI, canvasImage.type()); - } - target_ROI.copyTo(canvasImage(roi)); - x_end += resizeWidth[k] + edgeThickness; - } - } - return canvasImage; - } - - int fontFace = cv::FONT_HERSHEY_SIMPLEX; - double fontScale = 0.75; - int thickness_font = 2; - Scalar red(0, 0, 255); - Scalar green(0,255,0); - Scalar blue(255,0,0); - Scalar yellow(0,255,255); - - void drawTextTopLeft(cv::Mat image, std::string text, cv::Scalar color) - { - cv::putText(image, text, cv::Point(25,50), fontFace, fontScale, color, thickness_font, 16); - } - - cv::Mat makeCanvasMultiImages(std::vector& imgs, cv::Size cellSize, std::vector messages) - { - - bool printmssg = false; - if (messages.size() == imgs.size()) printmssg = true; - - float nImgs=imgs.size(); - int imgsInRow=ceil(sqrt(nImgs)); // You can set this explicitly - int imgsInCol=ceil(nImgs/imgsInRow); // You can set this explicitly - - int resultImgW=cellSize.width*imgsInRow; - int resultImgH=cellSize.height*imgsInCol; - - Mat resultImg=Mat::zeros(resultImgH,resultImgW,CV_8UC3); - int ind=0; - Mat tmp; - for(int i=0;i string_hash; - int hashed = string_hash(name); - - return CV_RGB((hashed + constadd) % 255, (hashed + 2*constadd) % 255, (hashed + 3*constadd) % 255); - } - - cv::Mat makeCanvasMultiImage1(std::vector& vecMat, int windowHeight, int nRows) - { - int N = vecMat.size(); - nRows = nRows > N ? N : nRows; - int edgeThickness = 10; - int imagesPerRow = ceil(double(N) / nRows); - int resizeHeight = floor(2.0 * ((floor(double(windowHeight - edgeThickness) / nRows)) / 2.0)) - edgeThickness; - int maxRowLength = 0; - - std::vector resizeWidth; - for (int i = 0; i < N;) { - int thisRowLen = 0; - for (int k = 0; k < imagesPerRow; k++) { - double aspectRatio = double(vecMat[i].cols) / vecMat[i].rows; - int temp = int( ceil(resizeHeight * aspectRatio)); - resizeWidth.push_back(temp); - thisRowLen += temp; - if (++i == N) break; - } - if ((thisRowLen + edgeThickness * (imagesPerRow + 1)) > maxRowLength) { - maxRowLength = thisRowLen + edgeThickness * (imagesPerRow + 1); - } - } - int windowWidth = maxRowLength; - cv::Mat canvasImage(windowHeight, windowWidth, CV_8UC3, cv::Scalar(0, 0, 0)); - - for (int k = 0, i = 0; i < nRows; i++) { - int y = i * resizeHeight + (i + 1) * edgeThickness; - int x_end = edgeThickness; - for (int j = 0; j < imagesPerRow && k < N; k++, j++) { - int x = x_end; - cv::Rect roi(x, y, resizeWidth[k], resizeHeight); - cv::Size s = canvasImage(roi).size(); - // change the number of channels to three - cv::Mat target_ROI(s, CV_8UC3); - if (vecMat[k].channels() != canvasImage.channels()) { - if (vecMat[k].channels() == 1) { - cv::cvtColor(vecMat[k], target_ROI, CV_GRAY2BGR); - } - } - cv::resize(target_ROI, target_ROI, s); - if (target_ROI.type() != canvasImage.type()) { - target_ROI.convertTo(target_ROI, canvasImage.type()); - } - target_ROI.copyTo(canvasImage(roi)); - x_end += resizeWidth[k] + edgeThickness; - } - } - return canvasImage; - } -} - diff --git a/common/utils/utils.h b/common/utils/utils.h deleted file mode 100644 index 0bee4314..00000000 --- a/common/utils/utils.h +++ /dev/null @@ -1,375 +0,0 @@ -// -// Created by sarkar on 09.06.15. -// - -#ifndef OPENDETECTION_UTILS_H -#define OPENDETECTION_UTILS_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - - -namespace bf = boost::filesystem; - -/** \brief misclenious helping functions; will be refactored later - * - * \author Kripasindhu Sarkar - * - */ - - -#define X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE(r, data, elem) \ - case elem : return BOOST_PP_STRINGIZE(elem); - -#define OD_DEFINE_ENUM_WITH_STRING_CONVERSIONS(name, enumerators) \ - enum name { \ - BOOST_PP_SEQ_ENUM(enumerators) \ - }; \ - \ - inline const char* enumToString(name v) \ - { \ - switch (v) \ - { \ - BOOST_PP_SEQ_FOR_EACH( \ - X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE, \ - name, \ - enumerators \ - ) \ - default: return "[Unknown " BOOST_PP_STRINGIZE(name) "]"; \ - } \ - } - - -namespace od -{ - - template - std::string toString(T Number) - { - std::ostringstream ss; - ss << Number; - return ss.str(); - } - - std::vector myglob(const std::string &pat); - - void normL2(cv::Mat &descriptors); - - - /** - * @brief Makes composite image from the given images. Equal number of rows and columns are preferred. Therefore, number of rows = sqrt(number of input images) - * - * @param imgs Vector of Images. - * @param cellSize Size of individual images to be placed inside the composite images. images from `imgs` will be resized to this size before appending. - * @param messages Messages to be put on the top left of each image in `imgs`. Note `message.size()` should be equal to `imgs.size()`. - * @return new composite image. - */ - cv::Mat makeCanvasMultiImages(std::vector& imgs, cv::Size cellSize, std::vector messages); - - cv::Scalar getHashedColor(std::string name, int constadd); - - static std::string getTexfileinObj(std::string objfilename) - { - - boost::filesystem::path p(objfilename); - std::string input_dir = boost::filesystem::path(objfilename).parent_path().c_str(); - - std::ifstream input(objfilename.c_str()); - std::string line; - while(getline(input, line)) - { - std::istringstream iss(line); - std::string tok1; - iss >> tok1; - if(tok1 == "mtllib") - { - std::string tok2; - - iss >> tok2; - std::string linemtl; - - std::ifstream inputmtl((input_dir + "/" + tok2).c_str()); - while(getline(inputmtl, linemtl)) - { - std::istringstream issmtl(linemtl); - issmtl >> tok1; - if(tok1 == "map_Kd") - { - issmtl >> tok2; - return input_dir + "/" + tok2; - } - } - } - } - return ""; - } - -/** \brief An utility class for Timer related operations. - * - * \author Kripasindhu Sarkar - * - */ - class Timer - { - private: - - timeval startTime; - - public: - - double duration_; - - void start() - { - gettimeofday(&startTime, NULL); - } - - double stop() - { - timeval endTime; - long seconds, useconds; - double duration; - - gettimeofday(&endTime, NULL); - - seconds = endTime.tv_sec - startTime.tv_sec; - useconds = endTime.tv_usec - startTime.tv_usec; - - duration = seconds + useconds / 1000000.0; - duration_ = duration; - return duration; - } - - - double getDuration() - { return duration_; } - - static void printTime(double duration) - { - printf("%5.6f seconds\n", duration); - } - }; - - - template - void printListIn(std::vector list, int n = 0) - { - int num; - if(n == 0) num = list.size(); else num = n < list.size() ? n : list.size(); - - for(int i = 0; i < num; i++) - std::cout << (Ptype) list[i] << " "; - std::cout << std::endl; - } - - template - void printList(std::vector list) - { - for(int i = 0; i < list.size(); i++) - std::cout << list[i] << " "; - std::cout << std::endl; - } - - - /** \brief Utility class for File and directory handling. - * - * \author Kripasindhu Sarkar - * - */ - class FileUtils - { - public: - - static std::string getFirstFile(std::string base_path, std::string extension) - { - std::vector files; - std::string start = ""; - std::string ext = extension; - bf::path dir = base_path; - FileUtils::getFilesInDirectoryInternal(dir, start, files, ext); - if (files.size() == 0) - { - std::cout << "No file with extension " << extension << " present!\nReturning NULL"; - return ""; - } - else return files[0]; - } - - static void getFilesInDirectoryRec(std::string base_path, std::string extension, std::vector &files) - { - std::string start = ""; - std::string ext = extension; - bf::path dir = base_path; - FileUtils::getFilesInDirectoryInternal(dir, start, files, ext); - } - - static void getFilesInDirectoryRec(std::string base_path, std::vector extensions, std::vector &files) - { - std::string start = ""; - std::vector exts = extensions; - bf::path dir = base_path; - FileUtils::getFilesInDirectoryInternal(dir, start, files, exts); - } - - static void getFilesInDirectoryInternal(bf::path &dir, std::string &rel_path_so_far, std::vector &relative_paths, std::vector exts) - { - bf::directory_iterator end_itr; - for(bf::directory_iterator itr(dir); itr != end_itr; ++itr) { - //check if its a directory, then get models in it - if(bf::is_directory(*itr)) { -#if BOOST_FILESYSTEM_VERSION == 3 - std::string so_far = rel_path_so_far + (itr->path().filename()).string() + "/"; -#else - std::string so_far = rel_path_so_far + (itr->path ()).filename () + "/"; -#endif - - bf::path curr_path = itr->path(); - getFilesInDirectoryInternal(curr_path, so_far, relative_paths, exts); - } else { - //check that it is a ply file and then add, otherwise ignore.. - std::vector strs; -#if BOOST_FILESYSTEM_VERSION == 3 - std::string file = (itr->path().filename()).string(); -#else - std::string file = (itr->path ()).filename (); -#endif - - boost::split(strs, file, boost::is_any_of(".")); - std::string extension = strs[strs.size() - 1]; - - bool flagfound = false; - for (int exti = 0; exti < exts.size(); exti ++) - if(file.rfind(exts[exti]) != std::string::npos) - { flagfound = true; break; } - - if( flagfound == true ) - { -#if BOOST_FILESYSTEM_VERSION == 3 - std::string path = rel_path_so_far + (itr->path().filename()).string(); -#else - std::string path = rel_path_so_far + (itr->path ()).filename (); -#endif - std::string fullpath = rel_path_so_far + itr->path().string(); - relative_paths.push_back(fullpath); - } - } - } - } - - static void getFilesInDirectoryInternal(bf::path &dir, std::string &rel_path_so_far, std::vector &relative_paths, std::string const &ext) - { - bf::directory_iterator end_itr; - for(bf::directory_iterator itr(dir); itr != end_itr; ++itr) { - //check if its a directory, then get models in it - if(bf::is_directory(*itr)) { -#if BOOST_FILESYSTEM_VERSION == 3 - std::string so_far = rel_path_so_far + (itr->path().filename()).string() + "/"; -#else - std::string so_far = rel_path_so_far + (itr->path ()).filename () + "/"; -#endif - - bf::path curr_path = itr->path(); - getFilesInDirectoryInternal(curr_path, so_far, relative_paths, ext); - } else { - //check that it is a ply file and then add, otherwise ignore.. - std::vector strs; -#if BOOST_FILESYSTEM_VERSION == 3 - std::string file = (itr->path().filename()).string(); -#else - std::string file = (itr->path ()).filename (); -#endif - - boost::split(strs, file, boost::is_any_of(".")); - std::string extension = strs[strs.size() - 1]; - - if( file.rfind(ext) != std::string::npos ) - { -#if BOOST_FILESYSTEM_VERSION == 3 - std::string path = rel_path_so_far + (itr->path().filename()).string(); -#else - std::string path = rel_path_so_far + (itr->path ()).filename (); -#endif - std::string fullpath = rel_path_so_far + itr->path().string(); - relative_paths.push_back(fullpath); - } - } - } - } - - static void getFilesInDirectory(bf::path &dir, std::string &rel_path_so_far, std::vector &relative_paths, std::string const &ext) - { - bf::directory_iterator end_itr; - for(bf::directory_iterator itr(dir); itr != end_itr; ++itr) { - //check if its a directory, then get models in it - if(bf::is_directory(*itr)) { -#if BOOST_FILESYSTEM_VERSION == 3 - std::string so_far = rel_path_so_far + (itr->path().filename()).string() + "/"; -#else - std::string so_far = rel_path_so_far + (itr->path ()).filename () + "/"; -#endif - - bf::path curr_path = itr->path(); - getFilesInDirectoryInternal(curr_path, so_far, relative_paths, ext); - } else { - //check that it is a ply file and then add, otherwise ignore.. - std::vector strs; -#if BOOST_FILESYSTEM_VERSION == 3 - std::string file = (itr->path().filename()).string(); -#else - std::string file = (itr->path ()).filename (); -#endif - - boost::split(strs, file, boost::is_any_of(".")); - std::string extension = strs[strs.size() - 1]; - - if( file.rfind(ext) != std::string::npos ) - { -#if BOOST_FILESYSTEM_VERSION == 3 - std::string path = rel_path_so_far + (itr->path().filename()).string(); -#else - std::string path = rel_path_so_far + (itr->path ()).filename (); -#endif - std::string fullpath = rel_path_so_far + itr->path().string(); - relative_paths.push_back(path); - } - } - } - } - - static void createTrainingDir(std::string training_dir) - { - bf::path trained_dir = training_dir; - if(!bf::exists(trained_dir)) - bf::create_directory(trained_dir); - } - - static void getArgvArgc(std::string const &commandline, char ***argv, int &argc) - { - enum - { - kMaxArgs = 64 - }; - - argc = 0; - *argv = new char *[kMaxArgs]; - (*argv)[argc++] = (char *) "program"; - - char *p; - p = strtok((char *) commandline.c_str(), " "); - while(p && argc < kMaxArgs) { - (*argv)[argc++] = p; - p = strtok(0, " "); - } - } - }; -} -#endif //OPENDETECTION_UTILS_H diff --git a/data/haarcascade_frontalface_alt.xml b/data/haarcascade_frontalface_alt.xml new file mode 100644 index 00000000..5a6f2754 --- /dev/null +++ b/data/haarcascade_frontalface_alt.xml @@ -0,0 +1,26161 @@ + + + + + 20 20 + + <_> + + + <_> + + <_> + + + + <_>3 7 14 4 -1. + <_>3 9 14 2 2. + 0 + 4.0141958743333817e-003 + 0.0337941907346249 + 0.8378106951713562 + <_> + + <_> + + + + <_>1 2 18 4 -1. + <_>7 2 6 4 3. + 0 + 0.0151513395830989 + 0.1514132022857666 + 0.7488812208175659 + <_> + + <_> + + + + <_>1 7 15 9 -1. + <_>1 10 15 3 3. + 0 + 4.2109931819140911e-003 + 0.0900492817163467 + 0.6374819874763489 + 0.8226894140243530 + -1 + -1 + <_> + + + <_> + + <_> + + + + <_>5 6 2 6 -1. + <_>5 9 2 3 2. + 0 + 1.6227109590545297e-003 + 0.0693085864186287 + 0.7110946178436279 + <_> + + <_> + + + + <_>7 5 6 3 -1. + <_>9 5 2 3 3. + 0 + 2.2906649392098188e-003 + 0.1795803010463715 + 0.6668692231178284 + <_> + + <_> + + + + <_>4 0 12 9 -1. + <_>4 3 12 3 3. + 0 + 5.0025708042085171e-003 + 0.1693672984838486 + 0.6554006934165955 + <_> + + <_> + + + + <_>6 9 10 8 -1. + <_>6 13 10 4 2. + 0 + 7.9659894108772278e-003 + 0.5866332054138184 + 0.0914145186543465 + <_> + + <_> + + + + <_>3 6 14 8 -1. + <_>3 10 14 4 2. + 0 + -3.5227010957896709e-003 + 0.1413166970014572 + 0.6031895875930786 + <_> + + <_> + + + + <_>14 1 6 10 -1. + <_>14 1 3 10 2. + 0 + 0.0366676896810532 + 0.3675672113895416 + 0.7920318245887756 + <_> + + <_> + + + + <_>7 8 5 12 -1. + <_>7 12 5 4 3. + 0 + 9.3361474573612213e-003 + 0.6161385774612427 + 0.2088509947061539 + <_> + + <_> + + + + <_>1 1 18 3 -1. + <_>7 1 6 3 3. + 0 + 8.6961314082145691e-003 + 0.2836230993270874 + 0.6360273957252502 + <_> + + <_> + + + + <_>1 8 17 2 -1. + <_>1 9 17 1 2. + 0 + 1.1488880263641477e-003 + 0.2223580926656723 + 0.5800700783729553 + <_> + + <_> + + + + <_>16 6 4 2 -1. + <_>16 7 4 1 2. + 0 + -2.1484689787030220e-003 + 0.2406464070081711 + 0.5787054896354675 + <_> + + <_> + + + + <_>5 17 2 2 -1. + <_>5 18 2 1 2. + 0 + 2.1219060290604830e-003 + 0.5559654831886292 + 0.1362237036228180 + <_> + + <_> + + + + <_>14 2 6 12 -1. + <_>14 2 3 12 2. + 0 + -0.0939491465687752 + 0.8502737283706665 + 0.4717740118503571 + <_> + + <_> + + + + <_>4 0 4 12 -1. + <_>4 0 2 6 2. + <_>6 6 2 6 2. + 0 + 1.3777789426967502e-003 + 0.5993673801422119 + 0.2834529876708984 + <_> + + <_> + + + + <_>2 11 18 8 -1. + <_>8 11 6 8 3. + 0 + 0.0730631574988365 + 0.4341886043548584 + 0.7060034275054932 + <_> + + <_> + + + + <_>5 7 10 2 -1. + <_>5 8 10 1 2. + 0 + 3.6767389974556863e-004 + 0.3027887940406799 + 0.6051574945449829 + <_> + + <_> + + + + <_>15 11 5 3 -1. + <_>15 12 5 1 3. + 0 + -6.0479710809886456e-003 + 0.1798433959484100 + 0.5675256848335266 + 6.9566087722778320 + 0 + -1 + <_> + + + <_> + + <_> + + + + <_>5 3 10 9 -1. + <_>5 6 10 3 3. + 0 + -0.0165106896311045 + 0.6644225120544434 + 0.1424857974052429 + <_> + + <_> + + + + <_>9 4 2 14 -1. + <_>9 11 2 7 2. + 0 + 2.7052499353885651e-003 + 0.6325352191925049 + 0.1288477033376694 + <_> + + <_> + + + + <_>3 5 4 12 -1. + <_>3 9 4 4 3. + 0 + 2.8069869149476290e-003 + 0.1240288019180298 + 0.6193193197250366 + <_> + + <_> + + + + <_>4 5 12 5 -1. + <_>8 5 4 5 3. + 0 + -1.5402400167658925e-003 + 0.1432143002748489 + 0.5670015811920166 + <_> + + <_> + + + + <_>5 6 10 8 -1. + <_>5 10 10 4 2. + 0 + -5.6386279175058007e-004 + 0.1657433062791824 + 0.5905207991600037 + <_> + + <_> + + + + <_>8 0 6 9 -1. + <_>8 3 6 3 3. + 0 + 1.9253729842603207e-003 + 0.2695507109165192 + 0.5738824009895325 + <_> + + <_> + + + + <_>9 12 1 8 -1. + <_>9 16 1 4 2. + 0 + -5.0214841030538082e-003 + 0.1893538981676102 + 0.5782774090766907 + <_> + + <_> + + + + <_>0 7 20 6 -1. + <_>0 9 20 2 3. + 0 + 2.6365420781075954e-003 + 0.2309329062700272 + 0.5695425868034363 + <_> + + <_> + + + + <_>7 0 6 17 -1. + <_>9 0 2 17 3. + 0 + -1.5127769438549876e-003 + 0.2759602069854736 + 0.5956642031669617 + <_> + + <_> + + + + <_>9 0 6 4 -1. + <_>11 0 2 4 3. + 0 + -0.0101574398577213 + 0.1732538044452667 + 0.5522047281265259 + <_> + + <_> + + + + <_>5 1 6 4 -1. + <_>7 1 2 4 3. + 0 + -0.0119536602869630 + 0.1339409947395325 + 0.5559014081954956 + <_> + + <_> + + + + <_>12 1 6 16 -1. + <_>14 1 2 16 3. + 0 + 4.8859491944313049e-003 + 0.3628703951835632 + 0.6188849210739136 + <_> + + <_> + + + + <_>0 5 18 8 -1. + <_>0 5 9 4 2. + <_>9 9 9 4 2. + 0 + -0.0801329165697098 + 0.0912110507488251 + 0.5475944876670837 + <_> + + <_> + + + + <_>8 15 10 4 -1. + <_>13 15 5 2 2. + <_>8 17 5 2 2. + 0 + 1.0643280111253262e-003 + 0.3715142905712128 + 0.5711399912834168 + <_> + + <_> + + + + <_>3 1 4 8 -1. + <_>3 1 2 4 2. + <_>5 5 2 4 2. + 0 + -1.3419450260698795e-003 + 0.5953313708305359 + 0.3318097889423370 + <_> + + <_> + + + + <_>3 6 14 10 -1. + <_>10 6 7 5 2. + <_>3 11 7 5 2. + 0 + -0.0546011403203011 + 0.1844065934419632 + 0.5602846145629883 + <_> + + <_> + + + + <_>2 1 6 16 -1. + <_>4 1 2 16 3. + 0 + 2.9071690514683723e-003 + 0.3594244122505188 + 0.6131715178489685 + <_> + + <_> + + + + <_>0 18 20 2 -1. + <_>0 19 20 1 2. + 0 + 7.4718717951327562e-004 + 0.5994353294372559 + 0.3459562957286835 + <_> + + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 4.3013808317482471e-003 + 0.4172652065753937 + 0.6990845203399658 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 4.5017572119832039e-003 + 0.4509715139865875 + 0.7801457047462463 + <_> + + <_> + + + + <_>0 12 9 6 -1. + <_>0 14 9 2 3. + 0 + 0.0241385009139776 + 0.5438212752342224 + 0.1319826990365982 + 9.4985427856445313 + 1 + -1 + <_> + + + <_> + + <_> + + + + <_>5 7 3 4 -1. + <_>5 9 3 2 2. + 0 + 1.9212230108678341e-003 + 0.1415266990661621 + 0.6199870705604553 + <_> + + <_> + + + + <_>9 3 2 16 -1. + <_>9 11 2 8 2. + 0 + -1.2748669541906565e-004 + 0.6191074252128601 + 0.1884928941726685 + <_> + + <_> + + + + <_>3 6 13 8 -1. + <_>3 10 13 4 2. + 0 + 5.1409931620582938e-004 + 0.1487396955490112 + 0.5857927799224854 + <_> + + <_> + + + + <_>12 3 8 2 -1. + <_>12 3 4 2 2. + 0 + 4.1878609918057919e-003 + 0.2746909856796265 + 0.6359239816665649 + <_> + + <_> + + + + <_>8 8 4 12 -1. + <_>8 12 4 4 3. + 0 + 5.1015717908740044e-003 + 0.5870851278305054 + 0.2175628989934921 + <_> + + <_> + + + + <_>11 3 8 6 -1. + <_>15 3 4 3 2. + <_>11 6 4 3 2. + 0 + -2.1448440384119749e-003 + 0.5880944728851318 + 0.2979590892791748 + <_> + + <_> + + + + <_>7 1 6 19 -1. + <_>9 1 2 19 3. + 0 + -2.8977119363844395e-003 + 0.2373327016830444 + 0.5876647233963013 + <_> + + <_> + + + + <_>9 0 6 4 -1. + <_>11 0 2 4 3. + 0 + -0.0216106791049242 + 0.1220654994249344 + 0.5194202065467835 + <_> + + <_> + + + + <_>3 1 9 3 -1. + <_>6 1 3 3 3. + 0 + -4.6299318782985210e-003 + 0.2631230950355530 + 0.5817409157752991 + <_> + + <_> + + + + <_>8 15 10 4 -1. + <_>13 15 5 2 2. + <_>8 17 5 2 2. + 0 + 5.9393711853772402e-004 + 0.3638620078563690 + 0.5698544979095459 + <_> + + <_> + + + + <_>0 3 6 10 -1. + <_>3 3 3 10 2. + 0 + 0.0538786612451077 + 0.4303531050682068 + 0.7559366226196289 + <_> + + <_> + + + + <_>3 4 15 15 -1. + <_>3 9 15 5 3. + 0 + 1.8887349870055914e-003 + 0.2122603058815002 + 0.5613427162170410 + <_> + + <_> + + + + <_>6 5 8 6 -1. + <_>6 7 8 2 3. + 0 + -2.3635339457541704e-003 + 0.5631849169731140 + 0.2642767131328583 + <_> + + <_> + + + + <_>4 4 12 10 -1. + <_>10 4 6 5 2. + <_>4 9 6 5 2. + 0 + 0.0240177996456623 + 0.5797107815742493 + 0.2751705944538117 + <_> + + <_> + + + + <_>6 4 4 4 -1. + <_>8 4 2 4 2. + 0 + 2.0543030404951423e-004 + 0.2705242037773132 + 0.5752568840980530 + <_> + + <_> + + + + <_>15 11 1 2 -1. + <_>15 12 1 1 2. + 0 + 8.4790197433903813e-004 + 0.5435624718666077 + 0.2334876954555512 + <_> + + <_> + + + + <_>3 11 2 2 -1. + <_>3 12 2 1 2. + 0 + 1.4091329649090767e-003 + 0.5319424867630005 + 0.2063155025243759 + <_> + + <_> + + + + <_>16 11 1 3 -1. + <_>16 12 1 1 3. + 0 + 1.4642629539594054e-003 + 0.5418980717658997 + 0.3068861067295075 + <_> + + <_> + + + + <_>3 15 6 4 -1. + <_>3 15 3 2 2. + <_>6 17 3 2 2. + 0 + 1.6352549428120255e-003 + 0.3695372939109802 + 0.6112868189811707 + <_> + + <_> + + + + <_>6 7 8 2 -1. + <_>6 8 8 1 2. + 0 + 8.3172752056270838e-004 + 0.3565036952495575 + 0.6025236248970032 + <_> + + <_> + + + + <_>3 11 1 3 -1. + <_>3 12 1 1 3. + 0 + -2.0998890977352858e-003 + 0.1913982033729553 + 0.5362827181816101 + <_> + + <_> + + + + <_>6 0 12 2 -1. + <_>6 1 12 1 2. + 0 + -7.4213981861248612e-004 + 0.3835555016994476 + 0.5529310107231140 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 3.2655049581080675e-003 + 0.4312896132469177 + 0.7101895809173584 + <_> + + <_> + + + + <_>7 15 6 2 -1. + <_>7 16 6 1 2. + 0 + 8.9134991867467761e-004 + 0.3984830975532532 + 0.6391963958740234 + <_> + + <_> + + + + <_>0 5 4 6 -1. + <_>0 7 4 2 3. + 0 + -0.0152841797098517 + 0.2366732954978943 + 0.5433713793754578 + <_> + + <_> + + + + <_>4 12 12 2 -1. + <_>8 12 4 2 3. + 0 + 4.8381411470472813e-003 + 0.5817500948905945 + 0.3239189088344574 + <_> + + <_> + + + + <_>6 3 1 9 -1. + <_>6 6 1 3 3. + 0 + -9.1093179071322083e-004 + 0.5540593862533569 + 0.2911868989467621 + <_> + + <_> + + + + <_>10 17 3 2 -1. + <_>11 17 1 2 3. + 0 + -6.1275060288608074e-003 + 0.1775255054235458 + 0.5196629166603088 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -4.4576259097084403e-004 + 0.3024170100688934 + 0.5533593893051148 + <_> + + <_> + + + + <_>7 6 6 4 -1. + <_>9 6 2 4 3. + 0 + 0.0226465407758951 + 0.4414930939674377 + 0.6975377202033997 + <_> + + <_> + + + + <_>7 17 3 2 -1. + <_>8 17 1 2 3. + 0 + -1.8804960418492556e-003 + 0.2791394889354706 + 0.5497952103614807 + <_> + + <_> + + + + <_>10 17 3 3 -1. + <_>11 17 1 3 3. + 0 + 7.0889107882976532e-003 + 0.5263199210166931 + 0.2385547012090683 + <_> + + <_> + + + + <_>8 12 3 2 -1. + <_>8 13 3 1 2. + 0 + 1.7318050377070904e-003 + 0.4319379031658173 + 0.6983600854873657 + <_> + + <_> + + + + <_>9 3 6 2 -1. + <_>11 3 2 2 3. + 0 + -6.8482700735330582e-003 + 0.3082042932510376 + 0.5390920042991638 + <_> + + <_> + + + + <_>3 11 14 4 -1. + <_>3 13 14 2 2. + 0 + -1.5062530110299122e-005 + 0.5521922111511231 + 0.3120366036891937 + <_> + + <_> + + + + <_>1 10 18 4 -1. + <_>10 10 9 2 2. + <_>1 12 9 2 2. + 0 + 0.0294755697250366 + 0.5401322841644287 + 0.1770603060722351 + <_> + + <_> + + + + <_>0 10 3 3 -1. + <_>0 11 3 1 3. + 0 + 8.1387329846620560e-003 + 0.5178617835044861 + 0.1211019009351730 + <_> + + <_> + + + + <_>9 1 6 6 -1. + <_>11 1 2 6 3. + 0 + 0.0209429506212473 + 0.5290294289588928 + 0.3311221897602081 + <_> + + <_> + + + + <_>8 7 3 6 -1. + <_>9 7 1 6 3. + 0 + -9.5665529370307922e-003 + 0.7471994161605835 + 0.4451968967914581 + 18.4129695892333980 + 2 + -1 + <_> + + + <_> + + <_> + + + + <_>1 0 18 9 -1. + <_>1 3 18 3 3. + 0 + -2.8206960996612906e-004 + 0.2064086049795151 + 0.6076732277870178 + <_> + + <_> + + + + <_>12 10 2 6 -1. + <_>12 13 2 3 2. + 0 + 1.6790600493550301e-003 + 0.5851997137069702 + 0.1255383938550949 + <_> + + <_> + + + + <_>0 5 19 8 -1. + <_>0 9 19 4 2. + 0 + 6.9827912375330925e-004 + 0.0940184295177460 + 0.5728961229324341 + <_> + + <_> + + + + <_>7 0 6 9 -1. + <_>9 0 2 9 3. + 0 + 7.8959012171253562e-004 + 0.1781987994909287 + 0.5694308876991272 + <_> + + <_> + + + + <_>5 3 6 1 -1. + <_>7 3 2 1 3. + 0 + -2.8560499195009470e-003 + 0.1638399064540863 + 0.5788664817810059 + <_> + + <_> + + + + <_>11 3 6 1 -1. + <_>13 3 2 1 3. + 0 + -3.8122469559311867e-003 + 0.2085440009832382 + 0.5508564710617065 + <_> + + <_> + + + + <_>5 10 4 6 -1. + <_>5 13 4 3 2. + 0 + 1.5896620461717248e-003 + 0.5702760815620422 + 0.1857215017080307 + <_> + + <_> + + + + <_>11 3 6 1 -1. + <_>13 3 2 1 3. + 0 + 0.0100783398374915 + 0.5116943120956421 + 0.2189770042896271 + <_> + + <_> + + + + <_>4 4 12 6 -1. + <_>4 6 12 2 3. + 0 + -0.0635263025760651 + 0.7131379842758179 + 0.4043813049793243 + <_> + + <_> + + + + <_>15 12 2 6 -1. + <_>15 14 2 2 3. + 0 + -9.1031491756439209e-003 + 0.2567181885242462 + 0.5463973283767700 + <_> + + <_> + + + + <_>9 3 2 2 -1. + <_>10 3 1 2 2. + 0 + -2.4035000242292881e-003 + 0.1700665950775147 + 0.5590974092483521 + <_> + + <_> + + + + <_>9 3 3 1 -1. + <_>10 3 1 1 3. + 0 + 1.5226360410451889e-003 + 0.5410556793212891 + 0.2619054019451141 + <_> + + <_> + + + + <_>1 1 4 14 -1. + <_>3 1 2 14 2. + 0 + 0.0179974399507046 + 0.3732436895370483 + 0.6535220742225647 + <_> + + <_> + + + + <_>9 0 4 4 -1. + <_>11 0 2 2 2. + <_>9 2 2 2 2. + 0 + -6.4538191072642803e-003 + 0.2626481950283051 + 0.5537446141242981 + <_> + + <_> + + + + <_>7 5 1 14 -1. + <_>7 12 1 7 2. + 0 + -0.0118807600811124 + 0.2003753930330277 + 0.5544745922088623 + <_> + + <_> + + + + <_>19 0 1 4 -1. + <_>19 2 1 2 2. + 0 + 1.2713660253211856e-003 + 0.5591902732849121 + 0.3031975924968720 + <_> + + <_> + + + + <_>5 5 6 4 -1. + <_>8 5 3 4 2. + 0 + 1.1376109905540943e-003 + 0.2730407118797302 + 0.5646508932113648 + <_> + + <_> + + + + <_>9 18 3 2 -1. + <_>10 18 1 2 3. + 0 + -4.2651998810470104e-003 + 0.1405909061431885 + 0.5461820960044861 + <_> + + <_> + + + + <_>8 18 3 2 -1. + <_>9 18 1 2 3. + 0 + -2.9602861031889915e-003 + 0.1795035004615784 + 0.5459290146827698 + <_> + + <_> + + + + <_>4 5 12 6 -1. + <_>4 7 12 2 3. + 0 + -8.8448226451873779e-003 + 0.5736783146858215 + 0.2809219956398010 + <_> + + <_> + + + + <_>3 12 2 6 -1. + <_>3 14 2 2 3. + 0 + -6.6430689767003059e-003 + 0.2370675951242447 + 0.5503826141357422 + <_> + + <_> + + + + <_>10 8 2 12 -1. + <_>10 12 2 4 3. + 0 + 3.9997808635234833e-003 + 0.5608199834823608 + 0.3304282128810883 + <_> + + <_> + + + + <_>7 18 3 2 -1. + <_>8 18 1 2 3. + 0 + -4.1221720166504383e-003 + 0.1640105992555618 + 0.5378993153572083 + <_> + + <_> + + + + <_>9 0 6 2 -1. + <_>11 0 2 2 3. + 0 + 0.0156249096617103 + 0.5227649211883545 + 0.2288603931665421 + <_> + + <_> + + + + <_>5 11 9 3 -1. + <_>5 12 9 1 3. + 0 + -0.0103564197197557 + 0.7016193866729736 + 0.4252927899360657 + <_> + + <_> + + + + <_>9 0 6 2 -1. + <_>11 0 2 2 3. + 0 + -8.7960809469223022e-003 + 0.2767347097396851 + 0.5355830192565918 + <_> + + <_> + + + + <_>1 1 18 5 -1. + <_>7 1 6 5 3. + 0 + 0.1622693985700607 + 0.4342240095138550 + 0.7442579269409180 + <_> + + <_> + + + + <_>8 0 4 4 -1. + <_>10 0 2 2 2. + <_>8 2 2 2 2. + 0 + 4.5542530715465546e-003 + 0.5726485848426819 + 0.2582125067710877 + <_> + + <_> + + + + <_>3 12 1 3 -1. + <_>3 13 1 1 3. + 0 + -2.1309209987521172e-003 + 0.2106848061084747 + 0.5361018776893616 + <_> + + <_> + + + + <_>8 14 5 3 -1. + <_>8 15 5 1 3. + 0 + -0.0132084200158715 + 0.7593790888786316 + 0.4552468061447144 + <_> + + <_> + + + + <_>5 4 10 12 -1. + <_>5 4 5 6 2. + <_>10 10 5 6 2. + 0 + -0.0659966766834259 + 0.1252475976943970 + 0.5344039797782898 + <_> + + <_> + + + + <_>9 6 9 12 -1. + <_>9 10 9 4 3. + 0 + 7.9142656177282333e-003 + 0.3315384089946747 + 0.5601043105125427 + <_> + + <_> + + + + <_>2 2 12 14 -1. + <_>2 2 6 7 2. + <_>8 9 6 7 2. + 0 + 0.0208942797034979 + 0.5506049990653992 + 0.2768838107585907 + 15.3241395950317380 + 3 + -1 + <_> + + + <_> + + <_> + + + + <_>4 7 12 2 -1. + <_>8 7 4 2 3. + 0 + 1.1961159761995077e-003 + 0.1762690991163254 + 0.6156241297721863 + <_> + + <_> + + + + <_>7 4 6 4 -1. + <_>7 6 6 2 2. + 0 + -1.8679830245673656e-003 + 0.6118106842041016 + 0.1832399964332581 + <_> + + <_> + + + + <_>4 5 11 8 -1. + <_>4 9 11 4 2. + 0 + -1.9579799845814705e-004 + 0.0990442633628845 + 0.5723816156387329 + <_> + + <_> + + + + <_>3 10 16 4 -1. + <_>3 12 16 2 2. + 0 + -8.0255657667294145e-004 + 0.5579879879951477 + 0.2377282977104187 + <_> + + <_> + + + + <_>0 0 16 2 -1. + <_>0 1 16 1 2. + 0 + -2.4510810617357492e-003 + 0.2231457978487015 + 0.5858935117721558 + <_> + + <_> + + + + <_>7 5 6 2 -1. + <_>9 5 2 2 3. + 0 + 5.0361850298941135e-004 + 0.2653993964195252 + 0.5794103741645813 + <_> + + <_> + + + + <_>3 2 6 10 -1. + <_>3 2 3 5 2. + <_>6 7 3 5 2. + 0 + 4.0293349884450436e-003 + 0.5803827047348023 + 0.2484865039587021 + <_> + + <_> + + + + <_>10 5 8 15 -1. + <_>10 10 8 5 3. + 0 + -0.0144517095759511 + 0.1830351948738098 + 0.5484204888343811 + <_> + + <_> + + + + <_>3 14 8 6 -1. + <_>3 14 4 3 2. + <_>7 17 4 3 2. + 0 + 2.0380979403853416e-003 + 0.3363558948040009 + 0.6051092743873596 + <_> + + <_> + + + + <_>14 2 2 2 -1. + <_>14 3 2 1 2. + 0 + -1.6155190533027053e-003 + 0.2286642044782639 + 0.5441246032714844 + <_> + + <_> + + + + <_>1 10 7 6 -1. + <_>1 13 7 3 2. + 0 + 3.3458340913057327e-003 + 0.5625913143157959 + 0.2392338067293167 + <_> + + <_> + + + + <_>15 4 4 3 -1. + <_>15 4 2 3 2. + 0 + 1.6379579901695251e-003 + 0.3906993865966797 + 0.5964621901512146 + <_> + + <_> + + + + <_>2 9 14 6 -1. + <_>2 9 7 3 2. + <_>9 12 7 3 2. + 0 + 0.0302512105554342 + 0.5248482227325440 + 0.1575746983289719 + <_> + + <_> + + + + <_>5 7 10 4 -1. + <_>5 9 10 2 2. + 0 + 0.0372519902884960 + 0.4194310903549194 + 0.6748418807983398 + <_> + + <_> + + + + <_>6 9 8 8 -1. + <_>6 9 4 4 2. + <_>10 13 4 4 2. + 0 + -0.0251097902655602 + 0.1882549971342087 + 0.5473451018333435 + <_> + + <_> + + + + <_>14 1 3 2 -1. + <_>14 2 3 1 2. + 0 + -5.3099058568477631e-003 + 0.1339973062276840 + 0.5227110981941223 + <_> + + <_> + + + + <_>1 4 4 2 -1. + <_>3 4 2 2 2. + 0 + 1.2086479691788554e-003 + 0.3762088119983673 + 0.6109635829925537 + <_> + + <_> + + + + <_>11 10 2 8 -1. + <_>11 14 2 4 2. + 0 + -0.0219076797366142 + 0.2663142979145050 + 0.5404006838798523 + <_> + + <_> + + + + <_>0 0 5 3 -1. + <_>0 1 5 1 3. + 0 + 5.4116579703986645e-003 + 0.5363578796386719 + 0.2232273072004318 + <_> + + <_> + + + + <_>2 5 18 8 -1. + <_>11 5 9 4 2. + <_>2 9 9 4 2. + 0 + 0.0699463263154030 + 0.5358232855796814 + 0.2453698068857193 + <_> + + <_> + + + + <_>6 6 1 6 -1. + <_>6 9 1 3 2. + 0 + 3.4520021290518343e-004 + 0.2409671992063522 + 0.5376930236816406 + <_> + + <_> + + + + <_>19 1 1 3 -1. + <_>19 2 1 1 3. + 0 + 1.2627709656953812e-003 + 0.5425856709480286 + 0.3155693113803864 + <_> + + <_> + + + + <_>7 6 6 6 -1. + <_>9 6 2 6 3. + 0 + 0.0227195098996162 + 0.4158405959606171 + 0.6597865223884583 + <_> + + <_> + + + + <_>19 1 1 3 -1. + <_>19 2 1 1 3. + 0 + -1.8111000536009669e-003 + 0.2811253070831299 + 0.5505244731903076 + <_> + + <_> + + + + <_>3 13 2 3 -1. + <_>3 14 2 1 3. + 0 + 3.3469670452177525e-003 + 0.5260028243064880 + 0.1891465038061142 + <_> + + <_> + + + + <_>8 4 8 12 -1. + <_>12 4 4 6 2. + <_>8 10 4 6 2. + 0 + 4.0791751234792173e-004 + 0.5673509240150452 + 0.3344210088253021 + <_> + + <_> + + + + <_>5 2 6 3 -1. + <_>7 2 2 3 3. + 0 + 0.0127347996458411 + 0.5343592166900635 + 0.2395612001419067 + <_> + + <_> + + + + <_>6 1 9 10 -1. + <_>6 6 9 5 2. + 0 + -7.3119727894663811e-003 + 0.6010890007019043 + 0.4022207856178284 + <_> + + <_> + + + + <_>0 4 6 12 -1. + <_>2 4 2 12 3. + 0 + -0.0569487512111664 + 0.8199151158332825 + 0.4543190896511078 + <_> + + <_> + + + + <_>15 13 2 3 -1. + <_>15 14 2 1 3. + 0 + -5.0116591155529022e-003 + 0.2200281023979187 + 0.5357710719108582 + <_> + + <_> + + + + <_>7 14 5 3 -1. + <_>7 15 5 1 3. + 0 + 6.0334368608891964e-003 + 0.4413081109523773 + 0.7181751132011414 + <_> + + <_> + + + + <_>15 13 3 3 -1. + <_>15 14 3 1 3. + 0 + 3.9437441155314445e-003 + 0.5478860735893250 + 0.2791733145713806 + <_> + + <_> + + + + <_>6 14 8 3 -1. + <_>6 15 8 1 3. + 0 + -3.6591119132936001e-003 + 0.6357867717742920 + 0.3989723920822144 + <_> + + <_> + + + + <_>15 13 3 3 -1. + <_>15 14 3 1 3. + 0 + -3.8456181064248085e-003 + 0.3493686020374298 + 0.5300664901733398 + <_> + + <_> + + + + <_>2 13 3 3 -1. + <_>2 14 3 1 3. + 0 + -7.1926261298358440e-003 + 0.1119614988565445 + 0.5229672789573669 + <_> + + <_> + + + + <_>4 7 12 12 -1. + <_>10 7 6 6 2. + <_>4 13 6 6 2. + 0 + -0.0527989417314529 + 0.2387102991342545 + 0.5453451275825501 + <_> + + <_> + + + + <_>9 7 2 6 -1. + <_>10 7 1 6 2. + 0 + -7.9537667334079742e-003 + 0.7586917877197266 + 0.4439376890659332 + <_> + + <_> + + + + <_>8 9 5 2 -1. + <_>8 10 5 1 2. + 0 + -2.7344180271029472e-003 + 0.2565476894378662 + 0.5489321947097778 + <_> + + <_> + + + + <_>8 6 3 4 -1. + <_>9 6 1 4 3. + 0 + -1.8507939530536532e-003 + 0.6734347939491272 + 0.4252474904060364 + <_> + + <_> + + + + <_>9 6 2 8 -1. + <_>9 10 2 4 2. + 0 + 0.0159189198166132 + 0.5488352775573731 + 0.2292661964893341 + <_> + + <_> + + + + <_>7 7 3 6 -1. + <_>8 7 1 6 3. + 0 + -1.2687679845839739e-003 + 0.6104331016540527 + 0.4022389948368073 + <_> + + <_> + + + + <_>11 3 3 3 -1. + <_>12 3 1 3 3. + 0 + 6.2883910723030567e-003 + 0.5310853123664856 + 0.1536193042993546 + <_> + + <_> + + + + <_>5 4 6 1 -1. + <_>7 4 2 1 3. + 0 + -6.2259892001748085e-003 + 0.1729111969470978 + 0.5241606235504150 + <_> + + <_> + + + + <_>5 6 10 3 -1. + <_>5 7 10 1 3. + 0 + -0.0121325999498367 + 0.6597759723663330 + 0.4325182139873505 + 21.0106391906738280 + 4 + -1 + <_> + + + <_> + + <_> + + + + <_>7 3 6 9 -1. + <_>7 6 6 3 3. + 0 + -3.9184908382594585e-003 + 0.6103435158729553 + 0.1469330936670303 + <_> + + <_> + + + + <_>6 7 9 1 -1. + <_>9 7 3 1 3. + 0 + 1.5971299726516008e-003 + 0.2632363140583038 + 0.5896466970443726 + <_> + + <_> + + + + <_>2 8 16 8 -1. + <_>2 12 16 4 2. + 0 + 0.0177801102399826 + 0.5872874259948731 + 0.1760361939668655 + <_> + + <_> + + + + <_>14 6 2 6 -1. + <_>14 9 2 3 2. + 0 + 6.5334769897162914e-004 + 0.1567801982164383 + 0.5596066117286682 + <_> + + <_> + + + + <_>1 5 6 15 -1. + <_>1 10 6 5 3. + 0 + -2.8353091329336166e-004 + 0.1913153976202011 + 0.5732036232948303 + <_> + + <_> + + + + <_>10 0 6 9 -1. + <_>10 3 6 3 3. + 0 + 1.6104689566418529e-003 + 0.2914913892745972 + 0.5623080730438232 + <_> + + <_> + + + + <_>6 6 7 14 -1. + <_>6 13 7 7 2. + 0 + -0.0977506190538406 + 0.1943476945161820 + 0.5648233294487000 + <_> + + <_> + + + + <_>13 7 3 6 -1. + <_>13 9 3 2 3. + 0 + 5.5182358482852578e-004 + 0.3134616911411285 + 0.5504639744758606 + <_> + + <_> + + + + <_>1 8 15 4 -1. + <_>6 8 5 4 3. + 0 + -0.0128582203760743 + 0.2536481916904450 + 0.5760142803192139 + <_> + + <_> + + + + <_>11 2 3 10 -1. + <_>11 7 3 5 2. + 0 + 4.1530239395797253e-003 + 0.5767722129821777 + 0.3659774065017700 + <_> + + <_> + + + + <_>3 7 4 6 -1. + <_>3 9 4 2 3. + 0 + 1.7092459602281451e-003 + 0.2843191027641296 + 0.5918939113616943 + <_> + + <_> + + + + <_>13 3 6 10 -1. + <_>15 3 2 10 3. + 0 + 7.5217359699308872e-003 + 0.4052427113056183 + 0.6183109283447266 + <_> + + <_> + + + + <_>5 7 8 10 -1. + <_>5 7 4 5 2. + <_>9 12 4 5 2. + 0 + 2.2479810286313295e-003 + 0.5783755183219910 + 0.3135401010513306 + <_> + + <_> + + + + <_>4 4 12 12 -1. + <_>10 4 6 6 2. + <_>4 10 6 6 2. + 0 + 0.0520062111318111 + 0.5541312098503113 + 0.1916636973619461 + <_> + + <_> + + + + <_>1 4 6 9 -1. + <_>3 4 2 9 3. + 0 + 0.0120855299755931 + 0.4032655954360962 + 0.6644591093063355 + <_> + + <_> + + + + <_>11 3 2 5 -1. + <_>11 3 1 5 2. + 0 + 1.4687820112158079e-005 + 0.3535977900028229 + 0.5709382891654968 + <_> + + <_> + + + + <_>7 3 2 5 -1. + <_>8 3 1 5 2. + 0 + 7.1395188570022583e-006 + 0.3037444949150085 + 0.5610269904136658 + <_> + + <_> + + + + <_>10 14 2 3 -1. + <_>10 15 2 1 3. + 0 + -4.6001640148460865e-003 + 0.7181087136268616 + 0.4580326080322266 + <_> + + <_> + + + + <_>5 12 6 2 -1. + <_>8 12 3 2 2. + 0 + 2.0058949012309313e-003 + 0.5621951818466187 + 0.2953684031963348 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 4.5050270855426788e-003 + 0.4615387916564941 + 0.7619017958641052 + <_> + + <_> + + + + <_>4 11 12 6 -1. + <_>4 14 12 3 2. + 0 + 0.0117468303069472 + 0.5343837141990662 + 0.1772529035806656 + <_> + + <_> + + + + <_>11 11 5 9 -1. + <_>11 14 5 3 3. + 0 + -0.0583163388073444 + 0.1686245948076248 + 0.5340772271156311 + <_> + + <_> + + + + <_>6 15 3 2 -1. + <_>6 16 3 1 2. + 0 + 2.3629379575140774e-004 + 0.3792056143283844 + 0.6026803851127625 + <_> + + <_> + + + + <_>11 0 3 5 -1. + <_>12 0 1 5 3. + 0 + -7.8156180679798126e-003 + 0.1512867063283920 + 0.5324323773384094 + <_> + + <_> + + + + <_>5 5 6 7 -1. + <_>8 5 3 7 2. + 0 + -0.0108761601150036 + 0.2081822007894516 + 0.5319945216178894 + <_> + + <_> + + + + <_>13 0 1 9 -1. + <_>13 3 1 3 3. + 0 + -2.7745519764721394e-003 + 0.4098246991634369 + 0.5210328102111816 + <_> + + <_> + + + + <_>3 2 4 8 -1. + <_>3 2 2 4 2. + <_>5 6 2 4 2. + 0 + -7.8276381827890873e-004 + 0.5693274140357971 + 0.3478842079639435 + <_> + + <_> + + + + <_>13 12 4 6 -1. + <_>13 14 4 2 3. + 0 + 0.0138704096898437 + 0.5326750874519348 + 0.2257698029279709 + <_> + + <_> + + + + <_>3 12 4 6 -1. + <_>3 14 4 2 3. + 0 + -0.0236749108880758 + 0.1551305055618286 + 0.5200707912445068 + <_> + + <_> + + + + <_>13 11 3 4 -1. + <_>13 13 3 2 2. + 0 + -1.4879409718560055e-005 + 0.5500566959381104 + 0.3820176124572754 + <_> + + <_> + + + + <_>4 4 4 3 -1. + <_>4 5 4 1 3. + 0 + 3.6190641112625599e-003 + 0.4238683879375458 + 0.6639748215675354 + <_> + + <_> + + + + <_>7 5 11 8 -1. + <_>7 9 11 4 2. + 0 + -0.0198171101510525 + 0.2150038033723831 + 0.5382357835769653 + <_> + + <_> + + + + <_>7 8 3 4 -1. + <_>8 8 1 4 3. + 0 + -3.8154039066284895e-003 + 0.6675711274147034 + 0.4215297102928162 + <_> + + <_> + + + + <_>9 1 6 1 -1. + <_>11 1 2 1 3. + 0 + -4.9775829538702965e-003 + 0.2267289012670517 + 0.5386328101158142 + <_> + + <_> + + + + <_>5 5 3 3 -1. + <_>5 6 3 1 3. + 0 + 2.2441020701080561e-003 + 0.4308691024780273 + 0.6855735778808594 + <_> + + <_> + + + + <_>0 9 20 6 -1. + <_>10 9 10 3 2. + <_>0 12 10 3 2. + 0 + 0.0122824599966407 + 0.5836614966392517 + 0.3467479050159454 + <_> + + <_> + + + + <_>8 6 3 5 -1. + <_>9 6 1 5 3. + 0 + -2.8548699337989092e-003 + 0.7016944885253906 + 0.4311453998088837 + <_> + + <_> + + + + <_>11 0 1 3 -1. + <_>11 1 1 1 3. + 0 + -3.7875669077038765e-003 + 0.2895345091819763 + 0.5224946141242981 + <_> + + <_> + + + + <_>4 2 4 2 -1. + <_>4 3 4 1 2. + 0 + -1.2201230274513364e-003 + 0.2975570857524872 + 0.5481644868850708 + <_> + + <_> + + + + <_>12 6 4 3 -1. + <_>12 7 4 1 3. + 0 + 0.0101605998352170 + 0.4888817965984345 + 0.8182697892189026 + <_> + + <_> + + + + <_>5 0 6 4 -1. + <_>7 0 2 4 3. + 0 + -0.0161745697259903 + 0.1481492966413498 + 0.5239992737770081 + <_> + + <_> + + + + <_>9 7 3 8 -1. + <_>10 7 1 8 3. + 0 + 0.0192924607545137 + 0.4786309897899628 + 0.7378190755844116 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>10 7 1 2 2. + 0 + -3.2479539513587952e-003 + 0.7374222874641419 + 0.4470643997192383 + <_> + + <_> + + + + <_>6 7 14 4 -1. + <_>13 7 7 2 2. + <_>6 9 7 2 2. + 0 + -9.3803480267524719e-003 + 0.3489154875278473 + 0.5537996292114258 + <_> + + <_> + + + + <_>0 5 3 6 -1. + <_>0 7 3 2 3. + 0 + -0.0126061299815774 + 0.2379686981439591 + 0.5315443277359009 + <_> + + <_> + + + + <_>13 11 3 4 -1. + <_>13 13 3 2 2. + 0 + -0.0256219301372766 + 0.1964688003063202 + 0.5138769745826721 + <_> + + <_> + + + + <_>4 11 3 4 -1. + <_>4 13 3 2 2. + 0 + -7.5741496402770281e-005 + 0.5590522885322571 + 0.3365853130817413 + <_> + + <_> + + + + <_>5 9 12 8 -1. + <_>11 9 6 4 2. + <_>5 13 6 4 2. + 0 + -0.0892108827829361 + 0.0634046569466591 + 0.5162634849548340 + <_> + + <_> + + + + <_>9 12 1 3 -1. + <_>9 13 1 1 3. + 0 + -2.7670480776578188e-003 + 0.7323467731475830 + 0.4490706026554108 + <_> + + <_> + + + + <_>10 15 2 4 -1. + <_>10 17 2 2 2. + 0 + 2.7152578695677221e-004 + 0.4114834964275360 + 0.5985518097877502 + 23.9187908172607420 + 5 + -1 + <_> + + + <_> + + <_> + + + + <_>7 7 6 1 -1. + <_>9 7 2 1 3. + 0 + 1.4786219689995050e-003 + 0.2663545012474060 + 0.6643316745758057 + <_> + + <_> + + + + <_>12 3 6 6 -1. + <_>15 3 3 3 2. + <_>12 6 3 3 2. + 0 + -1.8741659587249160e-003 + 0.6143848896026611 + 0.2518512904644013 + <_> + + <_> + + + + <_>0 4 10 6 -1. + <_>0 6 10 2 3. + 0 + -1.7151009524241090e-003 + 0.5766341090202332 + 0.2397463023662567 + <_> + + <_> + + + + <_>8 3 8 14 -1. + <_>12 3 4 7 2. + <_>8 10 4 7 2. + 0 + -1.8939269939437509e-003 + 0.5682045817375183 + 0.2529144883155823 + <_> + + <_> + + + + <_>4 4 7 15 -1. + <_>4 9 7 5 3. + 0 + -5.3006052039563656e-003 + 0.1640675961971283 + 0.5556079745292664 + <_> + + <_> + + + + <_>12 2 6 8 -1. + <_>15 2 3 4 2. + <_>12 6 3 4 2. + 0 + -0.0466625317931175 + 0.6123154163360596 + 0.4762830138206482 + <_> + + <_> + + + + <_>2 2 6 8 -1. + <_>2 2 3 4 2. + <_>5 6 3 4 2. + 0 + -7.9431332414969802e-004 + 0.5707858800888062 + 0.2839404046535492 + <_> + + <_> + + + + <_>2 13 18 7 -1. + <_>8 13 6 7 3. + 0 + 0.0148916700854898 + 0.4089672863483429 + 0.6006367206573486 + <_> + + <_> + + + + <_>4 3 8 14 -1. + <_>4 3 4 7 2. + <_>8 10 4 7 2. + 0 + -1.2046529445797205e-003 + 0.5712450742721558 + 0.2705289125442505 + <_> + + <_> + + + + <_>18 1 2 6 -1. + <_>18 3 2 2 3. + 0 + 6.0619381256401539e-003 + 0.5262504220008850 + 0.3262225985527039 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -2.5286648888140917e-003 + 0.6853830814361572 + 0.4199256896972656 + <_> + + <_> + + + + <_>18 1 2 6 -1. + <_>18 3 2 2 3. + 0 + -5.9010218828916550e-003 + 0.3266282081604004 + 0.5434812903404236 + <_> + + <_> + + + + <_>0 1 2 6 -1. + <_>0 3 2 2 3. + 0 + 5.6702760048210621e-003 + 0.5468410849571228 + 0.2319003939628601 + <_> + + <_> + + + + <_>1 5 18 6 -1. + <_>1 7 18 2 3. + 0 + -3.0304100364446640e-003 + 0.5570667982101440 + 0.2708238065242767 + <_> + + <_> + + + + <_>0 2 6 7 -1. + <_>3 2 3 7 2. + 0 + 2.9803649522364140e-003 + 0.3700568974018097 + 0.5890625715255737 + <_> + + <_> + + + + <_>7 3 6 14 -1. + <_>7 10 6 7 2. + 0 + -0.0758405104279518 + 0.2140070050954819 + 0.5419948101043701 + <_> + + <_> + + + + <_>3 7 13 10 -1. + <_>3 12 13 5 2. + 0 + 0.0192625392228365 + 0.5526772141456604 + 0.2726590037345886 + <_> + + <_> + + + + <_>11 15 2 2 -1. + <_>11 16 2 1 2. + 0 + 1.8888259364757687e-004 + 0.3958011865615845 + 0.6017209887504578 + <_> + + <_> + + + + <_>2 11 16 4 -1. + <_>2 11 8 2 2. + <_>10 13 8 2 2. + 0 + 0.0293695498257875 + 0.5241373777389526 + 0.1435758024454117 + <_> + + <_> + + + + <_>13 7 6 4 -1. + <_>16 7 3 2 2. + <_>13 9 3 2 2. + 0 + 1.0417619487270713e-003 + 0.3385409116744995 + 0.5929983258247376 + <_> + + <_> + + + + <_>6 10 3 9 -1. + <_>6 13 3 3 3. + 0 + 2.6125640142709017e-003 + 0.5485377907752991 + 0.3021597862243652 + <_> + + <_> + + + + <_>14 6 1 6 -1. + <_>14 9 1 3 2. + 0 + 9.6977467183023691e-004 + 0.3375276029109955 + 0.5532032847404480 + <_> + + <_> + + + + <_>5 10 4 1 -1. + <_>7 10 2 1 2. + 0 + 5.9512659208849072e-004 + 0.5631743073463440 + 0.3359399139881134 + <_> + + <_> + + + + <_>3 8 15 5 -1. + <_>8 8 5 5 3. + 0 + -0.1015655994415283 + 0.0637350380420685 + 0.5230425000190735 + <_> + + <_> + + + + <_>1 6 5 4 -1. + <_>1 8 5 2 2. + 0 + 0.0361566990613937 + 0.5136963129043579 + 0.1029528975486755 + <_> + + <_> + + + + <_>3 1 17 6 -1. + <_>3 3 17 2 3. + 0 + 3.4624140243977308e-003 + 0.3879320025444031 + 0.5558289289474487 + <_> + + <_> + + + + <_>6 7 8 2 -1. + <_>10 7 4 2 2. + 0 + 0.0195549800992012 + 0.5250086784362793 + 0.1875859946012497 + <_> + + <_> + + + + <_>9 7 3 2 -1. + <_>10 7 1 2 3. + 0 + -2.3121440317481756e-003 + 0.6672028899192810 + 0.4679641127586365 + <_> + + <_> + + + + <_>8 7 3 2 -1. + <_>9 7 1 2 3. + 0 + -1.8605289515107870e-003 + 0.7163379192352295 + 0.4334670901298523 + <_> + + <_> + + + + <_>8 9 4 2 -1. + <_>8 10 4 1 2. + 0 + -9.4026362057775259e-004 + 0.3021360933780670 + 0.5650203227996826 + <_> + + <_> + + + + <_>8 8 4 3 -1. + <_>8 9 4 1 3. + 0 + -5.2418331615626812e-003 + 0.1820009052753449 + 0.5250256061553955 + <_> + + <_> + + + + <_>9 5 6 4 -1. + <_>9 5 3 4 2. + 0 + 1.1729019752237946e-004 + 0.3389188051223755 + 0.5445973277091980 + <_> + + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 1.1878840159624815e-003 + 0.4085349142551422 + 0.6253563165664673 + <_> + + <_> + + + + <_>4 7 12 6 -1. + <_>10 7 6 3 2. + <_>4 10 6 3 2. + 0 + -0.0108813596889377 + 0.3378399014472961 + 0.5700082778930664 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 1.7354859737679362e-003 + 0.4204635918140411 + 0.6523038744926453 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>9 8 3 1 3. + 0 + -6.5119052305817604e-003 + 0.2595216035842896 + 0.5428143739700317 + <_> + + <_> + + + + <_>7 4 3 8 -1. + <_>8 4 1 8 3. + 0 + -1.2136430013924837e-003 + 0.6165143847465515 + 0.3977893888950348 + <_> + + <_> + + + + <_>10 0 3 6 -1. + <_>11 0 1 6 3. + 0 + -0.0103542404249310 + 0.1628028005361557 + 0.5219504833221436 + <_> + + <_> + + + + <_>6 3 4 8 -1. + <_>8 3 2 8 2. + 0 + 5.5858830455690622e-004 + 0.3199650943279266 + 0.5503574013710022 + <_> + + <_> + + + + <_>14 3 6 13 -1. + <_>14 3 3 13 2. + 0 + 0.0152996499091387 + 0.4103994071483612 + 0.6122388243675232 + <_> + + <_> + + + + <_>8 13 3 6 -1. + <_>8 16 3 3 2. + 0 + -0.0215882100164890 + 0.1034912988543510 + 0.5197384953498840 + <_> + + <_> + + + + <_>14 3 6 13 -1. + <_>14 3 3 13 2. + 0 + -0.1283462941646576 + 0.8493865132331848 + 0.4893102943897247 + <_> + + <_> + + + + <_>0 7 10 4 -1. + <_>0 7 5 2 2. + <_>5 9 5 2 2. + 0 + -2.2927189711481333e-003 + 0.3130157887935638 + 0.5471575260162354 + <_> + + <_> + + + + <_>14 3 6 13 -1. + <_>14 3 3 13 2. + 0 + 0.0799151062965393 + 0.4856320917606354 + 0.6073989272117615 + <_> + + <_> + + + + <_>0 3 6 13 -1. + <_>3 3 3 13 2. + 0 + -0.0794410929083824 + 0.8394674062728882 + 0.4624533057212830 + <_> + + <_> + + + + <_>9 1 4 1 -1. + <_>9 1 2 1 2. + 0 + -5.2800010889768600e-003 + 0.1881695985794067 + 0.5306698083877564 + <_> + + <_> + + + + <_>8 0 2 1 -1. + <_>9 0 1 1 2. + 0 + 1.0463109938427806e-003 + 0.5271229147911072 + 0.2583065927028656 + <_> + + <_> + + + + <_>10 16 4 4 -1. + <_>12 16 2 2 2. + <_>10 18 2 2 2. + 0 + 2.6317298761568964e-004 + 0.4235304892063141 + 0.5735440850257874 + <_> + + <_> + + + + <_>9 6 2 3 -1. + <_>10 6 1 3 2. + 0 + -3.6173160187900066e-003 + 0.6934396028518677 + 0.4495444893836975 + <_> + + <_> + + + + <_>4 5 12 2 -1. + <_>8 5 4 2 3. + 0 + 0.0114218797534704 + 0.5900921225547791 + 0.4138193130493164 + <_> + + <_> + + + + <_>8 7 3 5 -1. + <_>9 7 1 5 3. + 0 + -1.9963278900831938e-003 + 0.6466382741928101 + 0.4327239990234375 + 24.5278797149658200 + 6 + -1 + <_> + + + <_> + + <_> + + + + <_>6 4 8 6 -1. + <_>6 6 8 2 3. + 0 + -9.9691245704889297e-003 + 0.6142324209213257 + 0.2482212036848068 + <_> + + <_> + + + + <_>9 5 2 12 -1. + <_>9 11 2 6 2. + 0 + 7.3073059320449829e-004 + 0.5704951882362366 + 0.2321965992450714 + <_> + + <_> + + + + <_>4 6 6 8 -1. + <_>4 10 6 4 2. + 0 + 6.4045301405712962e-004 + 0.2112251967191696 + 0.5814933180809021 + <_> + + <_> + + + + <_>12 2 8 5 -1. + <_>12 2 4 5 2. + 0 + 4.5424019917845726e-003 + 0.2950482070446014 + 0.5866311788558960 + <_> + + <_> + + + + <_>0 8 18 3 -1. + <_>0 9 18 1 3. + 0 + 9.2477443104144186e-005 + 0.2990990877151489 + 0.5791326761245728 + <_> + + <_> + + + + <_>8 12 4 8 -1. + <_>8 16 4 4 2. + 0 + -8.6603146046400070e-003 + 0.2813029885292053 + 0.5635542273521423 + <_> + + <_> + + + + <_>0 2 8 5 -1. + <_>4 2 4 5 2. + 0 + 8.0515816807746887e-003 + 0.3535369038581848 + 0.6054757237434387 + <_> + + <_> + + + + <_>13 11 3 4 -1. + <_>13 13 3 2 2. + 0 + 4.3835240649059415e-004 + 0.5596532225608826 + 0.2731510996818543 + <_> + + <_> + + + + <_>5 11 6 1 -1. + <_>7 11 2 1 3. + 0 + -9.8168973636347800e-005 + 0.5978031754493713 + 0.3638561069965363 + <_> + + <_> + + + + <_>11 3 3 1 -1. + <_>12 3 1 1 3. + 0 + -1.1298790341243148e-003 + 0.2755252122879028 + 0.5432729125022888 + <_> + + <_> + + + + <_>7 13 5 3 -1. + <_>7 14 5 1 3. + 0 + 6.4356150105595589e-003 + 0.4305641949176788 + 0.7069833278656006 + <_> + + <_> + + + + <_>11 11 7 6 -1. + <_>11 14 7 3 2. + 0 + -0.0568293295800686 + 0.2495242953300476 + 0.5294997096061707 + <_> + + <_> + + + + <_>2 11 7 6 -1. + <_>2 14 7 3 2. + 0 + 4.0668169967830181e-003 + 0.5478553175926209 + 0.2497723996639252 + <_> + + <_> + + + + <_>12 14 2 6 -1. + <_>12 16 2 2 3. + 0 + 4.8164798499783501e-005 + 0.3938601016998291 + 0.5706356167793274 + <_> + + <_> + + + + <_>8 14 3 3 -1. + <_>8 15 3 1 3. + 0 + 6.1795017682015896e-003 + 0.4407606124877930 + 0.7394766807556152 + <_> + + <_> + + + + <_>11 0 3 5 -1. + <_>12 0 1 5 3. + 0 + 6.4985752105712891e-003 + 0.5445243120193481 + 0.2479152977466583 + <_> + + <_> + + + + <_>6 1 4 9 -1. + <_>8 1 2 9 2. + 0 + -1.0211090557277203e-003 + 0.2544766962528229 + 0.5338971018791199 + <_> + + <_> + + + + <_>10 3 6 1 -1. + <_>12 3 2 1 3. + 0 + -5.4247528314590454e-003 + 0.2718858122825623 + 0.5324069261550903 + <_> + + <_> + + + + <_>8 8 3 4 -1. + <_>8 10 3 2 2. + 0 + -1.0559899965301156e-003 + 0.3178288042545319 + 0.5534508824348450 + <_> + + <_> + + + + <_>8 12 4 2 -1. + <_>8 13 4 1 2. + 0 + 6.6465808777138591e-004 + 0.4284219145774841 + 0.6558194160461426 + <_> + + <_> + + + + <_>5 18 4 2 -1. + <_>5 19 4 1 2. + 0 + -2.7524109464138746e-004 + 0.5902860760688782 + 0.3810262978076935 + <_> + + <_> + + + + <_>2 1 18 6 -1. + <_>2 3 18 2 3. + 0 + 4.2293202131986618e-003 + 0.3816489875316620 + 0.5709385871887207 + <_> + + <_> + + + + <_>6 0 3 2 -1. + <_>7 0 1 2 3. + 0 + -3.2868210691958666e-003 + 0.1747743934392929 + 0.5259544253349304 + <_> + + <_> + + + + <_>13 8 6 2 -1. + <_>16 8 3 1 2. + <_>13 9 3 1 2. + 0 + 1.5611879643984139e-004 + 0.3601722121238709 + 0.5725612044334412 + <_> + + <_> + + + + <_>6 10 3 6 -1. + <_>6 13 3 3 2. + 0 + -7.3621381488919724e-006 + 0.5401858091354370 + 0.3044497072696686 + <_> + + <_> + + + + <_>0 13 20 4 -1. + <_>10 13 10 2 2. + <_>0 15 10 2 2. + 0 + -0.0147672500461340 + 0.3220770061016083 + 0.5573434829711914 + <_> + + <_> + + + + <_>7 7 6 5 -1. + <_>9 7 2 5 3. + 0 + 0.0244895908981562 + 0.4301528036594391 + 0.6518812775611877 + <_> + + <_> + + + + <_>11 0 2 2 -1. + <_>11 1 2 1 2. + 0 + -3.7652091123163700e-004 + 0.3564583063125610 + 0.5598236918449402 + <_> + + <_> + + + + <_>1 8 6 2 -1. + <_>1 8 3 1 2. + <_>4 9 3 1 2. + 0 + 7.3657688517414499e-006 + 0.3490782976150513 + 0.5561897754669190 + <_> + + <_> + + + + <_>0 2 20 2 -1. + <_>10 2 10 1 2. + <_>0 3 10 1 2. + 0 + -0.0150999398902059 + 0.1776272058486939 + 0.5335299968719482 + <_> + + <_> + + + + <_>7 14 5 3 -1. + <_>7 15 5 1 3. + 0 + -3.8316650316119194e-003 + 0.6149687767028809 + 0.4221394062042236 + <_> + + <_> + + + + <_>7 13 6 6 -1. + <_>10 13 3 3 2. + <_>7 16 3 3 2. + 0 + 0.0169254001230001 + 0.5413014888763428 + 0.2166585028171539 + <_> + + <_> + + + + <_>9 12 2 3 -1. + <_>9 13 2 1 3. + 0 + -3.0477850232273340e-003 + 0.6449490785598755 + 0.4354617893695831 + <_> + + <_> + + + + <_>16 11 1 6 -1. + <_>16 13 1 2 3. + 0 + 3.2140589319169521e-003 + 0.5400155186653137 + 0.3523217141628265 + <_> + + <_> + + + + <_>3 11 1 6 -1. + <_>3 13 1 2 3. + 0 + -4.0023201145231724e-003 + 0.2774524092674255 + 0.5338417291641235 + <_> + + <_> + + + + <_>4 4 14 12 -1. + <_>11 4 7 6 2. + <_>4 10 7 6 2. + 0 + 7.4182129465043545e-003 + 0.5676739215850830 + 0.3702817857265472 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + -8.8764587417244911e-003 + 0.7749221920967102 + 0.4583688974380493 + <_> + + <_> + + + + <_>12 3 3 3 -1. + <_>13 3 1 3 3. + 0 + 2.7311739977449179e-003 + 0.5338721871376038 + 0.3996661007404327 + <_> + + <_> + + + + <_>6 6 8 3 -1. + <_>6 7 8 1 3. + 0 + -2.5082379579544067e-003 + 0.5611963272094727 + 0.3777498900890350 + <_> + + <_> + + + + <_>12 3 3 3 -1. + <_>13 3 1 3 3. + 0 + -8.0541074275970459e-003 + 0.2915228903293610 + 0.5179182887077332 + <_> + + <_> + + + + <_>3 1 4 10 -1. + <_>3 1 2 5 2. + <_>5 6 2 5 2. + 0 + -9.7938813269138336e-004 + 0.5536432862281799 + 0.3700192868709564 + <_> + + <_> + + + + <_>5 7 10 2 -1. + <_>5 7 5 2 2. + 0 + -5.8745909482240677e-003 + 0.3754391074180603 + 0.5679376125335693 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>9 7 1 3 3. + 0 + -4.4936719350516796e-003 + 0.7019699215888977 + 0.4480949938297272 + <_> + + <_> + + + + <_>15 12 2 3 -1. + <_>15 13 2 1 3. + 0 + -5.4389229044318199e-003 + 0.2310364991426468 + 0.5313386917114258 + <_> + + <_> + + + + <_>7 8 3 4 -1. + <_>8 8 1 4 3. + 0 + -7.5094640487805009e-004 + 0.5864868760108948 + 0.4129343032836914 + <_> + + <_> + + + + <_>13 4 1 12 -1. + <_>13 10 1 6 2. + 0 + 1.4528800420521293e-005 + 0.3732407093048096 + 0.5619621276855469 + <_> + + <_> + + + + <_>4 5 12 12 -1. + <_>4 5 6 6 2. + <_>10 11 6 6 2. + 0 + 0.0407580696046352 + 0.5312091112136841 + 0.2720521986484528 + <_> + + <_> + + + + <_>7 14 7 3 -1. + <_>7 15 7 1 3. + 0 + 6.6505931317806244e-003 + 0.4710015952587128 + 0.6693493723869324 + <_> + + <_> + + + + <_>3 12 2 3 -1. + <_>3 13 2 1 3. + 0 + 4.5759351924061775e-003 + 0.5167819261550903 + 0.1637275964021683 + <_> + + <_> + + + + <_>3 2 14 2 -1. + <_>10 2 7 1 2. + <_>3 3 7 1 2. + 0 + 6.5269311890006065e-003 + 0.5397608876228333 + 0.2938531935214996 + <_> + + <_> + + + + <_>0 1 3 10 -1. + <_>1 1 1 10 3. + 0 + -0.0136603796854615 + 0.7086488008499146 + 0.4532200098037720 + <_> + + <_> + + + + <_>9 0 6 5 -1. + <_>11 0 2 5 3. + 0 + 0.0273588690906763 + 0.5206481218338013 + 0.3589231967926025 + <_> + + <_> + + + + <_>5 7 6 2 -1. + <_>8 7 3 2 2. + 0 + 6.2197551596909761e-004 + 0.3507075905799866 + 0.5441123247146606 + <_> + + <_> + + + + <_>7 1 6 10 -1. + <_>7 6 6 5 2. + 0 + -3.3077080734074116e-003 + 0.5859522819519043 + 0.4024891853332520 + <_> + + <_> + + + + <_>1 1 18 3 -1. + <_>7 1 6 3 3. + 0 + -0.0106311095878482 + 0.6743267178535461 + 0.4422602951526642 + <_> + + <_> + + + + <_>16 3 3 6 -1. + <_>16 5 3 2 3. + 0 + 0.0194416493177414 + 0.5282716155052185 + 0.1797904968261719 + 27.1533508300781250 + 7 + -1 + <_> + + + <_> + + <_> + + + + <_>6 3 7 6 -1. + <_>6 6 7 3 2. + 0 + -5.5052167735993862e-003 + 0.5914731025695801 + 0.2626559138298035 + <_> + + <_> + + + + <_>4 7 12 2 -1. + <_>8 7 4 2 3. + 0 + 1.9562279339879751e-003 + 0.2312581986188889 + 0.5741627216339111 + <_> + + <_> + + + + <_>0 4 17 10 -1. + <_>0 9 17 5 2. + 0 + -8.8924784213304520e-003 + 0.1656530052423477 + 0.5626654028892517 + <_> + + <_> + + + + <_>3 4 15 16 -1. + <_>3 12 15 8 2. + 0 + 0.0836383774876595 + 0.5423449873924255 + 0.1957294940948486 + <_> + + <_> + + + + <_>7 15 6 4 -1. + <_>7 17 6 2 2. + 0 + 1.2282270472496748e-003 + 0.3417904078960419 + 0.5992503762245178 + <_> + + <_> + + + + <_>15 2 4 9 -1. + <_>15 2 2 9 2. + 0 + 5.7629169896245003e-003 + 0.3719581961631775 + 0.6079903841018677 + <_> + + <_> + + + + <_>2 3 3 2 -1. + <_>2 4 3 1 2. + 0 + -1.6417410224676132e-003 + 0.2577486038208008 + 0.5576915740966797 + <_> + + <_> + + + + <_>13 6 7 9 -1. + <_>13 9 7 3 3. + 0 + 3.4113149158656597e-003 + 0.2950749099254608 + 0.5514171719551086 + <_> + + <_> + + + + <_>8 11 4 3 -1. + <_>8 12 4 1 3. + 0 + -0.0110693201422691 + 0.7569358944892883 + 0.4477078914642334 + <_> + + <_> + + + + <_>0 2 20 6 -1. + <_>10 2 10 3 2. + <_>0 5 10 3 2. + 0 + 0.0348659716546535 + 0.5583708882331848 + 0.2669621109962463 + <_> + + <_> + + + + <_>3 2 6 10 -1. + <_>3 2 3 5 2. + <_>6 7 3 5 2. + 0 + 6.5701099811121821e-004 + 0.5627313256263733 + 0.2988890111446381 + <_> + + <_> + + + + <_>13 10 3 4 -1. + <_>13 12 3 2 2. + 0 + -0.0243391301482916 + 0.2771185040473938 + 0.5108863115310669 + <_> + + <_> + + + + <_>4 10 3 4 -1. + <_>4 12 3 2 2. + 0 + 5.9435202274471521e-004 + 0.5580651760101318 + 0.3120341897010803 + <_> + + <_> + + + + <_>7 5 6 3 -1. + <_>9 5 2 3 3. + 0 + 2.2971509024500847e-003 + 0.3330250084400177 + 0.5679075717926025 + <_> + + <_> + + + + <_>7 6 6 8 -1. + <_>7 10 6 4 2. + 0 + -3.7801829166710377e-003 + 0.2990534901618958 + 0.5344808101654053 + <_> + + <_> + + + + <_>0 11 20 6 -1. + <_>0 14 20 3 2. + 0 + -0.1342066973447800 + 0.1463858932256699 + 0.5392568111419678 + <_> + + <_> + + + + <_>4 13 4 6 -1. + <_>4 13 2 3 2. + <_>6 16 2 3 2. + 0 + 7.5224548345431685e-004 + 0.3746953904628754 + 0.5692734718322754 + <_> + + <_> + + + + <_>6 0 8 12 -1. + <_>10 0 4 6 2. + <_>6 6 4 6 2. + 0 + -0.0405455417931080 + 0.2754747867584229 + 0.5484297871589661 + <_> + + <_> + + + + <_>2 0 15 2 -1. + <_>2 1 15 1 2. + 0 + 1.2572970008477569e-003 + 0.3744584023952484 + 0.5756075978279114 + <_> + + <_> + + + + <_>9 12 2 3 -1. + <_>9 13 2 1 3. + 0 + -7.4249948374927044e-003 + 0.7513859272003174 + 0.4728231132030487 + <_> + + <_> + + + + <_>3 12 1 2 -1. + <_>3 13 1 1 2. + 0 + 5.0908129196614027e-004 + 0.5404896736145020 + 0.2932321131229401 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -1.2808450264856219e-003 + 0.6169779896736145 + 0.4273349046707153 + <_> + + <_> + + + + <_>7 3 3 1 -1. + <_>8 3 1 1 3. + 0 + -1.8348860321566463e-003 + 0.2048496007919312 + 0.5206472277641296 + <_> + + <_> + + + + <_>17 7 3 6 -1. + <_>17 9 3 2 3. + 0 + 0.0274848695844412 + 0.5252984762191773 + 0.1675522029399872 + <_> + + <_> + + + + <_>7 2 3 2 -1. + <_>8 2 1 2 3. + 0 + 2.2372419480234385e-003 + 0.5267782807350159 + 0.2777658104896545 + <_> + + <_> + + + + <_>11 4 5 3 -1. + <_>11 5 5 1 3. + 0 + -8.8635291904211044e-003 + 0.6954557895660400 + 0.4812048971652985 + <_> + + <_> + + + + <_>4 4 5 3 -1. + <_>4 5 5 1 3. + 0 + 4.1753971017897129e-003 + 0.4291887879371643 + 0.6349195837974548 + <_> + + <_> + + + + <_>19 3 1 2 -1. + <_>19 4 1 1 2. + 0 + -1.7098189564421773e-003 + 0.2930536866188049 + 0.5361248850822449 + <_> + + <_> + + + + <_>5 5 4 3 -1. + <_>5 6 4 1 3. + 0 + 6.5328548662364483e-003 + 0.4495325088500977 + 0.7409694194793701 + <_> + + <_> + + + + <_>17 7 3 6 -1. + <_>17 9 3 2 3. + 0 + -9.5372907817363739e-003 + 0.3149119913578033 + 0.5416501760482788 + <_> + + <_> + + + + <_>0 7 3 6 -1. + <_>0 9 3 2 3. + 0 + 0.0253109894692898 + 0.5121892094612122 + 0.1311707943677902 + <_> + + <_> + + + + <_>14 2 6 9 -1. + <_>14 5 6 3 3. + 0 + 0.0364609695971012 + 0.5175911784172058 + 0.2591339945793152 + <_> + + <_> + + + + <_>0 4 5 6 -1. + <_>0 6 5 2 3. + 0 + 0.0208543296903372 + 0.5137140154838562 + 0.1582316011190414 + <_> + + <_> + + + + <_>10 5 6 2 -1. + <_>12 5 2 2 3. + 0 + -8.7207747856155038e-004 + 0.5574309825897217 + 0.4398978948593140 + <_> + + <_> + + + + <_>4 5 6 2 -1. + <_>6 5 2 2 3. + 0 + -1.5227000403683633e-005 + 0.5548940896987915 + 0.3708069920539856 + <_> + + <_> + + + + <_>8 1 4 6 -1. + <_>8 3 4 2 3. + 0 + -8.4316509310156107e-004 + 0.3387419879436493 + 0.5554211139678955 + <_> + + <_> + + + + <_>0 2 3 6 -1. + <_>0 4 3 2 3. + 0 + 3.6037859972566366e-003 + 0.5358061790466309 + 0.3411171138286591 + <_> + + <_> + + + + <_>6 6 8 3 -1. + <_>6 7 8 1 3. + 0 + -6.8057891912758350e-003 + 0.6125202775001526 + 0.4345862865447998 + <_> + + <_> + + + + <_>0 1 5 9 -1. + <_>0 4 5 3 3. + 0 + -0.0470216609537601 + 0.2358165979385376 + 0.5193738937377930 + <_> + + <_> + + + + <_>16 0 4 15 -1. + <_>16 0 2 15 2. + 0 + -0.0369541086256504 + 0.7323111295700073 + 0.4760943949222565 + <_> + + <_> + + + + <_>1 10 3 2 -1. + <_>1 11 3 1 2. + 0 + 1.0439479956403375e-003 + 0.5419455170631409 + 0.3411330878734589 + <_> + + <_> + + + + <_>14 4 1 10 -1. + <_>14 9 1 5 2. + 0 + -2.1050689974799752e-004 + 0.2821694016456604 + 0.5554947257041931 + <_> + + <_> + + + + <_>0 1 4 12 -1. + <_>2 1 2 12 2. + 0 + -0.0808315873146057 + 0.9129930138587952 + 0.4697434902191162 + <_> + + <_> + + + + <_>11 11 4 2 -1. + <_>11 11 2 2 2. + 0 + -3.6579059087671340e-004 + 0.6022670269012451 + 0.3978292942047119 + <_> + + <_> + + + + <_>5 11 4 2 -1. + <_>7 11 2 2 2. + 0 + -1.2545920617412776e-004 + 0.5613213181495667 + 0.3845539987087250 + <_> + + <_> + + + + <_>3 8 15 5 -1. + <_>8 8 5 5 3. + 0 + -0.0687864869832993 + 0.2261611968278885 + 0.5300496816635132 + <_> + + <_> + + + + <_>0 0 6 10 -1. + <_>3 0 3 10 2. + 0 + 0.0124157899990678 + 0.4075691998004913 + 0.5828812122344971 + <_> + + <_> + + + + <_>11 4 3 2 -1. + <_>12 4 1 2 3. + 0 + -4.7174817882478237e-003 + 0.2827253937721252 + 0.5267757773399353 + <_> + + <_> + + + + <_>8 12 3 8 -1. + <_>8 16 3 4 2. + 0 + 0.0381368584930897 + 0.5074741244316101 + 0.1023615971207619 + <_> + + <_> + + + + <_>8 14 5 3 -1. + <_>8 15 5 1 3. + 0 + -2.8168049175292253e-003 + 0.6169006824493408 + 0.4359692931175232 + <_> + + <_> + + + + <_>7 14 4 3 -1. + <_>7 15 4 1 3. + 0 + 8.1303603947162628e-003 + 0.4524433016777039 + 0.7606095075607300 + <_> + + <_> + + + + <_>11 4 3 2 -1. + <_>12 4 1 2 3. + 0 + 6.0056019574403763e-003 + 0.5240408778190613 + 0.1859712004661560 + <_> + + <_> + + + + <_>3 15 14 4 -1. + <_>3 15 7 2 2. + <_>10 17 7 2 2. + 0 + 0.0191393196582794 + 0.5209379196166992 + 0.2332071959972382 + <_> + + <_> + + + + <_>2 2 16 4 -1. + <_>10 2 8 2 2. + <_>2 4 8 2 2. + 0 + 0.0164457596838474 + 0.5450702905654907 + 0.3264234960079193 + <_> + + <_> + + + + <_>0 8 6 12 -1. + <_>3 8 3 12 2. + 0 + -0.0373568907380104 + 0.6999046802520752 + 0.4533241987228394 + <_> + + <_> + + + + <_>5 7 10 2 -1. + <_>5 7 5 2 2. + 0 + -0.0197279006242752 + 0.2653664946556091 + 0.5412809848785400 + <_> + + <_> + + + + <_>9 7 2 5 -1. + <_>10 7 1 5 2. + 0 + 6.6972579807043076e-003 + 0.4480566084384918 + 0.7138652205467224 + <_> + + <_> + + + + <_>13 7 6 4 -1. + <_>16 7 3 2 2. + <_>13 9 3 2 2. + 0 + 7.4457528535276651e-004 + 0.4231350123882294 + 0.5471320152282715 + <_> + + <_> + + + + <_>0 13 8 2 -1. + <_>0 14 8 1 2. + 0 + 1.1790640419349074e-003 + 0.5341702103614807 + 0.3130455017089844 + <_> + + <_> + + + + <_>13 7 6 4 -1. + <_>16 7 3 2 2. + <_>13 9 3 2 2. + 0 + 0.0349806100130081 + 0.5118659734725952 + 0.3430530130863190 + <_> + + <_> + + + + <_>1 7 6 4 -1. + <_>1 7 3 2 2. + <_>4 9 3 2 2. + 0 + 5.6859792675822973e-004 + 0.3532187044620514 + 0.5468639731407166 + <_> + + <_> + + + + <_>12 6 1 12 -1. + <_>12 12 1 6 2. + 0 + -0.0113406497985125 + 0.2842353880405426 + 0.5348700881004334 + <_> + + <_> + + + + <_>9 5 2 6 -1. + <_>10 5 1 6 2. + 0 + -6.6228108480572701e-003 + 0.6883640289306641 + 0.4492664933204651 + <_> + + <_> + + + + <_>14 12 2 3 -1. + <_>14 13 2 1 3. + 0 + -8.0160330981016159e-003 + 0.1709893941879273 + 0.5224308967590332 + <_> + + <_> + + + + <_>4 12 2 3 -1. + <_>4 13 2 1 3. + 0 + 1.4206819469109178e-003 + 0.5290846228599548 + 0.2993383109569550 + <_> + + <_> + + + + <_>8 12 4 3 -1. + <_>8 13 4 1 3. + 0 + -2.7801711112260818e-003 + 0.6498854160308838 + 0.4460499882698059 + <_> + + <_> + + + + <_>5 2 2 4 -1. + <_>5 2 1 2 2. + <_>6 4 1 2 2. + 0 + -1.4747589593753219e-003 + 0.3260438144207001 + 0.5388113260269165 + <_> + + <_> + + + + <_>5 5 11 3 -1. + <_>5 6 11 1 3. + 0 + -0.0238303393125534 + 0.7528941035270691 + 0.4801219999790192 + <_> + + <_> + + + + <_>7 6 4 12 -1. + <_>7 12 4 6 2. + 0 + 6.9369790144264698e-003 + 0.5335165858268738 + 0.3261427879333496 + <_> + + <_> + + + + <_>12 13 8 5 -1. + <_>12 13 4 5 2. + 0 + 8.2806255668401718e-003 + 0.4580394029617310 + 0.5737829804420471 + <_> + + <_> + + + + <_>7 6 1 12 -1. + <_>7 12 1 6 2. + 0 + -0.0104395002126694 + 0.2592320144176483 + 0.5233827829360962 + 34.5541114807128910 + 8 + -1 + <_> + + + <_> + + <_> + + + + <_>1 2 6 3 -1. + <_>4 2 3 3 2. + 0 + 7.2006587870419025e-003 + 0.3258886039257050 + 0.6849808096885681 + <_> + + <_> + + + + <_>9 5 6 10 -1. + <_>12 5 3 5 2. + <_>9 10 3 5 2. + 0 + -2.8593589086085558e-003 + 0.5838881134986877 + 0.2537829875946045 + <_> + + <_> + + + + <_>5 5 8 12 -1. + <_>5 5 4 6 2. + <_>9 11 4 6 2. + 0 + 6.8580528022721410e-004 + 0.5708081722259522 + 0.2812424004077911 + <_> + + <_> + + + + <_>0 7 20 6 -1. + <_>0 9 20 2 3. + 0 + 7.9580191522836685e-003 + 0.2501051127910614 + 0.5544260740280151 + <_> + + <_> + + + + <_>4 2 2 2 -1. + <_>4 3 2 1 2. + 0 + -1.2124150525778532e-003 + 0.2385368049144745 + 0.5433350205421448 + <_> + + <_> + + + + <_>4 18 12 2 -1. + <_>8 18 4 2 3. + 0 + 7.9426132142543793e-003 + 0.3955070972442627 + 0.6220757961273193 + <_> + + <_> + + + + <_>7 4 4 16 -1. + <_>7 12 4 8 2. + 0 + 2.4630590341985226e-003 + 0.5639708042144775 + 0.2992357909679413 + <_> + + <_> + + + + <_>7 6 7 8 -1. + <_>7 10 7 4 2. + 0 + -6.0396599583327770e-003 + 0.2186512947082520 + 0.5411676764488220 + <_> + + <_> + + + + <_>6 3 3 1 -1. + <_>7 3 1 1 3. + 0 + -1.2988339876756072e-003 + 0.2350706011056900 + 0.5364584922790527 + <_> + + <_> + + + + <_>11 15 2 4 -1. + <_>11 17 2 2 2. + 0 + 2.2299369447864592e-004 + 0.3804112970829010 + 0.5729606151580811 + <_> + + <_> + + + + <_>3 5 4 8 -1. + <_>3 9 4 4 2. + 0 + 1.4654280385002494e-003 + 0.2510167956352234 + 0.5258268713951111 + <_> + + <_> + + + + <_>7 1 6 12 -1. + <_>7 7 6 6 2. + 0 + -8.1210042117163539e-004 + 0.5992823839187622 + 0.3851158916950226 + <_> + + <_> + + + + <_>4 6 6 2 -1. + <_>6 6 2 2 3. + 0 + -1.3836020370945334e-003 + 0.5681396126747131 + 0.3636586964130402 + <_> + + <_> + + + + <_>16 4 4 6 -1. + <_>16 6 4 2 3. + 0 + -0.0279364492744207 + 0.1491317003965378 + 0.5377560257911682 + <_> + + <_> + + + + <_>3 3 5 2 -1. + <_>3 4 5 1 2. + 0 + -4.6919551095925272e-004 + 0.3692429959774017 + 0.5572484731674194 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -4.9829659983515739e-003 + 0.6758509278297424 + 0.4532504081726074 + <_> + + <_> + + + + <_>2 16 4 2 -1. + <_>2 17 4 1 2. + 0 + 1.8815309740602970e-003 + 0.5368022918701172 + 0.2932539880275726 + <_> + + <_> + + + + <_>7 13 6 6 -1. + <_>10 13 3 3 2. + <_>7 16 3 3 2. + 0 + -0.0190675500780344 + 0.1649377048015595 + 0.5330067276954651 + <_> + + <_> + + + + <_>7 0 3 4 -1. + <_>8 0 1 4 3. + 0 + -4.6906559728085995e-003 + 0.1963925957679749 + 0.5119361877441406 + <_> + + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + 5.9777139686048031e-003 + 0.4671171903610230 + 0.7008398175239563 + <_> + + <_> + + + + <_>0 4 4 6 -1. + <_>0 6 4 2 3. + 0 + -0.0333031304180622 + 0.1155416965484619 + 0.5104162096977234 + <_> + + <_> + + + + <_>5 6 12 3 -1. + <_>9 6 4 3 3. + 0 + 0.0907441079616547 + 0.5149660110473633 + 0.1306173056364059 + <_> + + <_> + + + + <_>7 6 6 14 -1. + <_>9 6 2 14 3. + 0 + 9.3555898638442159e-004 + 0.3605481088161469 + 0.5439859032630920 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + 0.0149016501381993 + 0.4886212050914764 + 0.7687569856643677 + <_> + + <_> + + + + <_>6 12 2 4 -1. + <_>6 14 2 2 2. + 0 + 6.1594118596985936e-004 + 0.5356813073158264 + 0.3240939080715179 + <_> + + <_> + + + + <_>10 12 7 6 -1. + <_>10 14 7 2 3. + 0 + -0.0506709888577461 + 0.1848621964454651 + 0.5230404138565064 + <_> + + <_> + + + + <_>1 0 15 2 -1. + <_>1 1 15 1 2. + 0 + 6.8665749859064817e-004 + 0.3840579986572266 + 0.5517945885658264 + <_> + + <_> + + + + <_>14 0 6 6 -1. + <_>14 0 3 6 2. + 0 + 8.3712432533502579e-003 + 0.4288564026355743 + 0.6131753921508789 + <_> + + <_> + + + + <_>5 3 3 1 -1. + <_>6 3 1 1 3. + 0 + -1.2953069526702166e-003 + 0.2913674116134644 + 0.5280737876892090 + <_> + + <_> + + + + <_>14 0 6 6 -1. + <_>14 0 3 6 2. + 0 + -0.0419416800141335 + 0.7554799914360046 + 0.4856030941009522 + <_> + + <_> + + + + <_>0 3 20 10 -1. + <_>0 8 20 5 2. + 0 + -0.0235293805599213 + 0.2838279902935028 + 0.5256081223487854 + <_> + + <_> + + + + <_>14 0 6 6 -1. + <_>14 0 3 6 2. + 0 + 0.0408574491739273 + 0.4870935082435608 + 0.6277297139167786 + <_> + + <_> + + + + <_>0 0 6 6 -1. + <_>3 0 3 6 2. + 0 + -0.0254068691283464 + 0.7099707722663879 + 0.4575029015541077 + <_> + + <_> + + + + <_>19 15 1 2 -1. + <_>19 16 1 1 2. + 0 + -4.1415440500713885e-004 + 0.4030886888504028 + 0.5469412207603455 + <_> + + <_> + + + + <_>0 2 4 8 -1. + <_>2 2 2 8 2. + 0 + 0.0218241196125746 + 0.4502024054527283 + 0.6768701076507568 + <_> + + <_> + + + + <_>2 1 18 4 -1. + <_>11 1 9 2 2. + <_>2 3 9 2 2. + 0 + 0.0141140399500728 + 0.5442860722541809 + 0.3791700005531311 + <_> + + <_> + + + + <_>8 12 1 2 -1. + <_>8 13 1 1 2. + 0 + 6.7214590671937913e-005 + 0.4200463891029358 + 0.5873476266860962 + <_> + + <_> + + + + <_>5 2 10 6 -1. + <_>10 2 5 3 2. + <_>5 5 5 3 2. + 0 + -7.9417638480663300e-003 + 0.3792561888694763 + 0.5585265755653381 + <_> + + <_> + + + + <_>9 7 2 4 -1. + <_>10 7 1 4 2. + 0 + -7.2144409641623497e-003 + 0.7253103852272034 + 0.4603548943996429 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + 2.5817339774221182e-003 + 0.4693301916122437 + 0.5900238752365112 + <_> + + <_> + + + + <_>4 5 12 8 -1. + <_>8 5 4 8 3. + 0 + 0.1340931951999664 + 0.5149213075637817 + 0.1808844953775406 + <_> + + <_> + + + + <_>15 15 4 3 -1. + <_>15 16 4 1 3. + 0 + 2.2962710354477167e-003 + 0.5399743914604187 + 0.3717867136001587 + <_> + + <_> + + + + <_>8 18 3 1 -1. + <_>9 18 1 1 3. + 0 + -2.1575849968940020e-003 + 0.2408495992422104 + 0.5148863792419434 + <_> + + <_> + + + + <_>9 13 4 3 -1. + <_>9 14 4 1 3. + 0 + -4.9196188338100910e-003 + 0.6573588252067566 + 0.4738740026950836 + <_> + + <_> + + + + <_>7 13 4 3 -1. + <_>7 14 4 1 3. + 0 + 1.6267469618469477e-003 + 0.4192821979522705 + 0.6303114295005798 + <_> + + <_> + + + + <_>19 15 1 2 -1. + <_>19 16 1 1 2. + 0 + 3.3413388882763684e-004 + 0.5540298223495483 + 0.3702101111412048 + <_> + + <_> + + + + <_>0 15 8 4 -1. + <_>0 17 8 2 2. + 0 + -0.0266980808228254 + 0.1710917949676514 + 0.5101410746574402 + <_> + + <_> + + + + <_>9 3 6 4 -1. + <_>11 3 2 4 3. + 0 + -0.0305618792772293 + 0.1904218047857285 + 0.5168793797492981 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 2.8511548880487680e-003 + 0.4447506964206696 + 0.6313853859901428 + <_> + + <_> + + + + <_>3 14 14 6 -1. + <_>3 16 14 2 3. + 0 + -0.0362114794552326 + 0.2490727007389069 + 0.5377349257469177 + <_> + + <_> + + + + <_>6 3 6 6 -1. + <_>6 6 6 3 2. + 0 + -2.4115189444273710e-003 + 0.5381243228912354 + 0.3664236962795258 + <_> + + <_> + + + + <_>5 11 10 6 -1. + <_>5 14 10 3 2. + 0 + -7.7253201743587852e-004 + 0.5530232191085815 + 0.3541550040245056 + <_> + + <_> + + + + <_>3 10 3 4 -1. + <_>4 10 1 4 3. + 0 + 2.9481729143299162e-004 + 0.4132699072360992 + 0.5667243003845215 + <_> + + <_> + + + + <_>13 9 2 2 -1. + <_>13 9 1 2 2. + 0 + -6.2334560789167881e-003 + 0.0987872332334518 + 0.5198668837547302 + <_> + + <_> + + + + <_>5 3 6 4 -1. + <_>7 3 2 4 3. + 0 + -0.0262747295200825 + 0.0911274924874306 + 0.5028107166290283 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + 5.3212260827422142e-003 + 0.4726648926734924 + 0.6222720742225647 + <_> + + <_> + + + + <_>2 12 2 3 -1. + <_>2 13 2 1 3. + 0 + -4.1129058226943016e-003 + 0.2157457023859024 + 0.5137804746627808 + <_> + + <_> + + + + <_>9 8 3 12 -1. + <_>9 12 3 4 3. + 0 + 3.2457809429615736e-003 + 0.5410770773887634 + 0.3721776902675629 + <_> + + <_> + + + + <_>3 14 4 6 -1. + <_>3 14 2 3 2. + <_>5 17 2 3 2. + 0 + -0.0163597092032433 + 0.7787874937057495 + 0.4685291945934296 + <_> + + <_> + + + + <_>16 15 2 2 -1. + <_>16 16 2 1 2. + 0 + 3.2166109303943813e-004 + 0.5478987097740173 + 0.4240373969078064 + <_> + + <_> + + + + <_>2 15 2 2 -1. + <_>2 16 2 1 2. + 0 + 6.4452440710738301e-004 + 0.5330560803413391 + 0.3501324951648712 + <_> + + <_> + + + + <_>8 12 4 3 -1. + <_>8 13 4 1 3. + 0 + -7.8909732401371002e-003 + 0.6923521161079407 + 0.4726569056510925 + <_> + + <_> + + + + <_>0 7 20 1 -1. + <_>10 7 10 1 2. + 0 + 0.0483362115919590 + 0.5055900216102600 + 0.0757492035627365 + <_> + + <_> + + + + <_>7 6 8 3 -1. + <_>7 6 4 3 2. + 0 + -7.5178127735853195e-004 + 0.3783741891384125 + 0.5538573861122131 + <_> + + <_> + + + + <_>5 7 8 2 -1. + <_>9 7 4 2 2. + 0 + -2.4953910615295172e-003 + 0.3081651031970978 + 0.5359612107276917 + <_> + + <_> + + + + <_>9 7 3 5 -1. + <_>10 7 1 5 3. + 0 + -2.2385010961443186e-003 + 0.6633958816528320 + 0.4649342894554138 + <_> + + <_> + + + + <_>8 7 3 5 -1. + <_>9 7 1 5 3. + 0 + -1.7988430336117744e-003 + 0.6596844792366028 + 0.4347187876701355 + <_> + + <_> + + + + <_>11 1 3 5 -1. + <_>12 1 1 5 3. + 0 + 8.7860915809869766e-003 + 0.5231832861900330 + 0.2315579950809479 + <_> + + <_> + + + + <_>6 2 3 6 -1. + <_>7 2 1 6 3. + 0 + 3.6715380847454071e-003 + 0.5204250216484070 + 0.2977376878261566 + <_> + + <_> + + + + <_>14 14 6 5 -1. + <_>14 14 3 5 2. + 0 + -0.0353364497423172 + 0.7238878011703491 + 0.4861505031585693 + <_> + + <_> + + + + <_>9 8 2 2 -1. + <_>9 9 2 1 2. + 0 + -6.9189240457490087e-004 + 0.3105022013187408 + 0.5229824781417847 + <_> + + <_> + + + + <_>10 7 1 3 -1. + <_>10 8 1 1 3. + 0 + -3.3946109469980001e-003 + 0.3138968050479889 + 0.5210173726081848 + <_> + + <_> + + + + <_>6 6 2 2 -1. + <_>6 6 1 1 2. + <_>7 7 1 1 2. + 0 + 9.8569283727556467e-004 + 0.4536580145359039 + 0.6585097908973694 + <_> + + <_> + + + + <_>2 11 18 4 -1. + <_>11 11 9 2 2. + <_>2 13 9 2 2. + 0 + -0.0501631014049053 + 0.1804454028606415 + 0.5198916792869568 + <_> + + <_> + + + + <_>6 6 2 2 -1. + <_>6 6 1 1 2. + <_>7 7 1 1 2. + 0 + -2.2367259953171015e-003 + 0.7255702018737793 + 0.4651359021663666 + <_> + + <_> + + + + <_>0 15 20 2 -1. + <_>0 16 20 1 2. + 0 + 7.4326287722215056e-004 + 0.4412921071052551 + 0.5898545980453491 + <_> + + <_> + + + + <_>4 14 2 3 -1. + <_>4 15 2 1 3. + 0 + -9.3485182151198387e-004 + 0.3500052988529205 + 0.5366017818450928 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 0.0174979399889708 + 0.4912194907665253 + 0.8315284848213196 + <_> + + <_> + + + + <_>8 7 2 3 -1. + <_>8 8 2 1 3. + 0 + -1.5200000489130616e-003 + 0.3570275902748108 + 0.5370560288429260 + <_> + + <_> + + + + <_>9 10 2 3 -1. + <_>9 11 2 1 3. + 0 + 7.8003940870985389e-004 + 0.4353772103786469 + 0.5967335104942322 + 39.1072883605957030 + 9 + -1 + <_> + + + <_> + + <_> + + + + <_>5 4 10 4 -1. + <_>5 6 10 2 2. + 0 + -9.9945552647113800e-003 + 0.6162583231925964 + 0.3054533004760742 + <_> + + <_> + + + + <_>9 7 6 4 -1. + <_>12 7 3 2 2. + <_>9 9 3 2 2. + 0 + -1.1085229925811291e-003 + 0.5818294882774353 + 0.3155578076839447 + <_> + + <_> + + + + <_>4 7 3 6 -1. + <_>4 9 3 2 3. + 0 + 1.0364380432292819e-003 + 0.2552052140235901 + 0.5692911744117737 + <_> + + <_> + + + + <_>11 15 4 4 -1. + <_>13 15 2 2 2. + <_>11 17 2 2 2. + 0 + 6.8211311008781195e-004 + 0.3685089945793152 + 0.5934931039810181 + <_> + + <_> + + + + <_>7 8 4 2 -1. + <_>7 9 4 1 2. + 0 + -6.8057340104132891e-004 + 0.2332392036914825 + 0.5474792122840881 + <_> + + <_> + + + + <_>13 1 4 3 -1. + <_>13 1 2 3 2. + 0 + 2.6068789884448051e-004 + 0.3257457017898560 + 0.5667545795440674 + <_> + + <_> + + + + <_>5 15 4 4 -1. + <_>5 15 2 2 2. + <_>7 17 2 2 2. + 0 + 5.1607372006401420e-004 + 0.3744716942310333 + 0.5845472812652588 + <_> + + <_> + + + + <_>9 5 4 7 -1. + <_>9 5 2 7 2. + 0 + 8.5007521556690335e-004 + 0.3420371115207672 + 0.5522807240486145 + <_> + + <_> + + + + <_>5 6 8 3 -1. + <_>9 6 4 3 2. + 0 + -1.8607829697430134e-003 + 0.2804419994354248 + 0.5375424027442932 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -1.5033970121294260e-003 + 0.2579050958156586 + 0.5498952269554138 + <_> + + <_> + + + + <_>7 15 5 3 -1. + <_>7 16 5 1 3. + 0 + 2.3478909861296415e-003 + 0.4175156056880951 + 0.6313710808753967 + <_> + + <_> + + + + <_>11 10 4 3 -1. + <_>11 10 2 3 2. + 0 + -2.8880240279249847e-004 + 0.5865169763565064 + 0.4052666127681732 + <_> + + <_> + + + + <_>6 9 8 10 -1. + <_>6 14 8 5 2. + 0 + 8.9405477046966553e-003 + 0.5211141109466553 + 0.2318654060363770 + <_> + + <_> + + + + <_>10 11 6 2 -1. + <_>10 11 3 2 2. + 0 + -0.0193277392536402 + 0.2753432989120483 + 0.5241525769233704 + <_> + + <_> + + + + <_>4 11 6 2 -1. + <_>7 11 3 2 2. + 0 + -2.0202060113660991e-004 + 0.5722978711128235 + 0.3677195906639099 + <_> + + <_> + + + + <_>11 3 8 1 -1. + <_>11 3 4 1 2. + 0 + 2.1179069299250841e-003 + 0.4466108083724976 + 0.5542430877685547 + <_> + + <_> + + + + <_>6 3 3 2 -1. + <_>7 3 1 2 3. + 0 + -1.7743760254234076e-003 + 0.2813253104686737 + 0.5300959944725037 + <_> + + <_> + + + + <_>14 5 6 5 -1. + <_>14 5 3 5 2. + 0 + 4.2234458960592747e-003 + 0.4399709999561310 + 0.5795428156852722 + <_> + + <_> + + + + <_>7 5 2 12 -1. + <_>7 11 2 6 2. + 0 + -0.0143752200528979 + 0.2981117963790894 + 0.5292059183120728 + <_> + + <_> + + + + <_>8 11 4 3 -1. + <_>8 12 4 1 3. + 0 + -0.0153491804376245 + 0.7705215215682983 + 0.4748171865940094 + <_> + + <_> + + + + <_>4 1 2 3 -1. + <_>5 1 1 3 2. + 0 + 1.5152279956964776e-005 + 0.3718844056129456 + 0.5576897263526917 + <_> + + <_> + + + + <_>18 3 2 6 -1. + <_>18 5 2 2 3. + 0 + -9.1293919831514359e-003 + 0.3615196049213409 + 0.5286766886711121 + <_> + + <_> + + + + <_>0 3 2 6 -1. + <_>0 5 2 2 3. + 0 + 2.2512159775942564e-003 + 0.5364704728126526 + 0.3486298024654388 + <_> + + <_> + + + + <_>9 12 2 3 -1. + <_>9 13 2 1 3. + 0 + -4.9696918576955795e-003 + 0.6927651762962341 + 0.4676836133003235 + <_> + + <_> + + + + <_>7 13 4 3 -1. + <_>7 14 4 1 3. + 0 + -0.0128290103748441 + 0.7712153792381287 + 0.4660735130310059 + <_> + + <_> + + + + <_>18 0 2 6 -1. + <_>18 2 2 2 3. + 0 + -9.3660065904259682e-003 + 0.3374983966350555 + 0.5351287722587585 + <_> + + <_> + + + + <_>0 0 2 6 -1. + <_>0 2 2 2 3. + 0 + 3.2452319283038378e-003 + 0.5325189828872681 + 0.3289610147476196 + <_> + + <_> + + + + <_>8 14 6 3 -1. + <_>8 15 6 1 3. + 0 + -0.0117235602810979 + 0.6837652921676636 + 0.4754300117492676 + <_> + + <_> + + + + <_>7 4 2 4 -1. + <_>8 4 1 4 2. + 0 + 2.9257940695970319e-005 + 0.3572087883949280 + 0.5360502004623413 + <_> + + <_> + + + + <_>8 5 4 6 -1. + <_>8 7 4 2 3. + 0 + -2.2244219508138485e-005 + 0.5541427135467529 + 0.3552064001560211 + <_> + + <_> + + + + <_>6 4 2 2 -1. + <_>7 4 1 2 2. + 0 + 5.0881509669125080e-003 + 0.5070844292640686 + 0.1256462037563324 + <_> + + <_> + + + + <_>3 14 14 4 -1. + <_>10 14 7 2 2. + <_>3 16 7 2 2. + 0 + 0.0274296794086695 + 0.5269560217857361 + 0.1625818014144898 + <_> + + <_> + + + + <_>6 15 6 2 -1. + <_>6 15 3 1 2. + <_>9 16 3 1 2. + 0 + -6.4142867922782898e-003 + 0.7145588994026184 + 0.4584197103977203 + <_> + + <_> + + + + <_>14 15 6 2 -1. + <_>14 16 6 1 2. + 0 + 3.3479959238320589e-003 + 0.5398612022399902 + 0.3494696915149689 + <_> + + <_> + + + + <_>2 12 12 8 -1. + <_>2 16 12 4 2. + 0 + -0.0826354920864105 + 0.2439192980527878 + 0.5160226225852966 + <_> + + <_> + + + + <_>7 7 7 2 -1. + <_>7 8 7 1 2. + 0 + 1.0261740535497665e-003 + 0.3886891901493073 + 0.5767908096313477 + <_> + + <_> + + + + <_>0 2 18 2 -1. + <_>0 3 18 1 2. + 0 + -1.6307090409100056e-003 + 0.3389458060264587 + 0.5347700715065002 + <_> + + <_> + + + + <_>9 6 2 5 -1. + <_>9 6 1 5 2. + 0 + 2.4546680506318808e-003 + 0.4601413905620575 + 0.6387246847152710 + <_> + + <_> + + + + <_>7 5 3 8 -1. + <_>8 5 1 8 3. + 0 + -9.9476519972085953e-004 + 0.5769879221916199 + 0.4120396077632904 + <_> + + <_> + + + + <_>9 6 3 4 -1. + <_>10 6 1 4 3. + 0 + 0.0154091902077198 + 0.4878709018230438 + 0.7089822292327881 + <_> + + <_> + + + + <_>4 13 3 2 -1. + <_>4 14 3 1 2. + 0 + 1.1784400558099151e-003 + 0.5263553261756897 + 0.2895244956016541 + <_> + + <_> + + + + <_>9 4 6 3 -1. + <_>11 4 2 3 3. + 0 + -0.0277019198983908 + 0.1498828977346420 + 0.5219606757164002 + <_> + + <_> + + + + <_>5 4 6 3 -1. + <_>7 4 2 3 3. + 0 + -0.0295053999871016 + 0.0248933192342520 + 0.4999816119670868 + <_> + + <_> + + + + <_>14 11 5 2 -1. + <_>14 12 5 1 2. + 0 + 4.5159430010244250e-004 + 0.5464622974395752 + 0.4029662907123566 + <_> + + <_> + + + + <_>1 2 6 9 -1. + <_>3 2 2 9 3. + 0 + 7.1772639639675617e-003 + 0.4271056950092316 + 0.5866296887397766 + <_> + + <_> + + + + <_>14 6 6 13 -1. + <_>14 6 3 13 2. + 0 + -0.0741820484399796 + 0.6874179244041443 + 0.4919027984142304 + <_> + + <_> + + + + <_>3 6 14 8 -1. + <_>3 6 7 4 2. + <_>10 10 7 4 2. + 0 + -0.0172541607171297 + 0.3370676040649414 + 0.5348739027976990 + <_> + + <_> + + + + <_>16 0 4 11 -1. + <_>16 0 2 11 2. + 0 + 0.0148515598848462 + 0.4626792967319489 + 0.6129904985427856 + <_> + + <_> + + + + <_>3 4 12 12 -1. + <_>3 4 6 6 2. + <_>9 10 6 6 2. + 0 + 0.0100020002573729 + 0.5346122980117798 + 0.3423453867435455 + <_> + + <_> + + + + <_>11 4 5 3 -1. + <_>11 5 5 1 3. + 0 + 2.0138120744377375e-003 + 0.4643830060958862 + 0.5824304223060608 + <_> + + <_> + + + + <_>4 11 4 2 -1. + <_>4 12 4 1 2. + 0 + 1.5135470312088728e-003 + 0.5196396112442017 + 0.2856149971485138 + <_> + + <_> + + + + <_>10 7 2 2 -1. + <_>10 7 1 2 2. + 0 + 3.1381431035697460e-003 + 0.4838162958621979 + 0.5958529710769653 + <_> + + <_> + + + + <_>8 7 2 2 -1. + <_>9 7 1 2 2. + 0 + -5.1450440660119057e-003 + 0.8920302987098694 + 0.4741412103176117 + <_> + + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + -4.4736708514392376e-003 + 0.2033942937850952 + 0.5337278842926025 + <_> + + <_> + + + + <_>5 6 3 3 -1. + <_>5 7 3 1 3. + 0 + 1.9628470763564110e-003 + 0.4571633934974670 + 0.6725863218307495 + <_> + + <_> + + + + <_>10 0 3 3 -1. + <_>11 0 1 3 3. + 0 + 5.4260450415313244e-003 + 0.5271108150482178 + 0.2845670878887177 + <_> + + <_> + + + + <_>5 6 6 2 -1. + <_>5 6 3 1 2. + <_>8 7 3 1 2. + 0 + 4.9611460417509079e-004 + 0.4138312935829163 + 0.5718597769737244 + <_> + + <_> + + + + <_>12 16 4 3 -1. + <_>12 17 4 1 3. + 0 + 9.3728788197040558e-003 + 0.5225151181221008 + 0.2804847061634064 + <_> + + <_> + + + + <_>3 12 3 2 -1. + <_>3 13 3 1 2. + 0 + 6.0500897234305739e-004 + 0.5236768722534180 + 0.3314523994922638 + <_> + + <_> + + + + <_>9 12 3 2 -1. + <_>9 13 3 1 2. + 0 + 5.6792551185935736e-004 + 0.4531059861183167 + 0.6276971101760864 + <_> + + <_> + + + + <_>1 11 16 4 -1. + <_>1 11 8 2 2. + <_>9 13 8 2 2. + 0 + 0.0246443394571543 + 0.5130851864814758 + 0.2017143964767456 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -0.0102904504165053 + 0.7786595225334168 + 0.4876641035079956 + <_> + + <_> + + + + <_>4 4 5 3 -1. + <_>4 5 5 1 3. + 0 + 2.0629419013857841e-003 + 0.4288598895072937 + 0.5881264209747315 + <_> + + <_> + + + + <_>12 16 4 3 -1. + <_>12 17 4 1 3. + 0 + -5.0519481301307678e-003 + 0.3523977994918823 + 0.5286008715629578 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + -5.7692620903253555e-003 + 0.6841086149215698 + 0.4588094055652618 + <_> + + <_> + + + + <_>9 0 2 2 -1. + <_>9 1 2 1 2. + 0 + -4.5789941214025021e-004 + 0.3565520048141480 + 0.5485978126525879 + <_> + + <_> + + + + <_>8 9 4 2 -1. + <_>8 10 4 1 2. + 0 + -7.5918837683275342e-004 + 0.3368793129920960 + 0.5254197120666504 + <_> + + <_> + + + + <_>8 8 4 3 -1. + <_>8 9 4 1 3. + 0 + -1.7737259622663260e-003 + 0.3422161042690277 + 0.5454015135765076 + <_> + + <_> + + + + <_>0 13 6 3 -1. + <_>2 13 2 3 3. + 0 + -8.5610467940568924e-003 + 0.6533612012863159 + 0.4485856890678406 + <_> + + <_> + + + + <_>16 14 3 2 -1. + <_>16 15 3 1 2. + 0 + 1.7277270089834929e-003 + 0.5307580232620239 + 0.3925352990627289 + <_> + + <_> + + + + <_>1 18 18 2 -1. + <_>7 18 6 2 3. + 0 + -0.0281996093690395 + 0.6857458949089050 + 0.4588584005832672 + <_> + + <_> + + + + <_>16 14 3 2 -1. + <_>16 15 3 1 2. + 0 + -1.7781109781935811e-003 + 0.4037851095199585 + 0.5369856953620911 + <_> + + <_> + + + + <_>1 14 3 2 -1. + <_>1 15 3 1 2. + 0 + 3.3177141449414194e-004 + 0.5399798750877380 + 0.3705750107765198 + <_> + + <_> + + + + <_>7 14 6 3 -1. + <_>7 15 6 1 3. + 0 + 2.6385399978607893e-003 + 0.4665437042713165 + 0.6452730894088745 + <_> + + <_> + + + + <_>5 14 8 3 -1. + <_>5 15 8 1 3. + 0 + -2.1183069329708815e-003 + 0.5914781093597412 + 0.4064677059650421 + <_> + + <_> + + + + <_>10 6 4 14 -1. + <_>10 6 2 14 2. + 0 + -0.0147732896730304 + 0.3642038106918335 + 0.5294762849807739 + <_> + + <_> + + + + <_>6 6 4 14 -1. + <_>8 6 2 14 2. + 0 + -0.0168154407292604 + 0.2664231956005096 + 0.5144972801208496 + <_> + + <_> + + + + <_>13 5 2 3 -1. + <_>13 6 2 1 3. + 0 + -6.3370140269398689e-003 + 0.6779531240463257 + 0.4852097928524017 + <_> + + <_> + + + + <_>7 16 6 1 -1. + <_>9 16 2 1 3. + 0 + -4.4560048991115764e-005 + 0.5613964796066284 + 0.4153054058551788 + <_> + + <_> + + + + <_>9 12 3 3 -1. + <_>9 13 3 1 3. + 0 + -1.0240620467811823e-003 + 0.5964478254318237 + 0.4566304087638855 + <_> + + <_> + + + + <_>7 0 3 3 -1. + <_>8 0 1 3 3. + 0 + -2.3161689750850201e-003 + 0.2976115047931671 + 0.5188159942626953 + <_> + + <_> + + + + <_>4 0 16 18 -1. + <_>4 9 16 9 2. + 0 + 0.5321757197380066 + 0.5187839269638062 + 0.2202631980180740 + <_> + + <_> + + + + <_>1 1 16 14 -1. + <_>1 8 16 7 2. + 0 + -0.1664305031299591 + 0.1866022944450378 + 0.5060343146324158 + <_> + + <_> + + + + <_>3 9 15 4 -1. + <_>8 9 5 4 3. + 0 + 0.1125352978706360 + 0.5212125182151794 + 0.1185022965073586 + <_> + + <_> + + + + <_>6 12 7 3 -1. + <_>6 13 7 1 3. + 0 + 9.3046864494681358e-003 + 0.4589937031269074 + 0.6826149225234985 + <_> + + <_> + + + + <_>14 15 2 3 -1. + <_>14 16 2 1 3. + 0 + -4.6255099587142467e-003 + 0.3079940974712372 + 0.5225008726119995 + <_> + + <_> + + + + <_>2 3 16 14 -1. + <_>2 3 8 7 2. + <_>10 10 8 7 2. + 0 + -0.1111646965146065 + 0.2101044058799744 + 0.5080801844596863 + <_> + + <_> + + + + <_>16 2 4 18 -1. + <_>18 2 2 9 2. + <_>16 11 2 9 2. + 0 + -0.0108884396031499 + 0.5765355229377747 + 0.4790464043617249 + <_> + + <_> + + + + <_>4 15 2 3 -1. + <_>4 16 2 1 3. + 0 + 5.8564301580190659e-003 + 0.5065100193023682 + 0.1563598960638046 + <_> + + <_> + + + + <_>16 2 4 18 -1. + <_>18 2 2 9 2. + <_>16 11 2 9 2. + 0 + 0.0548543892800808 + 0.4966914951801300 + 0.7230510711669922 + <_> + + <_> + + + + <_>1 1 8 3 -1. + <_>1 2 8 1 3. + 0 + -0.0111973397433758 + 0.2194979041814804 + 0.5098798274993897 + <_> + + <_> + + + + <_>8 11 4 3 -1. + <_>8 12 4 1 3. + 0 + 4.4069071300327778e-003 + 0.4778401851654053 + 0.6770902872085571 + <_> + + <_> + + + + <_>5 11 5 9 -1. + <_>5 14 5 3 3. + 0 + -0.0636652931571007 + 0.1936362981796265 + 0.5081024169921875 + <_> + + <_> + + + + <_>16 0 4 11 -1. + <_>16 0 2 11 2. + 0 + -9.8081491887569427e-003 + 0.5999063253402710 + 0.4810341000556946 + <_> + + <_> + + + + <_>7 0 6 1 -1. + <_>9 0 2 1 3. + 0 + -2.1717099007219076e-003 + 0.3338333964347839 + 0.5235472917556763 + <_> + + <_> + + + + <_>16 3 3 7 -1. + <_>17 3 1 7 3. + 0 + -0.0133155202493072 + 0.6617069840431213 + 0.4919213056564331 + <_> + + <_> + + + + <_>1 3 3 7 -1. + <_>2 3 1 7 3. + 0 + 2.5442079640924931e-003 + 0.4488744139671326 + 0.6082184910774231 + <_> + + <_> + + + + <_>7 8 6 12 -1. + <_>7 12 6 4 3. + 0 + 0.0120378397405148 + 0.5409392118453980 + 0.3292432129383087 + <_> + + <_> + + + + <_>0 0 4 11 -1. + <_>2 0 2 11 2. + 0 + -0.0207010507583618 + 0.6819120049476624 + 0.4594995975494385 + <_> + + <_> + + + + <_>14 0 6 20 -1. + <_>14 0 3 20 2. + 0 + 0.0276082791388035 + 0.4630792140960693 + 0.5767282843589783 + <_> + + <_> + + + + <_>0 3 1 2 -1. + <_>0 4 1 1 2. + 0 + 1.2370620388537645e-003 + 0.5165379047393799 + 0.2635016143321991 + <_> + + <_> + + + + <_>5 5 10 8 -1. + <_>10 5 5 4 2. + <_>5 9 5 4 2. + 0 + -0.0376693382859230 + 0.2536393105983734 + 0.5278980135917664 + <_> + + <_> + + + + <_>4 7 12 4 -1. + <_>4 7 6 2 2. + <_>10 9 6 2 2. + 0 + -1.8057259730994701e-003 + 0.3985156118869782 + 0.5517500042915344 + 50.6104812622070310 + 10 + -1 + <_> + + + <_> + + <_> + + + + <_>2 1 6 4 -1. + <_>5 1 3 4 2. + 0 + 4.4299028813838959e-003 + 0.2891018092632294 + 0.6335226297378540 + <_> + + <_> + + + + <_>9 7 6 4 -1. + <_>12 7 3 2 2. + <_>9 9 3 2 2. + 0 + -2.3813319858163595e-003 + 0.6211789250373840 + 0.3477487862110138 + <_> + + <_> + + + + <_>5 6 2 6 -1. + <_>5 9 2 3 2. + 0 + 2.2915711160749197e-003 + 0.2254412025213242 + 0.5582118034362793 + <_> + + <_> + + + + <_>9 16 6 4 -1. + <_>12 16 3 2 2. + <_>9 18 3 2 2. + 0 + 9.9457940086722374e-004 + 0.3711710870265961 + 0.5930070877075195 + <_> + + <_> + + + + <_>9 4 2 12 -1. + <_>9 10 2 6 2. + 0 + 7.7164667891338468e-004 + 0.5651720166206360 + 0.3347995877265930 + <_> + + <_> + + + + <_>7 1 6 18 -1. + <_>9 1 2 18 3. + 0 + -1.1386410333216190e-003 + 0.3069126009941101 + 0.5508630871772766 + <_> + + <_> + + + + <_>4 12 12 2 -1. + <_>8 12 4 2 3. + 0 + -1.6403039626311511e-004 + 0.5762827992439270 + 0.3699047863483429 + <_> + + <_> + + + + <_>8 8 6 2 -1. + <_>8 9 6 1 2. + 0 + 2.9793529392918572e-005 + 0.2644244134426117 + 0.5437911152839661 + <_> + + <_> + + + + <_>8 0 3 6 -1. + <_>9 0 1 6 3. + 0 + 8.5774902254343033e-003 + 0.5051138997077942 + 0.1795724928379059 + <_> + + <_> + + + + <_>11 18 3 2 -1. + <_>11 19 3 1 2. + 0 + -2.6032689493149519e-004 + 0.5826969146728516 + 0.4446826875209808 + <_> + + <_> + + + + <_>1 1 17 4 -1. + <_>1 3 17 2 2. + 0 + -6.1404630541801453e-003 + 0.3113852143287659 + 0.5346971750259399 + <_> + + <_> + + + + <_>11 8 4 12 -1. + <_>11 8 2 12 2. + 0 + -0.0230869501829147 + 0.3277946114540100 + 0.5331197977066040 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + -0.0142436502501369 + 0.7381709814071655 + 0.4588063061237335 + <_> + + <_> + + + + <_>12 3 2 17 -1. + <_>12 3 1 17 2. + 0 + 0.0194871295243502 + 0.5256630778312683 + 0.2274471968412399 + <_> + + <_> + + + + <_>4 7 6 1 -1. + <_>6 7 2 1 3. + 0 + -9.6681108698248863e-004 + 0.5511230826377869 + 0.3815006911754608 + <_> + + <_> + + + + <_>18 3 2 3 -1. + <_>18 4 2 1 3. + 0 + 3.1474709976464510e-003 + 0.5425636768341065 + 0.2543726861476898 + <_> + + <_> + + + + <_>8 4 3 4 -1. + <_>8 6 3 2 2. + 0 + -1.8026070029009134e-004 + 0.5380191802978516 + 0.3406304121017456 + <_> + + <_> + + + + <_>4 5 12 10 -1. + <_>4 10 12 5 2. + 0 + -6.0266260989010334e-003 + 0.3035801947116852 + 0.5420572161674500 + <_> + + <_> + + + + <_>5 18 4 2 -1. + <_>7 18 2 2 2. + 0 + 4.4462960795499384e-004 + 0.3990997076034546 + 0.5660110116004944 + <_> + + <_> + + + + <_>17 2 3 6 -1. + <_>17 4 3 2 3. + 0 + 2.2609760053455830e-003 + 0.5562806725502014 + 0.3940688073635101 + <_> + + <_> + + + + <_>7 7 6 6 -1. + <_>9 7 2 6 3. + 0 + 0.0511330589652061 + 0.4609653949737549 + 0.7118561863899231 + <_> + + <_> + + + + <_>17 2 3 6 -1. + <_>17 4 3 2 3. + 0 + -0.0177863091230392 + 0.2316166013479233 + 0.5322144031524658 + <_> + + <_> + + + + <_>8 0 3 4 -1. + <_>9 0 1 4 3. + 0 + -4.9679628573358059e-003 + 0.2330771982669830 + 0.5122029185295105 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 2.0667689386755228e-003 + 0.4657444059848785 + 0.6455488204956055 + <_> + + <_> + + + + <_>0 12 6 3 -1. + <_>0 13 6 1 3. + 0 + 7.4413768015801907e-003 + 0.5154392123222351 + 0.2361633926630020 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + -3.6277279723435640e-003 + 0.6219773292541504 + 0.4476661086082459 + <_> + + <_> + + + + <_>3 12 2 3 -1. + <_>3 13 2 1 3. + 0 + -5.3530759178102016e-003 + 0.1837355047464371 + 0.5102208256721497 + <_> + + <_> + + + + <_>5 6 12 7 -1. + <_>9 6 4 7 3. + 0 + 0.1453091949224472 + 0.5145987272262573 + 0.1535930931568146 + <_> + + <_> + + + + <_>0 2 3 6 -1. + <_>0 4 3 2 3. + 0 + 2.4394490756094456e-003 + 0.5343660116195679 + 0.3624661862850189 + <_> + + <_> + + + + <_>14 6 1 3 -1. + <_>14 7 1 1 3. + 0 + -3.1283390708267689e-003 + 0.6215007901191711 + 0.4845592081546783 + <_> + + <_> + + + + <_>2 0 3 14 -1. + <_>3 0 1 14 3. + 0 + 1.7940260004252195e-003 + 0.4299261868000031 + 0.5824198126792908 + <_> + + <_> + + + + <_>12 14 5 6 -1. + <_>12 16 5 2 3. + 0 + 0.0362538211047649 + 0.5260334014892578 + 0.1439467966556549 + <_> + + <_> + + + + <_>4 14 5 6 -1. + <_>4 16 5 2 3. + 0 + -5.1746722310781479e-003 + 0.3506538867950440 + 0.5287045240402222 + <_> + + <_> + + + + <_>11 10 2 2 -1. + <_>12 10 1 1 2. + <_>11 11 1 1 2. + 0 + 6.5383297624066472e-004 + 0.4809640944004059 + 0.6122040152549744 + <_> + + <_> + + + + <_>5 0 3 14 -1. + <_>6 0 1 14 3. + 0 + -0.0264802295714617 + 0.1139362007379532 + 0.5045586228370667 + <_> + + <_> + + + + <_>10 15 2 3 -1. + <_>10 16 2 1 3. + 0 + -3.0440660193562508e-003 + 0.6352095007896423 + 0.4794734120368958 + <_> + + <_> + + + + <_>0 2 2 3 -1. + <_>0 3 2 1 3. + 0 + 3.6993520334362984e-003 + 0.5131118297576904 + 0.2498510926961899 + <_> + + <_> + + + + <_>5 11 12 6 -1. + <_>5 14 12 3 2. + 0 + -3.6762931267730892e-004 + 0.5421394705772400 + 0.3709532022476196 + <_> + + <_> + + + + <_>6 11 3 9 -1. + <_>6 14 3 3 3. + 0 + -0.0413822606205940 + 0.1894959956407547 + 0.5081691741943359 + <_> + + <_> + + + + <_>11 10 2 2 -1. + <_>12 10 1 1 2. + <_>11 11 1 1 2. + 0 + -1.0532729793339968e-003 + 0.6454367041587830 + 0.4783608913421631 + <_> + + <_> + + + + <_>5 6 1 3 -1. + <_>5 7 1 1 3. + 0 + -2.1648600231856108e-003 + 0.6215031147003174 + 0.4499826133251190 + <_> + + <_> + + + + <_>4 9 13 3 -1. + <_>4 10 13 1 3. + 0 + -5.6747748749330640e-004 + 0.3712610900402069 + 0.5419334769248962 + <_> + + <_> + + + + <_>1 7 15 6 -1. + <_>6 7 5 6 3. + 0 + 0.1737584024667740 + 0.5023643970489502 + 0.1215742006897926 + <_> + + <_> + + + + <_>4 5 12 6 -1. + <_>8 5 4 6 3. + 0 + -2.9049699660390615e-003 + 0.3240267932415009 + 0.5381883978843689 + <_> + + <_> + + + + <_>8 10 4 3 -1. + <_>8 11 4 1 3. + 0 + 1.2299539521336555e-003 + 0.4165507853031158 + 0.5703486204147339 + <_> + + <_> + + + + <_>15 14 1 3 -1. + <_>15 15 1 1 3. + 0 + -5.4329237900674343e-004 + 0.3854042887687683 + 0.5547549128532410 + <_> + + <_> + + + + <_>1 11 5 3 -1. + <_>1 12 5 1 3. + 0 + -8.3297258242964745e-003 + 0.2204494029283524 + 0.5097082853317261 + <_> + + <_> + + + + <_>7 1 7 12 -1. + <_>7 7 7 6 2. + 0 + -1.0417630255687982e-004 + 0.5607066154479981 + 0.4303036034107208 + <_> + + <_> + + + + <_>0 1 6 10 -1. + <_>0 1 3 5 2. + <_>3 6 3 5 2. + 0 + 0.0312047004699707 + 0.4621657133102417 + 0.6982004046440125 + <_> + + <_> + + + + <_>16 1 4 3 -1. + <_>16 2 4 1 3. + 0 + 7.8943502157926559e-003 + 0.5269594192504883 + 0.2269068062305450 + <_> + + <_> + + + + <_>5 5 2 3 -1. + <_>5 6 2 1 3. + 0 + -4.3645310215651989e-003 + 0.6359223127365112 + 0.4537956118583679 + <_> + + <_> + + + + <_>12 2 3 5 -1. + <_>13 2 1 5 3. + 0 + 7.6793059706687927e-003 + 0.5274767875671387 + 0.2740483880043030 + <_> + + <_> + + + + <_>0 3 4 6 -1. + <_>0 5 4 2 3. + 0 + -0.0254311393946409 + 0.2038519978523254 + 0.5071732997894287 + <_> + + <_> + + + + <_>8 12 4 2 -1. + <_>8 13 4 1 2. + 0 + 8.2000601105391979e-004 + 0.4587455093860626 + 0.6119868159294128 + <_> + + <_> + + + + <_>8 18 3 1 -1. + <_>9 18 1 1 3. + 0 + 2.9284600168466568e-003 + 0.5071274042129517 + 0.2028204947710037 + <_> + + <_> + + + + <_>11 10 2 2 -1. + <_>12 10 1 1 2. + <_>11 11 1 1 2. + 0 + 4.5256470912136137e-005 + 0.4812104105949402 + 0.5430821776390076 + <_> + + <_> + + + + <_>7 10 2 2 -1. + <_>7 10 1 1 2. + <_>8 11 1 1 2. + 0 + 1.3158309739083052e-003 + 0.4625813961029053 + 0.6779323220252991 + <_> + + <_> + + + + <_>11 11 4 4 -1. + <_>11 13 4 2 2. + 0 + 1.5870389761403203e-003 + 0.5386291742324829 + 0.3431465029716492 + <_> + + <_> + + + + <_>8 12 3 8 -1. + <_>9 12 1 8 3. + 0 + -0.0215396601706743 + 0.0259425006806850 + 0.5003222823143005 + <_> + + <_> + + + + <_>13 0 6 3 -1. + <_>13 1 6 1 3. + 0 + 0.0143344802781940 + 0.5202844738960266 + 0.1590632945299149 + <_> + + <_> + + + + <_>8 8 3 4 -1. + <_>9 8 1 4 3. + 0 + -8.3881383761763573e-003 + 0.7282481193542481 + 0.4648044109344482 + <_> + + <_> + + + + <_>5 7 10 10 -1. + <_>10 7 5 5 2. + <_>5 12 5 5 2. + 0 + 9.1906841844320297e-003 + 0.5562356710433960 + 0.3923191130161285 + <_> + + <_> + + + + <_>3 18 8 2 -1. + <_>3 18 4 1 2. + <_>7 19 4 1 2. + 0 + -5.8453059755265713e-003 + 0.6803392767906189 + 0.4629127979278565 + <_> + + <_> + + + + <_>10 2 6 8 -1. + <_>12 2 2 8 3. + 0 + -0.0547077991068363 + 0.2561671137809753 + 0.5206125974655151 + <_> + + <_> + + + + <_>4 2 6 8 -1. + <_>6 2 2 8 3. + 0 + 9.1142775490880013e-003 + 0.5189620256423950 + 0.3053877055644989 + <_> + + <_> + + + + <_>11 0 3 7 -1. + <_>12 0 1 7 3. + 0 + -0.0155750000849366 + 0.1295074969530106 + 0.5169094800949097 + <_> + + <_> + + + + <_>7 11 2 1 -1. + <_>8 11 1 1 2. + 0 + -1.2050600344082341e-004 + 0.5735098123550415 + 0.4230825006961823 + <_> + + <_> + + + + <_>15 14 1 3 -1. + <_>15 15 1 1 3. + 0 + 1.2273970060050488e-003 + 0.5289878249168396 + 0.4079791903495789 + <_> + + <_> + + + + <_>7 15 2 2 -1. + <_>7 15 1 1 2. + <_>8 16 1 1 2. + 0 + -1.2186600361019373e-003 + 0.6575639843940735 + 0.4574409127235413 + <_> + + <_> + + + + <_>15 14 1 3 -1. + <_>15 15 1 1 3. + 0 + -3.3256649039685726e-003 + 0.3628047108650208 + 0.5195019841194153 + <_> + + <_> + + + + <_>6 0 3 7 -1. + <_>7 0 1 7 3. + 0 + -0.0132883097976446 + 0.1284265965223312 + 0.5043488740921021 + <_> + + <_> + + + + <_>18 1 2 7 -1. + <_>18 1 1 7 2. + 0 + -3.3839771058410406e-003 + 0.6292240023612976 + 0.4757505953311920 + <_> + + <_> + + + + <_>2 0 8 20 -1. + <_>2 10 8 10 2. + 0 + -0.2195422053337097 + 0.1487731933593750 + 0.5065013766288757 + <_> + + <_> + + + + <_>3 0 15 6 -1. + <_>3 2 15 2 3. + 0 + 4.9111708067357540e-003 + 0.4256102144718170 + 0.5665838718414307 + <_> + + <_> + + + + <_>4 3 12 2 -1. + <_>4 4 12 1 2. + 0 + -1.8744950648397207e-004 + 0.4004144072532654 + 0.5586857199668884 + <_> + + <_> + + + + <_>16 0 4 5 -1. + <_>16 0 2 5 2. + 0 + -5.2178641781210899e-003 + 0.6009116172790527 + 0.4812706112861633 + <_> + + <_> + + + + <_>7 0 3 4 -1. + <_>8 0 1 4 3. + 0 + -1.1111519997939467e-003 + 0.3514933884143829 + 0.5287089943885803 + <_> + + <_> + + + + <_>16 0 4 5 -1. + <_>16 0 2 5 2. + 0 + 4.4036400504410267e-003 + 0.4642275869846344 + 0.5924085974693298 + <_> + + <_> + + + + <_>1 7 6 13 -1. + <_>3 7 2 13 3. + 0 + 0.1229949966073036 + 0.5025529265403748 + 0.0691524818539619 + <_> + + <_> + + + + <_>16 0 4 5 -1. + <_>16 0 2 5 2. + 0 + -0.0123135102912784 + 0.5884591937065125 + 0.4934012889862061 + <_> + + <_> + + + + <_>0 0 4 5 -1. + <_>2 0 2 5 2. + 0 + 4.1471039876341820e-003 + 0.4372239112854004 + 0.5893477797508240 + <_> + + <_> + + + + <_>14 12 3 6 -1. + <_>14 14 3 2 3. + 0 + -3.5502649843692780e-003 + 0.4327551126480103 + 0.5396270155906677 + <_> + + <_> + + + + <_>3 12 3 6 -1. + <_>3 14 3 2 3. + 0 + -0.0192242693156004 + 0.1913134008646011 + 0.5068330764770508 + <_> + + <_> + + + + <_>16 1 4 3 -1. + <_>16 2 4 1 3. + 0 + 1.4395059552043676e-003 + 0.5308178067207336 + 0.4243533015251160 + <_> + + <_> + + + + <_>8 7 2 10 -1. + <_>8 7 1 5 2. + <_>9 12 1 5 2. + 0 + -6.7751999013125896e-003 + 0.6365395784378052 + 0.4540086090564728 + <_> + + <_> + + + + <_>11 11 4 4 -1. + <_>11 13 4 2 2. + 0 + 7.0119630545377731e-003 + 0.5189834237098694 + 0.3026199936866760 + <_> + + <_> + + + + <_>0 1 4 3 -1. + <_>0 2 4 1 3. + 0 + 5.4014651104807854e-003 + 0.5105062127113342 + 0.2557682991027832 + <_> + + <_> + + + + <_>13 4 1 3 -1. + <_>13 5 1 1 3. + 0 + 9.0274988906458020e-004 + 0.4696914851665497 + 0.5861827731132507 + <_> + + <_> + + + + <_>7 15 3 5 -1. + <_>8 15 1 5 3. + 0 + 0.0114744501188397 + 0.5053645968437195 + 0.1527177989482880 + <_> + + <_> + + + + <_>9 7 3 5 -1. + <_>10 7 1 5 3. + 0 + -6.7023430019617081e-003 + 0.6508980989456177 + 0.4890604019165039 + <_> + + <_> + + + + <_>8 7 3 5 -1. + <_>9 7 1 5 3. + 0 + -2.0462959073483944e-003 + 0.6241816878318787 + 0.4514600038528442 + <_> + + <_> + + + + <_>10 6 4 14 -1. + <_>10 6 2 14 2. + 0 + -9.9951568990945816e-003 + 0.3432781100273132 + 0.5400953888893127 + <_> + + <_> + + + + <_>0 5 5 6 -1. + <_>0 7 5 2 3. + 0 + -0.0357007086277008 + 0.1878059059381485 + 0.5074077844619751 + <_> + + <_> + + + + <_>9 5 6 4 -1. + <_>9 5 3 4 2. + 0 + 4.5584561303257942e-004 + 0.3805277049541473 + 0.5402569770812988 + <_> + + <_> + + + + <_>0 0 18 10 -1. + <_>6 0 6 10 3. + 0 + -0.0542606003582478 + 0.6843714714050293 + 0.4595097005367279 + <_> + + <_> + + + + <_>10 6 4 14 -1. + <_>10 6 2 14 2. + 0 + 6.0600461438298225e-003 + 0.5502905249595642 + 0.4500527977943420 + <_> + + <_> + + + + <_>6 6 4 14 -1. + <_>8 6 2 14 2. + 0 + -6.4791832119226456e-003 + 0.3368858098983765 + 0.5310757160186768 + <_> + + <_> + + + + <_>13 4 1 3 -1. + <_>13 5 1 1 3. + 0 + -1.4939469983801246e-003 + 0.6487640142440796 + 0.4756175875663757 + <_> + + <_> + + + + <_>5 1 2 3 -1. + <_>6 1 1 3 2. + 0 + 1.4610530342906713e-005 + 0.4034579098224640 + 0.5451064109802246 + <_> + + <_> + + + + <_>18 1 2 18 -1. + <_>19 1 1 9 2. + <_>18 10 1 9 2. + 0 + -7.2321938350796700e-003 + 0.6386873722076416 + 0.4824739992618561 + <_> + + <_> + + + + <_>2 1 4 3 -1. + <_>2 2 4 1 3. + 0 + -4.0645818226039410e-003 + 0.2986421883106232 + 0.5157335996627808 + <_> + + <_> + + + + <_>18 1 2 18 -1. + <_>19 1 1 9 2. + <_>18 10 1 9 2. + 0 + 0.0304630808532238 + 0.5022199749946594 + 0.7159956097602844 + <_> + + <_> + + + + <_>1 14 4 6 -1. + <_>1 14 2 3 2. + <_>3 17 2 3 2. + 0 + -8.0544911324977875e-003 + 0.6492452025413513 + 0.4619275033473969 + <_> + + <_> + + + + <_>10 11 7 6 -1. + <_>10 13 7 2 3. + 0 + 0.0395051389932632 + 0.5150570869445801 + 0.2450613975524902 + <_> + + <_> + + + + <_>0 10 6 10 -1. + <_>0 10 3 5 2. + <_>3 15 3 5 2. + 0 + 8.4530208259820938e-003 + 0.4573669135570526 + 0.6394037008285523 + <_> + + <_> + + + + <_>11 0 3 4 -1. + <_>12 0 1 4 3. + 0 + -1.1688120430335402e-003 + 0.3865512013435364 + 0.5483661293983460 + <_> + + <_> + + + + <_>5 10 5 6 -1. + <_>5 13 5 3 2. + 0 + 2.8070670086890459e-003 + 0.5128579139709473 + 0.2701480090618134 + <_> + + <_> + + + + <_>14 6 1 8 -1. + <_>14 10 1 4 2. + 0 + 4.7365209320560098e-004 + 0.4051581919193268 + 0.5387461185455322 + <_> + + <_> + + + + <_>1 7 18 6 -1. + <_>1 7 9 3 2. + <_>10 10 9 3 2. + 0 + 0.0117410803213716 + 0.5295950174331665 + 0.3719413876533508 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>9 7 1 2 2. + 0 + 3.1833238899707794e-003 + 0.4789406955242157 + 0.6895126104354858 + <_> + + <_> + + + + <_>5 9 4 5 -1. + <_>7 9 2 5 2. + 0 + 7.0241501089185476e-004 + 0.5384489297866821 + 0.3918080925941467 + 54.6200714111328130 + 11 + -1 + <_> + + + <_> + + <_> + + + + <_>7 6 6 3 -1. + <_>9 6 2 3 3. + 0 + 0.0170599296689034 + 0.3948527872562408 + 0.7142534852027893 + <_> + + <_> + + + + <_>1 0 18 4 -1. + <_>7 0 6 4 3. + 0 + 0.0218408405780792 + 0.3370316028594971 + 0.6090016961097717 + <_> + + <_> + + + + <_>7 15 2 4 -1. + <_>7 17 2 2 2. + 0 + 2.4520049919374287e-004 + 0.3500576019287109 + 0.5987902283668518 + <_> + + <_> + + + + <_>1 0 19 9 -1. + <_>1 3 19 3 3. + 0 + 8.3272606134414673e-003 + 0.3267528116703033 + 0.5697240829467773 + <_> + + <_> + + + + <_>3 7 3 6 -1. + <_>3 9 3 2 3. + 0 + 5.7148298947140574e-004 + 0.3044599890708923 + 0.5531656742095947 + <_> + + <_> + + + + <_>13 7 4 4 -1. + <_>15 7 2 2 2. + <_>13 9 2 2 2. + 0 + 6.7373987985774875e-004 + 0.3650012016296387 + 0.5672631263732910 + <_> + + <_> + + + + <_>3 7 4 4 -1. + <_>3 7 2 2 2. + <_>5 9 2 2 2. + 0 + 3.4681590477703139e-005 + 0.3313541114330292 + 0.5388727188110352 + <_> + + <_> + + + + <_>9 6 10 8 -1. + <_>9 10 10 4 2. + 0 + -5.8563398197293282e-003 + 0.2697942852973938 + 0.5498778820037842 + <_> + + <_> + + + + <_>3 8 14 12 -1. + <_>3 14 14 6 2. + 0 + 8.5102273151278496e-003 + 0.5269358158111572 + 0.2762879133224487 + <_> + + <_> + + + + <_>6 5 10 12 -1. + <_>11 5 5 6 2. + <_>6 11 5 6 2. + 0 + -0.0698172077536583 + 0.2909603118896484 + 0.5259246826171875 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -8.6113670840859413e-004 + 0.5892577171325684 + 0.4073697924613953 + <_> + + <_> + + + + <_>9 5 6 5 -1. + <_>9 5 3 5 2. + 0 + 9.7149249631911516e-004 + 0.3523564040660858 + 0.5415862202644348 + <_> + + <_> + + + + <_>9 4 2 4 -1. + <_>9 6 2 2 2. + 0 + -1.4727490452060010e-005 + 0.5423017740249634 + 0.3503156006336212 + <_> + + <_> + + + + <_>9 5 6 5 -1. + <_>9 5 3 5 2. + 0 + 0.0484202913939953 + 0.5193945765495300 + 0.3411195874214172 + <_> + + <_> + + + + <_>5 5 6 5 -1. + <_>8 5 3 5 2. + 0 + 1.3257140526548028e-003 + 0.3157769143581390 + 0.5335376262664795 + <_> + + <_> + + + + <_>11 2 6 1 -1. + <_>13 2 2 1 3. + 0 + 1.4922149603080470e-005 + 0.4451299905776978 + 0.5536553859710693 + <_> + + <_> + + + + <_>3 2 6 1 -1. + <_>5 2 2 1 3. + 0 + -2.7173398993909359e-003 + 0.3031741976737976 + 0.5248088836669922 + <_> + + <_> + + + + <_>13 5 2 3 -1. + <_>13 6 2 1 3. + 0 + 2.9219500720500946e-003 + 0.4781453013420105 + 0.6606041789054871 + <_> + + <_> + + + + <_>0 10 1 4 -1. + <_>0 12 1 2 2. + 0 + -1.9804988987743855e-003 + 0.3186308145523071 + 0.5287625193595886 + <_> + + <_> + + + + <_>13 5 2 3 -1. + <_>13 6 2 1 3. + 0 + -4.0012109093368053e-003 + 0.6413596868515015 + 0.4749928116798401 + <_> + + <_> + + + + <_>8 18 3 2 -1. + <_>9 18 1 2 3. + 0 + -4.3491991236805916e-003 + 0.1507498025894165 + 0.5098996758460999 + <_> + + <_> + + + + <_>6 15 9 2 -1. + <_>6 16 9 1 2. + 0 + 1.3490889687091112e-003 + 0.4316158890724182 + 0.5881167054176331 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 0.0185970701277256 + 0.4735553860664368 + 0.9089794158935547 + <_> + + <_> + + + + <_>18 4 2 4 -1. + <_>18 6 2 2 2. + 0 + -1.8562379991635680e-003 + 0.3553189039230347 + 0.5577837228775024 + <_> + + <_> + + + + <_>5 5 2 3 -1. + <_>5 6 2 1 3. + 0 + 2.2940430790185928e-003 + 0.4500094950199127 + 0.6580877900123596 + <_> + + <_> + + + + <_>15 16 3 2 -1. + <_>15 17 3 1 2. + 0 + 2.9982850537635386e-004 + 0.5629242062568665 + 0.3975878953933716 + <_> + + <_> + + + + <_>0 0 3 9 -1. + <_>0 3 3 3 3. + 0 + 3.5455459728837013e-003 + 0.5381547212600708 + 0.3605485856533051 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>9 8 3 1 3. + 0 + 9.6104722470045090e-003 + 0.5255997180938721 + 0.1796745955944061 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>8 8 3 1 3. + 0 + -6.2783220782876015e-003 + 0.2272856980562210 + 0.5114030241966248 + <_> + + <_> + + + + <_>9 5 2 6 -1. + <_>9 5 1 6 2. + 0 + 3.4598479978740215e-003 + 0.4626308083534241 + 0.6608219146728516 + <_> + + <_> + + + + <_>8 6 3 4 -1. + <_>9 6 1 4 3. + 0 + -1.3112019514665008e-003 + 0.6317539811134338 + 0.4436857998371124 + <_> + + <_> + + + + <_>7 6 8 12 -1. + <_>11 6 4 6 2. + <_>7 12 4 6 2. + 0 + 2.6876179035753012e-003 + 0.5421109795570374 + 0.4054022133350372 + <_> + + <_> + + + + <_>5 6 8 12 -1. + <_>5 6 4 6 2. + <_>9 12 4 6 2. + 0 + 3.9118169806897640e-003 + 0.5358477830886841 + 0.3273454904556274 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -0.0142064504325390 + 0.7793576717376709 + 0.4975781142711639 + <_> + + <_> + + + + <_>2 16 3 2 -1. + <_>2 17 3 1 2. + 0 + 7.1705528534948826e-004 + 0.5297319889068604 + 0.3560903966426849 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + 1.6635019565001130e-003 + 0.4678094089031220 + 0.5816481709480286 + <_> + + <_> + + + + <_>2 12 6 6 -1. + <_>2 14 6 2 3. + 0 + 3.3686188980937004e-003 + 0.5276734232902527 + 0.3446420133113861 + <_> + + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + 0.0127995302900672 + 0.4834679961204529 + 0.7472159266471863 + <_> + + <_> + + + + <_>6 14 6 3 -1. + <_>6 15 6 1 3. + 0 + 3.3901201095432043e-003 + 0.4511859118938446 + 0.6401721239089966 + <_> + + <_> + + + + <_>14 15 5 3 -1. + <_>14 16 5 1 3. + 0 + 4.7070779837667942e-003 + 0.5335658788681030 + 0.3555220961570740 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 1.4819339849054813e-003 + 0.4250707030296326 + 0.5772724151611328 + <_> + + <_> + + + + <_>14 15 5 3 -1. + <_>14 16 5 1 3. + 0 + -6.9995759986341000e-003 + 0.3003320097923279 + 0.5292900204658508 + <_> + + <_> + + + + <_>5 3 6 2 -1. + <_>7 3 2 2 3. + 0 + 0.0159390103071928 + 0.5067319273948669 + 0.1675581932067871 + <_> + + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + 7.6377349905669689e-003 + 0.4795069992542267 + 0.7085601091384888 + <_> + + <_> + + + + <_>1 15 5 3 -1. + <_>1 16 5 1 3. + 0 + 6.7334040068089962e-003 + 0.5133113265037537 + 0.2162470072507858 + <_> + + <_> + + + + <_>8 13 4 6 -1. + <_>10 13 2 3 2. + <_>8 16 2 3 2. + 0 + -0.0128588099032640 + 0.1938841938972473 + 0.5251371860504150 + <_> + + <_> + + + + <_>7 8 3 3 -1. + <_>8 8 1 3 3. + 0 + -6.2270800117403269e-004 + 0.5686538219451904 + 0.4197868108749390 + <_> + + <_> + + + + <_>12 0 5 4 -1. + <_>12 2 5 2 2. + 0 + -5.2651681471616030e-004 + 0.4224168956279755 + 0.5429695844650269 + <_> + + <_> + + + + <_>0 2 20 2 -1. + <_>0 2 10 1 2. + <_>10 3 10 1 2. + 0 + 0.0110750999301672 + 0.5113775134086609 + 0.2514517903327942 + <_> + + <_> + + + + <_>1 0 18 4 -1. + <_>7 0 6 4 3. + 0 + -0.0367282517254353 + 0.7194662094116211 + 0.4849618971347809 + <_> + + <_> + + + + <_>4 3 6 1 -1. + <_>6 3 2 1 3. + 0 + -2.8207109426148236e-004 + 0.3840261995792389 + 0.5394446253776550 + <_> + + <_> + + + + <_>4 18 13 2 -1. + <_>4 19 13 1 2. + 0 + -2.7489690110087395e-003 + 0.5937088727951050 + 0.4569182097911835 + <_> + + <_> + + + + <_>2 10 3 6 -1. + <_>2 12 3 2 3. + 0 + 0.0100475195795298 + 0.5138576030731201 + 0.2802298069000244 + <_> + + <_> + + + + <_>14 12 6 8 -1. + <_>17 12 3 4 2. + <_>14 16 3 4 2. + 0 + -8.1497840583324432e-003 + 0.6090037226676941 + 0.4636121094226837 + <_> + + <_> + + + + <_>4 13 10 6 -1. + <_>4 13 5 3 2. + <_>9 16 5 3 2. + 0 + -6.8833888508379459e-003 + 0.3458611071109772 + 0.5254660248756409 + <_> + + <_> + + + + <_>14 12 1 2 -1. + <_>14 13 1 1 2. + 0 + -1.4039360394235700e-005 + 0.5693104267120361 + 0.4082083106040955 + <_> + + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 1.5498419525101781e-003 + 0.4350537061691284 + 0.5806517004966736 + <_> + + <_> + + + + <_>14 12 2 2 -1. + <_>14 13 2 1 2. + 0 + -6.7841499112546444e-003 + 0.1468873023986816 + 0.5182775259017944 + <_> + + <_> + + + + <_>4 12 2 2 -1. + <_>4 13 2 1 2. + 0 + 2.1705629478674382e-004 + 0.5293524265289307 + 0.3456174135208130 + <_> + + <_> + + + + <_>8 12 9 2 -1. + <_>8 13 9 1 2. + 0 + 3.1198898795992136e-004 + 0.4652450978755951 + 0.5942413806915283 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 5.4507530294358730e-003 + 0.4653508961200714 + 0.7024846076965332 + <_> + + <_> + + + + <_>11 10 3 6 -1. + <_>11 13 3 3 2. + 0 + -2.5818689027801156e-004 + 0.5497295260429382 + 0.3768967092037201 + <_> + + <_> + + + + <_>5 6 9 12 -1. + <_>5 12 9 6 2. + 0 + -0.0174425393342972 + 0.3919087946414948 + 0.5457497835159302 + <_> + + <_> + + + + <_>11 10 3 6 -1. + <_>11 13 3 3 2. + 0 + -0.0453435294330120 + 0.1631357073783875 + 0.5154908895492554 + <_> + + <_> + + + + <_>6 10 3 6 -1. + <_>6 13 3 3 2. + 0 + 1.9190689781680703e-003 + 0.5145897865295410 + 0.2791895866394043 + <_> + + <_> + + + + <_>5 4 11 3 -1. + <_>5 5 11 1 3. + 0 + -6.0177869163453579e-003 + 0.6517636179924011 + 0.4756332933902741 + <_> + + <_> + + + + <_>7 1 5 10 -1. + <_>7 6 5 5 2. + 0 + -4.0720738470554352e-003 + 0.5514652729034424 + 0.4092685878276825 + <_> + + <_> + + + + <_>2 8 18 2 -1. + <_>2 9 18 1 2. + 0 + 3.9855059003457427e-004 + 0.3165240883827210 + 0.5285550951957703 + <_> + + <_> + + + + <_>7 17 5 3 -1. + <_>7 18 5 1 3. + 0 + -6.5418570302426815e-003 + 0.6853377819061279 + 0.4652808904647827 + <_> + + <_> + + + + <_>5 9 12 1 -1. + <_>9 9 4 1 3. + 0 + 3.4845089539885521e-003 + 0.5484588146209717 + 0.4502759873867035 + <_> + + <_> + + + + <_>0 14 6 6 -1. + <_>0 14 3 3 2. + <_>3 17 3 3 2. + 0 + -0.0136967804282904 + 0.6395779848098755 + 0.4572555124759674 + <_> + + <_> + + + + <_>5 9 12 1 -1. + <_>9 9 4 1 3. + 0 + -0.0173471402376890 + 0.2751072943210602 + 0.5181614756584168 + <_> + + <_> + + + + <_>3 9 12 1 -1. + <_>7 9 4 1 3. + 0 + -4.0885428898036480e-003 + 0.3325636088848114 + 0.5194984078407288 + <_> + + <_> + + + + <_>14 10 6 7 -1. + <_>14 10 3 7 2. + 0 + -9.4687901437282562e-003 + 0.5942280888557434 + 0.4851819872856140 + <_> + + <_> + + + + <_>1 0 16 2 -1. + <_>1 1 16 1 2. + 0 + 1.7084840219467878e-003 + 0.4167110919952393 + 0.5519806146621704 + <_> + + <_> + + + + <_>10 9 10 9 -1. + <_>10 12 10 3 3. + 0 + 9.4809094443917274e-003 + 0.5433894991874695 + 0.4208514988422394 + <_> + + <_> + + + + <_>0 1 10 2 -1. + <_>5 1 5 2 2. + 0 + -4.7389650717377663e-003 + 0.6407189965248108 + 0.4560655057430267 + <_> + + <_> + + + + <_>17 3 2 3 -1. + <_>17 4 2 1 3. + 0 + 6.5761050209403038e-003 + 0.5214555263519287 + 0.2258227020502091 + <_> + + <_> + + + + <_>1 3 2 3 -1. + <_>1 4 2 1 3. + 0 + -2.1690549328923225e-003 + 0.3151527941226959 + 0.5156704783439636 + <_> + + <_> + + + + <_>9 7 3 6 -1. + <_>10 7 1 6 3. + 0 + 0.0146601703017950 + 0.4870837032794952 + 0.6689941287040710 + <_> + + <_> + + + + <_>6 5 4 3 -1. + <_>8 5 2 3 2. + 0 + 1.7231999663636088e-004 + 0.3569748997688294 + 0.5251078009605408 + <_> + + <_> + + + + <_>7 5 6 6 -1. + <_>9 5 2 6 3. + 0 + -0.0218037609010935 + 0.8825920820236206 + 0.4966329932212830 + <_> + + <_> + + + + <_>3 4 12 12 -1. + <_>3 4 6 6 2. + <_>9 10 6 6 2. + 0 + -0.0947361066937447 + 0.1446162015199661 + 0.5061113834381104 + <_> + + <_> + + + + <_>9 2 6 15 -1. + <_>11 2 2 15 3. + 0 + 5.5825551971793175e-003 + 0.5396478772163391 + 0.4238066077232361 + <_> + + <_> + + + + <_>2 2 6 17 -1. + <_>4 2 2 17 3. + 0 + 1.9517090404406190e-003 + 0.4170410931110382 + 0.5497786998748779 + <_> + + <_> + + + + <_>14 10 6 7 -1. + <_>14 10 3 7 2. + 0 + 0.0121499001979828 + 0.4698367118835449 + 0.5664274096488953 + <_> + + <_> + + + + <_>0 10 6 7 -1. + <_>3 10 3 7 2. + 0 + -7.5169620104134083e-003 + 0.6267772912979126 + 0.4463135898113251 + <_> + + <_> + + + + <_>9 2 6 15 -1. + <_>11 2 2 15 3. + 0 + -0.0716679096221924 + 0.3097011148929596 + 0.5221003293991089 + <_> + + <_> + + + + <_>5 2 6 15 -1. + <_>7 2 2 15 3. + 0 + -0.0882924199104309 + 0.0811238884925842 + 0.5006365180015564 + <_> + + <_> + + + + <_>17 9 3 6 -1. + <_>17 11 3 2 3. + 0 + 0.0310630798339844 + 0.5155503749847412 + 0.1282255947589874 + <_> + + <_> + + + + <_>6 7 6 6 -1. + <_>8 7 2 6 3. + 0 + 0.0466218404471874 + 0.4699777960777283 + 0.7363960742950440 + <_> + + <_> + + + + <_>1 10 18 6 -1. + <_>10 10 9 3 2. + <_>1 13 9 3 2. + 0 + -0.0121894897893071 + 0.3920530080795288 + 0.5518996715545654 + <_> + + <_> + + + + <_>0 9 10 9 -1. + <_>0 12 10 3 3. + 0 + 0.0130161102861166 + 0.5260658264160156 + 0.3685136139392853 + <_> + + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + -3.4952899441123009e-003 + 0.6339294910430908 + 0.4716280996799469 + <_> + + <_> + + + + <_>5 12 3 4 -1. + <_>5 14 3 2 2. + 0 + -4.4015039748046547e-005 + 0.5333027243614197 + 0.3776184916496277 + <_> + + <_> + + + + <_>3 3 16 12 -1. + <_>3 9 16 6 2. + 0 + -0.1096649020910263 + 0.1765342056751251 + 0.5198346972465515 + <_> + + <_> + + + + <_>1 1 12 12 -1. + <_>1 1 6 6 2. + <_>7 7 6 6 2. + 0 + -9.0279558207839727e-004 + 0.5324159860610962 + 0.3838908076286316 + <_> + + <_> + + + + <_>10 4 2 4 -1. + <_>11 4 1 2 2. + <_>10 6 1 2 2. + 0 + 7.1126641705632210e-004 + 0.4647929966449738 + 0.5755224227905273 + <_> + + <_> + + + + <_>0 9 10 2 -1. + <_>0 9 5 1 2. + <_>5 10 5 1 2. + 0 + -3.1250279862433672e-003 + 0.3236708939075470 + 0.5166770815849304 + <_> + + <_> + + + + <_>9 11 3 3 -1. + <_>9 12 3 1 3. + 0 + 2.4144679773598909e-003 + 0.4787439107894898 + 0.6459717750549316 + <_> + + <_> + + + + <_>3 12 9 2 -1. + <_>3 13 9 1 2. + 0 + 4.4391240226104856e-004 + 0.4409308135509491 + 0.6010255813598633 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -2.2611189342569560e-004 + 0.4038113951683044 + 0.5493255853652954 + 50.1697311401367190 + 12 + -1 + <_> + + + <_> + + <_> + + + + <_>3 4 13 6 -1. + <_>3 6 13 2 3. + 0 + -0.0469012893736362 + 0.6600171923637390 + 0.3743801116943359 + <_> + + <_> + + + + <_>9 7 6 4 -1. + <_>12 7 3 2 2. + <_>9 9 3 2 2. + 0 + -1.4568349579349160e-003 + 0.5783991217613220 + 0.3437797129154205 + <_> + + <_> + + + + <_>1 0 6 8 -1. + <_>4 0 3 8 2. + 0 + 5.5598369799554348e-003 + 0.3622266948223114 + 0.5908216238021851 + <_> + + <_> + + + + <_>9 5 2 12 -1. + <_>9 11 2 6 2. + 0 + 7.3170487303286791e-004 + 0.5500419139862061 + 0.2873558104038239 + <_> + + <_> + + + + <_>4 4 3 10 -1. + <_>4 9 3 5 2. + 0 + 1.3318009441718459e-003 + 0.2673169970512390 + 0.5431019067764282 + <_> + + <_> + + + + <_>6 17 8 3 -1. + <_>6 18 8 1 3. + 0 + 2.4347059661522508e-004 + 0.3855027854442596 + 0.5741388797760010 + <_> + + <_> + + + + <_>0 5 10 6 -1. + <_>0 7 10 2 3. + 0 + -3.0512469820678234e-003 + 0.5503209829330444 + 0.3462845087051392 + <_> + + <_> + + + + <_>13 2 3 2 -1. + <_>13 3 3 1 2. + 0 + -6.8657199153676629e-004 + 0.3291221857070923 + 0.5429509282112122 + <_> + + <_> + + + + <_>7 5 4 5 -1. + <_>9 5 2 5 2. + 0 + 1.4668200165033340e-003 + 0.3588382005691528 + 0.5351811051368713 + <_> + + <_> + + + + <_>12 14 3 6 -1. + <_>12 16 3 2 3. + 0 + 3.2021870720200241e-004 + 0.4296841919422150 + 0.5700234174728394 + <_> + + <_> + + + + <_>1 11 8 2 -1. + <_>1 12 8 1 2. + 0 + 7.4122188379988074e-004 + 0.5282164812088013 + 0.3366870880126953 + <_> + + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + 3.8330298848450184e-003 + 0.4559567868709564 + 0.6257336139678955 + <_> + + <_> + + + + <_>0 5 3 6 -1. + <_>0 7 3 2 3. + 0 + -0.0154564399272203 + 0.2350116968154907 + 0.5129452943801880 + <_> + + <_> + + + + <_>13 2 3 2 -1. + <_>13 3 3 1 2. + 0 + 2.6796779129654169e-003 + 0.5329415202140808 + 0.4155062139034271 + <_> + + <_> + + + + <_>4 14 4 6 -1. + <_>4 14 2 3 2. + <_>6 17 2 3 2. + 0 + 2.8296569362282753e-003 + 0.4273087978363037 + 0.5804538130760193 + <_> + + <_> + + + + <_>13 2 3 2 -1. + <_>13 3 3 1 2. + 0 + -3.9444249123334885e-003 + 0.2912611961364746 + 0.5202686190605164 + <_> + + <_> + + + + <_>8 2 4 12 -1. + <_>8 6 4 4 3. + 0 + 2.7179559692740440e-003 + 0.5307688117027283 + 0.3585677146911621 + <_> + + <_> + + + + <_>14 0 6 8 -1. + <_>17 0 3 4 2. + <_>14 4 3 4 2. + 0 + 5.9077627956867218e-003 + 0.4703775048255920 + 0.5941585898399353 + <_> + + <_> + + + + <_>7 17 3 2 -1. + <_>8 17 1 2 3. + 0 + -4.2240349575877190e-003 + 0.2141567021608353 + 0.5088796019554138 + <_> + + <_> + + + + <_>8 12 4 2 -1. + <_>8 13 4 1 2. + 0 + 4.0725888684391975e-003 + 0.4766413867473602 + 0.6841061115264893 + <_> + + <_> + + + + <_>6 0 8 12 -1. + <_>6 0 4 6 2. + <_>10 6 4 6 2. + 0 + 0.0101495301350951 + 0.5360798835754395 + 0.3748497068881989 + <_> + + <_> + + + + <_>14 0 2 10 -1. + <_>15 0 1 5 2. + <_>14 5 1 5 2. + 0 + -1.8864999583456665e-004 + 0.5720130205154419 + 0.3853805065155029 + <_> + + <_> + + + + <_>5 3 8 6 -1. + <_>5 3 4 3 2. + <_>9 6 4 3 2. + 0 + -4.8864358104765415e-003 + 0.3693122863769531 + 0.5340958833694458 + <_> + + <_> + + + + <_>14 0 6 10 -1. + <_>17 0 3 5 2. + <_>14 5 3 5 2. + 0 + 0.0261584799736738 + 0.4962374866008759 + 0.6059989929199219 + <_> + + <_> + + + + <_>9 14 1 2 -1. + <_>9 15 1 1 2. + 0 + 4.8560759751126170e-004 + 0.4438945949077606 + 0.6012468934059143 + <_> + + <_> + + + + <_>15 10 4 3 -1. + <_>15 11 4 1 3. + 0 + 0.0112687097862363 + 0.5244250297546387 + 0.1840388029813767 + <_> + + <_> + + + + <_>8 14 2 3 -1. + <_>8 15 2 1 3. + 0 + -2.8114619199186563e-003 + 0.6060283780097961 + 0.4409897029399872 + <_> + + <_> + + + + <_>3 13 14 4 -1. + <_>10 13 7 2 2. + <_>3 15 7 2 2. + 0 + -5.6112729944288731e-003 + 0.3891170918941498 + 0.5589237213134766 + <_> + + <_> + + + + <_>1 10 4 3 -1. + <_>1 11 4 1 3. + 0 + 8.5680093616247177e-003 + 0.5069345831871033 + 0.2062619030475617 + <_> + + <_> + + + + <_>9 11 6 1 -1. + <_>11 11 2 1 3. + 0 + -3.8172779022715986e-004 + 0.5882201790809631 + 0.4192610979080200 + <_> + + <_> + + + + <_>5 11 6 1 -1. + <_>7 11 2 1 3. + 0 + -1.7680290329735726e-004 + 0.5533605813980103 + 0.4003368914127350 + <_> + + <_> + + + + <_>3 5 16 15 -1. + <_>3 10 16 5 3. + 0 + 6.5112537704408169e-003 + 0.3310146927833557 + 0.5444191098213196 + <_> + + <_> + + + + <_>6 12 4 2 -1. + <_>8 12 2 2 2. + 0 + -6.5948683186434209e-005 + 0.5433831810951233 + 0.3944905996322632 + <_> + + <_> + + + + <_>4 4 12 10 -1. + <_>10 4 6 5 2. + <_>4 9 6 5 2. + 0 + 6.9939051754772663e-003 + 0.5600358247756958 + 0.4192714095115662 + <_> + + <_> + + + + <_>8 6 3 4 -1. + <_>9 6 1 4 3. + 0 + -4.6744439750909805e-003 + 0.6685466766357422 + 0.4604960978031158 + <_> + + <_> + + + + <_>8 12 4 8 -1. + <_>10 12 2 4 2. + <_>8 16 2 4 2. + 0 + 0.0115898502990603 + 0.5357121229171753 + 0.2926830053329468 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 0.0130078401416540 + 0.4679817855358124 + 0.7307463288307190 + <_> + + <_> + + + + <_>12 2 3 2 -1. + <_>13 2 1 2 3. + 0 + -1.1008579749614000e-003 + 0.3937501013278961 + 0.5415065288543701 + <_> + + <_> + + + + <_>8 15 3 2 -1. + <_>8 16 3 1 2. + 0 + 6.0472649056464434e-004 + 0.4242376089096069 + 0.5604041218757629 + <_> + + <_> + + + + <_>6 0 9 14 -1. + <_>9 0 3 14 3. + 0 + -0.0144948400557041 + 0.3631210029125214 + 0.5293182730674744 + <_> + + <_> + + + + <_>9 6 2 3 -1. + <_>10 6 1 3 2. + 0 + -5.3056948818266392e-003 + 0.6860452294349670 + 0.4621821045875549 + <_> + + <_> + + + + <_>10 8 2 3 -1. + <_>10 9 2 1 3. + 0 + -8.1829127157106996e-004 + 0.3944096863269806 + 0.5420439243316650 + <_> + + <_> + + + + <_>0 9 4 6 -1. + <_>0 11 4 2 3. + 0 + -0.0190775208175182 + 0.1962621957063675 + 0.5037891864776611 + <_> + + <_> + + + + <_>6 0 8 2 -1. + <_>6 1 8 1 2. + 0 + 3.5549470339901745e-004 + 0.4086259007453919 + 0.5613973140716553 + <_> + + <_> + + + + <_>6 14 7 3 -1. + <_>6 15 7 1 3. + 0 + 1.9679730758070946e-003 + 0.4489121139049530 + 0.5926123261451721 + <_> + + <_> + + + + <_>8 10 8 9 -1. + <_>8 13 8 3 3. + 0 + 6.9189141504466534e-003 + 0.5335925817489624 + 0.3728385865688324 + <_> + + <_> + + + + <_>5 2 3 2 -1. + <_>6 2 1 2 3. + 0 + 2.9872779268771410e-003 + 0.5111321210861206 + 0.2975643873214722 + <_> + + <_> + + + + <_>14 1 6 8 -1. + <_>17 1 3 4 2. + <_>14 5 3 4 2. + 0 + -6.2264618463814259e-003 + 0.5541489720344544 + 0.4824537932872772 + <_> + + <_> + + + + <_>0 1 6 8 -1. + <_>0 1 3 4 2. + <_>3 5 3 4 2. + 0 + 0.0133533002808690 + 0.4586423933506012 + 0.6414797902107239 + <_> + + <_> + + + + <_>1 2 18 6 -1. + <_>10 2 9 3 2. + <_>1 5 9 3 2. + 0 + 0.0335052385926247 + 0.5392425060272217 + 0.3429994881153107 + <_> + + <_> + + + + <_>9 3 2 1 -1. + <_>10 3 1 1 2. + 0 + -2.5294460356235504e-003 + 0.1703713983297348 + 0.5013315081596375 + <_> + + <_> + + + + <_>13 2 4 6 -1. + <_>15 2 2 3 2. + <_>13 5 2 3 2. + 0 + -1.2801629491150379e-003 + 0.5305461883544922 + 0.4697405099868774 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 7.0687388069927692e-003 + 0.4615545868873596 + 0.6436504721641541 + <_> + + <_> + + + + <_>13 5 1 3 -1. + <_>13 6 1 1 3. + 0 + 9.6880499040707946e-004 + 0.4833599030971527 + 0.6043894290924072 + <_> + + <_> + + + + <_>2 16 5 3 -1. + <_>2 17 5 1 3. + 0 + 3.9647659286856651e-003 + 0.5187637209892273 + 0.3231816887855530 + <_> + + <_> + + + + <_>13 2 4 6 -1. + <_>15 2 2 3 2. + <_>13 5 2 3 2. + 0 + -0.0220577307045460 + 0.4079256951808929 + 0.5200980901718140 + <_> + + <_> + + + + <_>3 2 4 6 -1. + <_>3 2 2 3 2. + <_>5 5 2 3 2. + 0 + -6.6906312713399529e-004 + 0.5331609249114990 + 0.3815600872039795 + <_> + + <_> + + + + <_>13 5 1 2 -1. + <_>13 6 1 1 2. + 0 + -6.7009328631684184e-004 + 0.5655422210693359 + 0.4688901901245117 + <_> + + <_> + + + + <_>5 5 2 2 -1. + <_>5 6 2 1 2. + 0 + 7.4284552829340100e-004 + 0.4534381031990051 + 0.6287400126457214 + <_> + + <_> + + + + <_>13 9 2 2 -1. + <_>13 9 1 2 2. + 0 + 2.2227810695767403e-003 + 0.5350633263587952 + 0.3303655982017517 + <_> + + <_> + + + + <_>5 9 2 2 -1. + <_>6 9 1 2 2. + 0 + -5.4130521602928638e-003 + 0.1113687008619309 + 0.5005434751510620 + <_> + + <_> + + + + <_>13 17 3 2 -1. + <_>13 18 3 1 2. + 0 + -1.4520040167553816e-005 + 0.5628737807273865 + 0.4325133860111237 + <_> + + <_> + + + + <_>6 16 4 4 -1. + <_>6 16 2 2 2. + <_>8 18 2 2 2. + 0 + 2.3369169502984732e-004 + 0.4165835082530975 + 0.5447791218757629 + <_> + + <_> + + + + <_>9 16 2 3 -1. + <_>9 17 2 1 3. + 0 + 4.2894547805190086e-003 + 0.4860391020774841 + 0.6778649091720581 + <_> + + <_> + + + + <_>0 13 9 6 -1. + <_>0 15 9 2 3. + 0 + 5.9103150852024555e-003 + 0.5262305140495300 + 0.3612113893032074 + <_> + + <_> + + + + <_>9 14 2 6 -1. + <_>9 17 2 3 2. + 0 + 0.0129005396738648 + 0.5319377183914185 + 0.3250288069248200 + <_> + + <_> + + + + <_>9 15 2 3 -1. + <_>9 16 2 1 3. + 0 + 4.6982979401946068e-003 + 0.4618245065212250 + 0.6665925979614258 + <_> + + <_> + + + + <_>1 10 18 6 -1. + <_>1 12 18 2 3. + 0 + 0.0104398597031832 + 0.5505670905113220 + 0.3883604109287262 + <_> + + <_> + + + + <_>8 11 4 2 -1. + <_>8 12 4 1 2. + 0 + 3.0443191062659025e-003 + 0.4697853028774262 + 0.7301844954490662 + <_> + + <_> + + + + <_>7 9 6 2 -1. + <_>7 10 6 1 2. + 0 + -6.1593751888722181e-004 + 0.3830839097499847 + 0.5464984178543091 + <_> + + <_> + + + + <_>8 8 2 3 -1. + <_>8 9 2 1 3. + 0 + -3.4247159492224455e-003 + 0.2566300034523010 + 0.5089530944824219 + <_> + + <_> + + + + <_>17 5 3 4 -1. + <_>18 5 1 4 3. + 0 + -9.3538565561175346e-003 + 0.6469966173171997 + 0.4940795898437500 + <_> + + <_> + + + + <_>1 19 18 1 -1. + <_>7 19 6 1 3. + 0 + 0.0523389987647533 + 0.4745982885360718 + 0.7878770828247070 + <_> + + <_> + + + + <_>9 0 3 2 -1. + <_>10 0 1 2 3. + 0 + 3.5765620414167643e-003 + 0.5306664705276489 + 0.2748498022556305 + <_> + + <_> + + + + <_>1 8 1 6 -1. + <_>1 10 1 2 3. + 0 + 7.1555317845195532e-004 + 0.5413125753402710 + 0.4041908979415894 + <_> + + <_> + + + + <_>12 17 8 3 -1. + <_>12 17 4 3 2. + 0 + -0.0105166798457503 + 0.6158512234687805 + 0.4815283119678497 + <_> + + <_> + + + + <_>0 5 3 4 -1. + <_>1 5 1 4 3. + 0 + 7.7347927726805210e-003 + 0.4695805907249451 + 0.7028980851173401 + <_> + + <_> + + + + <_>9 7 2 3 -1. + <_>9 8 2 1 3. + 0 + -4.3226778507232666e-003 + 0.2849566042423248 + 0.5304684042930603 + <_> + + <_> + + + + <_>7 11 2 2 -1. + <_>7 11 1 1 2. + <_>8 12 1 1 2. + 0 + -2.5534399319440126e-003 + 0.7056984901428223 + 0.4688892066478729 + <_> + + <_> + + + + <_>11 3 2 5 -1. + <_>11 3 1 5 2. + 0 + 1.0268510231981054e-004 + 0.3902932107448578 + 0.5573464035987854 + <_> + + <_> + + + + <_>7 3 2 5 -1. + <_>8 3 1 5 2. + 0 + 7.1395188570022583e-006 + 0.3684231936931610 + 0.5263987779617310 + <_> + + <_> + + + + <_>15 13 2 3 -1. + <_>15 14 2 1 3. + 0 + -1.6711989883333445e-003 + 0.3849175870418549 + 0.5387271046638489 + <_> + + <_> + + + + <_>5 6 2 3 -1. + <_>5 7 2 1 3. + 0 + 4.9260449595749378e-003 + 0.4729771912097931 + 0.7447251081466675 + <_> + + <_> + + + + <_>4 19 15 1 -1. + <_>9 19 5 1 3. + 0 + 4.3908702209591866e-003 + 0.4809181094169617 + 0.5591921806335449 + <_> + + <_> + + + + <_>1 19 15 1 -1. + <_>6 19 5 1 3. + 0 + -0.0177936293184757 + 0.6903678178787231 + 0.4676927030086517 + <_> + + <_> + + + + <_>15 13 2 3 -1. + <_>15 14 2 1 3. + 0 + 2.0469669252634048e-003 + 0.5370690226554871 + 0.3308162093162537 + <_> + + <_> + + + + <_>5 0 4 15 -1. + <_>7 0 2 15 2. + 0 + 0.0298914890736341 + 0.5139865279197693 + 0.3309059143066406 + <_> + + <_> + + + + <_>9 6 2 5 -1. + <_>9 6 1 5 2. + 0 + 1.5494900289922953e-003 + 0.4660237133502960 + 0.6078342795372009 + <_> + + <_> + + + + <_>9 5 2 7 -1. + <_>10 5 1 7 2. + 0 + 1.4956969534978271e-003 + 0.4404835999011993 + 0.5863919854164124 + <_> + + <_> + + + + <_>16 11 3 3 -1. + <_>16 12 3 1 3. + 0 + 9.5885928021743894e-004 + 0.5435971021652222 + 0.4208523035049439 + <_> + + <_> + + + + <_>1 11 3 3 -1. + <_>1 12 3 1 3. + 0 + 4.9643701640889049e-004 + 0.5370578169822693 + 0.4000622034072876 + <_> + + <_> + + + + <_>6 6 8 3 -1. + <_>6 7 8 1 3. + 0 + -2.7280810754746199e-003 + 0.5659412741661072 + 0.4259642958641052 + <_> + + <_> + + + + <_>0 15 6 2 -1. + <_>0 16 6 1 2. + 0 + 2.3026480339467525e-003 + 0.5161657929420471 + 0.3350869119167328 + <_> + + <_> + + + + <_>1 0 18 6 -1. + <_>7 0 6 6 3. + 0 + 0.2515163123607636 + 0.4869661927223206 + 0.7147309780120850 + <_> + + <_> + + + + <_>6 0 3 4 -1. + <_>7 0 1 4 3. + 0 + -4.6328022144734859e-003 + 0.2727448940277100 + 0.5083789825439453 + <_> + + <_> + + + + <_>14 10 4 10 -1. + <_>16 10 2 5 2. + <_>14 15 2 5 2. + 0 + -0.0404344908893108 + 0.6851438879966736 + 0.5021767020225525 + <_> + + <_> + + + + <_>3 2 3 2 -1. + <_>4 2 1 2 3. + 0 + 1.4972220014897175e-005 + 0.4284465014934540 + 0.5522555112838745 + <_> + + <_> + + + + <_>11 2 2 2 -1. + <_>11 3 2 1 2. + 0 + -2.4050309730228037e-004 + 0.4226118922233582 + 0.5390074849128723 + <_> + + <_> + + + + <_>2 10 4 10 -1. + <_>2 10 2 5 2. + <_>4 15 2 5 2. + 0 + 0.0236578397452831 + 0.4744631946086884 + 0.7504366040229797 + <_> + + <_> + + + + <_>0 13 20 6 -1. + <_>10 13 10 3 2. + <_>0 16 10 3 2. + 0 + -8.1449104472994804e-003 + 0.4245058894157410 + 0.5538362860679627 + <_> + + <_> + + + + <_>0 5 2 15 -1. + <_>1 5 1 15 2. + 0 + -3.6992130335420370e-003 + 0.5952357053756714 + 0.4529713094234467 + <_> + + <_> + + + + <_>1 7 18 4 -1. + <_>10 7 9 2 2. + <_>1 9 9 2 2. + 0 + -6.7718601785600185e-003 + 0.4137794077396393 + 0.5473399758338928 + <_> + + <_> + + + + <_>0 0 2 17 -1. + <_>1 0 1 17 2. + 0 + 4.2669530957937241e-003 + 0.4484114944934845 + 0.5797994136810303 + <_> + + <_> + + + + <_>2 6 16 6 -1. + <_>10 6 8 3 2. + <_>2 9 8 3 2. + 0 + 1.7791989957913756e-003 + 0.5624858736991882 + 0.4432444870471954 + <_> + + <_> + + + + <_>8 14 1 3 -1. + <_>8 15 1 1 3. + 0 + 1.6774770338088274e-003 + 0.4637751877307892 + 0.6364241838455200 + <_> + + <_> + + + + <_>8 15 4 2 -1. + <_>8 16 4 1 2. + 0 + 1.1732629500329494e-003 + 0.4544503092765808 + 0.5914415717124939 + <_> + + <_> + + + + <_>5 2 8 2 -1. + <_>5 2 4 1 2. + <_>9 3 4 1 2. + 0 + 8.6998171173036098e-004 + 0.5334752798080444 + 0.3885917961597443 + <_> + + <_> + + + + <_>6 11 8 6 -1. + <_>6 14 8 3 2. + 0 + 7.6378340600058436e-004 + 0.5398585200309753 + 0.3744941949844360 + <_> + + <_> + + + + <_>9 13 2 2 -1. + <_>9 14 2 1 2. + 0 + 1.5684569370932877e-004 + 0.4317873120307922 + 0.5614616274833679 + <_> + + <_> + + + + <_>18 4 2 6 -1. + <_>18 6 2 2 3. + 0 + -0.0215113703161478 + 0.1785925030708313 + 0.5185542702674866 + <_> + + <_> + + + + <_>9 12 2 2 -1. + <_>9 13 2 1 2. + 0 + 1.3081369979772717e-004 + 0.4342499077320099 + 0.5682849884033203 + <_> + + <_> + + + + <_>18 4 2 6 -1. + <_>18 6 2 2 3. + 0 + 0.0219920407980680 + 0.5161716938018799 + 0.2379394024610519 + <_> + + <_> + + + + <_>9 13 1 3 -1. + <_>9 14 1 1 3. + 0 + -8.0136500764638186e-004 + 0.5986763238906860 + 0.4466426968574524 + <_> + + <_> + + + + <_>18 4 2 6 -1. + <_>18 6 2 2 3. + 0 + -8.2736099138855934e-003 + 0.4108217954635620 + 0.5251057147979736 + <_> + + <_> + + + + <_>0 4 2 6 -1. + <_>0 6 2 2 3. + 0 + 3.6831789184361696e-003 + 0.5173814296722412 + 0.3397518098354340 + <_> + + <_> + + + + <_>9 12 3 3 -1. + <_>9 13 3 1 3. + 0 + -7.9525681212544441e-003 + 0.6888983249664307 + 0.4845924079418182 + <_> + + <_> + + + + <_>3 13 2 3 -1. + <_>3 14 2 1 3. + 0 + 1.5382299898192286e-003 + 0.5178567171096802 + 0.3454113900661469 + <_> + + <_> + + + + <_>13 13 4 3 -1. + <_>13 14 4 1 3. + 0 + -0.0140435304492712 + 0.1678421050310135 + 0.5188667774200440 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 1.4315890148282051e-003 + 0.4368256926536560 + 0.5655773878097534 + <_> + + <_> + + + + <_>5 2 10 6 -1. + <_>5 4 10 2 3. + 0 + -0.0340142287313938 + 0.7802296280860901 + 0.4959217011928558 + <_> + + <_> + + + + <_>3 13 4 3 -1. + <_>3 14 4 1 3. + 0 + -0.0120272999629378 + 0.1585101038217545 + 0.5032231807708740 + <_> + + <_> + + + + <_>3 7 15 5 -1. + <_>8 7 5 5 3. + 0 + 0.1331661939620972 + 0.5163304805755615 + 0.2755128145217896 + <_> + + <_> + + + + <_>3 7 12 2 -1. + <_>7 7 4 2 3. + 0 + -1.5221949433907866e-003 + 0.3728317916393280 + 0.5214552283287048 + <_> + + <_> + + + + <_>10 3 3 9 -1. + <_>11 3 1 9 3. + 0 + -9.3929271679371595e-004 + 0.5838379263877869 + 0.4511165022850037 + <_> + + <_> + + + + <_>8 6 4 6 -1. + <_>10 6 2 6 2. + 0 + 0.0277197398245335 + 0.4728286862373352 + 0.7331544756889343 + <_> + + <_> + + + + <_>9 7 4 3 -1. + <_>9 8 4 1 3. + 0 + 3.1030150130391121e-003 + 0.5302202105522156 + 0.4101563096046448 + <_> + + <_> + + + + <_>0 9 4 9 -1. + <_>2 9 2 9 2. + 0 + 0.0778612196445465 + 0.4998334050178528 + 0.1272961944341660 + <_> + + <_> + + + + <_>9 13 3 5 -1. + <_>10 13 1 5 3. + 0 + -0.0158549398183823 + 0.0508333593606949 + 0.5165656208992004 + <_> + + <_> + + + + <_>7 7 6 3 -1. + <_>9 7 2 3 3. + 0 + -4.9725300632417202e-003 + 0.6798133850097656 + 0.4684231877326965 + <_> + + <_> + + + + <_>9 7 3 5 -1. + <_>10 7 1 5 3. + 0 + -9.7676506265997887e-004 + 0.6010771989822388 + 0.4788931906223297 + <_> + + <_> + + + + <_>5 7 8 2 -1. + <_>9 7 4 2 2. + 0 + -2.4647710379213095e-003 + 0.3393397927284241 + 0.5220503807067871 + <_> + + <_> + + + + <_>5 9 12 2 -1. + <_>9 9 4 2 3. + 0 + -6.7937700077891350e-003 + 0.4365136921405792 + 0.5239663124084473 + <_> + + <_> + + + + <_>5 6 10 3 -1. + <_>10 6 5 3 2. + 0 + 0.0326080210506916 + 0.5052723884582520 + 0.2425214946269989 + <_> + + <_> + + + + <_>10 12 3 1 -1. + <_>11 12 1 1 3. + 0 + -5.8514421107247472e-004 + 0.5733973979949951 + 0.4758574068546295 + <_> + + <_> + + + + <_>0 1 11 15 -1. + <_>0 6 11 5 3. + 0 + -0.0296326000243425 + 0.3892289102077484 + 0.5263597965240479 + 66.6691207885742190 + 13 + -1 + <_> + + + <_> + + <_> + + + + <_>1 0 18 6 -1. + <_>7 0 6 6 3. + 0 + 0.0465508513152599 + 0.3276950120925903 + 0.6240522861480713 + <_> + + <_> + + + + <_>7 7 6 1 -1. + <_>9 7 2 1 3. + 0 + 7.9537127166986465e-003 + 0.4256485104560852 + 0.6942939162254334 + <_> + + <_> + + + + <_>5 16 6 4 -1. + <_>5 16 3 2 2. + <_>8 18 3 2 2. + 0 + 6.8221561377868056e-004 + 0.3711487054824829 + 0.5900732874870300 + <_> + + <_> + + + + <_>6 5 9 8 -1. + <_>6 9 9 4 2. + 0 + -1.9348249770700932e-004 + 0.2041133940219879 + 0.5300545096397400 + <_> + + <_> + + + + <_>5 10 2 6 -1. + <_>5 13 2 3 2. + 0 + -2.6710508973337710e-004 + 0.5416126251220703 + 0.3103179037570953 + <_> + + <_> + + + + <_>7 6 8 10 -1. + <_>11 6 4 5 2. + <_>7 11 4 5 2. + 0 + 2.7818060480058193e-003 + 0.5277832746505737 + 0.3467069864273071 + <_> + + <_> + + + + <_>5 6 8 10 -1. + <_>5 6 4 5 2. + <_>9 11 4 5 2. + 0 + -4.6779078547842801e-004 + 0.5308231115341187 + 0.3294492065906525 + <_> + + <_> + + + + <_>9 5 2 2 -1. + <_>9 6 2 1 2. + 0 + -3.0335160772665404e-005 + 0.5773872733116150 + 0.3852097094058991 + <_> + + <_> + + + + <_>5 12 8 2 -1. + <_>5 13 8 1 2. + 0 + 7.8038009814918041e-004 + 0.4317438900470734 + 0.6150057911872864 + <_> + + <_> + + + + <_>10 2 8 2 -1. + <_>10 3 8 1 2. + 0 + -4.2553851380944252e-003 + 0.2933903932571411 + 0.5324292778968811 + <_> + + <_> + + + + <_>4 0 2 10 -1. + <_>4 0 1 5 2. + <_>5 5 1 5 2. + 0 + -2.4735610350035131e-004 + 0.5468844771385193 + 0.3843030035495758 + <_> + + <_> + + + + <_>9 10 2 2 -1. + <_>9 11 2 1 2. + 0 + -1.4724259381182492e-004 + 0.4281542897224426 + 0.5755587220191956 + <_> + + <_> + + + + <_>2 8 15 3 -1. + <_>2 9 15 1 3. + 0 + 1.1864770203828812e-003 + 0.3747301101684570 + 0.5471466183662415 + <_> + + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 2.3936580400913954e-003 + 0.4537783861160278 + 0.6111528873443604 + <_> + + <_> + + + + <_>7 2 3 2 -1. + <_>8 2 1 2 3. + 0 + -1.5390539774671197e-003 + 0.2971341907978058 + 0.5189538002014160 + <_> + + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + -7.1968790143728256e-003 + 0.6699066758155823 + 0.4726476967334747 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -4.1499789222143590e-004 + 0.3384954035282135 + 0.5260317921638489 + <_> + + <_> + + + + <_>17 2 3 6 -1. + <_>17 4 3 2 3. + 0 + 4.4359830208122730e-003 + 0.5399122238159180 + 0.3920140862464905 + <_> + + <_> + + + + <_>1 5 3 4 -1. + <_>2 5 1 4 3. + 0 + 2.6606200262904167e-003 + 0.4482578039169312 + 0.6119617819786072 + <_> + + <_> + + + + <_>14 8 4 6 -1. + <_>14 10 4 2 3. + 0 + -1.5287200221791863e-003 + 0.3711237907409668 + 0.5340266227722168 + <_> + + <_> + + + + <_>1 4 3 8 -1. + <_>2 4 1 8 3. + 0 + -4.7397250309586525e-003 + 0.6031088232994080 + 0.4455145001411438 + <_> + + <_> + + + + <_>8 13 4 6 -1. + <_>8 16 4 3 2. + 0 + -0.0148291299119592 + 0.2838754057884216 + 0.5341861844062805 + <_> + + <_> + + + + <_>3 14 2 2 -1. + <_>3 15 2 1 2. + 0 + 9.2275557108223438e-004 + 0.5209547281265259 + 0.3361653983592987 + <_> + + <_> + + + + <_>14 8 4 6 -1. + <_>14 10 4 2 3. + 0 + 0.0835298076272011 + 0.5119969844818115 + 0.0811644494533539 + <_> + + <_> + + + + <_>2 8 4 6 -1. + <_>2 10 4 2 3. + 0 + -7.5633148662745953e-004 + 0.3317120075225830 + 0.5189831256866455 + <_> + + <_> + + + + <_>10 14 1 6 -1. + <_>10 17 1 3 2. + 0 + 9.8403859883546829e-003 + 0.5247598290443420 + 0.2334959059953690 + <_> + + <_> + + + + <_>7 5 3 6 -1. + <_>8 5 1 6 3. + 0 + -1.5953830443322659e-003 + 0.5750094056129456 + 0.4295622110366821 + <_> + + <_> + + + + <_>11 2 2 6 -1. + <_>12 2 1 3 2. + <_>11 5 1 3 2. + 0 + 3.4766020689858124e-005 + 0.4342445135116577 + 0.5564029216766357 + <_> + + <_> + + + + <_>6 6 6 5 -1. + <_>8 6 2 5 3. + 0 + 0.0298629105091095 + 0.4579147100448608 + 0.6579188108444214 + <_> + + <_> + + + + <_>17 1 3 6 -1. + <_>17 3 3 2 3. + 0 + 0.0113255903124809 + 0.5274311900138855 + 0.3673888146877289 + <_> + + <_> + + + + <_>8 7 3 5 -1. + <_>9 7 1 5 3. + 0 + -8.7828645482659340e-003 + 0.7100368738174439 + 0.4642167091369629 + <_> + + <_> + + + + <_>9 18 3 2 -1. + <_>10 18 1 2 3. + 0 + 4.3639959767460823e-003 + 0.5279216170310974 + 0.2705877125263214 + <_> + + <_> + + + + <_>8 18 3 2 -1. + <_>9 18 1 2 3. + 0 + 4.1804728098213673e-003 + 0.5072525143623352 + 0.2449083030223846 + <_> + + <_> + + + + <_>12 3 5 2 -1. + <_>12 4 5 1 2. + 0 + -4.5668511302210391e-004 + 0.4283105134963989 + 0.5548691153526306 + <_> + + <_> + + + + <_>7 1 5 12 -1. + <_>7 7 5 6 2. + 0 + -3.7140368949621916e-003 + 0.5519387722015381 + 0.4103653132915497 + <_> + + <_> + + + + <_>1 0 18 4 -1. + <_>7 0 6 4 3. + 0 + -0.0253042895346880 + 0.6867002248764038 + 0.4869889020919800 + <_> + + <_> + + + + <_>4 2 2 2 -1. + <_>4 3 2 1 2. + 0 + -3.4454080741852522e-004 + 0.3728874027729034 + 0.5287693142890930 + <_> + + <_> + + + + <_>11 14 4 2 -1. + <_>13 14 2 1 2. + <_>11 15 2 1 2. + 0 + -8.3935231668874621e-004 + 0.6060152053833008 + 0.4616062045097351 + <_> + + <_> + + + + <_>0 2 3 6 -1. + <_>0 4 3 2 3. + 0 + 0.0172800496220589 + 0.5049635767936707 + 0.1819823980331421 + <_> + + <_> + + + + <_>9 7 2 3 -1. + <_>9 8 2 1 3. + 0 + -6.3595077954232693e-003 + 0.1631239950656891 + 0.5232778787612915 + <_> + + <_> + + + + <_>5 5 1 3 -1. + <_>5 6 1 1 3. + 0 + 1.0298109846189618e-003 + 0.4463278055191040 + 0.6176549196243286 + <_> + + <_> + + + + <_>10 10 6 1 -1. + <_>10 10 3 1 2. + 0 + 1.0117109632119536e-003 + 0.5473384857177734 + 0.4300698935985565 + <_> + + <_> + + + + <_>4 10 6 1 -1. + <_>7 10 3 1 2. + 0 + -0.0103088002651930 + 0.1166985034942627 + 0.5000867247581482 + <_> + + <_> + + + + <_>9 17 3 3 -1. + <_>9 18 3 1 3. + 0 + 5.4682018235325813e-003 + 0.4769287109375000 + 0.6719213724136353 + <_> + + <_> + + + + <_>4 14 1 3 -1. + <_>4 15 1 1 3. + 0 + -9.1696460731327534e-004 + 0.3471089899539948 + 0.5178164839744568 + <_> + + <_> + + + + <_>12 5 3 3 -1. + <_>12 6 3 1 3. + 0 + 2.3922820109874010e-003 + 0.4785236120223999 + 0.6216310858726502 + <_> + + <_> + + + + <_>4 5 12 3 -1. + <_>4 6 12 1 3. + 0 + -7.5573818758130074e-003 + 0.5814796090126038 + 0.4410085082054138 + <_> + + <_> + + + + <_>9 8 2 3 -1. + <_>9 9 2 1 3. + 0 + -7.7024032361805439e-004 + 0.3878000080585480 + 0.5465722084045410 + <_> + + <_> + + + + <_>4 9 3 3 -1. + <_>5 9 1 3 3. + 0 + -8.7125990539789200e-003 + 0.1660051047801971 + 0.4995836019515991 + <_> + + <_> + + + + <_>6 0 9 17 -1. + <_>9 0 3 17 3. + 0 + -0.0103063201531768 + 0.4093391001224518 + 0.5274233818054199 + <_> + + <_> + + + + <_>9 12 1 3 -1. + <_>9 13 1 1 3. + 0 + -2.0940979011356831e-003 + 0.6206194758415222 + 0.4572280049324036 + <_> + + <_> + + + + <_>9 5 2 15 -1. + <_>9 10 2 5 3. + 0 + 6.8099051713943481e-003 + 0.5567759275436401 + 0.4155600070953369 + <_> + + <_> + + + + <_>8 14 2 3 -1. + <_>8 15 2 1 3. + 0 + -1.0746059706434608e-003 + 0.5638927817344666 + 0.4353024959564209 + <_> + + <_> + + + + <_>10 14 1 3 -1. + <_>10 15 1 1 3. + 0 + 2.1550289820879698e-003 + 0.4826265871524811 + 0.6749758124351502 + <_> + + <_> + + + + <_>7 1 6 5 -1. + <_>9 1 2 5 3. + 0 + 0.0317423194646835 + 0.5048379898071289 + 0.1883248984813690 + <_> + + <_> + + + + <_>0 0 20 2 -1. + <_>0 0 10 2 2. + 0 + -0.0783827230334282 + 0.2369548976421356 + 0.5260158181190491 + <_> + + <_> + + + + <_>2 13 5 3 -1. + <_>2 14 5 1 3. + 0 + 5.7415119372308254e-003 + 0.5048828721046448 + 0.2776469886302948 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -2.9014600440859795e-003 + 0.6238604784011841 + 0.4693317115306854 + <_> + + <_> + + + + <_>2 5 9 15 -1. + <_>2 10 9 5 3. + 0 + -2.6427931152284145e-003 + 0.3314141929149628 + 0.5169777274131775 + <_> + + <_> + + + + <_>5 0 12 10 -1. + <_>11 0 6 5 2. + <_>5 5 6 5 2. + 0 + -0.1094966009259224 + 0.2380045056343079 + 0.5183441042900085 + <_> + + <_> + + + + <_>5 1 2 3 -1. + <_>6 1 1 3 2. + 0 + 7.4075913289561868e-005 + 0.4069635868072510 + 0.5362150073051453 + <_> + + <_> + + + + <_>10 7 6 1 -1. + <_>12 7 2 1 3. + 0 + -5.0593802006915212e-004 + 0.5506706237792969 + 0.4374594092369080 + <_> + + <_> + + + + <_>3 1 2 10 -1. + <_>3 1 1 5 2. + <_>4 6 1 5 2. + 0 + -8.2131777890026569e-004 + 0.5525709986686707 + 0.4209375977516174 + <_> + + <_> + + + + <_>13 7 2 1 -1. + <_>13 7 1 1 2. + 0 + -6.0276539443293586e-005 + 0.5455474853515625 + 0.4748266041278839 + <_> + + <_> + + + + <_>4 13 4 6 -1. + <_>4 15 4 2 3. + 0 + 6.8065142259001732e-003 + 0.5157995820045471 + 0.3424577116966248 + <_> + + <_> + + + + <_>13 7 2 1 -1. + <_>13 7 1 1 2. + 0 + 1.7202789895236492e-003 + 0.5013207793235779 + 0.6331263780593872 + <_> + + <_> + + + + <_>5 7 2 1 -1. + <_>6 7 1 1 2. + 0 + -1.3016929733566940e-004 + 0.5539718270301819 + 0.4226869940757752 + <_> + + <_> + + + + <_>2 12 18 4 -1. + <_>11 12 9 2 2. + <_>2 14 9 2 2. + 0 + -4.8016388900578022e-003 + 0.4425095021724701 + 0.5430780053138733 + <_> + + <_> + + + + <_>5 7 2 2 -1. + <_>5 7 1 1 2. + <_>6 8 1 1 2. + 0 + -2.5399310979992151e-003 + 0.7145782113075256 + 0.4697605073451996 + <_> + + <_> + + + + <_>16 3 4 2 -1. + <_>16 4 4 1 2. + 0 + -1.4278929447755218e-003 + 0.4070445001125336 + 0.5399605035781860 + <_> + + <_> + + + + <_>0 2 2 18 -1. + <_>0 2 1 9 2. + <_>1 11 1 9 2. + 0 + -0.0251425504684448 + 0.7884690761566162 + 0.4747352004051209 + <_> + + <_> + + + + <_>1 2 18 4 -1. + <_>10 2 9 2 2. + <_>1 4 9 2 2. + 0 + -3.8899609353393316e-003 + 0.4296191930770874 + 0.5577110052108765 + <_> + + <_> + + + + <_>9 14 1 3 -1. + <_>9 15 1 1 3. + 0 + 4.3947459198534489e-003 + 0.4693162143230438 + 0.7023944258689880 + <_> + + <_> + + + + <_>2 12 18 4 -1. + <_>11 12 9 2 2. + <_>2 14 9 2 2. + 0 + 0.0246784202754498 + 0.5242322087287903 + 0.3812510073184967 + <_> + + <_> + + + + <_>0 12 18 4 -1. + <_>0 12 9 2 2. + <_>9 14 9 2 2. + 0 + 0.0380476787686348 + 0.5011739730834961 + 0.1687828004360199 + <_> + + <_> + + + + <_>11 4 5 3 -1. + <_>11 5 5 1 3. + 0 + 7.9424865543842316e-003 + 0.4828582108020783 + 0.6369568109512329 + <_> + + <_> + + + + <_>6 4 7 3 -1. + <_>6 5 7 1 3. + 0 + -1.5110049862414598e-003 + 0.5906485915184021 + 0.4487667977809906 + <_> + + <_> + + + + <_>13 17 3 3 -1. + <_>13 18 3 1 3. + 0 + 6.4201741479337215e-003 + 0.5241097807884216 + 0.2990570068359375 + <_> + + <_> + + + + <_>8 1 3 4 -1. + <_>9 1 1 4 3. + 0 + -2.9802159406244755e-003 + 0.3041465878486633 + 0.5078489780426025 + <_> + + <_> + + + + <_>11 4 2 4 -1. + <_>11 4 1 4 2. + 0 + -7.4580078944563866e-004 + 0.4128139019012451 + 0.5256826281547546 + <_> + + <_> + + + + <_>0 17 9 3 -1. + <_>3 17 3 3 3. + 0 + -0.0104709500446916 + 0.5808395147323608 + 0.4494296014308929 + <_> + + <_> + + + + <_>11 0 2 8 -1. + <_>12 0 1 4 2. + <_>11 4 1 4 2. + 0 + 9.3369204550981522e-003 + 0.5246552824974060 + 0.2658948898315430 + <_> + + <_> + + + + <_>0 8 6 12 -1. + <_>0 8 3 6 2. + <_>3 14 3 6 2. + 0 + 0.0279369000345469 + 0.4674955010414124 + 0.7087256908416748 + <_> + + <_> + + + + <_>10 7 4 12 -1. + <_>10 13 4 6 2. + 0 + 7.4277678504586220e-003 + 0.5409486889839172 + 0.3758518099784851 + <_> + + <_> + + + + <_>5 3 8 14 -1. + <_>5 10 8 7 2. + 0 + -0.0235845092684031 + 0.3758639991283417 + 0.5238550901412964 + <_> + + <_> + + + + <_>14 10 6 1 -1. + <_>14 10 3 1 2. + 0 + 1.1452640173956752e-003 + 0.4329578876495361 + 0.5804247260093689 + <_> + + <_> + + + + <_>0 4 10 4 -1. + <_>0 6 10 2 2. + 0 + -4.3468660442158580e-004 + 0.5280618071556091 + 0.3873069882392883 + <_> + + <_> + + + + <_>10 0 5 8 -1. + <_>10 4 5 4 2. + 0 + 0.0106485402211547 + 0.4902113080024719 + 0.5681251883506775 + <_> + + <_> + + + + <_>8 1 4 8 -1. + <_>8 1 2 4 2. + <_>10 5 2 4 2. + 0 + -3.9418050437234342e-004 + 0.5570880174636841 + 0.4318251013755798 + <_> + + <_> + + + + <_>9 11 6 1 -1. + <_>11 11 2 1 3. + 0 + -1.3270479394122958e-004 + 0.5658439993858337 + 0.4343554973602295 + <_> + + <_> + + + + <_>8 9 3 4 -1. + <_>9 9 1 4 3. + 0 + -2.0125510636717081e-003 + 0.6056739091873169 + 0.4537523984909058 + <_> + + <_> + + + + <_>18 4 2 6 -1. + <_>18 6 2 2 3. + 0 + 2.4854319635778666e-003 + 0.5390477180480957 + 0.4138010144233704 + <_> + + <_> + + + + <_>8 8 3 4 -1. + <_>9 8 1 4 3. + 0 + 1.8237880431115627e-003 + 0.4354828894138336 + 0.5717188715934753 + <_> + + <_> + + + + <_>7 1 13 3 -1. + <_>7 2 13 1 3. + 0 + -0.0166566595435143 + 0.3010913133621216 + 0.5216122865676880 + <_> + + <_> + + + + <_>7 13 6 1 -1. + <_>9 13 2 1 3. + 0 + 8.0349558265879750e-004 + 0.5300151109695435 + 0.3818396925926209 + <_> + + <_> + + + + <_>12 11 3 6 -1. + <_>12 13 3 2 3. + 0 + 3.4170378930866718e-003 + 0.5328028798103333 + 0.4241400063037872 + <_> + + <_> + + + + <_>5 11 6 1 -1. + <_>7 11 2 1 3. + 0 + -3.6222729249857366e-004 + 0.5491728186607361 + 0.4186977148056030 + <_> + + <_> + + + + <_>1 4 18 10 -1. + <_>10 4 9 5 2. + <_>1 9 9 5 2. + 0 + -0.1163002029061317 + 0.1440722048282623 + 0.5226451158523560 + <_> + + <_> + + + + <_>8 6 4 9 -1. + <_>8 9 4 3 3. + 0 + -0.0146950101479888 + 0.7747725248336792 + 0.4715717136859894 + <_> + + <_> + + + + <_>8 6 4 3 -1. + <_>8 7 4 1 3. + 0 + 2.1972130052745342e-003 + 0.5355433821678162 + 0.3315644860267639 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>9 7 1 3 3. + 0 + -4.6965209185145795e-004 + 0.5767235159873962 + 0.4458136856555939 + <_> + + <_> + + + + <_>14 15 4 3 -1. + <_>14 16 4 1 3. + 0 + 6.5144998952746391e-003 + 0.5215674042701721 + 0.3647888898849487 + <_> + + <_> + + + + <_>5 10 3 10 -1. + <_>6 10 1 10 3. + 0 + 0.0213000606745481 + 0.4994204938411713 + 0.1567950993776321 + <_> + + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + 3.1881409231573343e-003 + 0.4742200076580048 + 0.6287270188331604 + <_> + + <_> + + + + <_>0 8 1 6 -1. + <_>0 10 1 2 3. + 0 + 9.0019777417182922e-004 + 0.5347954034805298 + 0.3943752050399780 + <_> + + <_> + + + + <_>10 15 1 3 -1. + <_>10 16 1 1 3. + 0 + -5.1772277802228928e-003 + 0.6727191805839539 + 0.5013138055801392 + <_> + + <_> + + + + <_>2 15 4 3 -1. + <_>2 16 4 1 3. + 0 + -4.3764649890363216e-003 + 0.3106675148010254 + 0.5128793120384216 + <_> + + <_> + + + + <_>18 3 2 8 -1. + <_>19 3 1 4 2. + <_>18 7 1 4 2. + 0 + 2.6299960445612669e-003 + 0.4886310100555420 + 0.5755215883255005 + <_> + + <_> + + + + <_>0 3 2 8 -1. + <_>0 3 1 4 2. + <_>1 7 1 4 2. + 0 + -2.0458688959479332e-003 + 0.6025794148445129 + 0.4558076858520508 + <_> + + <_> + + + + <_>3 7 14 10 -1. + <_>10 7 7 5 2. + <_>3 12 7 5 2. + 0 + 0.0694827064871788 + 0.5240747928619385 + 0.2185259014368057 + <_> + + <_> + + + + <_>0 7 19 3 -1. + <_>0 8 19 1 3. + 0 + 0.0240489393472672 + 0.5011867284774780 + 0.2090622037649155 + <_> + + <_> + + + + <_>12 6 3 3 -1. + <_>12 7 3 1 3. + 0 + 3.1095340382307768e-003 + 0.4866712093353272 + 0.7108548283576965 + <_> + + <_> + + + + <_>0 6 1 3 -1. + <_>0 7 1 1 3. + 0 + -1.2503260513767600e-003 + 0.3407891094684601 + 0.5156195163726807 + <_> + + <_> + + + + <_>12 6 3 3 -1. + <_>12 7 3 1 3. + 0 + -1.0281190043315291e-003 + 0.5575572252273560 + 0.4439432024955750 + <_> + + <_> + + + + <_>5 6 3 3 -1. + <_>5 7 3 1 3. + 0 + -8.8893622159957886e-003 + 0.6402000784873962 + 0.4620442092418671 + <_> + + <_> + + + + <_>8 2 4 2 -1. + <_>8 3 4 1 2. + 0 + -6.1094801640138030e-004 + 0.3766441941261292 + 0.5448899865150452 + <_> + + <_> + + + + <_>6 3 4 12 -1. + <_>8 3 2 12 2. + 0 + -5.7686357758939266e-003 + 0.3318648934364319 + 0.5133677124977112 + <_> + + <_> + + + + <_>13 6 2 3 -1. + <_>13 7 2 1 3. + 0 + 1.8506490159779787e-003 + 0.4903570115566254 + 0.6406934857368469 + <_> + + <_> + + + + <_>0 10 20 4 -1. + <_>0 12 20 2 2. + 0 + -0.0997994691133499 + 0.1536051034927368 + 0.5015562176704407 + <_> + + <_> + + + + <_>2 0 17 14 -1. + <_>2 7 17 7 2. + 0 + -0.3512834906578064 + 0.0588231310248375 + 0.5174378752708435 + <_> + + <_> + + + + <_>0 0 6 10 -1. + <_>0 0 3 5 2. + <_>3 5 3 5 2. + 0 + -0.0452445708215237 + 0.6961488723754883 + 0.4677872955799103 + <_> + + <_> + + + + <_>14 6 6 4 -1. + <_>14 6 3 4 2. + 0 + 0.0714815780520439 + 0.5167986154556274 + 0.1038092970848084 + <_> + + <_> + + + + <_>0 6 6 4 -1. + <_>3 6 3 4 2. + 0 + 2.1895780228078365e-003 + 0.4273078143596649 + 0.5532060861587524 + <_> + + <_> + + + + <_>13 2 7 2 -1. + <_>13 3 7 1 2. + 0 + -5.9242651332169771e-004 + 0.4638943970203400 + 0.5276389122009277 + <_> + + <_> + + + + <_>0 2 7 2 -1. + <_>0 3 7 1 2. + 0 + 1.6788389766588807e-003 + 0.5301648974418640 + 0.3932034969329834 + <_> + + <_> + + + + <_>6 11 14 2 -1. + <_>13 11 7 1 2. + <_>6 12 7 1 2. + 0 + -2.2163488902151585e-003 + 0.5630694031715393 + 0.4757033884525299 + <_> + + <_> + + + + <_>8 5 2 2 -1. + <_>8 5 1 1 2. + <_>9 6 1 1 2. + 0 + 1.1568699846975505e-004 + 0.4307535886764526 + 0.5535702705383301 + <_> + + <_> + + + + <_>13 9 2 3 -1. + <_>13 9 1 3 2. + 0 + -7.2017288766801357e-003 + 0.1444882005453110 + 0.5193064212799072 + <_> + + <_> + + + + <_>1 1 3 12 -1. + <_>2 1 1 12 3. + 0 + 8.9081272017210722e-004 + 0.4384432137012482 + 0.5593621134757996 + <_> + + <_> + + + + <_>17 4 1 3 -1. + <_>17 5 1 1 3. + 0 + 1.9605009583756328e-004 + 0.5340415835380554 + 0.4705956876277924 + <_> + + <_> + + + + <_>2 4 1 3 -1. + <_>2 5 1 1 3. + 0 + 5.2022142335772514e-004 + 0.5213856101036072 + 0.3810079097747803 + <_> + + <_> + + + + <_>14 5 1 3 -1. + <_>14 6 1 1 3. + 0 + 9.4588572392240167e-004 + 0.4769414961338043 + 0.6130738854408264 + <_> + + <_> + + + + <_>7 16 2 3 -1. + <_>7 17 2 1 3. + 0 + 9.1698471806012094e-005 + 0.4245009124279022 + 0.5429363250732422 + <_> + + <_> + + + + <_>8 13 4 6 -1. + <_>10 13 2 3 2. + <_>8 16 2 3 2. + 0 + 2.1833200007677078e-003 + 0.5457730889320374 + 0.4191075861454010 + <_> + + <_> + + + + <_>5 5 1 3 -1. + <_>5 6 1 1 3. + 0 + -8.6039671441540122e-004 + 0.5764588713645935 + 0.4471659958362579 + <_> + + <_> + + + + <_>16 0 4 20 -1. + <_>16 0 2 20 2. + 0 + -0.0132362395524979 + 0.6372823119163513 + 0.4695009887218475 + <_> + + <_> + + + + <_>5 1 2 6 -1. + <_>5 1 1 3 2. + <_>6 4 1 3 2. + 0 + 4.3376701069064438e-004 + 0.5317873954772949 + 0.3945829868316650 + 67.6989212036132810 + 14 + -1 + <_> + + + <_> + + <_> + + + + <_>5 4 10 4 -1. + <_>5 6 10 2 2. + 0 + -0.0248471498489380 + 0.6555516719818115 + 0.3873311877250671 + <_> + + <_> + + + + <_>15 2 4 12 -1. + <_>15 2 2 12 2. + 0 + 6.1348611488938332e-003 + 0.3748072087764740 + 0.5973997712135315 + <_> + + <_> + + + + <_>7 6 4 12 -1. + <_>7 12 4 6 2. + 0 + 6.4498498104512691e-003 + 0.5425491929054260 + 0.2548811137676239 + <_> + + <_> + + + + <_>14 5 1 8 -1. + <_>14 9 1 4 2. + 0 + 6.3491211039945483e-004 + 0.2462442070245743 + 0.5387253761291504 + <_> + + <_> + + + + <_>1 4 14 10 -1. + <_>1 4 7 5 2. + <_>8 9 7 5 2. + 0 + 1.4023890253156424e-003 + 0.5594322085380554 + 0.3528657853603363 + <_> + + <_> + + + + <_>11 6 6 14 -1. + <_>14 6 3 7 2. + <_>11 13 3 7 2. + 0 + 3.0044000595808029e-004 + 0.3958503901958466 + 0.5765938162803650 + <_> + + <_> + + + + <_>3 6 6 14 -1. + <_>3 6 3 7 2. + <_>6 13 3 7 2. + 0 + 1.0042409849120304e-004 + 0.3698996901512146 + 0.5534998178482056 + <_> + + <_> + + + + <_>4 9 15 2 -1. + <_>9 9 5 2 3. + 0 + -5.0841490738093853e-003 + 0.3711090981960297 + 0.5547800064086914 + <_> + + <_> + + + + <_>7 14 6 3 -1. + <_>7 15 6 1 3. + 0 + -0.0195372607558966 + 0.7492755055427551 + 0.4579297006130219 + <_> + + <_> + + + + <_>6 3 14 4 -1. + <_>13 3 7 2 2. + <_>6 5 7 2 2. + 0 + -7.4532740654831287e-006 + 0.5649787187576294 + 0.3904069960117340 + <_> + + <_> + + + + <_>1 9 15 2 -1. + <_>6 9 5 2 3. + 0 + -3.6079459823668003e-003 + 0.3381088078022003 + 0.5267801284790039 + <_> + + <_> + + + + <_>6 11 8 9 -1. + <_>6 14 8 3 3. + 0 + 2.0697501022368670e-003 + 0.5519291162490845 + 0.3714388906955719 + <_> + + <_> + + + + <_>7 4 3 8 -1. + <_>8 4 1 8 3. + 0 + -4.6463840408250690e-004 + 0.5608214735984802 + 0.4113566875457764 + <_> + + <_> + + + + <_>14 6 2 6 -1. + <_>14 9 2 3 2. + 0 + 7.5490452582016587e-004 + 0.3559206128120422 + 0.5329356193542481 + <_> + + <_> + + + + <_>5 7 6 4 -1. + <_>5 7 3 2 2. + <_>8 9 3 2 2. + 0 + -9.8322238773107529e-004 + 0.5414795875549316 + 0.3763205111026764 + <_> + + <_> + + + + <_>1 1 18 19 -1. + <_>7 1 6 19 3. + 0 + -0.0199406407773495 + 0.6347903013229370 + 0.4705299139022827 + <_> + + <_> + + + + <_>1 2 6 5 -1. + <_>4 2 3 5 2. + 0 + 3.7680300883948803e-003 + 0.3913489878177643 + 0.5563716292381287 + <_> + + <_> + + + + <_>12 17 6 2 -1. + <_>12 18 6 1 2. + 0 + -9.4528505578637123e-003 + 0.2554892897605896 + 0.5215116739273071 + <_> + + <_> + + + + <_>2 17 6 2 -1. + <_>2 18 6 1 2. + 0 + 2.9560849070549011e-003 + 0.5174679160118103 + 0.3063920140266419 + <_> + + <_> + + + + <_>17 3 3 6 -1. + <_>17 5 3 2 3. + 0 + 9.1078737750649452e-003 + 0.5388448238372803 + 0.2885963022708893 + <_> + + <_> + + + + <_>8 17 3 3 -1. + <_>8 18 3 1 3. + 0 + 1.8219229532405734e-003 + 0.4336043000221252 + 0.5852196812629700 + <_> + + <_> + + + + <_>10 13 2 6 -1. + <_>10 16 2 3 2. + 0 + 0.0146887395530939 + 0.5287361741065979 + 0.2870005965232849 + <_> + + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + -0.0143879903480411 + 0.7019448876380920 + 0.4647370874881744 + <_> + + <_> + + + + <_>17 3 3 6 -1. + <_>17 5 3 2 3. + 0 + -0.0189866498112679 + 0.2986552119255066 + 0.5247011780738831 + <_> + + <_> + + + + <_>8 13 2 3 -1. + <_>8 14 2 1 3. + 0 + 1.1527639580890536e-003 + 0.4323473870754242 + 0.5931661725044251 + <_> + + <_> + + + + <_>9 3 6 2 -1. + <_>11 3 2 2 3. + 0 + 0.0109336702153087 + 0.5286864042282105 + 0.3130319118499756 + <_> + + <_> + + + + <_>0 3 3 6 -1. + <_>0 5 3 2 3. + 0 + -0.0149327302351594 + 0.2658419013023377 + 0.5084077119827271 + <_> + + <_> + + + + <_>8 5 4 6 -1. + <_>8 7 4 2 3. + 0 + -2.9970539617352188e-004 + 0.5463526844978333 + 0.3740724027156830 + <_> + + <_> + + + + <_>5 5 3 2 -1. + <_>5 6 3 1 2. + 0 + 4.1677621193230152e-003 + 0.4703496992588043 + 0.7435721755027771 + <_> + + <_> + + + + <_>10 1 3 4 -1. + <_>11 1 1 4 3. + 0 + -6.3905320130288601e-003 + 0.2069258987903595 + 0.5280538201332092 + <_> + + <_> + + + + <_>1 2 5 9 -1. + <_>1 5 5 3 3. + 0 + 4.5029609464108944e-003 + 0.5182648897171021 + 0.3483543097972870 + <_> + + <_> + + + + <_>13 6 2 3 -1. + <_>13 7 2 1 3. + 0 + -9.2040365561842918e-003 + 0.6803777217864990 + 0.4932360053062439 + <_> + + <_> + + + + <_>0 6 14 3 -1. + <_>7 6 7 3 2. + 0 + 0.0813272595405579 + 0.5058398842811585 + 0.2253051996231079 + <_> + + <_> + + + + <_>2 11 18 8 -1. + <_>2 15 18 4 2. + 0 + -0.1507928073406220 + 0.2963424921035767 + 0.5264679789543152 + <_> + + <_> + + + + <_>5 6 2 3 -1. + <_>5 7 2 1 3. + 0 + 3.3179009333252907e-003 + 0.4655495882034302 + 0.7072932124137878 + <_> + + <_> + + + + <_>10 6 4 2 -1. + <_>12 6 2 1 2. + <_>10 7 2 1 2. + 0 + 7.7402801252901554e-004 + 0.4780347943305969 + 0.5668237805366516 + <_> + + <_> + + + + <_>6 6 4 2 -1. + <_>6 6 2 1 2. + <_>8 7 2 1 2. + 0 + 6.8199541419744492e-004 + 0.4286996126174927 + 0.5722156763076782 + <_> + + <_> + + + + <_>10 1 3 4 -1. + <_>11 1 1 4 3. + 0 + 5.3671570494771004e-003 + 0.5299307107925415 + 0.3114621937274933 + <_> + + <_> + + + + <_>7 1 2 7 -1. + <_>8 1 1 7 2. + 0 + 9.7018666565418243e-005 + 0.3674638867378235 + 0.5269461870193481 + <_> + + <_> + + + + <_>4 2 15 14 -1. + <_>4 9 15 7 2. + 0 + -0.1253408938646317 + 0.2351492047309876 + 0.5245791077613831 + <_> + + <_> + + + + <_>8 7 3 2 -1. + <_>9 7 1 2 3. + 0 + -5.2516269497573376e-003 + 0.7115936875343323 + 0.4693767130374908 + <_> + + <_> + + + + <_>2 3 18 4 -1. + <_>11 3 9 2 2. + <_>2 5 9 2 2. + 0 + -7.8342109918594360e-003 + 0.4462651014328003 + 0.5409085750579834 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>10 7 1 2 2. + 0 + -1.1310069821774960e-003 + 0.5945618748664856 + 0.4417662024497986 + <_> + + <_> + + + + <_>13 9 2 3 -1. + <_>13 9 1 3 2. + 0 + 1.7601120052859187e-003 + 0.5353249907493591 + 0.3973453044891357 + <_> + + <_> + + + + <_>5 2 6 2 -1. + <_>7 2 2 2 3. + 0 + -8.1581249833106995e-004 + 0.3760268092155457 + 0.5264726877212524 + <_> + + <_> + + + + <_>9 5 2 7 -1. + <_>9 5 1 7 2. + 0 + -3.8687589112669230e-003 + 0.6309912800788879 + 0.4749819934368134 + <_> + + <_> + + + + <_>5 9 2 3 -1. + <_>6 9 1 3 2. + 0 + 1.5207129763439298e-003 + 0.5230181813240051 + 0.3361223936080933 + <_> + + <_> + + + + <_>6 0 14 18 -1. + <_>6 9 14 9 2. + 0 + 0.5458673834800720 + 0.5167139768600464 + 0.1172635033726692 + <_> + + <_> + + + + <_>2 16 6 3 -1. + <_>2 17 6 1 3. + 0 + 0.0156501904129982 + 0.4979439079761505 + 0.1393294930458069 + <_> + + <_> + + + + <_>9 7 3 6 -1. + <_>10 7 1 6 3. + 0 + -0.0117318602278829 + 0.7129650712013245 + 0.4921196103096008 + <_> + + <_> + + + + <_>7 8 4 3 -1. + <_>7 9 4 1 3. + 0 + -6.1765122227370739e-003 + 0.2288102954626083 + 0.5049701929092407 + <_> + + <_> + + + + <_>7 12 6 3 -1. + <_>7 13 6 1 3. + 0 + 2.2457661107182503e-003 + 0.4632433950901032 + 0.6048725843429565 + <_> + + <_> + + + + <_>9 12 2 3 -1. + <_>9 13 2 1 3. + 0 + -5.1915869116783142e-003 + 0.6467421054840088 + 0.4602192938327789 + <_> + + <_> + + + + <_>7 12 6 2 -1. + <_>9 12 2 2 3. + 0 + -0.0238278806209564 + 0.1482000946998596 + 0.5226079225540161 + <_> + + <_> + + + + <_>5 11 4 6 -1. + <_>5 14 4 3 2. + 0 + 1.0284580057486892e-003 + 0.5135489106178284 + 0.3375957012176514 + <_> + + <_> + + + + <_>11 12 7 2 -1. + <_>11 13 7 1 2. + 0 + -0.0100788502022624 + 0.2740561068058014 + 0.5303567051887512 + <_> + + <_> + + + + <_>6 10 8 6 -1. + <_>6 10 4 3 2. + <_>10 13 4 3 2. + 0 + 2.6168930344283581e-003 + 0.5332670807838440 + 0.3972454071044922 + <_> + + <_> + + + + <_>11 10 3 4 -1. + <_>11 12 3 2 2. + 0 + 5.4385367548093200e-004 + 0.5365604162216187 + 0.4063411951065064 + <_> + + <_> + + + + <_>9 16 2 3 -1. + <_>9 17 2 1 3. + 0 + 5.3510512225329876e-003 + 0.4653759002685547 + 0.6889045834541321 + <_> + + <_> + + + + <_>13 3 1 9 -1. + <_>13 6 1 3 3. + 0 + -1.5274790348485112e-003 + 0.5449501276016235 + 0.3624723851680756 + <_> + + <_> + + + + <_>1 13 14 6 -1. + <_>1 15 14 2 3. + 0 + -0.0806244164705276 + 0.1656087040901184 + 0.5000287294387817 + <_> + + <_> + + + + <_>13 6 1 6 -1. + <_>13 9 1 3 2. + 0 + 0.0221920292824507 + 0.5132731199264526 + 0.2002808004617691 + <_> + + <_> + + + + <_>0 4 3 8 -1. + <_>1 4 1 8 3. + 0 + 7.3100631125271320e-003 + 0.4617947936058044 + 0.6366536021232605 + <_> + + <_> + + + + <_>18 0 2 18 -1. + <_>18 0 1 18 2. + 0 + -6.4063072204589844e-003 + 0.5916250944137573 + 0.4867860972881317 + <_> + + <_> + + + + <_>2 3 6 2 -1. + <_>2 4 6 1 2. + 0 + -7.6415040530264378e-004 + 0.3888409137725830 + 0.5315797924995422 + <_> + + <_> + + + + <_>9 0 8 6 -1. + <_>9 2 8 2 3. + 0 + 7.6734489994123578e-004 + 0.4159064888954163 + 0.5605279803276062 + <_> + + <_> + + + + <_>6 6 1 6 -1. + <_>6 9 1 3 2. + 0 + 6.1474501853808761e-004 + 0.3089022040367127 + 0.5120148062705994 + <_> + + <_> + + + + <_>14 8 6 3 -1. + <_>14 9 6 1 3. + 0 + -5.0105270929634571e-003 + 0.3972199857234955 + 0.5207306146621704 + <_> + + <_> + + + + <_>0 0 2 18 -1. + <_>1 0 1 18 2. + 0 + -8.6909132078289986e-003 + 0.6257408261299133 + 0.4608575999736786 + <_> + + <_> + + + + <_>1 18 18 2 -1. + <_>10 18 9 1 2. + <_>1 19 9 1 2. + 0 + -0.0163914598524570 + 0.2085209935903549 + 0.5242266058921814 + <_> + + <_> + + + + <_>3 15 2 2 -1. + <_>3 16 2 1 2. + 0 + 4.0973909199237823e-004 + 0.5222427248954773 + 0.3780320882797241 + <_> + + <_> + + + + <_>8 14 5 3 -1. + <_>8 15 5 1 3. + 0 + -2.5242289993911982e-003 + 0.5803927183151245 + 0.4611890017986298 + <_> + + <_> + + + + <_>8 14 2 3 -1. + <_>8 15 2 1 3. + 0 + 5.0945312250405550e-004 + 0.4401271939277649 + 0.5846015810966492 + <_> + + <_> + + + + <_>12 3 3 3 -1. + <_>13 3 1 3 3. + 0 + 1.9656419754028320e-003 + 0.5322325229644775 + 0.4184590876102448 + <_> + + <_> + + + + <_>7 5 6 2 -1. + <_>9 5 2 2 3. + 0 + 5.6298897834494710e-004 + 0.3741844892501831 + 0.5234565734863281 + <_> + + <_> + + + + <_>15 5 5 2 -1. + <_>15 6 5 1 2. + 0 + -6.7946797935292125e-004 + 0.4631041884422302 + 0.5356478095054627 + <_> + + <_> + + + + <_>0 5 5 2 -1. + <_>0 6 5 1 2. + 0 + 7.2856349870562553e-003 + 0.5044670104980469 + 0.2377564013004303 + <_> + + <_> + + + + <_>17 14 1 6 -1. + <_>17 17 1 3 2. + 0 + -0.0174594894051552 + 0.7289121150970459 + 0.5050435066223145 + <_> + + <_> + + + + <_>2 9 9 3 -1. + <_>5 9 3 3 3. + 0 + -0.0254217498004436 + 0.6667134761810303 + 0.4678100049495697 + <_> + + <_> + + + + <_>12 3 3 3 -1. + <_>13 3 1 3 3. + 0 + -1.5647639520466328e-003 + 0.4391759037971497 + 0.5323626995086670 + <_> + + <_> + + + + <_>0 0 4 18 -1. + <_>2 0 2 18 2. + 0 + 0.0114443600177765 + 0.4346440136432648 + 0.5680012106895447 + <_> + + <_> + + + + <_>17 6 1 3 -1. + <_>17 7 1 1 3. + 0 + -6.7352550104260445e-004 + 0.4477140903472900 + 0.5296812057495117 + <_> + + <_> + + + + <_>2 14 1 6 -1. + <_>2 17 1 3 2. + 0 + 9.3194209039211273e-003 + 0.4740200042724609 + 0.7462607026100159 + <_> + + <_> + + + + <_>19 8 1 2 -1. + <_>19 9 1 1 2. + 0 + 1.3328490604180843e-004 + 0.5365061759948731 + 0.4752134978771210 + <_> + + <_> + + + + <_>5 3 3 3 -1. + <_>6 3 1 3 3. + 0 + -7.8815799206495285e-003 + 0.1752219051122665 + 0.5015255212783814 + <_> + + <_> + + + + <_>9 16 2 3 -1. + <_>9 17 2 1 3. + 0 + -5.7985680177807808e-003 + 0.7271236777305603 + 0.4896200895309448 + <_> + + <_> + + + + <_>2 6 1 3 -1. + <_>2 7 1 1 3. + 0 + -3.8922499516047537e-004 + 0.4003908932209015 + 0.5344941020011902 + <_> + + <_> + + + + <_>12 4 8 2 -1. + <_>16 4 4 1 2. + <_>12 5 4 1 2. + 0 + -1.9288610201328993e-003 + 0.5605612993240356 + 0.4803955852985382 + <_> + + <_> + + + + <_>0 4 8 2 -1. + <_>0 4 4 1 2. + <_>4 5 4 1 2. + 0 + 8.4214154630899429e-003 + 0.4753246903419495 + 0.7623608708381653 + <_> + + <_> + + + + <_>2 16 18 4 -1. + <_>2 18 18 2 2. + 0 + 8.1655876711010933e-003 + 0.5393261909484863 + 0.4191643893718720 + <_> + + <_> + + + + <_>7 15 2 4 -1. + <_>7 17 2 2 2. + 0 + 4.8280550981871784e-004 + 0.4240800142288208 + 0.5399821996688843 + <_> + + <_> + + + + <_>4 0 14 3 -1. + <_>4 1 14 1 3. + 0 + -2.7186630759388208e-003 + 0.4244599938392639 + 0.5424923896789551 + <_> + + <_> + + + + <_>0 0 4 20 -1. + <_>2 0 2 20 2. + 0 + -0.0125072300434113 + 0.5895841717720032 + 0.4550411105155945 + <_> + + <_> + + + + <_>12 4 4 8 -1. + <_>14 4 2 4 2. + <_>12 8 2 4 2. + 0 + -0.0242865197360516 + 0.2647134959697723 + 0.5189179778099060 + <_> + + <_> + + + + <_>6 7 2 2 -1. + <_>6 7 1 1 2. + <_>7 8 1 1 2. + 0 + -2.9676330741494894e-003 + 0.7347682714462280 + 0.4749749898910523 + <_> + + <_> + + + + <_>10 6 2 3 -1. + <_>10 7 2 1 3. + 0 + -0.0125289997085929 + 0.2756049931049347 + 0.5177599787712097 + <_> + + <_> + + + + <_>8 7 3 2 -1. + <_>8 8 3 1 2. + 0 + -1.0104000102728605e-003 + 0.3510560989379883 + 0.5144724249839783 + <_> + + <_> + + + + <_>8 2 6 12 -1. + <_>8 8 6 6 2. + 0 + -2.1348530426621437e-003 + 0.5637925863265991 + 0.4667319953441620 + <_> + + <_> + + + + <_>4 0 11 12 -1. + <_>4 4 11 4 3. + 0 + 0.0195642597973347 + 0.4614573121070862 + 0.6137639880180359 + <_> + + <_> + + + + <_>14 9 6 11 -1. + <_>16 9 2 11 3. + 0 + -0.0971463471651077 + 0.2998378872871399 + 0.5193555951118469 + <_> + + <_> + + + + <_>0 14 4 3 -1. + <_>0 15 4 1 3. + 0 + 4.5014568604528904e-003 + 0.5077884793281555 + 0.3045755922794342 + <_> + + <_> + + + + <_>9 10 2 3 -1. + <_>9 11 2 1 3. + 0 + 6.3706971704959869e-003 + 0.4861018955707550 + 0.6887500882148743 + <_> + + <_> + + + + <_>5 11 3 2 -1. + <_>5 12 3 1 2. + 0 + -9.0721528977155685e-003 + 0.1673395931720734 + 0.5017563104629517 + <_> + + <_> + + + + <_>9 15 3 3 -1. + <_>10 15 1 3 3. + 0 + -5.3537208586931229e-003 + 0.2692756950855255 + 0.5242633223533630 + <_> + + <_> + + + + <_>8 8 3 4 -1. + <_>9 8 1 4 3. + 0 + -0.0109328404068947 + 0.7183864116668701 + 0.4736028909683228 + <_> + + <_> + + + + <_>9 15 3 3 -1. + <_>10 15 1 3 3. + 0 + 8.2356072962284088e-003 + 0.5223966836929321 + 0.2389862984418869 + <_> + + <_> + + + + <_>7 7 3 2 -1. + <_>8 7 1 2 3. + 0 + -1.0038160253316164e-003 + 0.5719355940818787 + 0.4433943033218384 + <_> + + <_> + + + + <_>2 10 16 4 -1. + <_>10 10 8 2 2. + <_>2 12 8 2 2. + 0 + 4.0859128348529339e-003 + 0.5472841858863831 + 0.4148836135864258 + <_> + + <_> + + + + <_>2 3 4 17 -1. + <_>4 3 2 17 2. + 0 + 0.1548541933298111 + 0.4973812103271484 + 0.0610615983605385 + <_> + + <_> + + + + <_>15 13 2 7 -1. + <_>15 13 1 7 2. + 0 + 2.0897459762636572e-004 + 0.4709174036979675 + 0.5423889160156250 + <_> + + <_> + + + + <_>2 2 6 1 -1. + <_>5 2 3 1 2. + 0 + 3.3316991175524890e-004 + 0.4089626967906952 + 0.5300992131233215 + <_> + + <_> + + + + <_>5 2 12 4 -1. + <_>9 2 4 4 3. + 0 + -0.0108134001493454 + 0.6104369759559631 + 0.4957334101200104 + <_> + + <_> + + + + <_>6 0 8 12 -1. + <_>6 0 4 6 2. + <_>10 6 4 6 2. + 0 + 0.0456560105085373 + 0.5069689154624939 + 0.2866660058498383 + <_> + + <_> + + + + <_>13 7 2 2 -1. + <_>14 7 1 1 2. + <_>13 8 1 1 2. + 0 + 1.2569549726322293e-003 + 0.4846917092800140 + 0.6318171024322510 + <_> + + <_> + + + + <_>0 12 20 6 -1. + <_>0 14 20 2 3. + 0 + -0.1201507002115250 + 0.0605261400341988 + 0.4980959892272949 + <_> + + <_> + + + + <_>14 7 2 3 -1. + <_>14 7 1 3 2. + 0 + -1.0533799650147557e-004 + 0.5363109707832336 + 0.4708042144775391 + <_> + + <_> + + + + <_>0 8 9 12 -1. + <_>3 8 3 12 3. + 0 + -0.2070319056510925 + 0.0596603304147720 + 0.4979098141193390 + <_> + + <_> + + + + <_>3 0 16 2 -1. + <_>3 0 8 2 2. + 0 + 1.2909180077258497e-004 + 0.4712977111339569 + 0.5377997756004334 + <_> + + <_> + + + + <_>6 15 3 3 -1. + <_>6 16 3 1 3. + 0 + 3.8818528992123902e-004 + 0.4363538026809692 + 0.5534191131591797 + <_> + + <_> + + + + <_>8 15 6 3 -1. + <_>8 16 6 1 3. + 0 + -2.9243610333651304e-003 + 0.5811185836791992 + 0.4825215935707092 + <_> + + <_> + + + + <_>0 10 1 6 -1. + <_>0 12 1 2 3. + 0 + 8.3882332546636462e-004 + 0.5311700105667114 + 0.4038138985633850 + <_> + + <_> + + + + <_>10 9 4 3 -1. + <_>10 10 4 1 3. + 0 + -1.9061550265178084e-003 + 0.3770701885223389 + 0.5260015130043030 + <_> + + <_> + + + + <_>9 15 2 3 -1. + <_>9 16 2 1 3. + 0 + 8.9514348655939102e-003 + 0.4766167998313904 + 0.7682183980941773 + <_> + + <_> + + + + <_>5 7 10 1 -1. + <_>5 7 5 1 2. + 0 + 0.0130834598094225 + 0.5264462828636169 + 0.3062222003936768 + <_> + + <_> + + + + <_>4 0 12 19 -1. + <_>10 0 6 19 2. + 0 + -0.2115933001041412 + 0.6737198233604431 + 0.4695810079574585 + <_> + + <_> + + + + <_>0 6 20 6 -1. + <_>10 6 10 3 2. + <_>0 9 10 3 2. + 0 + 3.1493250280618668e-003 + 0.5644835233688355 + 0.4386953115463257 + <_> + + <_> + + + + <_>3 6 2 2 -1. + <_>3 6 1 1 2. + <_>4 7 1 1 2. + 0 + 3.9754100725986063e-004 + 0.4526061117649078 + 0.5895630121231079 + <_> + + <_> + + + + <_>15 6 2 2 -1. + <_>16 6 1 1 2. + <_>15 7 1 1 2. + 0 + -1.3814480043947697e-003 + 0.6070582270622253 + 0.4942413866519928 + <_> + + <_> + + + + <_>3 6 2 2 -1. + <_>3 6 1 1 2. + <_>4 7 1 1 2. + 0 + -5.8122188784182072e-004 + 0.5998213291168213 + 0.4508252143859863 + <_> + + <_> + + + + <_>14 4 1 12 -1. + <_>14 10 1 6 2. + 0 + -2.3905329871922731e-003 + 0.4205588996410370 + 0.5223848223686218 + <_> + + <_> + + + + <_>2 5 16 10 -1. + <_>2 5 8 5 2. + <_>10 10 8 5 2. + 0 + 0.0272689294070005 + 0.5206447243690491 + 0.3563301861286163 + <_> + + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + -3.7658358924090862e-003 + 0.3144704103469849 + 0.5218814015388489 + <_> + + <_> + + + + <_>1 4 2 2 -1. + <_>1 5 2 1 2. + 0 + -1.4903489500284195e-003 + 0.3380196094512940 + 0.5124437212944031 + <_> + + <_> + + + + <_>5 0 15 5 -1. + <_>10 0 5 5 3. + 0 + -0.0174282304942608 + 0.5829960703849793 + 0.4919725954532623 + <_> + + <_> + + + + <_>0 0 15 5 -1. + <_>5 0 5 5 3. + 0 + -0.0152780301868916 + 0.6163144707679749 + 0.4617887139320374 + <_> + + <_> + + + + <_>11 2 2 17 -1. + <_>11 2 1 17 2. + 0 + 0.0319956094026566 + 0.5166357159614563 + 0.1712764054536820 + <_> + + <_> + + + + <_>7 2 2 17 -1. + <_>8 2 1 17 2. + 0 + -3.8256710395216942e-003 + 0.3408012092113495 + 0.5131387710571289 + <_> + + <_> + + + + <_>15 11 2 9 -1. + <_>15 11 1 9 2. + 0 + -8.5186436772346497e-003 + 0.6105518937110901 + 0.4997941851615906 + <_> + + <_> + + + + <_>3 11 2 9 -1. + <_>4 11 1 9 2. + 0 + 9.0641621500253677e-004 + 0.4327270984649658 + 0.5582311153411865 + <_> + + <_> + + + + <_>5 16 14 4 -1. + <_>5 16 7 4 2. + 0 + 0.0103448498994112 + 0.4855653047561646 + 0.5452420115470886 + 69.2298736572265630 + 15 + -1 + <_> + + + <_> + + <_> + + + + <_>1 4 18 1 -1. + <_>7 4 6 1 3. + 0 + 7.8981826081871986e-003 + 0.3332524895668030 + 0.5946462154388428 + <_> + + <_> + + + + <_>13 7 6 4 -1. + <_>16 7 3 2 2. + <_>13 9 3 2 2. + 0 + 1.6170160379260778e-003 + 0.3490641117095947 + 0.5577868819236755 + <_> + + <_> + + + + <_>9 8 2 12 -1. + <_>9 12 2 4 3. + 0 + -5.5449741194024682e-004 + 0.5542566180229187 + 0.3291530013084412 + <_> + + <_> + + + + <_>12 1 6 6 -1. + <_>12 3 6 2 3. + 0 + 1.5428980113938451e-003 + 0.3612579107284546 + 0.5545979142189026 + <_> + + <_> + + + + <_>5 2 6 6 -1. + <_>5 2 3 3 2. + <_>8 5 3 3 2. + 0 + -1.0329450014978647e-003 + 0.3530139029026032 + 0.5576140284538269 + <_> + + <_> + + + + <_>9 16 6 4 -1. + <_>12 16 3 2 2. + <_>9 18 3 2 2. + 0 + 7.7698158565908670e-004 + 0.3916778862476349 + 0.5645321011543274 + <_> + + <_> + + + + <_>1 2 18 3 -1. + <_>7 2 6 3 3. + 0 + 0.1432030051946640 + 0.4667482078075409 + 0.7023633122444153 + <_> + + <_> + + + + <_>7 4 9 10 -1. + <_>7 9 9 5 2. + 0 + -7.3866490274667740e-003 + 0.3073684871196747 + 0.5289257764816284 + <_> + + <_> + + + + <_>5 9 4 4 -1. + <_>7 9 2 4 2. + 0 + -6.2936742324382067e-004 + 0.5622118115425110 + 0.4037049114704132 + <_> + + <_> + + + + <_>11 10 3 6 -1. + <_>11 13 3 3 2. + 0 + 7.8893528552725911e-004 + 0.5267661213874817 + 0.3557874858379364 + <_> + + <_> + + + + <_>7 11 5 3 -1. + <_>7 12 5 1 3. + 0 + -0.0122280502691865 + 0.6668320894241333 + 0.4625549912452698 + <_> + + <_> + + + + <_>7 11 6 6 -1. + <_>10 11 3 3 2. + <_>7 14 3 3 2. + 0 + 3.5420239437371492e-003 + 0.5521438121795654 + 0.3869673013687134 + <_> + + <_> + + + + <_>0 0 10 9 -1. + <_>0 3 10 3 3. + 0 + -1.0585320414975286e-003 + 0.3628678023815155 + 0.5320926904678345 + <_> + + <_> + + + + <_>13 14 1 6 -1. + <_>13 16 1 2 3. + 0 + 1.4935660146875307e-005 + 0.4632444977760315 + 0.5363323092460632 + <_> + + <_> + + + + <_>0 2 3 6 -1. + <_>0 4 3 2 3. + 0 + 5.2537708543241024e-003 + 0.5132231712341309 + 0.3265708982944489 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + -8.2338023930788040e-003 + 0.6693689823150635 + 0.4774140119552612 + <_> + + <_> + + + + <_>6 14 1 6 -1. + <_>6 16 1 2 3. + 0 + 2.1866810129722580e-005 + 0.4053862094879150 + 0.5457931160926819 + <_> + + <_> + + + + <_>9 15 2 3 -1. + <_>9 16 2 1 3. + 0 + -3.8150229956954718e-003 + 0.6454995870590210 + 0.4793178141117096 + <_> + + <_> + + + + <_>6 4 3 3 -1. + <_>7 4 1 3 3. + 0 + 1.1105879675596952e-003 + 0.5270407199859619 + 0.3529678881168366 + <_> + + <_> + + + + <_>9 0 11 3 -1. + <_>9 1 11 1 3. + 0 + -5.7707689702510834e-003 + 0.3803547024726868 + 0.5352957844734192 + <_> + + <_> + + + + <_>0 6 20 3 -1. + <_>0 7 20 1 3. + 0 + -3.0158339068293571e-003 + 0.5339403152465820 + 0.3887133002281189 + <_> + + <_> + + + + <_>10 1 1 2 -1. + <_>10 2 1 1 2. + 0 + -8.5453689098358154e-004 + 0.3564616143703461 + 0.5273603796958923 + <_> + + <_> + + + + <_>9 6 2 6 -1. + <_>10 6 1 6 2. + 0 + 0.0110505102202296 + 0.4671907126903534 + 0.6849737763404846 + <_> + + <_> + + + + <_>5 8 12 1 -1. + <_>9 8 4 1 3. + 0 + 0.0426058396697044 + 0.5151473283767700 + 0.0702200904488564 + <_> + + <_> + + + + <_>3 8 12 1 -1. + <_>7 8 4 1 3. + 0 + -3.0781750101596117e-003 + 0.3041661083698273 + 0.5152602195739746 + <_> + + <_> + + + + <_>9 7 3 5 -1. + <_>10 7 1 5 3. + 0 + -5.4815728217363358e-003 + 0.6430295705795288 + 0.4897229969501495 + <_> + + <_> + + + + <_>3 9 6 2 -1. + <_>6 9 3 2 2. + 0 + 3.1881860923022032e-003 + 0.5307493209838867 + 0.3826209902763367 + <_> + + <_> + + + + <_>12 9 3 3 -1. + <_>12 10 3 1 3. + 0 + 3.5947180003859103e-004 + 0.4650047123432159 + 0.5421904921531677 + <_> + + <_> + + + + <_>7 0 6 1 -1. + <_>9 0 2 1 3. + 0 + -4.0705031715333462e-003 + 0.2849679887294769 + 0.5079116225242615 + <_> + + <_> + + + + <_>12 9 3 3 -1. + <_>12 10 3 1 3. + 0 + -0.0145941702648997 + 0.2971645891666412 + 0.5128461718559265 + <_> + + <_> + + + + <_>7 10 2 1 -1. + <_>8 10 1 1 2. + 0 + -1.1947689927183092e-004 + 0.5631098151206970 + 0.4343082010746002 + <_> + + <_> + + + + <_>6 4 9 13 -1. + <_>9 4 3 13 3. + 0 + -6.9344649091362953e-004 + 0.4403578042984009 + 0.5359959006309509 + <_> + + <_> + + + + <_>6 8 4 2 -1. + <_>6 9 4 1 2. + 0 + 1.4834799912932795e-005 + 0.3421008884906769 + 0.5164697766304016 + <_> + + <_> + + + + <_>16 2 4 6 -1. + <_>16 2 2 6 2. + 0 + 9.0296985581517220e-003 + 0.4639343023300171 + 0.6114075183868408 + <_> + + <_> + + + + <_>0 17 6 3 -1. + <_>0 18 6 1 3. + 0 + -8.0640818923711777e-003 + 0.2820158898830414 + 0.5075494050979614 + <_> + + <_> + + + + <_>10 10 3 10 -1. + <_>10 15 3 5 2. + 0 + 0.0260621197521687 + 0.5208905935287476 + 0.2688778042793274 + <_> + + <_> + + + + <_>8 7 3 5 -1. + <_>9 7 1 5 3. + 0 + 0.0173146594315767 + 0.4663713872432709 + 0.6738539934158325 + <_> + + <_> + + + + <_>10 4 4 3 -1. + <_>10 4 2 3 2. + 0 + 0.0226666405797005 + 0.5209349989891052 + 0.2212723940610886 + <_> + + <_> + + + + <_>8 4 3 8 -1. + <_>9 4 1 8 3. + 0 + -2.1965929772704840e-003 + 0.6063101291656494 + 0.4538190066814423 + <_> + + <_> + + + + <_>6 6 9 13 -1. + <_>9 6 3 13 3. + 0 + -9.5282476395368576e-003 + 0.4635204970836639 + 0.5247430801391602 + <_> + + <_> + + + + <_>6 0 8 12 -1. + <_>6 0 4 6 2. + <_>10 6 4 6 2. + 0 + 8.0943619832396507e-003 + 0.5289440155029297 + 0.3913882076740265 + <_> + + <_> + + + + <_>14 2 6 8 -1. + <_>16 2 2 8 3. + 0 + -0.0728773325681686 + 0.7752001881599426 + 0.4990234971046448 + <_> + + <_> + + + + <_>6 0 3 6 -1. + <_>7 0 1 6 3. + 0 + -6.9009521976113319e-003 + 0.2428039014339447 + 0.5048090219497681 + <_> + + <_> + + + + <_>14 2 6 8 -1. + <_>16 2 2 8 3. + 0 + -0.0113082397729158 + 0.5734364986419678 + 0.4842376112937927 + <_> + + <_> + + + + <_>0 5 6 6 -1. + <_>0 8 6 3 2. + 0 + 0.0596132017672062 + 0.5029836297035217 + 0.2524977028369904 + <_> + + <_> + + + + <_>9 12 6 2 -1. + <_>12 12 3 1 2. + <_>9 13 3 1 2. + 0 + -2.8624620754271746e-003 + 0.6073045134544373 + 0.4898459911346436 + <_> + + <_> + + + + <_>8 17 3 2 -1. + <_>9 17 1 2 3. + 0 + 4.4781449250876904e-003 + 0.5015289187431335 + 0.2220316976308823 + <_> + + <_> + + + + <_>11 6 2 2 -1. + <_>12 6 1 1 2. + <_>11 7 1 1 2. + 0 + -1.7513240454718471e-003 + 0.6614428758621216 + 0.4933868944644928 + <_> + + <_> + + + + <_>1 9 18 2 -1. + <_>7 9 6 2 3. + 0 + 0.0401634201407433 + 0.5180878043174744 + 0.3741044998168945 + <_> + + <_> + + + + <_>11 6 2 2 -1. + <_>12 6 1 1 2. + <_>11 7 1 1 2. + 0 + 3.4768949262797832e-004 + 0.4720416963100433 + 0.5818032026290894 + <_> + + <_> + + + + <_>3 4 12 8 -1. + <_>7 4 4 8 3. + 0 + 2.6551650371402502e-003 + 0.3805010914802551 + 0.5221335887908936 + <_> + + <_> + + + + <_>13 11 5 3 -1. + <_>13 12 5 1 3. + 0 + -8.7706279009580612e-003 + 0.2944166064262390 + 0.5231295228004456 + <_> + + <_> + + + + <_>9 10 2 3 -1. + <_>9 11 2 1 3. + 0 + -5.5122091434895992e-003 + 0.7346177101135254 + 0.4722816944122315 + <_> + + <_> + + + + <_>14 7 2 3 -1. + <_>14 7 1 3 2. + 0 + 6.8672042107209563e-004 + 0.5452876091003418 + 0.4242413043975830 + <_> + + <_> + + + + <_>5 4 1 3 -1. + <_>5 5 1 1 3. + 0 + 5.6019669864326715e-004 + 0.4398862123489380 + 0.5601285099983215 + <_> + + <_> + + + + <_>13 4 2 3 -1. + <_>13 5 2 1 3. + 0 + 2.4143769405782223e-003 + 0.4741686880588532 + 0.6136621832847595 + <_> + + <_> + + + + <_>5 4 2 3 -1. + <_>5 5 2 1 3. + 0 + -1.5680900542065501e-003 + 0.6044552922248840 + 0.4516409933567047 + <_> + + <_> + + + + <_>9 8 2 3 -1. + <_>9 9 2 1 3. + 0 + -3.6827491130679846e-003 + 0.2452459037303925 + 0.5294982194900513 + <_> + + <_> + + + + <_>8 9 2 2 -1. + <_>8 10 2 1 2. + 0 + -2.9409190756268799e-004 + 0.3732838034629822 + 0.5251451134681702 + <_> + + <_> + + + + <_>15 14 1 4 -1. + <_>15 16 1 2 2. + 0 + 4.2847759323194623e-004 + 0.5498809814453125 + 0.4065535068511963 + <_> + + <_> + + + + <_>3 12 2 2 -1. + <_>3 13 2 1 2. + 0 + -4.8817070201039314e-003 + 0.2139908969402313 + 0.4999957084655762 + <_> + + <_> + + + + <_>12 15 2 2 -1. + <_>13 15 1 1 2. + <_>12 16 1 1 2. + 0 + 2.7272020815871656e-004 + 0.4650287032127380 + 0.5813428759574890 + <_> + + <_> + + + + <_>9 13 2 2 -1. + <_>9 14 2 1 2. + 0 + 2.0947199664078653e-004 + 0.4387486875057221 + 0.5572792887687683 + <_> + + <_> + + + + <_>4 11 14 9 -1. + <_>4 14 14 3 3. + 0 + 0.0485011897981167 + 0.5244972705841065 + 0.3212889134883881 + <_> + + <_> + + + + <_>7 13 4 3 -1. + <_>7 14 4 1 3. + 0 + -4.5166411437094212e-003 + 0.6056813001632690 + 0.4545882046222687 + <_> + + <_> + + + + <_>15 14 1 4 -1. + <_>15 16 1 2 2. + 0 + -0.0122916800901294 + 0.2040929049253464 + 0.5152214169502258 + <_> + + <_> + + + + <_>4 14 1 4 -1. + <_>4 16 1 2 2. + 0 + 4.8549679922871292e-004 + 0.5237604975700378 + 0.3739503026008606 + <_> + + <_> + + + + <_>14 0 6 13 -1. + <_>16 0 2 13 3. + 0 + 0.0305560491979122 + 0.4960533976554871 + 0.5938246250152588 + <_> + + <_> + + + + <_>4 1 2 12 -1. + <_>4 1 1 6 2. + <_>5 7 1 6 2. + 0 + -1.5105320198927075e-004 + 0.5351303815841675 + 0.4145204126834869 + <_> + + <_> + + + + <_>11 14 6 6 -1. + <_>14 14 3 3 2. + <_>11 17 3 3 2. + 0 + 2.4937440175563097e-003 + 0.4693366885185242 + 0.5514941215515137 + <_> + + <_> + + + + <_>3 14 6 6 -1. + <_>3 14 3 3 2. + <_>6 17 3 3 2. + 0 + -0.0123821301385760 + 0.6791396737098694 + 0.4681667983531952 + <_> + + <_> + + + + <_>14 17 3 2 -1. + <_>14 18 3 1 2. + 0 + -5.1333461888134480e-003 + 0.3608739078044891 + 0.5229160189628601 + <_> + + <_> + + + + <_>3 17 3 2 -1. + <_>3 18 3 1 2. + 0 + 5.1919277757406235e-004 + 0.5300073027610779 + 0.3633613884449005 + <_> + + <_> + + + + <_>14 0 6 13 -1. + <_>16 0 2 13 3. + 0 + 0.1506042033433914 + 0.5157316923141480 + 0.2211782038211823 + <_> + + <_> + + + + <_>0 0 6 13 -1. + <_>2 0 2 13 3. + 0 + 7.7144149690866470e-003 + 0.4410496950149536 + 0.5776609182357788 + <_> + + <_> + + + + <_>10 10 7 6 -1. + <_>10 12 7 2 3. + 0 + 9.4443522393703461e-003 + 0.5401855111122131 + 0.3756650090217590 + <_> + + <_> + + + + <_>6 15 2 2 -1. + <_>6 15 1 1 2. + <_>7 16 1 1 2. + 0 + 2.5006249779835343e-004 + 0.4368270933628082 + 0.5607374906539917 + <_> + + <_> + + + + <_>6 11 8 6 -1. + <_>10 11 4 3 2. + <_>6 14 4 3 2. + 0 + -3.3077150583267212e-003 + 0.4244799017906189 + 0.5518230795860291 + <_> + + <_> + + + + <_>7 6 2 2 -1. + <_>7 6 1 1 2. + <_>8 7 1 1 2. + 0 + 7.4048910755664110e-004 + 0.4496962130069733 + 0.5900576710700989 + <_> + + <_> + + + + <_>2 2 16 6 -1. + <_>10 2 8 3 2. + <_>2 5 8 3 2. + 0 + 0.0440920516848564 + 0.5293493270874023 + 0.3156355023384094 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 3.3639909233897924e-003 + 0.4483296871185303 + 0.5848662257194519 + <_> + + <_> + + + + <_>11 7 3 10 -1. + <_>11 12 3 5 2. + 0 + -3.9760079234838486e-003 + 0.4559507071971893 + 0.5483639240264893 + <_> + + <_> + + + + <_>6 7 3 10 -1. + <_>6 12 3 5 2. + 0 + 2.7716930489987135e-003 + 0.5341786146163940 + 0.3792484104633331 + <_> + + <_> + + + + <_>10 7 3 2 -1. + <_>11 7 1 2 3. + 0 + -2.4123019829858094e-004 + 0.5667188763618469 + 0.4576973021030426 + <_> + + <_> + + + + <_>8 12 4 2 -1. + <_>8 13 4 1 2. + 0 + 4.9425667384639382e-004 + 0.4421244859695435 + 0.5628787279129028 + <_> + + <_> + + + + <_>10 1 1 3 -1. + <_>10 2 1 1 3. + 0 + -3.8876468897797167e-004 + 0.4288370907306671 + 0.5391063094139099 + <_> + + <_> + + + + <_>1 2 4 18 -1. + <_>1 2 2 9 2. + <_>3 11 2 9 2. + 0 + -0.0500488989055157 + 0.6899513006210327 + 0.4703742861747742 + <_> + + <_> + + + + <_>12 4 4 12 -1. + <_>12 10 4 6 2. + 0 + -0.0366354808211327 + 0.2217779010534287 + 0.5191826224327087 + <_> + + <_> + + + + <_>0 0 1 6 -1. + <_>0 2 1 2 3. + 0 + 2.4273579474538565e-003 + 0.5136224031448364 + 0.3497397899627686 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + 1.9558030180633068e-003 + 0.4826192855834961 + 0.6408380866050720 + <_> + + <_> + + + + <_>8 7 4 3 -1. + <_>8 8 4 1 3. + 0 + -1.7494610510766506e-003 + 0.3922835886478424 + 0.5272685289382935 + <_> + + <_> + + + + <_>10 7 3 2 -1. + <_>11 7 1 2 3. + 0 + 0.0139550799503922 + 0.5078201889991760 + 0.8416504859924316 + <_> + + <_> + + + + <_>7 7 3 2 -1. + <_>8 7 1 2 3. + 0 + -2.1896739781368524e-004 + 0.5520489811897278 + 0.4314234852790833 + <_> + + <_> + + + + <_>9 4 6 1 -1. + <_>11 4 2 1 3. + 0 + -1.5131309628486633e-003 + 0.3934605121612549 + 0.5382571220397949 + <_> + + <_> + + + + <_>8 7 2 3 -1. + <_>9 7 1 3 2. + 0 + -4.3622800149023533e-003 + 0.7370628714561462 + 0.4736475944519043 + <_> + + <_> + + + + <_>12 7 8 6 -1. + <_>16 7 4 3 2. + <_>12 10 4 3 2. + 0 + 0.0651605874300003 + 0.5159279704093933 + 0.3281595110893250 + <_> + + <_> + + + + <_>0 7 8 6 -1. + <_>0 7 4 3 2. + <_>4 10 4 3 2. + 0 + -2.3567399475723505e-003 + 0.3672826886177063 + 0.5172886252403259 + <_> + + <_> + + + + <_>18 2 2 10 -1. + <_>19 2 1 5 2. + <_>18 7 1 5 2. + 0 + 0.0151466596871614 + 0.5031493902206421 + 0.6687604188919067 + <_> + + <_> + + + + <_>0 2 6 4 -1. + <_>3 2 3 4 2. + 0 + -0.0228509604930878 + 0.6767519712448120 + 0.4709596931934357 + <_> + + <_> + + + + <_>9 4 6 1 -1. + <_>11 4 2 1 3. + 0 + 4.8867650330066681e-003 + 0.5257998108863831 + 0.4059878885746002 + <_> + + <_> + + + + <_>7 15 2 2 -1. + <_>7 15 1 1 2. + <_>8 16 1 1 2. + 0 + 1.7619599821045995e-003 + 0.4696272909641266 + 0.6688278913497925 + <_> + + <_> + + + + <_>11 13 1 6 -1. + <_>11 16 1 3 2. + 0 + -1.2942519970238209e-003 + 0.4320712983608246 + 0.5344281792640686 + <_> + + <_> + + + + <_>8 13 1 6 -1. + <_>8 16 1 3 2. + 0 + 0.0109299495816231 + 0.4997706115245819 + 0.1637486070394516 + <_> + + <_> + + + + <_>14 3 2 1 -1. + <_>14 3 1 1 2. + 0 + 2.9958489903947338e-005 + 0.4282417893409729 + 0.5633224248886108 + <_> + + <_> + + + + <_>8 15 2 3 -1. + <_>8 16 2 1 3. + 0 + -6.5884361974895000e-003 + 0.6772121191024780 + 0.4700526893138886 + <_> + + <_> + + + + <_>12 15 7 4 -1. + <_>12 17 7 2 2. + 0 + 3.2527779694646597e-003 + 0.5313397049903870 + 0.4536148905754089 + <_> + + <_> + + + + <_>4 14 12 3 -1. + <_>4 15 12 1 3. + 0 + -4.0435739792883396e-003 + 0.5660061836242676 + 0.4413388967514038 + <_> + + <_> + + + + <_>10 3 3 2 -1. + <_>11 3 1 2 3. + 0 + -1.2523540062829852e-003 + 0.3731913864612579 + 0.5356451869010925 + <_> + + <_> + + + + <_>4 12 2 2 -1. + <_>4 13 2 1 2. + 0 + 1.9246719602961093e-004 + 0.5189986228942871 + 0.3738811016082764 + <_> + + <_> + + + + <_>10 11 4 6 -1. + <_>10 14 4 3 2. + 0 + -0.0385896712541580 + 0.2956373989582062 + 0.5188810825347900 + <_> + + <_> + + + + <_>7 13 2 2 -1. + <_>7 13 1 1 2. + <_>8 14 1 1 2. + 0 + 1.5489870565943420e-004 + 0.4347135126590729 + 0.5509533286094666 + <_> + + <_> + + + + <_>4 11 14 4 -1. + <_>11 11 7 2 2. + <_>4 13 7 2 2. + 0 + -0.0337638482451439 + 0.3230330049991608 + 0.5195475816726685 + <_> + + <_> + + + + <_>1 18 18 2 -1. + <_>7 18 6 2 3. + 0 + -8.2657067105174065e-003 + 0.5975489020347595 + 0.4552114009857178 + <_> + + <_> + + + + <_>11 18 2 2 -1. + <_>12 18 1 1 2. + <_>11 19 1 1 2. + 0 + 1.4481440302915871e-005 + 0.4745678007602692 + 0.5497426986694336 + <_> + + <_> + + + + <_>7 18 2 2 -1. + <_>7 18 1 1 2. + <_>8 19 1 1 2. + 0 + 1.4951299817766994e-005 + 0.4324473142623901 + 0.5480644106864929 + <_> + + <_> + + + + <_>12 18 8 2 -1. + <_>12 19 8 1 2. + 0 + -0.0187417995184660 + 0.1580052971839905 + 0.5178533196449280 + <_> + + <_> + + + + <_>7 14 6 2 -1. + <_>7 15 6 1 2. + 0 + 1.7572239739820361e-003 + 0.4517636895179749 + 0.5773764252662659 + <_> + + <_> + + + + <_>8 12 4 8 -1. + <_>10 12 2 4 2. + <_>8 16 2 4 2. + 0 + -3.1391119118779898e-003 + 0.4149647951126099 + 0.5460842251777649 + <_> + + <_> + + + + <_>4 9 3 3 -1. + <_>4 10 3 1 3. + 0 + 6.6656779381446540e-005 + 0.4039090871810913 + 0.5293084979057312 + <_> + + <_> + + + + <_>7 10 6 2 -1. + <_>9 10 2 2 3. + 0 + 6.7743421532213688e-003 + 0.4767651855945587 + 0.6121956110000610 + <_> + + <_> + + + + <_>5 0 4 15 -1. + <_>7 0 2 15 2. + 0 + -7.3868161998689175e-003 + 0.3586258888244629 + 0.5187280774116516 + <_> + + <_> + + + + <_>8 6 12 14 -1. + <_>12 6 4 14 3. + 0 + 0.0140409301966429 + 0.4712139964103699 + 0.5576155781745911 + <_> + + <_> + + + + <_>5 16 3 3 -1. + <_>5 17 3 1 3. + 0 + -5.5258329957723618e-003 + 0.2661027014255524 + 0.5039281249046326 + <_> + + <_> + + + + <_>8 1 12 19 -1. + <_>12 1 4 19 3. + 0 + 0.3868423998355866 + 0.5144339799880981 + 0.2525899112224579 + <_> + + <_> + + + + <_>3 0 3 2 -1. + <_>3 1 3 1 2. + 0 + 1.1459240340627730e-004 + 0.4284994900226593 + 0.5423371195793152 + <_> + + <_> + + + + <_>10 12 4 5 -1. + <_>10 12 2 5 2. + 0 + -0.0184675697237253 + 0.3885835111141205 + 0.5213062167167664 + <_> + + <_> + + + + <_>6 12 4 5 -1. + <_>8 12 2 5 2. + 0 + -4.5907011372037232e-004 + 0.5412563085556030 + 0.4235909879207611 + <_> + + <_> + + + + <_>11 11 2 2 -1. + <_>12 11 1 1 2. + <_>11 12 1 1 2. + 0 + 1.2527540093287826e-003 + 0.4899305105209351 + 0.6624091267585754 + <_> + + <_> + + + + <_>0 2 3 6 -1. + <_>0 4 3 2 3. + 0 + 1.4910609461367130e-003 + 0.5286778211593628 + 0.4040051996707916 + <_> + + <_> + + + + <_>11 11 2 2 -1. + <_>12 11 1 1 2. + <_>11 12 1 1 2. + 0 + -7.5435562757775187e-004 + 0.6032990217208862 + 0.4795120060443878 + <_> + + <_> + + + + <_>7 6 4 10 -1. + <_>7 11 4 5 2. + 0 + -6.9478838704526424e-003 + 0.4084401130676270 + 0.5373504161834717 + <_> + + <_> + + + + <_>11 11 2 2 -1. + <_>12 11 1 1 2. + <_>11 12 1 1 2. + 0 + 2.8092920547351241e-004 + 0.4846062958240509 + 0.5759382247924805 + <_> + + <_> + + + + <_>2 13 5 2 -1. + <_>2 14 5 1 2. + 0 + 9.6073717577382922e-004 + 0.5164741277694702 + 0.3554979860782623 + <_> + + <_> + + + + <_>11 11 2 2 -1. + <_>12 11 1 1 2. + <_>11 12 1 1 2. + 0 + -2.6883929967880249e-004 + 0.5677582025527954 + 0.4731765985488892 + <_> + + <_> + + + + <_>7 11 2 2 -1. + <_>7 11 1 1 2. + <_>8 12 1 1 2. + 0 + 2.1599370520561934e-003 + 0.4731487035751343 + 0.7070567011833191 + <_> + + <_> + + + + <_>14 13 3 3 -1. + <_>14 14 3 1 3. + 0 + 5.6235301308333874e-003 + 0.5240243077278137 + 0.2781791985034943 + <_> + + <_> + + + + <_>3 13 3 3 -1. + <_>3 14 3 1 3. + 0 + -5.0243991427123547e-003 + 0.2837013900279999 + 0.5062304139137268 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + -9.7611639648675919e-003 + 0.7400717735290527 + 0.4934569001197815 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>8 8 3 1 3. + 0 + 4.1515100747346878e-003 + 0.5119131207466126 + 0.3407008051872253 + <_> + + <_> + + + + <_>13 5 3 3 -1. + <_>13 6 3 1 3. + 0 + 6.2465080991387367e-003 + 0.4923788011074066 + 0.6579058766365051 + <_> + + <_> + + + + <_>0 9 5 3 -1. + <_>0 10 5 1 3. + 0 + -7.0597478188574314e-003 + 0.2434711009263992 + 0.5032842159271240 + <_> + + <_> + + + + <_>13 5 3 3 -1. + <_>13 6 3 1 3. + 0 + -2.0587709732353687e-003 + 0.5900310873985291 + 0.4695087075233460 + <_> + + <_> + + + + <_>9 12 2 8 -1. + <_>9 12 1 4 2. + <_>10 16 1 4 2. + 0 + -2.4146060459315777e-003 + 0.3647317886352539 + 0.5189201831817627 + <_> + + <_> + + + + <_>11 7 2 2 -1. + <_>12 7 1 1 2. + <_>11 8 1 1 2. + 0 + -1.4817609917372465e-003 + 0.6034948229789734 + 0.4940128028392792 + <_> + + <_> + + + + <_>0 16 6 4 -1. + <_>3 16 3 4 2. + 0 + -6.3016400672495365e-003 + 0.5818989872932434 + 0.4560427963733673 + <_> + + <_> + + + + <_>10 6 2 3 -1. + <_>10 7 2 1 3. + 0 + 3.4763428848236799e-003 + 0.5217475891113281 + 0.3483993113040924 + <_> + + <_> + + + + <_>9 5 2 6 -1. + <_>9 7 2 2 3. + 0 + -0.0222508702427149 + 0.2360700070858002 + 0.5032082796096802 + <_> + + <_> + + + + <_>12 15 8 4 -1. + <_>12 15 4 4 2. + 0 + -0.0306125506758690 + 0.6499186754226685 + 0.4914919137954712 + <_> + + <_> + + + + <_>0 14 8 6 -1. + <_>4 14 4 6 2. + 0 + 0.0130574796348810 + 0.4413323104381561 + 0.5683764219284058 + <_> + + <_> + + + + <_>9 0 3 2 -1. + <_>10 0 1 2 3. + 0 + -6.0095742810517550e-004 + 0.4359731078147888 + 0.5333483219146729 + <_> + + <_> + + + + <_>4 15 4 2 -1. + <_>6 15 2 2 2. + 0 + -4.1514250915497541e-004 + 0.5504062771797180 + 0.4326060116291046 + <_> + + <_> + + + + <_>12 7 3 13 -1. + <_>13 7 1 13 3. + 0 + -0.0137762902304530 + 0.4064112901687622 + 0.5201548933982849 + <_> + + <_> + + + + <_>5 7 3 13 -1. + <_>6 7 1 13 3. + 0 + -0.0322965085506439 + 0.0473519712686539 + 0.4977194964885712 + <_> + + <_> + + + + <_>9 6 3 9 -1. + <_>9 9 3 3 3. + 0 + 0.0535569787025452 + 0.4881733059883118 + 0.6666939258575440 + <_> + + <_> + + + + <_>4 4 7 12 -1. + <_>4 10 7 6 2. + 0 + 8.1889545544981956e-003 + 0.5400037169456482 + 0.4240820109844208 + <_> + + <_> + + + + <_>12 12 2 2 -1. + <_>13 12 1 1 2. + <_>12 13 1 1 2. + 0 + 2.1055320394225419e-004 + 0.4802047908306122 + 0.5563852787017822 + <_> + + <_> + + + + <_>6 12 2 2 -1. + <_>6 12 1 1 2. + <_>7 13 1 1 2. + 0 + -2.4382730480283499e-003 + 0.7387793064117432 + 0.4773685038089752 + <_> + + <_> + + + + <_>8 9 4 2 -1. + <_>10 9 2 1 2. + <_>8 10 2 1 2. + 0 + 3.2835570164024830e-003 + 0.5288546085357666 + 0.3171291947364807 + <_> + + <_> + + + + <_>3 6 2 2 -1. + <_>3 6 1 1 2. + <_>4 7 1 1 2. + 0 + 2.3729570675641298e-003 + 0.4750812947750092 + 0.7060170769691467 + <_> + + <_> + + + + <_>16 6 3 2 -1. + <_>16 7 3 1 2. + 0 + -1.4541699783876538e-003 + 0.3811730146408081 + 0.5330739021301270 + 79.2490768432617190 + 16 + -1 + <_> + + + <_> + + <_> + + + + <_>0 7 19 4 -1. + <_>0 9 19 2 2. + 0 + 0.0557552389800549 + 0.4019156992435455 + 0.6806036829948425 + <_> + + <_> + + + + <_>10 2 10 1 -1. + <_>10 2 5 1 2. + 0 + 2.4730248842388391e-003 + 0.3351148962974548 + 0.5965719819068909 + <_> + + <_> + + + + <_>9 4 2 12 -1. + <_>9 10 2 6 2. + 0 + -3.5031698644161224e-004 + 0.5557708144187927 + 0.3482286930084229 + <_> + + <_> + + + + <_>12 18 4 1 -1. + <_>12 18 2 1 2. + 0 + 5.4167630150914192e-004 + 0.4260858893394470 + 0.5693380832672119 + <_> + + <_> + + + + <_>1 7 6 4 -1. + <_>1 7 3 2 2. + <_>4 9 3 2 2. + 0 + 7.7193678589537740e-004 + 0.3494240045547485 + 0.5433688759803772 + <_> + + <_> + + + + <_>12 0 6 13 -1. + <_>14 0 2 13 3. + 0 + -1.5999219613149762e-003 + 0.4028499126434326 + 0.5484359264373779 + <_> + + <_> + + + + <_>2 0 6 13 -1. + <_>4 0 2 13 3. + 0 + -1.1832080053864047e-004 + 0.3806901872158051 + 0.5425465106964111 + <_> + + <_> + + + + <_>10 5 8 8 -1. + <_>10 9 8 4 2. + 0 + 3.2909031142480671e-004 + 0.2620100080966950 + 0.5429521799087524 + <_> + + <_> + + + + <_>8 3 2 5 -1. + <_>9 3 1 5 2. + 0 + 2.9518108931370080e-004 + 0.3799768984317780 + 0.5399264097213745 + <_> + + <_> + + + + <_>8 4 9 1 -1. + <_>11 4 3 1 3. + 0 + 9.0466710389591753e-005 + 0.4433645009994507 + 0.5440226197242737 + <_> + + <_> + + + + <_>3 4 9 1 -1. + <_>6 4 3 1 3. + 0 + 1.5007190086180344e-005 + 0.3719654977321625 + 0.5409119725227356 + <_> + + <_> + + + + <_>1 0 18 10 -1. + <_>7 0 6 10 3. + 0 + 0.1393561065196991 + 0.5525395870208740 + 0.4479042887687683 + <_> + + <_> + + + + <_>7 17 5 3 -1. + <_>7 18 5 1 3. + 0 + 1.6461990308016539e-003 + 0.4264501035213471 + 0.5772169828414917 + <_> + + <_> + + + + <_>7 11 6 1 -1. + <_>9 11 2 1 3. + 0 + 4.9984431825578213e-004 + 0.4359526038169861 + 0.5685871243476868 + <_> + + <_> + + + + <_>2 2 3 2 -1. + <_>2 3 3 1 2. + 0 + -1.0971280280500650e-003 + 0.3390136957168579 + 0.5205408930778503 + <_> + + <_> + + + + <_>8 12 4 2 -1. + <_>8 13 4 1 2. + 0 + 6.6919892560690641e-004 + 0.4557456076145172 + 0.5980659723281860 + <_> + + <_> + + + + <_>6 10 3 6 -1. + <_>6 13 3 3 2. + 0 + 8.6471042595803738e-004 + 0.5134841203689575 + 0.2944033145904541 + <_> + + <_> + + + + <_>11 4 2 4 -1. + <_>11 4 1 4 2. + 0 + -2.7182599296793342e-004 + 0.3906578123569489 + 0.5377181172370911 + <_> + + <_> + + + + <_>7 4 2 4 -1. + <_>8 4 1 4 2. + 0 + 3.0249499104684219e-005 + 0.3679609894752502 + 0.5225688815116882 + <_> + + <_> + + + + <_>9 6 2 4 -1. + <_>9 6 1 4 2. + 0 + -8.5225896909832954e-003 + 0.7293102145195007 + 0.4892365038394928 + <_> + + <_> + + + + <_>6 13 8 3 -1. + <_>6 14 8 1 3. + 0 + 1.6705560265108943e-003 + 0.4345324933528900 + 0.5696138143539429 + <_> + + <_> + + + + <_>9 15 3 4 -1. + <_>10 15 1 4 3. + 0 + -7.1433838456869125e-003 + 0.2591280043125153 + 0.5225623846054077 + <_> + + <_> + + + + <_>9 2 2 17 -1. + <_>10 2 1 17 2. + 0 + -0.0163193698972464 + 0.6922279000282288 + 0.4651575982570648 + <_> + + <_> + + + + <_>7 0 6 1 -1. + <_>9 0 2 1 3. + 0 + 4.8034260980784893e-003 + 0.5352262854576111 + 0.3286302983760834 + <_> + + <_> + + + + <_>8 15 3 4 -1. + <_>9 15 1 4 3. + 0 + -7.5421929359436035e-003 + 0.2040544003248215 + 0.5034546256065369 + <_> + + <_> + + + + <_>7 13 7 3 -1. + <_>7 14 7 1 3. + 0 + -0.0143631100654602 + 0.6804888844490051 + 0.4889059066772461 + <_> + + <_> + + + + <_>8 16 3 3 -1. + <_>9 16 1 3 3. + 0 + 8.9063588529825211e-004 + 0.5310695767402649 + 0.3895480930805206 + <_> + + <_> + + + + <_>6 2 8 10 -1. + <_>6 7 8 5 2. + 0 + -4.4060191139578819e-003 + 0.5741562843322754 + 0.4372426867485046 + <_> + + <_> + + + + <_>2 5 8 8 -1. + <_>2 9 8 4 2. + 0 + -1.8862540309783071e-004 + 0.2831785976886749 + 0.5098205208778381 + <_> + + <_> + + + + <_>14 16 2 2 -1. + <_>14 17 2 1 2. + 0 + -3.7979281041771173e-003 + 0.3372507989406586 + 0.5246580243110657 + <_> + + <_> + + + + <_>4 16 2 2 -1. + <_>4 17 2 1 2. + 0 + 1.4627049677073956e-004 + 0.5306674242019653 + 0.3911710083484650 + <_> + + <_> + + + + <_>10 11 4 6 -1. + <_>10 14 4 3 2. + 0 + -4.9164638767251745e-005 + 0.5462496280670166 + 0.3942720890045166 + <_> + + <_> + + + + <_>6 11 4 6 -1. + <_>6 14 4 3 2. + 0 + -0.0335825011134148 + 0.2157824039459229 + 0.5048211812973023 + <_> + + <_> + + + + <_>10 14 1 3 -1. + <_>10 15 1 1 3. + 0 + -3.5339309833943844e-003 + 0.6465312242507935 + 0.4872696995735169 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 5.0144111737608910e-003 + 0.4617668092250824 + 0.6248074769973755 + <_> + + <_> + + + + <_>10 0 4 6 -1. + <_>12 0 2 3 2. + <_>10 3 2 3 2. + 0 + 0.0188173707574606 + 0.5220689177513123 + 0.2000052034854889 + <_> + + <_> + + + + <_>0 3 20 2 -1. + <_>0 4 20 1 2. + 0 + -1.3434339780360460e-003 + 0.4014537930488586 + 0.5301619768142700 + <_> + + <_> + + + + <_>12 0 8 2 -1. + <_>16 0 4 1 2. + <_>12 1 4 1 2. + 0 + 1.7557960236445069e-003 + 0.4794039130210877 + 0.5653169751167297 + <_> + + <_> + + + + <_>2 12 10 8 -1. + <_>2 16 10 4 2. + 0 + -0.0956374630331993 + 0.2034195065498352 + 0.5006706714630127 + <_> + + <_> + + + + <_>17 7 2 10 -1. + <_>18 7 1 5 2. + <_>17 12 1 5 2. + 0 + -0.0222412291914225 + 0.7672473192214966 + 0.5046340227127075 + <_> + + <_> + + + + <_>1 7 2 10 -1. + <_>1 7 1 5 2. + <_>2 12 1 5 2. + 0 + -0.0155758196488023 + 0.7490342259407044 + 0.4755851030349731 + <_> + + <_> + + + + <_>15 10 3 6 -1. + <_>15 12 3 2 3. + 0 + 5.3599118255078793e-003 + 0.5365303754806519 + 0.4004670977592468 + <_> + + <_> + + + + <_>4 4 6 2 -1. + <_>6 4 2 2 3. + 0 + -0.0217634998261929 + 0.0740154981613159 + 0.4964174926280975 + <_> + + <_> + + + + <_>0 5 20 6 -1. + <_>0 7 20 2 3. + 0 + -0.1656159013509750 + 0.2859103083610535 + 0.5218086242675781 + <_> + + <_> + + + + <_>0 0 8 2 -1. + <_>0 0 4 1 2. + <_>4 1 4 1 2. + 0 + 1.6461320046801120e-004 + 0.4191615879535675 + 0.5380793213844299 + <_> + + <_> + + + + <_>1 0 18 4 -1. + <_>7 0 6 4 3. + 0 + -8.9077502489089966e-003 + 0.6273192763328552 + 0.4877404868602753 + <_> + + <_> + + + + <_>1 13 6 2 -1. + <_>1 14 6 1 2. + 0 + 8.6346449097618461e-004 + 0.5159940719604492 + 0.3671025931835175 + <_> + + <_> + + + + <_>10 8 3 4 -1. + <_>11 8 1 4 3. + 0 + -1.3751760125160217e-003 + 0.5884376764297485 + 0.4579083919525147 + <_> + + <_> + + + + <_>6 1 6 1 -1. + <_>8 1 2 1 3. + 0 + -1.4081239933148026e-003 + 0.3560509979724884 + 0.5139945149421692 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + -3.9342888630926609e-003 + 0.5994288921356201 + 0.4664272069931030 + <_> + + <_> + + + + <_>1 6 18 2 -1. + <_>10 6 9 2 2. + 0 + -0.0319669283926487 + 0.3345462083816528 + 0.5144183039665222 + <_> + + <_> + + + + <_>15 11 1 2 -1. + <_>15 12 1 1 2. + 0 + -1.5089280168467667e-005 + 0.5582656264305115 + 0.4414057135581970 + <_> + + <_> + + + + <_>6 5 1 2 -1. + <_>6 6 1 1 2. + 0 + 5.1994470413774252e-004 + 0.4623680114746094 + 0.6168993711471558 + <_> + + <_> + + + + <_>13 4 1 3 -1. + <_>13 5 1 1 3. + 0 + -3.4220460802316666e-003 + 0.6557074785232544 + 0.4974805116653442 + <_> + + <_> + + + + <_>2 15 1 2 -1. + <_>2 16 1 1 2. + 0 + 1.7723299970384687e-004 + 0.5269501805305481 + 0.3901908099651337 + <_> + + <_> + + + + <_>12 4 4 3 -1. + <_>12 5 4 1 3. + 0 + 1.5716759953647852e-003 + 0.4633373022079468 + 0.5790457725524902 + <_> + + <_> + + + + <_>0 0 7 3 -1. + <_>0 1 7 1 3. + 0 + -8.9041329920291901e-003 + 0.2689608037471771 + 0.5053591132164002 + <_> + + <_> + + + + <_>9 12 6 2 -1. + <_>9 12 3 2 2. + 0 + 4.0677518700249493e-004 + 0.5456603169441223 + 0.4329898953437805 + <_> + + <_> + + + + <_>5 4 2 3 -1. + <_>5 5 2 1 3. + 0 + 6.7604780197143555e-003 + 0.4648993909358978 + 0.6689761877059937 + <_> + + <_> + + + + <_>18 4 2 3 -1. + <_>18 5 2 1 3. + 0 + 2.9100088868290186e-003 + 0.5309703946113586 + 0.3377839922904968 + <_> + + <_> + + + + <_>3 0 8 6 -1. + <_>3 2 8 2 3. + 0 + 1.3885459629818797e-003 + 0.4074738919734955 + 0.5349133014678955 + <_> + + <_> + + + + <_>0 2 20 6 -1. + <_>10 2 10 3 2. + <_>0 5 10 3 2. + 0 + -0.0767642632126808 + 0.1992176026105881 + 0.5228242278099060 + <_> + + <_> + + + + <_>4 7 2 4 -1. + <_>5 7 1 4 2. + 0 + -2.2688310127705336e-004 + 0.5438501834869385 + 0.4253072142601013 + <_> + + <_> + + + + <_>3 10 15 2 -1. + <_>8 10 5 2 3. + 0 + -6.3094152137637138e-003 + 0.4259178936481476 + 0.5378909707069397 + <_> + + <_> + + + + <_>3 0 12 11 -1. + <_>9 0 6 11 2. + 0 + -0.1100727990269661 + 0.6904156804084778 + 0.4721749126911163 + <_> + + <_> + + + + <_>13 0 2 6 -1. + <_>13 0 1 6 2. + 0 + 2.8619659133255482e-004 + 0.4524914920330048 + 0.5548306107521057 + <_> + + <_> + + + + <_>0 19 2 1 -1. + <_>1 19 1 1 2. + 0 + 2.9425329557852820e-005 + 0.5370373725891113 + 0.4236463904380798 + <_> + + <_> + + + + <_>16 10 4 10 -1. + <_>18 10 2 5 2. + <_>16 15 2 5 2. + 0 + -0.0248865708708763 + 0.6423557996749878 + 0.4969303905963898 + <_> + + <_> + + + + <_>4 8 10 3 -1. + <_>4 9 10 1 3. + 0 + 0.0331488512456417 + 0.4988475143909454 + 0.1613811999559403 + <_> + + <_> + + + + <_>14 12 3 3 -1. + <_>14 13 3 1 3. + 0 + 7.8491691965609789e-004 + 0.5416026115417481 + 0.4223009049892426 + <_> + + <_> + + + + <_>0 10 4 10 -1. + <_>0 10 2 5 2. + <_>2 15 2 5 2. + 0 + 4.7087189741432667e-003 + 0.4576328992843628 + 0.6027557849884033 + <_> + + <_> + + + + <_>18 3 2 6 -1. + <_>18 5 2 2 3. + 0 + 2.4144479539245367e-003 + 0.5308973193168640 + 0.4422498941421509 + <_> + + <_> + + + + <_>6 6 1 3 -1. + <_>6 7 1 1 3. + 0 + 1.9523180089890957e-003 + 0.4705634117126465 + 0.6663324832916260 + <_> + + <_> + + + + <_>7 7 7 2 -1. + <_>7 8 7 1 2. + 0 + 1.3031980488449335e-003 + 0.4406126141548157 + 0.5526962280273438 + <_> + + <_> + + + + <_>0 3 2 6 -1. + <_>0 5 2 2 3. + 0 + 4.4735497795045376e-003 + 0.5129023790359497 + 0.3301498889923096 + <_> + + <_> + + + + <_>11 1 3 1 -1. + <_>12 1 1 1 3. + 0 + -2.6652868837118149e-003 + 0.3135471045970917 + 0.5175036191940308 + <_> + + <_> + + + + <_>5 0 2 6 -1. + <_>6 0 1 6 2. + 0 + 1.3666770246345550e-004 + 0.4119370877742767 + 0.5306876897811890 + <_> + + <_> + + + + <_>1 1 18 14 -1. + <_>7 1 6 14 3. + 0 + -0.0171264503151178 + 0.6177806258201599 + 0.4836578965187073 + <_> + + <_> + + + + <_>4 6 8 3 -1. + <_>8 6 4 3 2. + 0 + -2.6601430727168918e-004 + 0.3654330968856812 + 0.5169736742973328 + <_> + + <_> + + + + <_>9 12 6 2 -1. + <_>9 12 3 2 2. + 0 + -0.0229323804378510 + 0.3490915000438690 + 0.5163992047309876 + <_> + + <_> + + + + <_>5 12 6 2 -1. + <_>8 12 3 2 2. + 0 + 2.3316550068557262e-003 + 0.5166299939155579 + 0.3709389865398407 + <_> + + <_> + + + + <_>10 7 3 5 -1. + <_>11 7 1 5 3. + 0 + 0.0169256608933210 + 0.5014736056327820 + 0.8053988218307495 + <_> + + <_> + + + + <_>7 7 3 5 -1. + <_>8 7 1 5 3. + 0 + -8.9858826249837875e-003 + 0.6470788717269898 + 0.4657020866870880 + <_> + + <_> + + + + <_>13 0 3 10 -1. + <_>14 0 1 10 3. + 0 + -0.0118746999651194 + 0.3246378898620606 + 0.5258755087852478 + <_> + + <_> + + + + <_>4 11 3 2 -1. + <_>4 12 3 1 2. + 0 + 1.9350569345988333e-004 + 0.5191941857337952 + 0.3839643895626068 + <_> + + <_> + + + + <_>17 3 3 6 -1. + <_>18 3 1 6 3. + 0 + 5.8713490143418312e-003 + 0.4918133914470673 + 0.6187043190002441 + <_> + + <_> + + + + <_>1 8 18 10 -1. + <_>1 13 18 5 2. + 0 + -0.2483879029750824 + 0.1836802959442139 + 0.4988150000572205 + <_> + + <_> + + + + <_>13 0 3 10 -1. + <_>14 0 1 10 3. + 0 + 0.0122560001909733 + 0.5227053761482239 + 0.3632029891014099 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 8.3990179700776935e-004 + 0.4490250051021576 + 0.5774148106575012 + <_> + + <_> + + + + <_>16 3 3 7 -1. + <_>17 3 1 7 3. + 0 + 2.5407369248569012e-003 + 0.4804787039756775 + 0.5858299136161804 + <_> + + <_> + + + + <_>4 0 3 10 -1. + <_>5 0 1 10 3. + 0 + -0.0148224299773574 + 0.2521049976348877 + 0.5023537278175354 + <_> + + <_> + + + + <_>16 3 3 7 -1. + <_>17 3 1 7 3. + 0 + -5.7973959483206272e-003 + 0.5996695756912231 + 0.4853715002536774 + <_> + + <_> + + + + <_>0 9 1 2 -1. + <_>0 10 1 1 2. + 0 + 7.2662148158997297e-004 + 0.5153716802597046 + 0.3671779930591583 + <_> + + <_> + + + + <_>18 1 2 10 -1. + <_>18 1 1 10 2. + 0 + -0.0172325801104307 + 0.6621719002723694 + 0.4994656145572662 + <_> + + <_> + + + + <_>0 1 2 10 -1. + <_>1 1 1 10 2. + 0 + 7.8624086454510689e-003 + 0.4633395075798035 + 0.6256101727485657 + <_> + + <_> + + + + <_>10 16 3 4 -1. + <_>11 16 1 4 3. + 0 + -4.7343620099127293e-003 + 0.3615573048591614 + 0.5281885266304016 + <_> + + <_> + + + + <_>2 8 3 3 -1. + <_>3 8 1 3 3. + 0 + 8.3048478700220585e-004 + 0.4442889094352722 + 0.5550957918167114 + <_> + + <_> + + + + <_>11 0 2 6 -1. + <_>12 0 1 3 2. + <_>11 3 1 3 2. + 0 + 7.6602199114859104e-003 + 0.5162935256958008 + 0.2613354921340942 + <_> + + <_> + + + + <_>7 0 2 6 -1. + <_>7 0 1 3 2. + <_>8 3 1 3 2. + 0 + -4.1048377752304077e-003 + 0.2789632081985474 + 0.5019031763076782 + <_> + + <_> + + + + <_>16 3 3 7 -1. + <_>17 3 1 7 3. + 0 + 4.8512578941881657e-003 + 0.4968984127044678 + 0.5661668181419373 + <_> + + <_> + + + + <_>1 3 3 7 -1. + <_>2 3 1 7 3. + 0 + 9.9896453320980072e-004 + 0.4445607960224152 + 0.5551813244819641 + <_> + + <_> + + + + <_>14 1 6 16 -1. + <_>16 1 2 16 3. + 0 + -0.2702363133430481 + 0.0293882098048925 + 0.5151314139366150 + <_> + + <_> + + + + <_>0 1 6 16 -1. + <_>2 1 2 16 3. + 0 + -0.0130906803533435 + 0.5699399709701538 + 0.4447459876537323 + <_> + + <_> + + + + <_>2 0 16 8 -1. + <_>10 0 8 4 2. + <_>2 4 8 4 2. + 0 + -9.4342790544033051e-003 + 0.4305466115474701 + 0.5487895011901856 + <_> + + <_> + + + + <_>6 8 5 3 -1. + <_>6 9 5 1 3. + 0 + -1.5482039889320731e-003 + 0.3680317103862763 + 0.5128080844879150 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + 5.3746132180094719e-003 + 0.4838916957378388 + 0.6101555824279785 + <_> + + <_> + + + + <_>8 8 4 3 -1. + <_>8 9 4 1 3. + 0 + 1.5786769799888134e-003 + 0.5325223207473755 + 0.4118548035621643 + <_> + + <_> + + + + <_>9 6 2 4 -1. + <_>9 6 1 4 2. + 0 + 3.6856050137430429e-003 + 0.4810948073863983 + 0.6252303123474121 + <_> + + <_> + + + + <_>0 7 15 1 -1. + <_>5 7 5 1 3. + 0 + 9.3887019902467728e-003 + 0.5200229883193970 + 0.3629410862922669 + <_> + + <_> + + + + <_>8 2 7 9 -1. + <_>8 5 7 3 3. + 0 + 0.0127926301211119 + 0.4961709976196289 + 0.6738016009330750 + <_> + + <_> + + + + <_>1 7 16 4 -1. + <_>1 7 8 2 2. + <_>9 9 8 2 2. + 0 + -3.3661040943115950e-003 + 0.4060279130935669 + 0.5283598899841309 + <_> + + <_> + + + + <_>6 12 8 2 -1. + <_>6 13 8 1 2. + 0 + 3.9771420415490866e-004 + 0.4674113988876343 + 0.5900775194168091 + <_> + + <_> + + + + <_>8 11 3 3 -1. + <_>8 12 3 1 3. + 0 + 1.4868030557408929e-003 + 0.4519116878509522 + 0.6082053780555725 + <_> + + <_> + + + + <_>4 5 14 10 -1. + <_>11 5 7 5 2. + <_>4 10 7 5 2. + 0 + -0.0886867493391037 + 0.2807899117469788 + 0.5180991888046265 + <_> + + <_> + + + + <_>4 12 3 2 -1. + <_>4 13 3 1 2. + 0 + -7.4296112870797515e-005 + 0.5295584201812744 + 0.4087625145912170 + <_> + + <_> + + + + <_>9 11 6 1 -1. + <_>11 11 2 1 3. + 0 + -1.4932939848222304e-005 + 0.5461400151252747 + 0.4538542926311493 + <_> + + <_> + + + + <_>4 9 7 6 -1. + <_>4 11 7 2 3. + 0 + 5.9162238612771034e-003 + 0.5329161286354065 + 0.4192134141921997 + <_> + + <_> + + + + <_>7 10 6 3 -1. + <_>7 11 6 1 3. + 0 + 1.1141640134155750e-003 + 0.4512017965316773 + 0.5706217288970947 + <_> + + <_> + + + + <_>9 11 2 2 -1. + <_>9 12 2 1 2. + 0 + 8.9249362645205110e-005 + 0.4577805995941162 + 0.5897638201713562 + <_> + + <_> + + + + <_>0 5 20 6 -1. + <_>0 7 20 2 3. + 0 + 2.5319510605186224e-003 + 0.5299603939056397 + 0.3357639014720917 + <_> + + <_> + + + + <_>6 4 6 1 -1. + <_>8 4 2 1 3. + 0 + 0.0124262003228068 + 0.4959059059619904 + 0.1346601992845535 + <_> + + <_> + + + + <_>9 11 6 1 -1. + <_>11 11 2 1 3. + 0 + 0.0283357501029968 + 0.5117079019546509 + 6.1043637106195092e-004 + <_> + + <_> + + + + <_>5 11 6 1 -1. + <_>7 11 2 1 3. + 0 + 6.6165882162749767e-003 + 0.4736349880695343 + 0.7011628150939941 + <_> + + <_> + + + + <_>10 16 3 4 -1. + <_>11 16 1 4 3. + 0 + 8.0468766391277313e-003 + 0.5216417908668518 + 0.3282819986343384 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>9 7 1 3 3. + 0 + -1.1193980462849140e-003 + 0.5809860825538635 + 0.4563739001750946 + <_> + + <_> + + + + <_>2 12 16 8 -1. + <_>2 16 16 4 2. + 0 + 0.0132775902748108 + 0.5398362278938294 + 0.4103901088237763 + <_> + + <_> + + + + <_>0 15 15 2 -1. + <_>0 16 15 1 2. + 0 + 4.8794739996083081e-004 + 0.4249286055564880 + 0.5410590767860413 + <_> + + <_> + + + + <_>15 4 5 6 -1. + <_>15 6 5 2 3. + 0 + 0.0112431701272726 + 0.5269963741302490 + 0.3438215851783752 + <_> + + <_> + + + + <_>9 5 2 4 -1. + <_>10 5 1 4 2. + 0 + -8.9896668214350939e-004 + 0.5633075833320618 + 0.4456613063812256 + <_> + + <_> + + + + <_>8 10 9 6 -1. + <_>8 12 9 2 3. + 0 + 6.6677159629762173e-003 + 0.5312889218330383 + 0.4362679123878479 + <_> + + <_> + + + + <_>2 19 15 1 -1. + <_>7 19 5 1 3. + 0 + 0.0289472993463278 + 0.4701794981956482 + 0.6575797796249390 + <_> + + <_> + + + + <_>10 16 3 4 -1. + <_>11 16 1 4 3. + 0 + -0.0234000496566296 + 0. + 0.5137398838996887 + <_> + + <_> + + + + <_>0 15 20 4 -1. + <_>0 17 20 2 2. + 0 + -0.0891170501708984 + 0.0237452797591686 + 0.4942430853843689 + <_> + + <_> + + + + <_>10 16 3 4 -1. + <_>11 16 1 4 3. + 0 + -0.0140546001493931 + 0.3127323091030121 + 0.5117511153221130 + <_> + + <_> + + + + <_>7 16 3 4 -1. + <_>8 16 1 4 3. + 0 + 8.1239398568868637e-003 + 0.5009049177169800 + 0.2520025968551636 + <_> + + <_> + + + + <_>9 16 3 3 -1. + <_>9 17 3 1 3. + 0 + -4.9964650534093380e-003 + 0.6387143731117249 + 0.4927811920642853 + <_> + + <_> + + + + <_>8 11 4 6 -1. + <_>8 14 4 3 2. + 0 + 3.1253970228135586e-003 + 0.5136849880218506 + 0.3680452108383179 + <_> + + <_> + + + + <_>9 6 2 12 -1. + <_>9 10 2 4 3. + 0 + 6.7669642157852650e-003 + 0.5509843826293945 + 0.4363631904125214 + <_> + + <_> + + + + <_>8 17 4 3 -1. + <_>8 18 4 1 3. + 0 + -2.3711440153419971e-003 + 0.6162335276603699 + 0.4586946964263916 + <_> + + <_> + + + + <_>9 18 8 2 -1. + <_>13 18 4 1 2. + <_>9 19 4 1 2. + 0 + -5.3522791713476181e-003 + 0.6185457706451416 + 0.4920490980148315 + <_> + + <_> + + + + <_>1 18 8 2 -1. + <_>1 19 8 1 2. + 0 + -0.0159688591957092 + 0.1382617950439453 + 0.4983252882957459 + <_> + + <_> + + + + <_>13 5 6 15 -1. + <_>15 5 2 15 3. + 0 + 4.7676060348749161e-003 + 0.4688057899475098 + 0.5490046143531799 + <_> + + <_> + + + + <_>9 8 2 2 -1. + <_>9 9 2 1 2. + 0 + -2.4714691098779440e-003 + 0.2368514984846115 + 0.5003952980041504 + <_> + + <_> + + + + <_>9 5 2 3 -1. + <_>9 5 1 3 2. + 0 + -7.1033788844943047e-004 + 0.5856394171714783 + 0.4721533060073853 + <_> + + <_> + + + + <_>1 5 6 15 -1. + <_>3 5 2 15 3. + 0 + -0.1411755979061127 + 0.0869000628590584 + 0.4961591064929962 + <_> + + <_> + + + + <_>4 1 14 8 -1. + <_>11 1 7 4 2. + <_>4 5 7 4 2. + 0 + 0.1065180972218514 + 0.5138837099075317 + 0.1741005033254623 + <_> + + <_> + + + + <_>2 4 4 16 -1. + <_>2 4 2 8 2. + <_>4 12 2 8 2. + 0 + -0.0527447499334812 + 0.7353636026382446 + 0.4772881865501404 + <_> + + <_> + + + + <_>12 4 3 12 -1. + <_>12 10 3 6 2. + 0 + -4.7431760467588902e-003 + 0.3884406089782715 + 0.5292701721191406 + <_> + + <_> + + + + <_>4 5 10 12 -1. + <_>4 5 5 6 2. + <_>9 11 5 6 2. + 0 + 9.9676765967160463e-004 + 0.5223492980003357 + 0.4003424048423767 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 8.0284131690859795e-003 + 0.4959106147289276 + 0.7212964296340942 + <_> + + <_> + + + + <_>5 4 2 3 -1. + <_>5 5 2 1 3. + 0 + 8.6025858763605356e-004 + 0.4444884061813355 + 0.5538476109504700 + <_> + + <_> + + + + <_>12 2 4 10 -1. + <_>14 2 2 5 2. + <_>12 7 2 5 2. + 0 + 9.3191501218825579e-004 + 0.5398371219635010 + 0.4163244068622589 + <_> + + <_> + + + + <_>6 4 7 3 -1. + <_>6 5 7 1 3. + 0 + -2.5082060601562262e-003 + 0.5854265093803406 + 0.4562500119209290 + <_> + + <_> + + + + <_>2 0 18 2 -1. + <_>11 0 9 1 2. + <_>2 1 9 1 2. + 0 + -2.1378761157393456e-003 + 0.4608069062232971 + 0.5280259251594544 + <_> + + <_> + + + + <_>0 0 18 2 -1. + <_>0 0 9 1 2. + <_>9 1 9 1 2. + 0 + -2.1546049974858761e-003 + 0.3791126906871796 + 0.5255997180938721 + <_> + + <_> + + + + <_>13 13 4 6 -1. + <_>15 13 2 3 2. + <_>13 16 2 3 2. + 0 + -7.6214009895920753e-003 + 0.5998609066009522 + 0.4952073991298676 + <_> + + <_> + + + + <_>3 13 4 6 -1. + <_>3 13 2 3 2. + <_>5 16 2 3 2. + 0 + 2.2055360022932291e-003 + 0.4484206140041351 + 0.5588530898094177 + <_> + + <_> + + + + <_>10 12 2 6 -1. + <_>10 15 2 3 2. + 0 + 1.2586950324475765e-003 + 0.5450747013092041 + 0.4423840939998627 + <_> + + <_> + + + + <_>5 9 10 10 -1. + <_>5 9 5 5 2. + <_>10 14 5 5 2. + 0 + -5.0926720723509789e-003 + 0.4118275046348572 + 0.5263035893440247 + <_> + + <_> + + + + <_>11 4 4 2 -1. + <_>13 4 2 1 2. + <_>11 5 2 1 2. + 0 + -2.5095739401876926e-003 + 0.5787907838821411 + 0.4998494982719421 + <_> + + <_> + + + + <_>7 12 6 8 -1. + <_>10 12 3 8 2. + 0 + -0.0773275569081306 + 0.8397865891456604 + 0.4811120033264160 + <_> + + <_> + + + + <_>12 2 4 10 -1. + <_>14 2 2 5 2. + <_>12 7 2 5 2. + 0 + -0.0414858199656010 + 0.2408611029386520 + 0.5176993012428284 + <_> + + <_> + + + + <_>8 11 2 1 -1. + <_>9 11 1 1 2. + 0 + 1.0355669655837119e-004 + 0.4355360865592957 + 0.5417054295539856 + <_> + + <_> + + + + <_>10 5 1 12 -1. + <_>10 9 1 4 3. + 0 + 1.3255809899419546e-003 + 0.5453971028327942 + 0.4894095063209534 + <_> + + <_> + + + + <_>0 11 6 9 -1. + <_>3 11 3 9 2. + 0 + -8.0598732456564903e-003 + 0.5771024227142334 + 0.4577918946743012 + <_> + + <_> + + + + <_>12 2 4 10 -1. + <_>14 2 2 5 2. + <_>12 7 2 5 2. + 0 + 0.0190586205571890 + 0.5169867873191834 + 0.3400475084781647 + <_> + + <_> + + + + <_>4 2 4 10 -1. + <_>4 2 2 5 2. + <_>6 7 2 5 2. + 0 + -0.0350578911602497 + 0.2203243970870972 + 0.5000503063201904 + <_> + + <_> + + + + <_>11 4 4 2 -1. + <_>13 4 2 1 2. + <_>11 5 2 1 2. + 0 + 5.7296059094369411e-003 + 0.5043408274650574 + 0.6597570776939392 + <_> + + <_> + + + + <_>0 14 6 3 -1. + <_>0 15 6 1 3. + 0 + -0.0116483299061656 + 0.2186284959316254 + 0.4996652901172638 + <_> + + <_> + + + + <_>11 4 4 2 -1. + <_>13 4 2 1 2. + <_>11 5 2 1 2. + 0 + 1.4544479781761765e-003 + 0.5007681846618652 + 0.5503727793693543 + <_> + + <_> + + + + <_>6 1 3 2 -1. + <_>7 1 1 2 3. + 0 + -2.5030909455381334e-004 + 0.4129841029644013 + 0.5241670012474060 + <_> + + <_> + + + + <_>11 4 4 2 -1. + <_>13 4 2 1 2. + <_>11 5 2 1 2. + 0 + -8.2907272735610604e-004 + 0.5412868261337280 + 0.4974496066570282 + <_> + + <_> + + + + <_>5 4 4 2 -1. + <_>5 4 2 1 2. + <_>7 5 2 1 2. + 0 + 1.0862209601327777e-003 + 0.4605529904365540 + 0.5879228711128235 + <_> + + <_> + + + + <_>13 0 2 12 -1. + <_>14 0 1 6 2. + <_>13 6 1 6 2. + 0 + 2.0000500080641359e-004 + 0.5278854966163635 + 0.4705209136009216 + <_> + + <_> + + + + <_>6 0 3 10 -1. + <_>7 0 1 10 3. + 0 + 2.9212920926511288e-003 + 0.5129609704017639 + 0.3755536973476410 + <_> + + <_> + + + + <_>3 0 17 8 -1. + <_>3 4 17 4 2. + 0 + 0.0253874007612467 + 0.4822691977024078 + 0.5790768265724182 + <_> + + <_> + + + + <_>0 4 20 4 -1. + <_>0 6 20 2 2. + 0 + -3.1968469265848398e-003 + 0.5248395204544067 + 0.3962840139865875 + 87.6960296630859380 + 17 + -1 + <_> + + + <_> + + <_> + + + + <_>0 3 8 2 -1. + <_>4 3 4 2 2. + 0 + 5.8031738735735416e-003 + 0.3498983979225159 + 0.5961983203887940 + <_> + + <_> + + + + <_>8 11 4 3 -1. + <_>8 12 4 1 3. + 0 + -9.0003069490194321e-003 + 0.6816636919975281 + 0.4478552043437958 + <_> + + <_> + + + + <_>5 7 6 4 -1. + <_>5 7 3 2 2. + <_>8 9 3 2 2. + 0 + -1.1549659539014101e-003 + 0.5585706233978272 + 0.3578251004219055 + <_> + + <_> + + + + <_>8 3 4 9 -1. + <_>8 6 4 3 3. + 0 + -1.1069850297644734e-003 + 0.5365036129951477 + 0.3050428032875061 + <_> + + <_> + + + + <_>8 15 1 4 -1. + <_>8 17 1 2 2. + 0 + 1.0308309720130637e-004 + 0.3639095127582550 + 0.5344635844230652 + <_> + + <_> + + + + <_>4 5 12 7 -1. + <_>8 5 4 7 3. + 0 + -5.0984839908778667e-003 + 0.2859157025814056 + 0.5504264831542969 + <_> + + <_> + + + + <_>4 2 4 10 -1. + <_>4 2 2 5 2. + <_>6 7 2 5 2. + 0 + 8.2572200335562229e-004 + 0.5236523747444153 + 0.3476041853427887 + <_> + + <_> + + + + <_>3 0 17 2 -1. + <_>3 1 17 1 2. + 0 + 9.9783325567841530e-003 + 0.4750322103500366 + 0.6219646930694580 + <_> + + <_> + + + + <_>2 2 16 15 -1. + <_>2 7 16 5 3. + 0 + -0.0374025292694569 + 0.3343375921249390 + 0.5278062820434570 + <_> + + <_> + + + + <_>15 2 5 2 -1. + <_>15 3 5 1 2. + 0 + 4.8548257909715176e-003 + 0.5192180871963501 + 0.3700444102287293 + <_> + + <_> + + + + <_>9 3 2 2 -1. + <_>10 3 1 2 2. + 0 + -1.8664470408111811e-003 + 0.2929843962192535 + 0.5091944932937622 + <_> + + <_> + + + + <_>4 5 16 15 -1. + <_>4 10 16 5 3. + 0 + 0.0168888904154301 + 0.3686845898628235 + 0.5431225895881653 + <_> + + <_> + + + + <_>7 13 5 6 -1. + <_>7 16 5 3 2. + 0 + -5.8372621424496174e-003 + 0.3632183969020844 + 0.5221335887908936 + <_> + + <_> + + + + <_>10 7 3 2 -1. + <_>11 7 1 2 3. + 0 + -1.4713739510625601e-003 + 0.5870683789253235 + 0.4700650870800018 + <_> + + <_> + + + + <_>8 3 3 1 -1. + <_>9 3 1 1 3. + 0 + -1.1522950371727347e-003 + 0.3195894956588745 + 0.5140954256057739 + <_> + + <_> + + + + <_>9 16 3 3 -1. + <_>9 17 3 1 3. + 0 + -4.2560300789773464e-003 + 0.6301859021186829 + 0.4814921021461487 + <_> + + <_> + + + + <_>0 2 5 2 -1. + <_>0 3 5 1 2. + 0 + -6.7378291860222816e-003 + 0.1977048069238663 + 0.5025808215141296 + <_> + + <_> + + + + <_>12 5 4 3 -1. + <_>12 6 4 1 3. + 0 + 0.0113826701417565 + 0.4954132139682770 + 0.6867045760154724 + <_> + + <_> + + + + <_>1 7 12 1 -1. + <_>5 7 4 1 3. + 0 + 5.1794708706438541e-003 + 0.5164427757263184 + 0.3350647985935211 + <_> + + <_> + + + + <_>7 5 6 14 -1. + <_>7 12 6 7 2. + 0 + -0.1174378991127014 + 0.2315246015787125 + 0.5234413743019104 + <_> + + <_> + + + + <_>0 0 8 10 -1. + <_>0 0 4 5 2. + <_>4 5 4 5 2. + 0 + 0.0287034492939711 + 0.4664297103881836 + 0.6722521185874939 + <_> + + <_> + + + + <_>9 1 3 2 -1. + <_>10 1 1 2 3. + 0 + 4.8231030814349651e-003 + 0.5220875144004822 + 0.2723532915115356 + <_> + + <_> + + + + <_>8 1 3 2 -1. + <_>9 1 1 2 3. + 0 + 2.6798530016094446e-003 + 0.5079277157783508 + 0.2906948924064636 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + 8.0504082143306732e-003 + 0.4885950982570648 + 0.6395021080970764 + <_> + + <_> + + + + <_>7 4 6 16 -1. + <_>7 12 6 8 2. + 0 + 4.8054959625005722e-003 + 0.5197256803512573 + 0.3656663894653320 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -2.2420159075409174e-003 + 0.6153467893600464 + 0.4763701856136322 + <_> + + <_> + + + + <_>2 3 2 6 -1. + <_>2 5 2 2 3. + 0 + -0.0137577103450894 + 0.2637344896793366 + 0.5030903220176697 + <_> + + <_> + + + + <_>14 2 6 9 -1. + <_>14 5 6 3 3. + 0 + -0.1033829972147942 + 0.2287521958351135 + 0.5182461142539978 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + -9.4432085752487183e-003 + 0.6953303813934326 + 0.4694949090480804 + <_> + + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + 8.0271181650459766e-004 + 0.5450655221939087 + 0.4268783926963806 + <_> + + <_> + + + + <_>5 5 2 3 -1. + <_>5 6 2 1 3. + 0 + -4.1945669800043106e-003 + 0.6091387867927551 + 0.4571642875671387 + <_> + + <_> + + + + <_>13 11 3 6 -1. + <_>13 13 3 2 3. + 0 + 0.0109422104433179 + 0.5241063237190247 + 0.3284547030925751 + <_> + + <_> + + + + <_>3 14 2 6 -1. + <_>3 17 2 3 2. + 0 + -5.7841069065034389e-004 + 0.5387929081916809 + 0.4179368913173676 + <_> + + <_> + + + + <_>14 3 6 2 -1. + <_>14 4 6 1 2. + 0 + -2.0888620056211948e-003 + 0.4292691051959992 + 0.5301715731620789 + <_> + + <_> + + + + <_>0 8 16 2 -1. + <_>0 9 16 1 2. + 0 + 3.2383969519287348e-003 + 0.3792347908020020 + 0.5220744013786316 + <_> + + <_> + + + + <_>14 3 6 2 -1. + <_>14 4 6 1 2. + 0 + 4.9075027927756310e-003 + 0.5237283110618591 + 0.4126757979393005 + <_> + + <_> + + + + <_>0 0 5 6 -1. + <_>0 2 5 2 3. + 0 + -0.0322779417037964 + 0.1947655975818634 + 0.4994502067565918 + <_> + + <_> + + + + <_>12 5 4 3 -1. + <_>12 6 4 1 3. + 0 + -8.9711230248212814e-003 + 0.6011285185813904 + 0.4929032027721405 + <_> + + <_> + + + + <_>4 11 3 6 -1. + <_>4 13 3 2 3. + 0 + 0.0153210898861289 + 0.5009753704071045 + 0.2039822041988373 + <_> + + <_> + + + + <_>12 5 4 3 -1. + <_>12 6 4 1 3. + 0 + 2.0855569746345282e-003 + 0.4862189888954163 + 0.5721694827079773 + <_> + + <_> + + + + <_>9 5 1 3 -1. + <_>9 6 1 1 3. + 0 + 5.0615021027624607e-003 + 0.5000218749046326 + 0.1801805943250656 + <_> + + <_> + + + + <_>12 5 4 3 -1. + <_>12 6 4 1 3. + 0 + -3.7174751050770283e-003 + 0.5530117154121399 + 0.4897592961788178 + <_> + + <_> + + + + <_>6 6 8 12 -1. + <_>6 12 8 6 2. + 0 + -0.0121705001220107 + 0.4178605973720551 + 0.5383723974227905 + <_> + + <_> + + + + <_>12 5 4 3 -1. + <_>12 6 4 1 3. + 0 + 4.6248398721218109e-003 + 0.4997169971466065 + 0.5761327147483826 + <_> + + <_> + + + + <_>5 12 9 2 -1. + <_>8 12 3 2 3. + 0 + -2.1040429419372231e-004 + 0.5331807136535645 + 0.4097681045532227 + <_> + + <_> + + + + <_>12 5 4 3 -1. + <_>12 6 4 1 3. + 0 + -0.0146417804062366 + 0.5755925178527832 + 0.5051776170730591 + <_> + + <_> + + + + <_>4 5 4 3 -1. + <_>4 6 4 1 3. + 0 + 3.3199489116668701e-003 + 0.4576976895332336 + 0.6031805872917175 + <_> + + <_> + + + + <_>6 6 9 2 -1. + <_>9 6 3 2 3. + 0 + 3.7236879579722881e-003 + 0.4380396902561188 + 0.5415883064270020 + <_> + + <_> + + + + <_>4 11 1 3 -1. + <_>4 12 1 1 3. + 0 + 8.2951161311939359e-004 + 0.5163031816482544 + 0.3702219128608704 + <_> + + <_> + + + + <_>14 12 6 6 -1. + <_>14 12 3 6 2. + 0 + -0.0114084901288152 + 0.6072946786880493 + 0.4862565100193024 + <_> + + <_> + + + + <_>7 0 3 7 -1. + <_>8 0 1 7 3. + 0 + -4.5320121571421623e-003 + 0.3292475938796997 + 0.5088962912559509 + <_> + + <_> + + + + <_>9 8 3 3 -1. + <_>10 8 1 3 3. + 0 + 5.1276017911732197e-003 + 0.4829767942428589 + 0.6122708916664124 + <_> + + <_> + + + + <_>8 8 3 3 -1. + <_>9 8 1 3 3. + 0 + 9.8583158105611801e-003 + 0.4660679996013641 + 0.6556177139282227 + <_> + + <_> + + + + <_>5 10 11 3 -1. + <_>5 11 11 1 3. + 0 + 0.0369859188795090 + 0.5204849243164063 + 0.1690472066402435 + <_> + + <_> + + + + <_>5 7 10 1 -1. + <_>10 7 5 1 2. + 0 + 4.6491161920130253e-003 + 0.5167322158813477 + 0.3725225031375885 + <_> + + <_> + + + + <_>9 7 3 2 -1. + <_>10 7 1 2 3. + 0 + -4.2664702050387859e-003 + 0.6406493186950684 + 0.4987342953681946 + <_> + + <_> + + + + <_>8 7 3 2 -1. + <_>9 7 1 2 3. + 0 + -4.7956590424291790e-004 + 0.5897293090820313 + 0.4464873969554901 + <_> + + <_> + + + + <_>11 9 4 2 -1. + <_>11 9 2 2 2. + 0 + 3.6827160511165857e-003 + 0.5441560745239258 + 0.3472662866115570 + <_> + + <_> + + + + <_>5 9 4 2 -1. + <_>7 9 2 2 2. + 0 + -0.0100598800927401 + 0.2143162935972214 + 0.5004829764366150 + <_> + + <_> + + + + <_>14 10 2 4 -1. + <_>14 12 2 2 2. + 0 + -3.0361840617842972e-004 + 0.5386424064636231 + 0.4590323865413666 + <_> + + <_> + + + + <_>7 7 3 2 -1. + <_>8 7 1 2 3. + 0 + -1.4545479789376259e-003 + 0.5751184225082398 + 0.4497095048427582 + <_> + + <_> + + + + <_>14 17 6 3 -1. + <_>14 18 6 1 3. + 0 + 1.6515209572389722e-003 + 0.5421937704086304 + 0.4238520860671997 + <_> + + <_> + + + + <_>4 5 12 12 -1. + <_>4 5 6 6 2. + <_>10 11 6 6 2. + 0 + -7.8468639403581619e-003 + 0.4077920913696289 + 0.5258157253265381 + <_> + + <_> + + + + <_>6 9 8 8 -1. + <_>10 9 4 4 2. + <_>6 13 4 4 2. + 0 + -5.1259850151836872e-003 + 0.4229275882244110 + 0.5479453206062317 + <_> + + <_> + + + + <_>0 4 15 4 -1. + <_>5 4 5 4 3. + 0 + -0.0368909612298012 + 0.6596375703811646 + 0.4674678146839142 + <_> + + <_> + + + + <_>13 2 4 1 -1. + <_>13 2 2 1 2. + 0 + 2.4035639944486320e-004 + 0.4251135885715485 + 0.5573202967643738 + <_> + + <_> + + + + <_>4 12 2 2 -1. + <_>4 13 2 1 2. + 0 + -1.5150169929256663e-005 + 0.5259246826171875 + 0.4074114859104157 + <_> + + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 2.2108471021056175e-003 + 0.4671722948551178 + 0.5886352062225342 + <_> + + <_> + + + + <_>9 13 2 3 -1. + <_>9 14 2 1 3. + 0 + -1.1568620102480054e-003 + 0.5711066126823425 + 0.4487161934375763 + <_> + + <_> + + + + <_>13 11 2 3 -1. + <_>13 12 2 1 3. + 0 + 4.9996292218565941e-003 + 0.5264198184013367 + 0.2898327112197876 + <_> + + <_> + + + + <_>7 12 4 4 -1. + <_>7 12 2 2 2. + <_>9 14 2 2 2. + 0 + -1.4656189596280456e-003 + 0.3891738057136536 + 0.5197871923446655 + <_> + + <_> + + + + <_>10 11 2 2 -1. + <_>11 11 1 1 2. + <_>10 12 1 1 2. + 0 + -1.1975039960816503e-003 + 0.5795872807502747 + 0.4927955865859985 + <_> + + <_> + + + + <_>8 17 3 2 -1. + <_>9 17 1 2 3. + 0 + -4.4954330660402775e-003 + 0.2377603054046631 + 0.5012555122375488 + <_> + + <_> + + + + <_>10 11 2 2 -1. + <_>11 11 1 1 2. + <_>10 12 1 1 2. + 0 + 1.4997160178609192e-004 + 0.4876626133918762 + 0.5617607831954956 + <_> + + <_> + + + + <_>0 17 6 3 -1. + <_>0 18 6 1 3. + 0 + 2.6391509454697371e-003 + 0.5168088078498840 + 0.3765509128570557 + <_> + + <_> + + + + <_>10 11 2 2 -1. + <_>11 11 1 1 2. + <_>10 12 1 1 2. + 0 + -2.9368131072260439e-004 + 0.5446649193763733 + 0.4874630868434906 + <_> + + <_> + + + + <_>8 11 2 2 -1. + <_>8 11 1 1 2. + <_>9 12 1 1 2. + 0 + 1.4211760135367513e-003 + 0.4687897861003876 + 0.6691331863403320 + <_> + + <_> + + + + <_>12 5 8 4 -1. + <_>12 5 4 4 2. + 0 + 0.0794276371598244 + 0.5193443894386292 + 0.2732945978641510 + <_> + + <_> + + + + <_>0 5 8 4 -1. + <_>4 5 4 4 2. + 0 + 0.0799375027418137 + 0.4971731007099152 + 0.1782083958387375 + <_> + + <_> + + + + <_>13 2 4 1 -1. + <_>13 2 2 1 2. + 0 + 0.0110892597585917 + 0.5165994763374329 + 0.3209475874900818 + <_> + + <_> + + + + <_>3 2 4 1 -1. + <_>5 2 2 1 2. + 0 + 1.6560709627810866e-004 + 0.4058471918106079 + 0.5307276248931885 + <_> + + <_> + + + + <_>10 0 4 2 -1. + <_>12 0 2 1 2. + <_>10 1 2 1 2. + 0 + -5.3354292176663876e-003 + 0.3445056974887848 + 0.5158129930496216 + <_> + + <_> + + + + <_>7 12 3 1 -1. + <_>8 12 1 1 3. + 0 + 1.1287260567769408e-003 + 0.4594863057136536 + 0.6075533032417297 + <_> + + <_> + + + + <_>8 11 4 8 -1. + <_>10 11 2 4 2. + <_>8 15 2 4 2. + 0 + -0.0219692196696997 + 0.1680400967597961 + 0.5228595733642578 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -2.1775320055894554e-004 + 0.3861596882343292 + 0.5215672850608826 + <_> + + <_> + + + + <_>3 18 15 2 -1. + <_>3 19 15 1 2. + 0 + 2.0200149447191507e-004 + 0.5517979264259338 + 0.4363039135932922 + <_> + + <_> + + + + <_>2 6 2 12 -1. + <_>2 6 1 6 2. + <_>3 12 1 6 2. + 0 + -0.0217331498861313 + 0.7999460101127625 + 0.4789851009845734 + <_> + + <_> + + + + <_>9 8 2 3 -1. + <_>9 9 2 1 3. + 0 + -8.4399932529777288e-004 + 0.4085975885391235 + 0.5374773144721985 + <_> + + <_> + + + + <_>7 10 3 2 -1. + <_>8 10 1 2 3. + 0 + -4.3895249837078154e-004 + 0.5470405220985413 + 0.4366143047809601 + <_> + + <_> + + + + <_>11 11 3 1 -1. + <_>12 11 1 1 3. + 0 + 1.5092400135472417e-003 + 0.4988996982574463 + 0.5842149257659912 + <_> + + <_> + + + + <_>6 11 3 1 -1. + <_>7 11 1 1 3. + 0 + -3.5547839943319559e-003 + 0.6753690242767334 + 0.4721005856990814 + <_> + + <_> + + + + <_>9 2 4 2 -1. + <_>11 2 2 1 2. + <_>9 3 2 1 2. + 0 + 4.8191400128416717e-004 + 0.5415853857994080 + 0.4357109069824219 + <_> + + <_> + + + + <_>4 12 2 3 -1. + <_>4 13 2 1 3. + 0 + -6.0264398343861103e-003 + 0.2258509993553162 + 0.4991880953311920 + <_> + + <_> + + + + <_>2 1 18 3 -1. + <_>8 1 6 3 3. + 0 + -0.0116681400686502 + 0.6256554722785950 + 0.4927498996257782 + <_> + + <_> + + + + <_>5 1 4 14 -1. + <_>7 1 2 14 2. + 0 + -2.8718370012938976e-003 + 0.3947784900665283 + 0.5245801806449890 + <_> + + <_> + + + + <_>8 16 12 3 -1. + <_>8 16 6 3 2. + 0 + 0.0170511696487665 + 0.4752511084079742 + 0.5794224143028259 + <_> + + <_> + + + + <_>1 17 18 3 -1. + <_>7 17 6 3 3. + 0 + -0.0133520802482963 + 0.6041104793548584 + 0.4544535875320435 + <_> + + <_> + + + + <_>9 14 2 6 -1. + <_>9 17 2 3 2. + 0 + -3.9301801007241011e-004 + 0.4258275926113129 + 0.5544905066490173 + <_> + + <_> + + + + <_>9 12 1 8 -1. + <_>9 16 1 4 2. + 0 + 3.0483349692076445e-003 + 0.5233420133590698 + 0.3780272901058197 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + -4.3579288758337498e-003 + 0.6371889114379883 + 0.4838674068450928 + <_> + + <_> + + + + <_>9 6 2 12 -1. + <_>9 10 2 4 3. + 0 + 5.6661018170416355e-003 + 0.5374705791473389 + 0.4163666069507599 + <_> + + <_> + + + + <_>12 9 3 3 -1. + <_>12 10 3 1 3. + 0 + 6.0677339206449687e-005 + 0.4638795852661133 + 0.5311625003814697 + <_> + + <_> + + + + <_>0 1 4 8 -1. + <_>2 1 2 8 2. + 0 + 0.0367381609976292 + 0.4688656032085419 + 0.6466524004936218 + <_> + + <_> + + + + <_>9 1 6 2 -1. + <_>12 1 3 1 2. + <_>9 2 3 1 2. + 0 + 8.6528137326240540e-003 + 0.5204318761825562 + 0.2188657969236374 + <_> + + <_> + + + + <_>1 3 12 14 -1. + <_>1 10 12 7 2. + 0 + -0.1537135988473892 + 0.1630371958017349 + 0.4958840012550354 + <_> + + <_> + + + + <_>8 12 4 2 -1. + <_>10 12 2 1 2. + <_>8 13 2 1 2. + 0 + -4.1560421232134104e-004 + 0.5774459242820740 + 0.4696458876132965 + <_> + + <_> + + + + <_>1 9 10 2 -1. + <_>1 9 5 1 2. + <_>6 10 5 1 2. + 0 + -1.2640169588848948e-003 + 0.3977175951004028 + 0.5217198133468628 + <_> + + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + -3.5473341122269630e-003 + 0.6046528220176697 + 0.4808315038681030 + <_> + + <_> + + + + <_>6 8 8 3 -1. + <_>6 9 8 1 3. + 0 + 3.0019069527043030e-005 + 0.3996723890304565 + 0.5228201150894165 + <_> + + <_> + + + + <_>9 15 5 3 -1. + <_>9 16 5 1 3. + 0 + 1.3113019522279501e-003 + 0.4712158143520355 + 0.5765997767448425 + <_> + + <_> + + + + <_>8 7 4 3 -1. + <_>8 8 4 1 3. + 0 + -1.3374709524214268e-003 + 0.4109584987163544 + 0.5253170132637024 + <_> + + <_> + + + + <_>7 7 6 2 -1. + <_>7 8 6 1 2. + 0 + 0.0208767093718052 + 0.5202993750572205 + 0.1757981926202774 + <_> + + <_> + + + + <_>5 7 8 2 -1. + <_>5 7 4 1 2. + <_>9 8 4 1 2. + 0 + -7.5497948564589024e-003 + 0.6566609740257263 + 0.4694975018501282 + <_> + + <_> + + + + <_>12 9 3 3 -1. + <_>12 10 3 1 3. + 0 + 0.0241885501891375 + 0.5128673911094666 + 0.3370220959186554 + <_> + + <_> + + + + <_>4 7 4 2 -1. + <_>4 8 4 1 2. + 0 + -2.9358828905969858e-003 + 0.6580786705017090 + 0.4694541096687317 + <_> + + <_> + + + + <_>14 2 6 9 -1. + <_>14 5 6 3 3. + 0 + 0.0575579293072224 + 0.5146445035934448 + 0.2775259912014008 + <_> + + <_> + + + + <_>4 9 3 3 -1. + <_>5 9 1 3 3. + 0 + -1.1343370424583554e-003 + 0.3836601972579956 + 0.5192667245864868 + <_> + + <_> + + + + <_>12 9 3 3 -1. + <_>12 10 3 1 3. + 0 + 0.0168169997632504 + 0.5085592865943909 + 0.6177260875701904 + <_> + + <_> + + + + <_>0 2 6 9 -1. + <_>0 5 6 3 3. + 0 + 5.0535178743302822e-003 + 0.5138763189315796 + 0.3684791922569275 + <_> + + <_> + + + + <_>17 3 3 6 -1. + <_>18 3 1 6 3. + 0 + -4.5874710194766521e-003 + 0.5989655256271362 + 0.4835202097892761 + <_> + + <_> + + + + <_>0 3 3 6 -1. + <_>1 3 1 6 3. + 0 + 1.6882460331544280e-003 + 0.4509486854076386 + 0.5723056793212891 + <_> + + <_> + + + + <_>17 14 1 2 -1. + <_>17 15 1 1 2. + 0 + -1.6554000321775675e-003 + 0.3496770858764648 + 0.5243319272994995 + <_> + + <_> + + + + <_>4 9 4 3 -1. + <_>6 9 2 3 2. + 0 + -0.0193738006055355 + 0.1120536997914314 + 0.4968712925910950 + <_> + + <_> + + + + <_>12 9 3 3 -1. + <_>12 10 3 1 3. + 0 + 0.0103744501248002 + 0.5148196816444397 + 0.4395213127136231 + <_> + + <_> + + + + <_>5 9 3 3 -1. + <_>5 10 3 1 3. + 0 + 1.4973050565458834e-004 + 0.4084999859333038 + 0.5269886851310730 + <_> + + <_> + + + + <_>9 5 6 8 -1. + <_>12 5 3 4 2. + <_>9 9 3 4 2. + 0 + -0.0429819300770760 + 0.6394104957580566 + 0.5018504261970520 + <_> + + <_> + + + + <_>5 5 6 8 -1. + <_>5 5 3 4 2. + <_>8 9 3 4 2. + 0 + 8.3065936341881752e-003 + 0.4707553982734680 + 0.6698353290557861 + <_> + + <_> + + + + <_>16 1 4 6 -1. + <_>16 4 4 3 2. + 0 + -4.1285790503025055e-003 + 0.4541369080543518 + 0.5323647260665894 + <_> + + <_> + + + + <_>1 0 6 20 -1. + <_>3 0 2 20 3. + 0 + 1.7399420030415058e-003 + 0.4333961904048920 + 0.5439866185188294 + <_> + + <_> + + + + <_>12 11 3 2 -1. + <_>13 11 1 2 3. + 0 + 1.1739750334527344e-004 + 0.4579687118530273 + 0.5543426275253296 + <_> + + <_> + + + + <_>5 11 3 2 -1. + <_>6 11 1 2 3. + 0 + 1.8585780344437808e-004 + 0.4324643909931183 + 0.5426754951477051 + <_> + + <_> + + + + <_>9 4 6 1 -1. + <_>11 4 2 1 3. + 0 + 5.5587692186236382e-003 + 0.5257220864295960 + 0.3550611138343811 + <_> + + <_> + + + + <_>0 0 8 3 -1. + <_>4 0 4 3 2. + 0 + -7.9851560294628143e-003 + 0.6043018102645874 + 0.4630635976791382 + <_> + + <_> + + + + <_>15 0 2 5 -1. + <_>15 0 1 5 2. + 0 + 6.0594122624024749e-004 + 0.4598254859447479 + 0.5533195137977600 + <_> + + <_> + + + + <_>4 1 3 2 -1. + <_>5 1 1 2 3. + 0 + -2.2983040253166109e-004 + 0.4130752086639404 + 0.5322461128234863 + <_> + + <_> + + + + <_>7 0 6 15 -1. + <_>9 0 2 15 3. + 0 + 4.3740210821852088e-004 + 0.4043039977550507 + 0.5409289002418518 + <_> + + <_> + + + + <_>6 11 3 1 -1. + <_>7 11 1 1 3. + 0 + 2.9482020181603730e-004 + 0.4494963884353638 + 0.5628852248191834 + <_> + + <_> + + + + <_>12 0 3 4 -1. + <_>13 0 1 4 3. + 0 + 0.0103126596659422 + 0.5177510976791382 + 0.2704316973686218 + <_> + + <_> + + + + <_>5 4 6 1 -1. + <_>7 4 2 1 3. + 0 + -7.7241109684109688e-003 + 0.1988019049167633 + 0.4980553984642029 + <_> + + <_> + + + + <_>12 7 3 2 -1. + <_>12 8 3 1 2. + 0 + -4.6797208487987518e-003 + 0.6644750237464905 + 0.5018296241760254 + <_> + + <_> + + + + <_>0 1 4 6 -1. + <_>0 4 4 3 2. + 0 + -5.0755459815263748e-003 + 0.3898304998874664 + 0.5185269117355347 + <_> + + <_> + + + + <_>12 7 3 2 -1. + <_>12 8 3 1 2. + 0 + 2.2479740437120199e-003 + 0.4801808893680573 + 0.5660336017608643 + <_> + + <_> + + + + <_>2 16 3 3 -1. + <_>2 17 3 1 3. + 0 + 8.3327008178457618e-004 + 0.5210919976234436 + 0.3957188129425049 + <_> + + <_> + + + + <_>13 8 6 10 -1. + <_>16 8 3 5 2. + <_>13 13 3 5 2. + 0 + -0.0412793308496475 + 0.6154541969299316 + 0.5007054209709168 + <_> + + <_> + + + + <_>0 9 5 2 -1. + <_>0 10 5 1 2. + 0 + -5.0930189900100231e-004 + 0.3975942134857178 + 0.5228403806686401 + <_> + + <_> + + + + <_>12 11 2 2 -1. + <_>13 11 1 1 2. + <_>12 12 1 1 2. + 0 + 1.2568780221045017e-003 + 0.4979138076305389 + 0.5939183235168457 + <_> + + <_> + + + + <_>3 15 3 3 -1. + <_>3 16 3 1 3. + 0 + 8.0048497766256332e-003 + 0.4984497129917145 + 0.1633366048336029 + <_> + + <_> + + + + <_>12 7 3 2 -1. + <_>12 8 3 1 2. + 0 + -1.1879300000146031e-003 + 0.5904964804649353 + 0.4942624866962433 + <_> + + <_> + + + + <_>5 7 3 2 -1. + <_>5 8 3 1 2. + 0 + 6.1948952497914433e-004 + 0.4199557900428772 + 0.5328726172447205 + <_> + + <_> + + + + <_>9 5 9 9 -1. + <_>9 8 9 3 3. + 0 + 6.6829859279096127e-003 + 0.5418602824211121 + 0.4905889034271240 + <_> + + <_> + + + + <_>5 0 3 7 -1. + <_>6 0 1 7 3. + 0 + -3.7062340416014194e-003 + 0.3725939095020294 + 0.5138000249862671 + <_> + + <_> + + + + <_>5 2 12 5 -1. + <_>9 2 4 5 3. + 0 + -0.0397394113242626 + 0.6478961110115051 + 0.5050346851348877 + <_> + + <_> + + + + <_>6 11 2 2 -1. + <_>6 11 1 1 2. + <_>7 12 1 1 2. + 0 + 1.4085009461268783e-003 + 0.4682339131832123 + 0.6377884149551392 + <_> + + <_> + + + + <_>15 15 3 2 -1. + <_>15 16 3 1 2. + 0 + 3.9322688826359808e-004 + 0.5458530187606812 + 0.4150482118129730 + <_> + + <_> + + + + <_>2 15 3 2 -1. + <_>2 16 3 1 2. + 0 + -1.8979819724336267e-003 + 0.3690159916877747 + 0.5149704217910767 + <_> + + <_> + + + + <_>14 12 6 8 -1. + <_>17 12 3 4 2. + <_>14 16 3 4 2. + 0 + -0.0139704402536154 + 0.6050562858581543 + 0.4811357855796814 + <_> + + <_> + + + + <_>2 8 15 6 -1. + <_>7 8 5 6 3. + 0 + -0.1010081991553307 + 0.2017080038785934 + 0.4992361962795258 + <_> + + <_> + + + + <_>2 2 18 17 -1. + <_>8 2 6 17 3. + 0 + -0.0173469204455614 + 0.5713148713111877 + 0.4899486005306244 + <_> + + <_> + + + + <_>5 1 4 1 -1. + <_>7 1 2 1 2. + 0 + 1.5619759506080300e-004 + 0.4215388894081116 + 0.5392642021179199 + <_> + + <_> + + + + <_>5 2 12 5 -1. + <_>9 2 4 5 3. + 0 + 0.1343892961740494 + 0.5136151909828186 + 0.3767612874507904 + <_> + + <_> + + + + <_>3 2 12 5 -1. + <_>7 2 4 5 3. + 0 + -0.0245822407305241 + 0.7027357816696167 + 0.4747906923294067 + <_> + + <_> + + + + <_>4 9 12 4 -1. + <_>10 9 6 2 2. + <_>4 11 6 2 2. + 0 + -3.8553720805794001e-003 + 0.4317409098148346 + 0.5427716970443726 + <_> + + <_> + + + + <_>5 15 6 2 -1. + <_>5 15 3 1 2. + <_>8 16 3 1 2. + 0 + -2.3165249731391668e-003 + 0.5942698717117310 + 0.4618647992610931 + <_> + + <_> + + + + <_>10 14 2 3 -1. + <_>10 15 2 1 3. + 0 + -4.8518120311200619e-003 + 0.6191568970680237 + 0.4884895086288452 + <_> + + <_> + + + + <_>0 13 20 2 -1. + <_>0 13 10 1 2. + <_>10 14 10 1 2. + 0 + 2.4699938949197531e-003 + 0.5256664752960205 + 0.4017199873924255 + <_> + + <_> + + + + <_>4 9 12 8 -1. + <_>10 9 6 4 2. + <_>4 13 6 4 2. + 0 + 0.0454969592392445 + 0.5237867832183838 + 0.2685773968696594 + <_> + + <_> + + + + <_>8 13 3 6 -1. + <_>8 16 3 3 2. + 0 + -0.0203195996582508 + 0.2130445986986160 + 0.4979738891124725 + <_> + + <_> + + + + <_>10 12 2 2 -1. + <_>10 13 2 1 2. + 0 + 2.6994998916052282e-004 + 0.4814041852951050 + 0.5543122291564941 + <_> + + <_> + + + + <_>9 12 2 2 -1. + <_>9 12 1 1 2. + <_>10 13 1 1 2. + 0 + -1.8232699949294329e-003 + 0.6482579708099365 + 0.4709989130496979 + <_> + + <_> + + + + <_>4 11 14 4 -1. + <_>11 11 7 2 2. + <_>4 13 7 2 2. + 0 + -6.3015790656208992e-003 + 0.4581927955150604 + 0.5306236147880554 + <_> + + <_> + + + + <_>8 5 4 2 -1. + <_>8 6 4 1 2. + 0 + -2.4139499873854220e-004 + 0.5232086777687073 + 0.4051763117313385 + <_> + + <_> + + + + <_>10 10 6 3 -1. + <_>12 10 2 3 3. + 0 + -1.0330369696021080e-003 + 0.5556201934814453 + 0.4789193868637085 + <_> + + <_> + + + + <_>2 14 1 2 -1. + <_>2 15 1 1 2. + 0 + 1.8041160365100950e-004 + 0.5229442715644836 + 0.4011810123920441 + <_> + + <_> + + + + <_>13 8 6 12 -1. + <_>16 8 3 6 2. + <_>13 14 3 6 2. + 0 + -0.0614078603684902 + 0.6298682093620300 + 0.5010703206062317 + <_> + + <_> + + + + <_>1 8 6 12 -1. + <_>1 8 3 6 2. + <_>4 14 3 6 2. + 0 + -0.0695439130067825 + 0.7228280901908875 + 0.4773184061050415 + <_> + + <_> + + + + <_>10 0 6 10 -1. + <_>12 0 2 10 3. + 0 + -0.0705426633358002 + 0.2269513010978699 + 0.5182529091835022 + <_> + + <_> + + + + <_>5 11 8 4 -1. + <_>5 11 4 2 2. + <_>9 13 4 2 2. + 0 + 2.4423799477517605e-003 + 0.5237097144126892 + 0.4098151028156281 + <_> + + <_> + + + + <_>10 16 8 4 -1. + <_>14 16 4 2 2. + <_>10 18 4 2 2. + 0 + 1.5494349645450711e-003 + 0.4773750901222229 + 0.5468043088912964 + <_> + + <_> + + + + <_>7 7 6 6 -1. + <_>9 7 2 6 3. + 0 + -0.0239142198115587 + 0.7146975994110107 + 0.4783824980258942 + <_> + + <_> + + + + <_>10 2 4 10 -1. + <_>10 2 2 10 2. + 0 + -0.0124536901712418 + 0.2635296881198883 + 0.5241122841835022 + <_> + + <_> + + + + <_>6 1 4 9 -1. + <_>8 1 2 9 2. + 0 + -2.0760179904755205e-004 + 0.3623757064342499 + 0.5113608837127686 + <_> + + <_> + + + + <_>12 19 2 1 -1. + <_>12 19 1 1 2. + 0 + 2.9781080229440704e-005 + 0.4705932140350342 + 0.5432801842689514 + 90.2533493041992190 + 18 + -1 + <_> + + + <_> + + <_> + + + + <_>1 2 4 9 -1. + <_>3 2 2 9 2. + 0 + 0.0117727499455214 + 0.3860518932342529 + 0.6421167254447937 + <_> + + <_> + + + + <_>7 5 6 4 -1. + <_>9 5 2 4 3. + 0 + 0.0270375702530146 + 0.4385654926300049 + 0.6754038929939270 + <_> + + <_> + + + + <_>9 4 2 4 -1. + <_>9 6 2 2 2. + 0 + -3.6419500247575343e-005 + 0.5487101078033447 + 0.3423315882682800 + <_> + + <_> + + + + <_>14 5 2 8 -1. + <_>14 9 2 4 2. + 0 + 1.9995409529656172e-003 + 0.3230532109737396 + 0.5400317907333374 + <_> + + <_> + + + + <_>7 6 5 12 -1. + <_>7 12 5 6 2. + 0 + 4.5278300531208515e-003 + 0.5091639757156372 + 0.2935043871402741 + <_> + + <_> + + + + <_>14 6 2 6 -1. + <_>14 9 2 3 2. + 0 + 4.7890920541249216e-004 + 0.4178153872489929 + 0.5344064235687256 + <_> + + <_> + + + + <_>4 6 2 6 -1. + <_>4 9 2 3 2. + 0 + 1.1720920447260141e-003 + 0.2899182140827179 + 0.5132070779800415 + <_> + + <_> + + + + <_>8 15 10 4 -1. + <_>13 15 5 2 2. + <_>8 17 5 2 2. + 0 + 9.5305702416226268e-004 + 0.4280124902725220 + 0.5560845136642456 + <_> + + <_> + + + + <_>6 18 2 2 -1. + <_>7 18 1 2 2. + 0 + 1.5099150004971307e-005 + 0.4044871926307678 + 0.5404760241508484 + <_> + + <_> + + + + <_>11 3 6 2 -1. + <_>11 4 6 1 2. + 0 + -6.0817901976406574e-004 + 0.4271768927574158 + 0.5503466129302979 + <_> + + <_> + + + + <_>2 0 16 6 -1. + <_>2 2 16 2 3. + 0 + 3.3224520739167929e-003 + 0.3962723910808563 + 0.5369734764099121 + <_> + + <_> + + + + <_>11 3 6 2 -1. + <_>11 4 6 1 2. + 0 + -1.1037490330636501e-003 + 0.4727177917957306 + 0.5237749814987183 + <_> + + <_> + + + + <_>4 11 10 3 -1. + <_>4 12 10 1 3. + 0 + -1.4350269921123981e-003 + 0.5603008270263672 + 0.4223509132862091 + <_> + + <_> + + + + <_>11 3 6 2 -1. + <_>11 4 6 1 2. + 0 + 2.0767399109899998e-003 + 0.5225917100906372 + 0.4732725918292999 + <_> + + <_> + + + + <_>3 3 6 2 -1. + <_>3 4 6 1 2. + 0 + -1.6412809782195836e-004 + 0.3999075889587402 + 0.5432739853858948 + <_> + + <_> + + + + <_>16 0 4 7 -1. + <_>16 0 2 7 2. + 0 + 8.8302437216043472e-003 + 0.4678385853767395 + 0.6027327179908752 + <_> + + <_> + + + + <_>0 14 9 6 -1. + <_>0 16 9 2 3. + 0 + -0.0105520701035857 + 0.3493967056274414 + 0.5213974714279175 + <_> + + <_> + + + + <_>9 16 3 3 -1. + <_>9 17 3 1 3. + 0 + -2.2731600329279900e-003 + 0.6185818910598755 + 0.4749062955379486 + <_> + + <_> + + + + <_>4 6 6 2 -1. + <_>6 6 2 2 3. + 0 + -8.4786332445219159e-004 + 0.5285341143608093 + 0.3843482136726379 + <_> + + <_> + + + + <_>15 11 1 3 -1. + <_>15 12 1 1 3. + 0 + 1.2081359745934606e-003 + 0.5360640883445740 + 0.3447335958480835 + <_> + + <_> + + + + <_>5 5 2 3 -1. + <_>5 6 2 1 3. + 0 + 2.6512730401009321e-003 + 0.4558292031288147 + 0.6193962097167969 + <_> + + <_> + + + + <_>10 9 2 2 -1. + <_>10 10 2 1 2. + 0 + -1.1012479662895203e-003 + 0.3680230081081390 + 0.5327628254890442 + <_> + + <_> + + + + <_>3 1 4 3 -1. + <_>5 1 2 3 2. + 0 + 4.9561518244445324e-004 + 0.3960595130920410 + 0.5274940729141235 + <_> + + <_> + + + + <_>16 0 4 7 -1. + <_>16 0 2 7 2. + 0 + -0.0439017713069916 + 0.7020444869995117 + 0.4992839097976685 + <_> + + <_> + + + + <_>0 0 20 1 -1. + <_>10 0 10 1 2. + 0 + 0.0346903502941132 + 0.5049164295196533 + 0.2766602933406830 + <_> + + <_> + + + + <_>15 11 1 3 -1. + <_>15 12 1 1 3. + 0 + -2.7442190330475569e-003 + 0.2672632932662964 + 0.5274971127510071 + <_> + + <_> + + + + <_>0 4 3 4 -1. + <_>1 4 1 4 3. + 0 + 3.3316588960587978e-003 + 0.4579482972621918 + 0.6001101732254028 + <_> + + <_> + + + + <_>16 3 3 6 -1. + <_>16 5 3 2 3. + 0 + -0.0200445707887411 + 0.3171594142913818 + 0.5235717892646790 + <_> + + <_> + + + + <_>1 3 3 6 -1. + <_>1 5 3 2 3. + 0 + 1.3492030557245016e-003 + 0.5265362858772278 + 0.4034324884414673 + <_> + + <_> + + + + <_>6 2 12 6 -1. + <_>12 2 6 3 2. + <_>6 5 6 3 2. + 0 + 2.9702018946409225e-003 + 0.5332456827163696 + 0.4571984112262726 + <_> + + <_> + + + + <_>8 10 4 3 -1. + <_>8 11 4 1 3. + 0 + 6.3039981760084629e-003 + 0.4593310952186585 + 0.6034635901451111 + <_> + + <_> + + + + <_>4 2 14 6 -1. + <_>11 2 7 3 2. + <_>4 5 7 3 2. + 0 + -0.0129365902394056 + 0.4437963962554932 + 0.5372971296310425 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + 4.0148729458451271e-003 + 0.4680323898792267 + 0.6437833905220032 + <_> + + <_> + + + + <_>15 13 2 3 -1. + <_>15 14 2 1 3. + 0 + -2.6401679497212172e-003 + 0.3709631860256195 + 0.5314332842826843 + <_> + + <_> + + + + <_>8 12 4 3 -1. + <_>8 13 4 1 3. + 0 + 0.0139184398576617 + 0.4723555147647858 + 0.7130808830261231 + <_> + + <_> + + + + <_>15 11 1 3 -1. + <_>15 12 1 1 3. + 0 + -4.5087869511917233e-004 + 0.4492394030094147 + 0.5370404124259949 + <_> + + <_> + + + + <_>7 13 5 2 -1. + <_>7 14 5 1 2. + 0 + 2.5384349282830954e-004 + 0.4406864047050476 + 0.5514402985572815 + <_> + + <_> + + + + <_>7 12 6 3 -1. + <_>7 13 6 1 3. + 0 + 2.2710000630468130e-003 + 0.4682416915893555 + 0.5967984199523926 + <_> + + <_> + + + + <_>5 11 4 4 -1. + <_>5 13 4 2 2. + 0 + 2.4120779708027840e-003 + 0.5079392194747925 + 0.3018598854541779 + <_> + + <_> + + + + <_>11 4 3 3 -1. + <_>12 4 1 3 3. + 0 + -3.6025670851813629e-005 + 0.5601037144660950 + 0.4471096992492676 + <_> + + <_> + + + + <_>6 4 3 3 -1. + <_>7 4 1 3 3. + 0 + -7.4905529618263245e-003 + 0.2207535058259964 + 0.4989944100379944 + <_> + + <_> + + + + <_>16 5 3 6 -1. + <_>17 5 1 6 3. + 0 + -0.0175131205469370 + 0.6531215906143189 + 0.5017648935317993 + <_> + + <_> + + + + <_>3 6 12 7 -1. + <_>7 6 4 7 3. + 0 + 0.1428163051605225 + 0.4967963099479675 + 0.1482062041759491 + <_> + + <_> + + + + <_>16 5 3 6 -1. + <_>17 5 1 6 3. + 0 + 5.5345268920063972e-003 + 0.4898946881294251 + 0.5954223871231079 + <_> + + <_> + + + + <_>3 13 2 3 -1. + <_>3 14 2 1 3. + 0 + -9.6323591424152255e-004 + 0.3927116990089417 + 0.5196074247360230 + <_> + + <_> + + + + <_>16 5 3 6 -1. + <_>17 5 1 6 3. + 0 + -2.0370010752230883e-003 + 0.5613325238227844 + 0.4884858131408691 + <_> + + <_> + + + + <_>1 5 3 6 -1. + <_>2 5 1 6 3. + 0 + 1.6614829655736685e-003 + 0.4472880065441132 + 0.5578880906105042 + <_> + + <_> + + + + <_>1 9 18 1 -1. + <_>7 9 6 1 3. + 0 + -3.1188090797513723e-003 + 0.3840532898902893 + 0.5397477746009827 + <_> + + <_> + + + + <_>0 9 8 7 -1. + <_>4 9 4 7 2. + 0 + -6.4000617712736130e-003 + 0.5843983888626099 + 0.4533218145370483 + <_> + + <_> + + + + <_>12 11 8 2 -1. + <_>12 12 8 1 2. + 0 + 3.1319601112045348e-004 + 0.5439221858978272 + 0.4234727919101715 + <_> + + <_> + + + + <_>0 11 8 2 -1. + <_>0 12 8 1 2. + 0 + -0.0182220991700888 + 0.1288464963436127 + 0.4958404898643494 + <_> + + <_> + + + + <_>9 13 2 3 -1. + <_>9 14 2 1 3. + 0 + 8.7969247251749039e-003 + 0.4951297938823700 + 0.7153480052947998 + <_> + + <_> + + + + <_>4 10 12 4 -1. + <_>4 10 6 2 2. + <_>10 12 6 2 2. + 0 + -4.2395070195198059e-003 + 0.3946599960327148 + 0.5194936990737915 + <_> + + <_> + + + + <_>9 3 3 7 -1. + <_>10 3 1 7 3. + 0 + 9.7086271271109581e-003 + 0.4897503852844238 + 0.6064900159835815 + <_> + + <_> + + + + <_>7 2 3 5 -1. + <_>8 2 1 5 3. + 0 + -3.9934171363711357e-003 + 0.3245440125465393 + 0.5060828924179077 + <_> + + <_> + + + + <_>9 12 4 6 -1. + <_>11 12 2 3 2. + <_>9 15 2 3 2. + 0 + -0.0167850591242313 + 0.1581953018903732 + 0.5203778743743897 + <_> + + <_> + + + + <_>8 7 3 6 -1. + <_>9 7 1 6 3. + 0 + 0.0182720907032490 + 0.4680935144424439 + 0.6626979112625122 + <_> + + <_> + + + + <_>15 4 4 2 -1. + <_>15 5 4 1 2. + 0 + 5.6872838176786900e-003 + 0.5211697816848755 + 0.3512184917926788 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>9 7 1 3 3. + 0 + -1.0739039862528443e-003 + 0.5768386125564575 + 0.4529845118522644 + <_> + + <_> + + + + <_>14 2 6 4 -1. + <_>14 4 6 2 2. + 0 + -3.7093870341777802e-003 + 0.4507763087749481 + 0.5313581228256226 + <_> + + <_> + + + + <_>7 16 6 1 -1. + <_>9 16 2 1 3. + 0 + -2.1110709349159151e-004 + 0.5460820198059082 + 0.4333376884460449 + <_> + + <_> + + + + <_>15 13 2 3 -1. + <_>15 14 2 1 3. + 0 + 1.0670139454305172e-003 + 0.5371856093406677 + 0.4078390896320343 + <_> + + <_> + + + + <_>8 7 3 10 -1. + <_>9 7 1 10 3. + 0 + 3.5943021066486835e-003 + 0.4471287131309509 + 0.5643836259841919 + <_> + + <_> + + + + <_>11 10 2 6 -1. + <_>11 12 2 2 3. + 0 + -5.1776031032204628e-003 + 0.4499393105506897 + 0.5280330181121826 + <_> + + <_> + + + + <_>6 10 4 1 -1. + <_>8 10 2 1 2. + 0 + -2.5414369883947074e-004 + 0.5516173243522644 + 0.4407708048820496 + <_> + + <_> + + + + <_>10 9 2 2 -1. + <_>10 10 2 1 2. + 0 + 6.3522560521960258e-003 + 0.5194190144538879 + 0.2465227991342545 + <_> + + <_> + + + + <_>8 9 2 2 -1. + <_>8 10 2 1 2. + 0 + -4.4205080484971404e-004 + 0.3830705881118774 + 0.5139682292938232 + <_> + + <_> + + + + <_>12 7 2 2 -1. + <_>13 7 1 1 2. + <_>12 8 1 1 2. + 0 + 7.4488727841526270e-004 + 0.4891090989112854 + 0.5974786877632141 + <_> + + <_> + + + + <_>5 7 2 2 -1. + <_>5 7 1 1 2. + <_>6 8 1 1 2. + 0 + -3.5116379149258137e-003 + 0.7413681745529175 + 0.4768764972686768 + <_> + + <_> + + + + <_>13 0 3 14 -1. + <_>14 0 1 14 3. + 0 + -0.0125409103929996 + 0.3648819029331207 + 0.5252826809883118 + <_> + + <_> + + + + <_>4 0 3 14 -1. + <_>5 0 1 14 3. + 0 + 9.4931852072477341e-003 + 0.5100492835044861 + 0.3629586994647980 + <_> + + <_> + + + + <_>13 4 3 14 -1. + <_>14 4 1 14 3. + 0 + 0.0129611501470208 + 0.5232442021369934 + 0.4333561062812805 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 4.7209449112415314e-003 + 0.4648149013519287 + 0.6331052780151367 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + -2.3119079414755106e-003 + 0.5930309891700745 + 0.4531058073043823 + <_> + + <_> + + + + <_>4 2 3 16 -1. + <_>5 2 1 16 3. + 0 + -2.8262299019843340e-003 + 0.3870477974414825 + 0.5257101058959961 + <_> + + <_> + + + + <_>7 2 8 10 -1. + <_>7 7 8 5 2. + 0 + -1.4311339473351836e-003 + 0.5522503256797791 + 0.4561854898929596 + <_> + + <_> + + + + <_>6 14 7 3 -1. + <_>6 15 7 1 3. + 0 + 1.9378310535103083e-003 + 0.4546220898628235 + 0.5736966729164124 + <_> + + <_> + + + + <_>9 2 10 12 -1. + <_>14 2 5 6 2. + <_>9 8 5 6 2. + 0 + 2.6343559147790074e-004 + 0.5345739126205444 + 0.4571875035762787 + <_> + + <_> + + + + <_>6 7 8 2 -1. + <_>6 8 8 1 2. + 0 + 7.8257522545754910e-004 + 0.3967815935611725 + 0.5220187902450562 + <_> + + <_> + + + + <_>8 13 4 6 -1. + <_>8 16 4 3 2. + 0 + -0.0195504408329725 + 0.2829642891883850 + 0.5243508219718933 + <_> + + <_> + + + + <_>6 6 1 3 -1. + <_>6 7 1 1 3. + 0 + 4.3914958951063454e-004 + 0.4590066969394684 + 0.5899090170860291 + <_> + + <_> + + + + <_>16 2 4 6 -1. + <_>16 4 4 2 3. + 0 + 0.0214520003646612 + 0.5231410861015320 + 0.2855378985404968 + <_> + + <_> + + + + <_>6 6 4 2 -1. + <_>6 6 2 1 2. + <_>8 7 2 1 2. + 0 + 5.8973580598831177e-004 + 0.4397256970405579 + 0.5506421923637390 + <_> + + <_> + + + + <_>16 2 4 6 -1. + <_>16 4 4 2 3. + 0 + -0.0261576101183891 + 0.3135079145431519 + 0.5189175009727478 + <_> + + <_> + + + + <_>0 2 4 6 -1. + <_>0 4 4 2 3. + 0 + -0.0139598604291677 + 0.3213272988796234 + 0.5040717720985413 + <_> + + <_> + + + + <_>9 6 2 6 -1. + <_>9 6 1 6 2. + 0 + -6.3699018210172653e-003 + 0.6387544870376587 + 0.4849506914615631 + <_> + + <_> + + + + <_>3 4 6 10 -1. + <_>3 9 6 5 2. + 0 + -8.5613820701837540e-003 + 0.2759132087230682 + 0.5032019019126892 + <_> + + <_> + + + + <_>9 5 2 6 -1. + <_>9 5 1 6 2. + 0 + 9.6622901037335396e-004 + 0.4685640931129456 + 0.5834879279136658 + <_> + + <_> + + + + <_>3 13 2 3 -1. + <_>3 14 2 1 3. + 0 + 7.6550268568098545e-004 + 0.5175207257270813 + 0.3896422088146210 + <_> + + <_> + + + + <_>13 13 3 2 -1. + <_>13 14 3 1 2. + 0 + -8.1833340227603912e-003 + 0.2069136947393417 + 0.5208122134208679 + <_> + + <_> + + + + <_>2 16 10 4 -1. + <_>2 16 5 2 2. + <_>7 18 5 2 2. + 0 + -9.3976939097046852e-003 + 0.6134091019630432 + 0.4641222953796387 + <_> + + <_> + + + + <_>5 6 10 6 -1. + <_>10 6 5 3 2. + <_>5 9 5 3 2. + 0 + 4.8028980381786823e-003 + 0.5454108119010925 + 0.4395219981670380 + <_> + + <_> + + + + <_>7 14 1 3 -1. + <_>7 15 1 1 3. + 0 + -3.5680569708347321e-003 + 0.6344485282897949 + 0.4681093990802765 + <_> + + <_> + + + + <_>14 16 6 3 -1. + <_>14 17 6 1 3. + 0 + 4.0733120404183865e-003 + 0.5292683243751526 + 0.4015620052814484 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 1.2568129459396005e-003 + 0.4392988085746765 + 0.5452824831008911 + <_> + + <_> + + + + <_>7 4 10 3 -1. + <_>7 5 10 1 3. + 0 + -2.9065010603517294e-003 + 0.5898832082748413 + 0.4863379895687103 + <_> + + <_> + + + + <_>0 4 5 4 -1. + <_>0 6 5 2 2. + 0 + -2.4409340694546700e-003 + 0.4069364964962006 + 0.5247421860694885 + <_> + + <_> + + + + <_>13 11 3 9 -1. + <_>13 14 3 3 3. + 0 + 0.0248307008296251 + 0.5182725787162781 + 0.3682524859905243 + <_> + + <_> + + + + <_>4 11 3 9 -1. + <_>4 14 3 3 3. + 0 + -0.0488540083169937 + 0.1307577937841415 + 0.4961281120777130 + <_> + + <_> + + + + <_>9 7 2 1 -1. + <_>9 7 1 1 2. + 0 + -1.6110379947349429e-003 + 0.6421005725860596 + 0.4872662127017975 + <_> + + <_> + + + + <_>5 0 6 17 -1. + <_>7 0 2 17 3. + 0 + -0.0970094799995422 + 0.0477693490684032 + 0.4950988888740540 + <_> + + <_> + + + + <_>10 3 6 3 -1. + <_>10 3 3 3 2. + 0 + 1.1209240183234215e-003 + 0.4616267085075378 + 0.5354745984077454 + <_> + + <_> + + + + <_>2 2 15 4 -1. + <_>7 2 5 4 3. + 0 + -1.3064090162515640e-003 + 0.6261854171752930 + 0.4638805985450745 + <_> + + <_> + + + + <_>8 2 8 2 -1. + <_>12 2 4 1 2. + <_>8 3 4 1 2. + 0 + 4.5771620352752507e-004 + 0.5384417772293091 + 0.4646640121936798 + <_> + + <_> + + + + <_>8 1 3 6 -1. + <_>8 3 3 2 3. + 0 + -6.3149951165542006e-004 + 0.3804047107696533 + 0.5130257010459900 + <_> + + <_> + + + + <_>9 17 2 2 -1. + <_>9 18 2 1 2. + 0 + 1.4505970466416329e-004 + 0.4554310142993927 + 0.5664461851119995 + <_> + + <_> + + + + <_>0 0 2 14 -1. + <_>1 0 1 14 2. + 0 + -0.0164745505899191 + 0.6596958041191101 + 0.4715859889984131 + <_> + + <_> + + + + <_>12 0 7 3 -1. + <_>12 1 7 1 3. + 0 + 0.0133695797994733 + 0.5195466279983521 + 0.3035964965820313 + <_> + + <_> + + + + <_>1 14 1 2 -1. + <_>1 15 1 1 2. + 0 + 1.0271780047332868e-004 + 0.5229176282882690 + 0.4107066094875336 + <_> + + <_> + + + + <_>14 12 2 8 -1. + <_>15 12 1 4 2. + <_>14 16 1 4 2. + 0 + -5.5311559699475765e-003 + 0.6352887749671936 + 0.4960907101631165 + <_> + + <_> + + + + <_>1 0 7 3 -1. + <_>1 1 7 1 3. + 0 + -2.6187049224972725e-003 + 0.3824546039104462 + 0.5140984058380127 + <_> + + <_> + + + + <_>14 12 2 8 -1. + <_>15 12 1 4 2. + <_>14 16 1 4 2. + 0 + 5.0834268331527710e-003 + 0.4950439929962158 + 0.6220818758010864 + <_> + + <_> + + + + <_>6 0 8 12 -1. + <_>6 0 4 6 2. + <_>10 6 4 6 2. + 0 + 0.0798181593418121 + 0.4952335953712463 + 0.1322475969791412 + <_> + + <_> + + + + <_>6 1 8 9 -1. + <_>6 4 8 3 3. + 0 + -0.0992265865206718 + 0.7542728781700134 + 0.5008416771888733 + <_> + + <_> + + + + <_>5 2 2 2 -1. + <_>5 3 2 1 2. + 0 + -6.5174017800018191e-004 + 0.3699302971363068 + 0.5130121111869812 + <_> + + <_> + + + + <_>13 14 6 6 -1. + <_>16 14 3 3 2. + <_>13 17 3 3 2. + 0 + -0.0189968496561050 + 0.6689178943634033 + 0.4921202957630158 + <_> + + <_> + + + + <_>0 17 20 2 -1. + <_>0 17 10 1 2. + <_>10 18 10 1 2. + 0 + 0.0173468999564648 + 0.4983300864696503 + 0.1859198063611984 + <_> + + <_> + + + + <_>10 3 2 6 -1. + <_>11 3 1 3 2. + <_>10 6 1 3 2. + 0 + 5.5082101607695222e-004 + 0.4574424028396606 + 0.5522121787071228 + <_> + + <_> + + + + <_>5 12 6 2 -1. + <_>8 12 3 2 2. + 0 + 2.0056050270795822e-003 + 0.5131744742393494 + 0.3856469988822937 + <_> + + <_> + + + + <_>10 7 6 13 -1. + <_>10 7 3 13 2. + 0 + -7.7688191086053848e-003 + 0.4361700117588043 + 0.5434309244155884 + <_> + + <_> + + + + <_>5 15 10 5 -1. + <_>10 15 5 5 2. + 0 + 0.0508782789111137 + 0.4682720899581909 + 0.6840639710426331 + <_> + + <_> + + + + <_>10 4 4 10 -1. + <_>10 4 2 10 2. + 0 + -2.2901780903339386e-003 + 0.4329245090484619 + 0.5306099057197571 + <_> + + <_> + + + + <_>5 7 2 1 -1. + <_>6 7 1 1 2. + 0 + -1.5715380141045898e-004 + 0.5370057225227356 + 0.4378164112567902 + <_> + + <_> + + + + <_>10 3 6 7 -1. + <_>10 3 3 7 2. + 0 + 0.1051924005150795 + 0.5137274265289307 + 0.0673614665865898 + <_> + + <_> + + + + <_>4 3 6 7 -1. + <_>7 3 3 7 2. + 0 + 2.7198919560760260e-003 + 0.4112060964107513 + 0.5255665183067322 + <_> + + <_> + + + + <_>1 7 18 5 -1. + <_>7 7 6 5 3. + 0 + 0.0483377799391747 + 0.5404623746871948 + 0.4438967108726502 + <_> + + <_> + + + + <_>3 17 4 3 -1. + <_>5 17 2 3 2. + 0 + 9.5703761326149106e-004 + 0.4355969130992889 + 0.5399510860443115 + <_> + + <_> + + + + <_>8 14 12 6 -1. + <_>14 14 6 3 2. + <_>8 17 6 3 2. + 0 + -0.0253712590783834 + 0.5995175242424011 + 0.5031024813652039 + <_> + + <_> + + + + <_>0 13 20 4 -1. + <_>0 13 10 2 2. + <_>10 15 10 2 2. + 0 + 0.0524579510092735 + 0.4950287938117981 + 0.1398351043462753 + <_> + + <_> + + + + <_>4 5 14 2 -1. + <_>11 5 7 1 2. + <_>4 6 7 1 2. + 0 + -0.0123656298965216 + 0.6397299170494080 + 0.4964106082916260 + <_> + + <_> + + + + <_>1 2 10 12 -1. + <_>1 2 5 6 2. + <_>6 8 5 6 2. + 0 + -0.1458971947431564 + 0.1001669988036156 + 0.4946322143077850 + <_> + + <_> + + + + <_>6 1 14 3 -1. + <_>6 2 14 1 3. + 0 + -0.0159086007624865 + 0.3312329947948456 + 0.5208340883255005 + <_> + + <_> + + + + <_>8 16 2 3 -1. + <_>8 17 2 1 3. + 0 + 3.9486068999394774e-004 + 0.4406363964080811 + 0.5426102876663208 + <_> + + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + -5.2454001270234585e-003 + 0.2799589931964874 + 0.5189967155456543 + <_> + + <_> + + + + <_>5 15 4 2 -1. + <_>5 15 2 1 2. + <_>7 16 2 1 2. + 0 + -5.0421799533069134e-003 + 0.6987580060958862 + 0.4752142131328583 + <_> + + <_> + + + + <_>10 15 1 3 -1. + <_>10 16 1 1 3. + 0 + 2.9812189750373363e-003 + 0.4983288943767548 + 0.6307479739189148 + <_> + + <_> + + + + <_>8 16 4 4 -1. + <_>8 16 2 2 2. + <_>10 18 2 2 2. + 0 + -7.2884308174252510e-003 + 0.2982333004474640 + 0.5026869773864746 + <_> + + <_> + + + + <_>6 11 8 6 -1. + <_>6 14 8 3 2. + 0 + 1.5094350092113018e-003 + 0.5308442115783691 + 0.3832970857620239 + <_> + + <_> + + + + <_>2 13 5 2 -1. + <_>2 14 5 1 2. + 0 + -9.3340799212455750e-003 + 0.2037964016199112 + 0.4969817101955414 + <_> + + <_> + + + + <_>13 14 6 6 -1. + <_>16 14 3 3 2. + <_>13 17 3 3 2. + 0 + 0.0286671407520771 + 0.5025696754455566 + 0.6928027272224426 + <_> + + <_> + + + + <_>1 9 18 4 -1. + <_>7 9 6 4 3. + 0 + 0.1701968014240265 + 0.4960052967071533 + 0.1476442962884903 + <_> + + <_> + + + + <_>13 14 6 6 -1. + <_>16 14 3 3 2. + <_>13 17 3 3 2. + 0 + -3.2614478841423988e-003 + 0.5603063702583313 + 0.4826056063175201 + <_> + + <_> + + + + <_>0 2 1 6 -1. + <_>0 4 1 2 3. + 0 + 5.5769277969375253e-004 + 0.5205562114715576 + 0.4129633009433746 + <_> + + <_> + + + + <_>5 0 15 20 -1. + <_>5 10 15 10 2. + 0 + 0.3625833988189697 + 0.5221652984619141 + 0.3768612146377564 + <_> + + <_> + + + + <_>1 14 6 6 -1. + <_>1 14 3 3 2. + <_>4 17 3 3 2. + 0 + -0.0116151301190257 + 0.6022682785987854 + 0.4637489914894104 + <_> + + <_> + + + + <_>8 14 4 6 -1. + <_>10 14 2 3 2. + <_>8 17 2 3 2. + 0 + -4.0795197710394859e-003 + 0.4070447087287903 + 0.5337479114532471 + <_> + + <_> + + + + <_>7 11 2 1 -1. + <_>8 11 1 1 2. + 0 + 5.7204300537705421e-004 + 0.4601835012435913 + 0.5900393128395081 + <_> + + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + 6.7543348995968699e-004 + 0.5398252010345459 + 0.4345428943634033 + <_> + + <_> + + + + <_>8 17 3 2 -1. + <_>9 17 1 2 3. + 0 + 6.3295697327703238e-004 + 0.5201563239097595 + 0.4051358997821808 + <_> + + <_> + + + + <_>12 14 4 6 -1. + <_>14 14 2 3 2. + <_>12 17 2 3 2. + 0 + 1.2435320531949401e-003 + 0.4642387926578522 + 0.5547441244125366 + <_> + + <_> + + + + <_>4 14 4 6 -1. + <_>4 14 2 3 2. + <_>6 17 2 3 2. + 0 + -4.7363857738673687e-003 + 0.6198567152023315 + 0.4672552049160004 + <_> + + <_> + + + + <_>13 14 2 6 -1. + <_>14 14 1 3 2. + <_>13 17 1 3 2. + 0 + -6.4658462069928646e-003 + 0.6837332844734192 + 0.5019000768661499 + <_> + + <_> + + + + <_>5 14 2 6 -1. + <_>5 14 1 3 2. + <_>6 17 1 3 2. + 0 + 3.5017321351915598e-004 + 0.4344803094863892 + 0.5363622903823853 + <_> + + <_> + + + + <_>7 0 6 12 -1. + <_>7 4 6 4 3. + 0 + 1.5754920605104417e-004 + 0.4760079085826874 + 0.5732020735740662 + <_> + + <_> + + + + <_>0 7 12 2 -1. + <_>4 7 4 2 3. + 0 + 9.9774366244673729e-003 + 0.5090985894203186 + 0.3635039925575256 + <_> + + <_> + + + + <_>10 3 3 13 -1. + <_>11 3 1 13 3. + 0 + -4.1464529931545258e-004 + 0.5570064783096314 + 0.4593802094459534 + <_> + + <_> + + + + <_>7 3 3 13 -1. + <_>8 3 1 13 3. + 0 + -3.5888899583369493e-004 + 0.5356845855712891 + 0.4339134991168976 + <_> + + <_> + + + + <_>10 8 6 3 -1. + <_>10 9 6 1 3. + 0 + 4.0463250479660928e-004 + 0.4439803063869476 + 0.5436776876449585 + <_> + + <_> + + + + <_>3 11 3 2 -1. + <_>4 11 1 2 3. + 0 + -8.2184787606820464e-004 + 0.4042294919490814 + 0.5176299214363098 + <_> + + <_> + + + + <_>13 12 6 8 -1. + <_>16 12 3 4 2. + <_>13 16 3 4 2. + 0 + 5.9467419050633907e-003 + 0.4927651882171631 + 0.5633779764175415 + <_> + + <_> + + + + <_>7 6 6 5 -1. + <_>9 6 2 5 3. + 0 + -0.0217533893883228 + 0.8006293773651123 + 0.4800840914249420 + <_> + + <_> + + + + <_>17 11 2 7 -1. + <_>17 11 1 7 2. + 0 + -0.0145403798669577 + 0.3946054875850678 + 0.5182222723960877 + <_> + + <_> + + + + <_>3 13 8 2 -1. + <_>7 13 4 2 2. + 0 + -0.0405107699334621 + 0.0213249903172255 + 0.4935792982578278 + <_> + + <_> + + + + <_>6 9 8 3 -1. + <_>6 10 8 1 3. + 0 + -5.8458268176764250e-004 + 0.4012795984745026 + 0.5314025282859802 + <_> + + <_> + + + + <_>4 3 4 3 -1. + <_>4 4 4 1 3. + 0 + 5.5151800625026226e-003 + 0.4642418920993805 + 0.5896260738372803 + <_> + + <_> + + + + <_>11 3 4 3 -1. + <_>11 4 4 1 3. + 0 + -6.0626221820712090e-003 + 0.6502159237861633 + 0.5016477704048157 + <_> + + <_> + + + + <_>1 4 17 12 -1. + <_>1 8 17 4 3. + 0 + 0.0945358425378799 + 0.5264708995819092 + 0.4126827120780945 + <_> + + <_> + + + + <_>11 3 4 3 -1. + <_>11 4 4 1 3. + 0 + 4.7315051779150963e-003 + 0.4879199862480164 + 0.5892447829246521 + <_> + + <_> + + + + <_>4 8 6 3 -1. + <_>4 9 6 1 3. + 0 + -5.2571471314877272e-004 + 0.3917280137538910 + 0.5189412832260132 + <_> + + <_> + + + + <_>12 3 5 3 -1. + <_>12 4 5 1 3. + 0 + -2.5464049540460110e-003 + 0.5837599039077759 + 0.4985705912113190 + <_> + + <_> + + + + <_>1 11 2 7 -1. + <_>2 11 1 7 2. + 0 + -0.0260756891220808 + 0.1261983960866928 + 0.4955821931362152 + <_> + + <_> + + + + <_>15 12 2 8 -1. + <_>16 12 1 4 2. + <_>15 16 1 4 2. + 0 + -5.4779709316790104e-003 + 0.5722513794898987 + 0.5010265707969666 + <_> + + <_> + + + + <_>4 8 11 3 -1. + <_>4 9 11 1 3. + 0 + 5.1337741315364838e-003 + 0.5273262262344360 + 0.4226376116275787 + <_> + + <_> + + + + <_>9 13 6 2 -1. + <_>12 13 3 1 2. + <_>9 14 3 1 2. + 0 + 4.7944980906322598e-004 + 0.4450066983699799 + 0.5819587111473084 + <_> + + <_> + + + + <_>6 13 4 3 -1. + <_>6 14 4 1 3. + 0 + -2.1114079281687737e-003 + 0.5757653117179871 + 0.4511714875698090 + <_> + + <_> + + + + <_>9 12 3 3 -1. + <_>10 12 1 3 3. + 0 + -0.0131799904629588 + 0.1884381026029587 + 0.5160734057426453 + <_> + + <_> + + + + <_>5 3 3 3 -1. + <_>5 4 3 1 3. + 0 + -4.7968099825084209e-003 + 0.6589789986610413 + 0.4736118912696838 + <_> + + <_> + + + + <_>9 4 2 3 -1. + <_>9 5 2 1 3. + 0 + 6.7483168095350266e-003 + 0.5259429812431335 + 0.3356395065784454 + <_> + + <_> + + + + <_>0 2 16 3 -1. + <_>0 3 16 1 3. + 0 + 1.4623369788751006e-003 + 0.5355271100997925 + 0.4264092147350311 + <_> + + <_> + + + + <_>15 12 2 8 -1. + <_>16 12 1 4 2. + <_>15 16 1 4 2. + 0 + 4.7645159065723419e-003 + 0.5034406781196594 + 0.5786827802658081 + <_> + + <_> + + + + <_>3 12 2 8 -1. + <_>3 12 1 4 2. + <_>4 16 1 4 2. + 0 + 6.8066660314798355e-003 + 0.4756605029106140 + 0.6677829027175903 + <_> + + <_> + + + + <_>14 13 3 6 -1. + <_>14 15 3 2 3. + 0 + 3.6608621012419462e-003 + 0.5369611978530884 + 0.4311546981334686 + <_> + + <_> + + + + <_>3 13 3 6 -1. + <_>3 15 3 2 3. + 0 + 0.0214496403932571 + 0.4968641996383667 + 0.1888816058635712 + <_> + + <_> + + + + <_>6 5 10 2 -1. + <_>11 5 5 1 2. + <_>6 6 5 1 2. + 0 + 4.1678901761770248e-003 + 0.4930733144283295 + 0.5815368890762329 + <_> + + <_> + + + + <_>2 14 14 6 -1. + <_>2 17 14 3 2. + 0 + 8.6467564105987549e-003 + 0.5205205082893372 + 0.4132595062255859 + <_> + + <_> + + + + <_>10 14 1 3 -1. + <_>10 15 1 1 3. + 0 + -3.6114078829996288e-004 + 0.5483555197715759 + 0.4800927937030792 + <_> + + <_> + + + + <_>4 16 2 2 -1. + <_>4 16 1 1 2. + <_>5 17 1 1 2. + 0 + 1.0808729566633701e-003 + 0.4689902067184448 + 0.6041421294212341 + <_> + + <_> + + + + <_>10 6 2 3 -1. + <_>10 7 2 1 3. + 0 + 5.7719959877431393e-003 + 0.5171142220497131 + 0.3053277134895325 + <_> + + <_> + + + + <_>0 17 20 2 -1. + <_>0 17 10 1 2. + <_>10 18 10 1 2. + 0 + 1.5720770461484790e-003 + 0.5219978094100952 + 0.4178803861141205 + <_> + + <_> + + + + <_>13 6 1 3 -1. + <_>13 7 1 1 3. + 0 + -1.9307859474793077e-003 + 0.5860369801521301 + 0.4812920093536377 + <_> + + <_> + + + + <_>8 13 3 2 -1. + <_>9 13 1 2 3. + 0 + -7.8926272690296173e-003 + 0.1749276965856552 + 0.4971733987331390 + <_> + + <_> + + + + <_>12 2 3 3 -1. + <_>13 2 1 3 3. + 0 + -2.2224679123610258e-003 + 0.4342589080333710 + 0.5212848186492920 + <_> + + <_> + + + + <_>3 18 2 2 -1. + <_>3 18 1 1 2. + <_>4 19 1 1 2. + 0 + 1.9011989934369922e-003 + 0.4765186905860901 + 0.6892055273056030 + <_> + + <_> + + + + <_>9 16 3 4 -1. + <_>10 16 1 4 3. + 0 + 2.7576119173318148e-003 + 0.5262191295623779 + 0.4337486028671265 + <_> + + <_> + + + + <_>6 6 1 3 -1. + <_>6 7 1 1 3. + 0 + 5.1787449046969414e-003 + 0.4804069101810455 + 0.7843729257583618 + <_> + + <_> + + + + <_>13 1 5 2 -1. + <_>13 2 5 1 2. + 0 + -9.0273341629654169e-004 + 0.4120846986770630 + 0.5353423953056335 + <_> + + <_> + + + + <_>7 14 6 2 -1. + <_>7 14 3 1 2. + <_>10 15 3 1 2. + 0 + 5.1797959022223949e-003 + 0.4740372896194458 + 0.6425960063934326 + <_> + + <_> + + + + <_>11 3 3 4 -1. + <_>12 3 1 4 3. + 0 + -0.0101140001788735 + 0.2468792051076889 + 0.5175017714500427 + <_> + + <_> + + + + <_>1 13 12 6 -1. + <_>5 13 4 6 3. + 0 + -0.0186170600354671 + 0.5756294131278992 + 0.4628978967666626 + <_> + + <_> + + + + <_>14 11 5 2 -1. + <_>14 12 5 1 2. + 0 + 5.9225959703326225e-003 + 0.5169625878334045 + 0.3214271068572998 + <_> + + <_> + + + + <_>2 15 14 4 -1. + <_>2 15 7 2 2. + <_>9 17 7 2 2. + 0 + -6.2945079989731312e-003 + 0.3872014880180359 + 0.5141636729240418 + <_> + + <_> + + + + <_>3 7 14 2 -1. + <_>10 7 7 1 2. + <_>3 8 7 1 2. + 0 + 6.5353019163012505e-003 + 0.4853048920631409 + 0.6310489773750305 + <_> + + <_> + + + + <_>1 11 4 2 -1. + <_>1 12 4 1 2. + 0 + 1.0878399480134249e-003 + 0.5117315053939819 + 0.3723258972167969 + <_> + + <_> + + + + <_>14 0 6 14 -1. + <_>16 0 2 14 3. + 0 + -0.0225422400981188 + 0.5692740082740784 + 0.4887112975120544 + <_> + + <_> + + + + <_>4 11 1 3 -1. + <_>4 12 1 1 3. + 0 + -3.0065660830587149e-003 + 0.2556012868881226 + 0.5003992915153503 + <_> + + <_> + + + + <_>14 0 6 14 -1. + <_>16 0 2 14 3. + 0 + 7.4741272255778313e-003 + 0.4810872972011566 + 0.5675926804542542 + <_> + + <_> + + + + <_>1 10 3 7 -1. + <_>2 10 1 7 3. + 0 + 0.0261623207479715 + 0.4971194863319397 + 0.1777237057685852 + <_> + + <_> + + + + <_>8 12 9 2 -1. + <_>8 13 9 1 2. + 0 + 9.4352738233283162e-004 + 0.4940010905265808 + 0.5491250753402710 + <_> + + <_> + + + + <_>0 6 20 1 -1. + <_>10 6 10 1 2. + 0 + 0.0333632417023182 + 0.5007612109184265 + 0.2790724039077759 + <_> + + <_> + + + + <_>8 4 4 4 -1. + <_>8 4 2 4 2. + 0 + -0.0151186501607299 + 0.7059578895568848 + 0.4973031878471375 + <_> + + <_> + + + + <_>0 0 2 2 -1. + <_>0 1 2 1 2. + 0 + 9.8648946732282639e-004 + 0.5128620266914368 + 0.3776761889457703 + 104.7491989135742200 + 19 + -1 + <_> + + + <_> + + <_> + + + + <_>5 3 10 9 -1. + <_>5 6 10 3 3. + 0 + -0.0951507985591888 + 0.6470757126808167 + 0.4017286896705627 + <_> + + <_> + + + + <_>15 2 4 10 -1. + <_>15 2 2 10 2. + 0 + 6.2702340073883533e-003 + 0.3999822139739990 + 0.5746449232101440 + <_> + + <_> + + + + <_>8 2 2 7 -1. + <_>9 2 1 7 2. + 0 + 3.0018089455552399e-004 + 0.3558770120143890 + 0.5538809895515442 + <_> + + <_> + + + + <_>7 4 12 1 -1. + <_>11 4 4 1 3. + 0 + 1.1757409665733576e-003 + 0.4256534874439240 + 0.5382617712020874 + <_> + + <_> + + + + <_>3 4 9 1 -1. + <_>6 4 3 1 3. + 0 + 4.4235268433112651e-005 + 0.3682908117771149 + 0.5589926838874817 + <_> + + <_> + + + + <_>15 10 1 4 -1. + <_>15 12 1 2 2. + 0 + -2.9936920327600092e-005 + 0.5452470183372498 + 0.4020367860794067 + <_> + + <_> + + + + <_>4 10 6 4 -1. + <_>7 10 3 4 2. + 0 + 3.0073199886828661e-003 + 0.5239058136940002 + 0.3317843973636627 + <_> + + <_> + + + + <_>15 9 1 6 -1. + <_>15 12 1 3 2. + 0 + -0.0105138896033168 + 0.4320689141750336 + 0.5307983756065369 + <_> + + <_> + + + + <_>7 17 6 3 -1. + <_>7 18 6 1 3. + 0 + 8.3476826548576355e-003 + 0.4504637122154236 + 0.6453298926353455 + <_> + + <_> + + + + <_>14 3 2 16 -1. + <_>15 3 1 8 2. + <_>14 11 1 8 2. + 0 + -3.1492270063608885e-003 + 0.4313425123691559 + 0.5370525121688843 + <_> + + <_> + + + + <_>4 9 1 6 -1. + <_>4 12 1 3 2. + 0 + -1.4435649973165710e-005 + 0.5326603055000305 + 0.3817971944808960 + <_> + + <_> + + + + <_>12 1 5 2 -1. + <_>12 2 5 1 2. + 0 + -4.2855090578086674e-004 + 0.4305163919925690 + 0.5382009744644165 + <_> + + <_> + + + + <_>6 18 4 2 -1. + <_>6 18 2 1 2. + <_>8 19 2 1 2. + 0 + 1.5062429883982986e-004 + 0.4235970973968506 + 0.5544965267181397 + <_> + + <_> + + + + <_>2 4 16 10 -1. + <_>10 4 8 5 2. + <_>2 9 8 5 2. + 0 + 0.0715598315000534 + 0.5303059816360474 + 0.2678802907466888 + <_> + + <_> + + + + <_>6 5 1 10 -1. + <_>6 10 1 5 2. + 0 + 8.4095180500298738e-004 + 0.3557108938694000 + 0.5205433964729309 + <_> + + <_> + + + + <_>4 8 15 2 -1. + <_>9 8 5 2 3. + 0 + 0.0629865005612373 + 0.5225362777709961 + 0.2861376106739044 + <_> + + <_> + + + + <_>1 8 15 2 -1. + <_>6 8 5 2 3. + 0 + -3.3798629883676767e-003 + 0.3624185919761658 + 0.5201697945594788 + <_> + + <_> + + + + <_>9 5 3 6 -1. + <_>9 7 3 2 3. + 0 + -1.1810739670181647e-004 + 0.5474476814270020 + 0.3959893882274628 + <_> + + <_> + + + + <_>5 7 8 2 -1. + <_>9 7 4 2 2. + 0 + -5.4505601292476058e-004 + 0.3740422129631043 + 0.5215715765953064 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -1.8454910023137927e-003 + 0.5893052220344544 + 0.4584448933601379 + <_> + + <_> + + + + <_>1 0 16 3 -1. + <_>1 1 16 1 3. + 0 + -4.3832371011376381e-004 + 0.4084582030773163 + 0.5385351181030273 + <_> + + <_> + + + + <_>11 2 7 2 -1. + <_>11 3 7 1 2. + 0 + -2.4000830017030239e-003 + 0.3777455091476440 + 0.5293580293655396 + <_> + + <_> + + + + <_>5 1 10 18 -1. + <_>5 7 10 6 3. + 0 + -0.0987957417964935 + 0.2963612079620361 + 0.5070089101791382 + <_> + + <_> + + + + <_>17 4 3 2 -1. + <_>18 4 1 2 3. + 0 + 3.1798239797353745e-003 + 0.4877632856369019 + 0.6726443767547607 + <_> + + <_> + + + + <_>8 13 1 3 -1. + <_>8 14 1 1 3. + 0 + 3.2406419632025063e-004 + 0.4366911053657532 + 0.5561109781265259 + <_> + + <_> + + + + <_>3 14 14 6 -1. + <_>3 16 14 2 3. + 0 + -0.0325472503900528 + 0.3128157854080200 + 0.5308616161346436 + <_> + + <_> + + + + <_>0 2 3 4 -1. + <_>1 2 1 4 3. + 0 + -7.7561130747199059e-003 + 0.6560224890708923 + 0.4639872014522553 + <_> + + <_> + + + + <_>12 1 5 2 -1. + <_>12 2 5 1 2. + 0 + 0.0160272493958473 + 0.5172680020332336 + 0.3141897916793823 + <_> + + <_> + + + + <_>3 1 5 2 -1. + <_>3 2 5 1 2. + 0 + 7.1002350523485802e-006 + 0.4084446132183075 + 0.5336294770240784 + <_> + + <_> + + + + <_>10 13 2 3 -1. + <_>10 14 2 1 3. + 0 + 7.3422808200120926e-003 + 0.4966922104358673 + 0.6603465080261231 + <_> + + <_> + + + + <_>8 13 2 3 -1. + <_>8 14 2 1 3. + 0 + -1.6970280557870865e-003 + 0.5908237099647522 + 0.4500182867050171 + <_> + + <_> + + + + <_>14 12 2 3 -1. + <_>14 13 2 1 3. + 0 + 2.4118260480463505e-003 + 0.5315160751342773 + 0.3599720895290375 + <_> + + <_> + + + + <_>7 2 2 3 -1. + <_>7 3 2 1 3. + 0 + -5.5300937965512276e-003 + 0.2334040999412537 + 0.4996814131736755 + <_> + + <_> + + + + <_>5 6 10 4 -1. + <_>10 6 5 2 2. + <_>5 8 5 2 2. + 0 + -2.6478730142116547e-003 + 0.5880935788154602 + 0.4684734046459198 + <_> + + <_> + + + + <_>9 13 1 6 -1. + <_>9 16 1 3 2. + 0 + 0.0112956296652555 + 0.4983777105808258 + 0.1884590983390808 + <_> + + <_> + + + + <_>10 12 2 2 -1. + <_>11 12 1 1 2. + <_>10 13 1 1 2. + 0 + -6.6952878842130303e-004 + 0.5872138142585754 + 0.4799019992351532 + <_> + + <_> + + + + <_>4 12 2 3 -1. + <_>4 13 2 1 3. + 0 + 1.4410680159926414e-003 + 0.5131189227104187 + 0.3501011133193970 + <_> + + <_> + + + + <_>14 4 6 6 -1. + <_>14 6 6 2 3. + 0 + 2.4637870956212282e-003 + 0.5339372158050537 + 0.4117639064788818 + <_> + + <_> + + + + <_>8 17 2 3 -1. + <_>8 18 2 1 3. + 0 + 3.3114518737420440e-004 + 0.4313383102416992 + 0.5398246049880981 + <_> + + <_> + + + + <_>16 4 4 6 -1. + <_>16 6 4 2 3. + 0 + -0.0335572697222233 + 0.2675336897373200 + 0.5179154872894287 + <_> + + <_> + + + + <_>0 4 4 6 -1. + <_>0 6 4 2 3. + 0 + 0.0185394193977118 + 0.4973869919776917 + 0.2317177057266235 + <_> + + <_> + + + + <_>14 6 2 3 -1. + <_>14 6 1 3 2. + 0 + -2.9698139405809343e-004 + 0.5529708266258240 + 0.4643664062023163 + <_> + + <_> + + + + <_>4 9 8 1 -1. + <_>8 9 4 1 2. + 0 + -4.5577259152196348e-004 + 0.5629584193229675 + 0.4469191133975983 + <_> + + <_> + + + + <_>8 12 4 3 -1. + <_>8 13 4 1 3. + 0 + -0.0101589802652597 + 0.6706212759017944 + 0.4925918877124786 + <_> + + <_> + + + + <_>5 12 10 6 -1. + <_>5 14 10 2 3. + 0 + -2.2413829356082715e-005 + 0.5239421725273132 + 0.3912901878356934 + <_> + + <_> + + + + <_>11 12 1 2 -1. + <_>11 13 1 1 2. + 0 + 7.2034963523037732e-005 + 0.4799438118934631 + 0.5501788854598999 + <_> + + <_> + + + + <_>8 15 4 2 -1. + <_>8 16 4 1 2. + 0 + -6.9267209619283676e-003 + 0.6930009722709656 + 0.4698084890842438 + <_> + + <_> + + + + <_>6 9 8 8 -1. + <_>10 9 4 4 2. + <_>6 13 4 4 2. + 0 + -7.6997838914394379e-003 + 0.4099623858928680 + 0.5480883121490479 + <_> + + <_> + + + + <_>7 12 4 6 -1. + <_>7 12 2 3 2. + <_>9 15 2 3 2. + 0 + -7.3130549862980843e-003 + 0.3283475935459137 + 0.5057886242866516 + <_> + + <_> + + + + <_>10 11 3 1 -1. + <_>11 11 1 1 3. + 0 + 1.9650589674711227e-003 + 0.4978047013282776 + 0.6398249864578247 + <_> + + <_> + + + + <_>9 7 2 10 -1. + <_>9 7 1 5 2. + <_>10 12 1 5 2. + 0 + 7.1647600270807743e-003 + 0.4661160111427307 + 0.6222137212753296 + <_> + + <_> + + + + <_>8 0 6 6 -1. + <_>10 0 2 6 3. + 0 + -0.0240786392241716 + 0.2334644943475723 + 0.5222162008285523 + <_> + + <_> + + + + <_>3 11 2 6 -1. + <_>3 13 2 2 3. + 0 + -0.0210279691964388 + 0.1183653995394707 + 0.4938226044178009 + <_> + + <_> + + + + <_>16 12 1 2 -1. + <_>16 13 1 1 2. + 0 + 3.6017020465806127e-004 + 0.5325019955635071 + 0.4116711020469666 + <_> + + <_> + + + + <_>1 14 6 6 -1. + <_>1 14 3 3 2. + <_>4 17 3 3 2. + 0 + -0.0172197297215462 + 0.6278762221336365 + 0.4664269089698792 + <_> + + <_> + + + + <_>13 1 3 6 -1. + <_>14 1 1 6 3. + 0 + -7.8672142699360847e-003 + 0.3403415083885193 + 0.5249736905097961 + <_> + + <_> + + + + <_>8 8 2 2 -1. + <_>8 9 2 1 2. + 0 + -4.4777389848604798e-004 + 0.3610411882400513 + 0.5086259245872498 + <_> + + <_> + + + + <_>9 9 3 3 -1. + <_>10 9 1 3 3. + 0 + 5.5486010387539864e-003 + 0.4884265959262848 + 0.6203498244285584 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>8 8 3 1 3. + 0 + -6.9461148232221603e-003 + 0.2625930011272430 + 0.5011097192764282 + <_> + + <_> + + + + <_>14 0 2 3 -1. + <_>14 0 1 3 2. + 0 + 1.3569870498031378e-004 + 0.4340794980525971 + 0.5628312230110169 + <_> + + <_> + + + + <_>1 0 18 9 -1. + <_>7 0 6 9 3. + 0 + -0.0458802506327629 + 0.6507998704910278 + 0.4696274995803833 + <_> + + <_> + + + + <_>11 5 4 15 -1. + <_>11 5 2 15 2. + 0 + -0.0215825606137514 + 0.3826502859592438 + 0.5287616848945618 + <_> + + <_> + + + + <_>5 5 4 15 -1. + <_>7 5 2 15 2. + 0 + -0.0202095396816731 + 0.3233368098735809 + 0.5074477195739746 + <_> + + <_> + + + + <_>14 0 2 3 -1. + <_>14 0 1 3 2. + 0 + 5.8496710844337940e-003 + 0.5177603960037231 + 0.4489670991897583 + <_> + + <_> + + + + <_>4 0 2 3 -1. + <_>5 0 1 3 2. + 0 + -5.7476379879517481e-005 + 0.4020850956439972 + 0.5246363878250122 + <_> + + <_> + + + + <_>11 12 2 2 -1. + <_>12 12 1 1 2. + <_>11 13 1 1 2. + 0 + -1.1513100471347570e-003 + 0.6315072178840637 + 0.4905154109001160 + <_> + + <_> + + + + <_>7 12 2 2 -1. + <_>7 12 1 1 2. + <_>8 13 1 1 2. + 0 + 1.9862831104546785e-003 + 0.4702459871768951 + 0.6497151255607605 + <_> + + <_> + + + + <_>12 0 3 4 -1. + <_>13 0 1 4 3. + 0 + -5.2719512023031712e-003 + 0.3650383949279785 + 0.5227652788162231 + <_> + + <_> + + + + <_>4 11 3 3 -1. + <_>4 12 3 1 3. + 0 + 1.2662699446082115e-003 + 0.5166100859642029 + 0.3877618014812470 + <_> + + <_> + + + + <_>12 7 4 2 -1. + <_>12 8 4 1 2. + 0 + -6.2919440679252148e-003 + 0.7375894188880920 + 0.5023847818374634 + <_> + + <_> + + + + <_>8 10 3 2 -1. + <_>9 10 1 2 3. + 0 + 6.7360111279413104e-004 + 0.4423226118087769 + 0.5495585799217224 + <_> + + <_> + + + + <_>9 9 3 2 -1. + <_>10 9 1 2 3. + 0 + -1.0523450328037143e-003 + 0.5976396203041077 + 0.4859583079814911 + <_> + + <_> + + + + <_>8 9 3 2 -1. + <_>9 9 1 2 3. + 0 + -4.4216238893568516e-004 + 0.5955939292907715 + 0.4398930966854096 + <_> + + <_> + + + + <_>12 0 3 4 -1. + <_>13 0 1 4 3. + 0 + 1.1747940443456173e-003 + 0.5349888205528259 + 0.4605058133602142 + <_> + + <_> + + + + <_>5 0 3 4 -1. + <_>6 0 1 4 3. + 0 + 5.2457437850534916e-003 + 0.5049191117286682 + 0.2941577136516571 + <_> + + <_> + + + + <_>4 14 12 4 -1. + <_>10 14 6 2 2. + <_>4 16 6 2 2. + 0 + -0.0245397202670574 + 0.2550177872180939 + 0.5218586921691895 + <_> + + <_> + + + + <_>8 13 2 3 -1. + <_>8 14 2 1 3. + 0 + 7.3793041519820690e-004 + 0.4424861073493958 + 0.5490816235542297 + <_> + + <_> + + + + <_>10 10 3 8 -1. + <_>10 14 3 4 2. + 0 + 1.4233799884095788e-003 + 0.5319514274597168 + 0.4081355929374695 + <_> + + <_> + + + + <_>8 10 4 8 -1. + <_>8 10 2 4 2. + <_>10 14 2 4 2. + 0 + -2.4149110540747643e-003 + 0.4087659120559692 + 0.5238950252532959 + <_> + + <_> + + + + <_>10 8 3 1 -1. + <_>11 8 1 1 3. + 0 + -1.2165299849584699e-003 + 0.5674579143524170 + 0.4908052980899811 + <_> + + <_> + + + + <_>9 12 1 6 -1. + <_>9 15 1 3 2. + 0 + -1.2438809499144554e-003 + 0.4129425883293152 + 0.5256118178367615 + <_> + + <_> + + + + <_>10 8 3 1 -1. + <_>11 8 1 1 3. + 0 + 6.1942739412188530e-003 + 0.5060194134712219 + 0.7313653230667114 + <_> + + <_> + + + + <_>7 8 3 1 -1. + <_>8 8 1 1 3. + 0 + -1.6607169527560472e-003 + 0.5979632139205933 + 0.4596369862556458 + <_> + + <_> + + + + <_>5 2 15 14 -1. + <_>5 9 15 7 2. + 0 + -0.0273162592202425 + 0.4174365103244782 + 0.5308842062950134 + <_> + + <_> + + + + <_>2 1 2 10 -1. + <_>2 1 1 5 2. + <_>3 6 1 5 2. + 0 + -1.5845570014789701e-003 + 0.5615804791450501 + 0.4519486129283905 + <_> + + <_> + + + + <_>14 14 2 3 -1. + <_>14 15 2 1 3. + 0 + -1.5514739789068699e-003 + 0.4076187014579773 + 0.5360785126686096 + <_> + + <_> + + + + <_>2 7 3 3 -1. + <_>3 7 1 3 3. + 0 + 3.8446558755822480e-004 + 0.4347293972969055 + 0.5430442094802856 + <_> + + <_> + + + + <_>17 4 3 3 -1. + <_>17 5 3 1 3. + 0 + -0.0146722598001361 + 0.1659304946660996 + 0.5146093964576721 + <_> + + <_> + + + + <_>0 4 3 3 -1. + <_>0 5 3 1 3. + 0 + 8.1608882173895836e-003 + 0.4961819052696228 + 0.1884745955467224 + <_> + + <_> + + + + <_>13 5 6 2 -1. + <_>16 5 3 1 2. + <_>13 6 3 1 2. + 0 + 1.1121659772470593e-003 + 0.4868263900279999 + 0.6093816161155701 + <_> + + <_> + + + + <_>4 19 12 1 -1. + <_>8 19 4 1 3. + 0 + -7.2603770531713963e-003 + 0.6284325122833252 + 0.4690375924110413 + <_> + + <_> + + + + <_>12 12 2 4 -1. + <_>12 14 2 2 2. + 0 + -2.4046430189628154e-004 + 0.5575000047683716 + 0.4046044051647186 + <_> + + <_> + + + + <_>3 15 1 3 -1. + <_>3 16 1 1 3. + 0 + -2.3348190006799996e-004 + 0.4115762114524841 + 0.5252848267555237 + <_> + + <_> + + + + <_>11 16 6 4 -1. + <_>11 16 3 4 2. + 0 + 5.5736480280756950e-003 + 0.4730072915554047 + 0.5690100789070129 + <_> + + <_> + + + + <_>2 10 3 10 -1. + <_>3 10 1 10 3. + 0 + 0.0306237693876028 + 0.4971886873245239 + 0.1740095019340515 + <_> + + <_> + + + + <_>12 8 2 4 -1. + <_>12 8 1 4 2. + 0 + 9.2074798885732889e-004 + 0.5372117757797241 + 0.4354872107505798 + <_> + + <_> + + + + <_>6 8 2 4 -1. + <_>7 8 1 4 2. + 0 + -4.3550739064812660e-005 + 0.5366883873939514 + 0.4347316920757294 + <_> + + <_> + + + + <_>10 14 2 3 -1. + <_>10 14 1 3 2. + 0 + -6.6452710889279842e-003 + 0.3435518145561218 + 0.5160533189773560 + <_> + + <_> + + + + <_>5 1 10 3 -1. + <_>10 1 5 3 2. + 0 + 0.0432219989597797 + 0.4766792058944702 + 0.7293652892112732 + <_> + + <_> + + + + <_>10 7 3 2 -1. + <_>11 7 1 2 3. + 0 + 2.2331769578158855e-003 + 0.5029315948486328 + 0.5633171200752258 + <_> + + <_> + + + + <_>5 6 9 2 -1. + <_>8 6 3 2 3. + 0 + 3.1829739455133677e-003 + 0.4016092121601105 + 0.5192136764526367 + <_> + + <_> + + + + <_>9 8 2 2 -1. + <_>9 9 2 1 2. + 0 + -1.8027749320026487e-004 + 0.4088315963745117 + 0.5417919754981995 + <_> + + <_> + + + + <_>2 11 16 6 -1. + <_>2 11 8 3 2. + <_>10 14 8 3 2. + 0 + -5.2934689447283745e-003 + 0.4075677096843720 + 0.5243561863899231 + <_> + + <_> + + + + <_>12 7 2 2 -1. + <_>13 7 1 1 2. + <_>12 8 1 1 2. + 0 + 1.2750959722325206e-003 + 0.4913282990455627 + 0.6387010812759399 + <_> + + <_> + + + + <_>9 5 2 3 -1. + <_>9 6 2 1 3. + 0 + 4.3385322205722332e-003 + 0.5031672120094299 + 0.2947346866130829 + <_> + + <_> + + + + <_>9 7 3 2 -1. + <_>10 7 1 2 3. + 0 + 8.5250744596123695e-003 + 0.4949789047241211 + 0.6308869123458862 + <_> + + <_> + + + + <_>5 1 8 12 -1. + <_>5 7 8 6 2. + 0 + -9.4266352243721485e-004 + 0.5328366756439209 + 0.4285649955272675 + <_> + + <_> + + + + <_>13 5 2 2 -1. + <_>13 6 2 1 2. + 0 + 1.3609660090878606e-003 + 0.4991525113582611 + 0.5941501259803772 + <_> + + <_> + + + + <_>5 5 2 2 -1. + <_>5 6 2 1 2. + 0 + 4.4782509212382138e-004 + 0.4573504030704498 + 0.5854480862617493 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + 1.3360050506889820e-003 + 0.4604358971118927 + 0.5849052071571350 + <_> + + <_> + + + + <_>4 14 2 3 -1. + <_>4 15 2 1 3. + 0 + -6.0967548051849008e-004 + 0.3969388902187347 + 0.5229423046112061 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -2.3656780831515789e-003 + 0.5808320045471191 + 0.4898357093334198 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 1.0734340175986290e-003 + 0.4351210892200470 + 0.5470039248466492 + <_> + + <_> + + + + <_>9 14 2 6 -1. + <_>10 14 1 3 2. + <_>9 17 1 3 2. + 0 + 2.1923359017819166e-003 + 0.5355060100555420 + 0.3842903971672058 + <_> + + <_> + + + + <_>8 14 3 2 -1. + <_>9 14 1 2 3. + 0 + 5.4968618787825108e-003 + 0.5018138885498047 + 0.2827191948890686 + <_> + + <_> + + + + <_>9 5 6 6 -1. + <_>11 5 2 6 3. + 0 + -0.0753688216209412 + 0.1225076019763947 + 0.5148826837539673 + <_> + + <_> + + + + <_>5 5 6 6 -1. + <_>7 5 2 6 3. + 0 + 0.0251344703137875 + 0.4731766879558563 + 0.7025446295738220 + <_> + + <_> + + + + <_>13 13 1 2 -1. + <_>13 14 1 1 2. + 0 + -2.9358599931583740e-005 + 0.5430532097816467 + 0.4656086862087250 + <_> + + <_> + + + + <_>0 2 10 2 -1. + <_>0 3 10 1 2. + 0 + -5.8355910005047917e-004 + 0.4031040072441101 + 0.5190119743347168 + <_> + + <_> + + + + <_>13 13 1 2 -1. + <_>13 14 1 1 2. + 0 + -2.6639450807124376e-003 + 0.4308126866817474 + 0.5161771178245544 + <_> + + <_> + + + + <_>5 7 2 2 -1. + <_>5 7 1 1 2. + <_>6 8 1 1 2. + 0 + -1.3804089976474643e-003 + 0.6219829916954041 + 0.4695515930652618 + <_> + + <_> + + + + <_>13 5 2 7 -1. + <_>13 5 1 7 2. + 0 + 1.2313219485804439e-003 + 0.5379363894462585 + 0.4425831139087677 + <_> + + <_> + + + + <_>6 13 1 2 -1. + <_>6 14 1 1 2. + 0 + -1.4644179827882908e-005 + 0.5281640291213989 + 0.4222503006458283 + <_> + + <_> + + + + <_>11 0 3 7 -1. + <_>12 0 1 7 3. + 0 + -0.0128188095986843 + 0.2582092881202698 + 0.5179932713508606 + <_> + + <_> + + + + <_>0 3 2 16 -1. + <_>0 3 1 8 2. + <_>1 11 1 8 2. + 0 + 0.0228521898388863 + 0.4778693020343781 + 0.7609264254570007 + <_> + + <_> + + + + <_>11 0 3 7 -1. + <_>12 0 1 7 3. + 0 + 8.2305970136076212e-004 + 0.5340992212295532 + 0.4671724140644074 + <_> + + <_> + + + + <_>6 0 3 7 -1. + <_>7 0 1 7 3. + 0 + 0.0127701200544834 + 0.4965761005878449 + 0.1472366005182266 + <_> + + <_> + + + + <_>11 16 8 4 -1. + <_>11 16 4 4 2. + 0 + -0.0500515103340149 + 0.6414994001388550 + 0.5016592144966126 + <_> + + <_> + + + + <_>1 16 8 4 -1. + <_>5 16 4 4 2. + 0 + 0.0157752707600594 + 0.4522320032119751 + 0.5685362219810486 + <_> + + <_> + + + + <_>13 5 2 7 -1. + <_>13 5 1 7 2. + 0 + -0.0185016207396984 + 0.2764748930931091 + 0.5137959122657776 + <_> + + <_> + + + + <_>5 5 2 7 -1. + <_>6 5 1 7 2. + 0 + 2.4626250378787518e-003 + 0.5141941905021668 + 0.3795408010482788 + <_> + + <_> + + + + <_>18 6 2 14 -1. + <_>18 13 2 7 2. + 0 + 0.0629161670804024 + 0.5060648918151856 + 0.6580433845520020 + <_> + + <_> + + + + <_>6 10 3 4 -1. + <_>6 12 3 2 2. + 0 + -2.1648500478477217e-005 + 0.5195388197898865 + 0.4019886851310730 + <_> + + <_> + + + + <_>14 7 1 2 -1. + <_>14 8 1 1 2. + 0 + 2.1180990152060986e-003 + 0.4962365031242371 + 0.5954458713531494 + <_> + + <_> + + + + <_>0 1 18 6 -1. + <_>0 1 9 3 2. + <_>9 4 9 3 2. + 0 + -0.0166348908096552 + 0.3757933080196381 + 0.5175446867942810 + <_> + + <_> + + + + <_>14 7 1 2 -1. + <_>14 8 1 1 2. + 0 + -2.8899470344185829e-003 + 0.6624013781547546 + 0.5057178735733032 + <_> + + <_> + + + + <_>0 6 2 14 -1. + <_>0 13 2 7 2. + 0 + 0.0767832621932030 + 0.4795796871185303 + 0.8047714829444885 + <_> + + <_> + + + + <_>17 0 3 12 -1. + <_>18 0 1 12 3. + 0 + 3.9170677773654461e-003 + 0.4937882125377655 + 0.5719941854476929 + <_> + + <_> + + + + <_>0 6 18 3 -1. + <_>0 7 18 1 3. + 0 + -0.0726706013083458 + 0.0538945607841015 + 0.4943903982639313 + <_> + + <_> + + + + <_>6 0 14 16 -1. + <_>6 8 14 8 2. + 0 + 0.5403950214385986 + 0.5129774212837219 + 0.1143338978290558 + <_> + + <_> + + + + <_>0 0 3 12 -1. + <_>1 0 1 12 3. + 0 + 2.9510019812732935e-003 + 0.4528343975543976 + 0.5698574185371399 + <_> + + <_> + + + + <_>13 0 3 7 -1. + <_>14 0 1 7 3. + 0 + 3.4508369863033295e-003 + 0.5357726812362671 + 0.4218730926513672 + <_> + + <_> + + + + <_>5 7 1 2 -1. + <_>5 8 1 1 2. + 0 + -4.2077939724549651e-004 + 0.5916172862052918 + 0.4637925922870636 + <_> + + <_> + + + + <_>14 4 6 6 -1. + <_>14 6 6 2 3. + 0 + 3.3051050268113613e-003 + 0.5273385047912598 + 0.4382042884826660 + <_> + + <_> + + + + <_>5 7 7 2 -1. + <_>5 8 7 1 2. + 0 + 4.7735060798004270e-004 + 0.4046528041362763 + 0.5181884765625000 + <_> + + <_> + + + + <_>8 6 6 9 -1. + <_>8 9 6 3 3. + 0 + -0.0259285103529692 + 0.7452235817909241 + 0.5089386105537415 + <_> + + <_> + + + + <_>5 4 6 1 -1. + <_>7 4 2 1 3. + 0 + -2.9729790985584259e-003 + 0.3295435905456543 + 0.5058795213699341 + <_> + + <_> + + + + <_>13 0 6 4 -1. + <_>16 0 3 2 2. + <_>13 2 3 2 2. + 0 + 5.8508329093456268e-003 + 0.4857144057750702 + 0.5793024897575378 + <_> + + <_> + + + + <_>1 2 18 12 -1. + <_>1 6 18 4 3. + 0 + -0.0459675192832947 + 0.4312731027603149 + 0.5380653142929077 + <_> + + <_> + + + + <_>3 2 17 12 -1. + <_>3 6 17 4 3. + 0 + 0.1558596044778824 + 0.5196170210838318 + 0.1684713959693909 + <_> + + <_> + + + + <_>5 14 7 3 -1. + <_>5 15 7 1 3. + 0 + 0.0151648297905922 + 0.4735757112503052 + 0.6735026836395264 + <_> + + <_> + + + + <_>10 14 1 3 -1. + <_>10 15 1 1 3. + 0 + -1.0604249546304345e-003 + 0.5822926759719849 + 0.4775702953338623 + <_> + + <_> + + + + <_>3 14 3 3 -1. + <_>3 15 3 1 3. + 0 + 6.6476291976869106e-003 + 0.4999198913574219 + 0.2319535017013550 + <_> + + <_> + + + + <_>14 4 6 6 -1. + <_>14 6 6 2 3. + 0 + -0.0122311301529408 + 0.4750893115997315 + 0.5262982249259949 + <_> + + <_> + + + + <_>0 4 6 6 -1. + <_>0 6 6 2 3. + 0 + 5.6528882123529911e-003 + 0.5069767832756043 + 0.3561818897724152 + <_> + + <_> + + + + <_>12 5 4 3 -1. + <_>12 6 4 1 3. + 0 + 1.2977829901501536e-003 + 0.4875693917274475 + 0.5619062781333923 + <_> + + <_> + + + + <_>4 5 4 3 -1. + <_>4 6 4 1 3. + 0 + 0.0107815898954868 + 0.4750770032405853 + 0.6782308220863342 + <_> + + <_> + + + + <_>18 0 2 6 -1. + <_>18 2 2 2 3. + 0 + 2.8654779307544231e-003 + 0.5305461883544922 + 0.4290736019611359 + <_> + + <_> + + + + <_>8 1 4 9 -1. + <_>10 1 2 9 2. + 0 + 2.8663428965955973e-003 + 0.4518479108810425 + 0.5539351105690002 + <_> + + <_> + + + + <_>6 6 8 2 -1. + <_>6 6 4 2 2. + 0 + -5.1983320154249668e-003 + 0.4149119853973389 + 0.5434188842773438 + <_> + + <_> + + + + <_>6 5 4 2 -1. + <_>6 5 2 1 2. + <_>8 6 2 1 2. + 0 + 5.3739990107715130e-003 + 0.4717896878719330 + 0.6507657170295715 + <_> + + <_> + + + + <_>10 5 2 3 -1. + <_>10 6 2 1 3. + 0 + -0.0146415298804641 + 0.2172164022922516 + 0.5161777138710022 + <_> + + <_> + + + + <_>9 5 1 3 -1. + <_>9 6 1 1 3. + 0 + -1.5042580344015732e-005 + 0.5337383747100830 + 0.4298836886882782 + <_> + + <_> + + + + <_>9 10 2 2 -1. + <_>9 11 2 1 2. + 0 + -1.1875660129589960e-004 + 0.4604594111442566 + 0.5582447052001953 + <_> + + <_> + + + + <_>0 8 4 3 -1. + <_>0 9 4 1 3. + 0 + 0.0169955305755138 + 0.4945895075798035 + 0.0738800764083862 + <_> + + <_> + + + + <_>6 0 8 6 -1. + <_>6 3 8 3 2. + 0 + -0.0350959412753582 + 0.7005509138107300 + 0.4977591037750244 + <_> + + <_> + + + + <_>1 0 6 4 -1. + <_>1 0 3 2 2. + <_>4 2 3 2 2. + 0 + 2.4217350874096155e-003 + 0.4466265141963959 + 0.5477694272994995 + <_> + + <_> + + + + <_>13 0 3 7 -1. + <_>14 0 1 7 3. + 0 + -9.6340337768197060e-004 + 0.4714098870754242 + 0.5313338041305542 + <_> + + <_> + + + + <_>9 16 2 2 -1. + <_>9 17 2 1 2. + 0 + 1.6391130338888615e-004 + 0.4331546127796173 + 0.5342242121696472 + <_> + + <_> + + + + <_>11 4 6 10 -1. + <_>11 9 6 5 2. + 0 + -0.0211414601653814 + 0.2644700109958649 + 0.5204498767852783 + <_> + + <_> + + + + <_>0 10 19 2 -1. + <_>0 11 19 1 2. + 0 + 8.7775202700868249e-004 + 0.5208349823951721 + 0.4152742922306061 + <_> + + <_> + + + + <_>9 5 8 9 -1. + <_>9 8 8 3 3. + 0 + -0.0279439203441143 + 0.6344125270843506 + 0.5018811821937561 + <_> + + <_> + + + + <_>4 0 3 7 -1. + <_>5 0 1 7 3. + 0 + 6.7297378554940224e-003 + 0.5050438046455383 + 0.3500863909721375 + <_> + + <_> + + + + <_>8 6 4 12 -1. + <_>10 6 2 6 2. + <_>8 12 2 6 2. + 0 + 0.0232810396701097 + 0.4966318011283875 + 0.6968677043914795 + <_> + + <_> + + + + <_>0 2 6 4 -1. + <_>0 4 6 2 2. + 0 + -0.0116449799388647 + 0.3300260007381439 + 0.5049629807472229 + <_> + + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + 0.0157643090933561 + 0.4991598129272461 + 0.7321153879165649 + <_> + + <_> + + + + <_>8 0 3 7 -1. + <_>9 0 1 7 3. + 0 + -1.3611479662358761e-003 + 0.3911735117435455 + 0.5160670876502991 + <_> + + <_> + + + + <_>9 5 3 4 -1. + <_>10 5 1 4 3. + 0 + -8.1522337859496474e-004 + 0.5628911256790161 + 0.4949719011783600 + <_> + + <_> + + + + <_>8 5 3 4 -1. + <_>9 5 1 4 3. + 0 + -6.0066272271797061e-004 + 0.5853595137596130 + 0.4550595879554749 + <_> + + <_> + + + + <_>7 6 6 1 -1. + <_>9 6 2 1 3. + 0 + 4.9715518252924085e-004 + 0.4271470010280609 + 0.5443599224090576 + <_> + + <_> + + + + <_>7 14 4 4 -1. + <_>7 14 2 2 2. + <_>9 16 2 2 2. + 0 + 2.3475370835512877e-003 + 0.5143110752105713 + 0.3887656927108765 + <_> + + <_> + + + + <_>13 14 4 6 -1. + <_>15 14 2 3 2. + <_>13 17 2 3 2. + 0 + -8.9261569082736969e-003 + 0.6044502258300781 + 0.4971720874309540 + <_> + + <_> + + + + <_>7 8 1 8 -1. + <_>7 12 1 4 2. + 0 + -0.0139199104160070 + 0.2583160996437073 + 0.5000367760658264 + <_> + + <_> + + + + <_>16 0 2 8 -1. + <_>17 0 1 4 2. + <_>16 4 1 4 2. + 0 + 1.0209949687123299e-003 + 0.4857374131679535 + 0.5560358166694641 + <_> + + <_> + + + + <_>2 0 2 8 -1. + <_>2 0 1 4 2. + <_>3 4 1 4 2. + 0 + -2.7441629208624363e-003 + 0.5936884880065918 + 0.4645777046680450 + <_> + + <_> + + + + <_>6 1 14 3 -1. + <_>6 2 14 1 3. + 0 + -0.0162001308053732 + 0.3163014948368073 + 0.5193495154380798 + <_> + + <_> + + + + <_>7 9 3 10 -1. + <_>7 14 3 5 2. + 0 + 4.3331980705261230e-003 + 0.5061224102973938 + 0.3458878993988037 + <_> + + <_> + + + + <_>9 14 2 2 -1. + <_>9 15 2 1 2. + 0 + 5.8497930876910686e-004 + 0.4779017865657806 + 0.5870177745819092 + <_> + + <_> + + + + <_>7 7 6 8 -1. + <_>7 11 6 4 2. + 0 + -2.2466450463980436e-003 + 0.4297851026058197 + 0.5374773144721985 + <_> + + <_> + + + + <_>9 7 3 6 -1. + <_>9 10 3 3 2. + 0 + 2.3146099410951138e-003 + 0.5438671708106995 + 0.4640969932079315 + <_> + + <_> + + + + <_>7 13 3 3 -1. + <_>7 14 3 1 3. + 0 + 8.7679121643304825e-003 + 0.4726893007755280 + 0.6771789789199829 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -2.2448020172305405e-004 + 0.4229173064231873 + 0.5428048968315125 + <_> + + <_> + + + + <_>0 1 18 2 -1. + <_>6 1 6 2 3. + 0 + -7.4336021207273006e-003 + 0.6098880767822266 + 0.4683673977851868 + <_> + + <_> + + + + <_>7 1 6 14 -1. + <_>7 8 6 7 2. + 0 + -2.3189240600913763e-003 + 0.5689436793327332 + 0.4424242079257965 + <_> + + <_> + + + + <_>1 9 18 1 -1. + <_>7 9 6 1 3. + 0 + -2.1042178850620985e-003 + 0.3762221038341522 + 0.5187087059020996 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>9 7 1 2 2. + 0 + 4.6034841216169298e-004 + 0.4699405133724213 + 0.5771207213401794 + <_> + + <_> + + + + <_>9 3 2 9 -1. + <_>10 3 1 9 2. + 0 + 1.0547629790380597e-003 + 0.4465216994285584 + 0.5601701736450195 + <_> + + <_> + + + + <_>18 14 2 3 -1. + <_>18 15 2 1 3. + 0 + 8.7148818420246243e-004 + 0.5449805259704590 + 0.3914709091186523 + <_> + + <_> + + + + <_>7 11 3 1 -1. + <_>8 11 1 1 3. + 0 + 3.3364820410497487e-004 + 0.4564009010791779 + 0.5645738840103149 + <_> + + <_> + + + + <_>10 8 3 4 -1. + <_>11 8 1 4 3. + 0 + -1.4853250468149781e-003 + 0.5747377872467041 + 0.4692778885364533 + <_> + + <_> + + + + <_>7 14 3 6 -1. + <_>8 14 1 6 3. + 0 + 3.0251620337367058e-003 + 0.5166196823120117 + 0.3762814104557037 + <_> + + <_> + + + + <_>10 8 3 4 -1. + <_>11 8 1 4 3. + 0 + 5.0280741415917873e-003 + 0.5002111792564392 + 0.6151527166366577 + <_> + + <_> + + + + <_>7 8 3 4 -1. + <_>8 8 1 4 3. + 0 + -5.8164511574432254e-004 + 0.5394598245620728 + 0.4390751123428345 + <_> + + <_> + + + + <_>7 9 6 9 -1. + <_>7 12 6 3 3. + 0 + 0.0451415292918682 + 0.5188326835632324 + 0.2063035964965820 + <_> + + <_> + + + + <_>0 14 2 3 -1. + <_>0 15 2 1 3. + 0 + -1.0795620037242770e-003 + 0.3904685080051422 + 0.5137907266616821 + <_> + + <_> + + + + <_>11 12 1 2 -1. + <_>11 13 1 1 2. + 0 + 1.5995999274309725e-004 + 0.4895322918891907 + 0.5427504181861877 + <_> + + <_> + + + + <_>4 3 8 3 -1. + <_>8 3 4 3 2. + 0 + -0.0193592701107264 + 0.6975228786468506 + 0.4773507118225098 + <_> + + <_> + + + + <_>0 4 20 6 -1. + <_>0 4 10 6 2. + 0 + 0.2072550952434540 + 0.5233635902404785 + 0.3034991919994354 + <_> + + <_> + + + + <_>9 14 1 3 -1. + <_>9 15 1 1 3. + 0 + -4.1953290929086506e-004 + 0.5419396758079529 + 0.4460186064243317 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 2.2582069505006075e-003 + 0.4815764129161835 + 0.6027408838272095 + <_> + + <_> + + + + <_>0 15 14 4 -1. + <_>0 17 14 2 2. + 0 + -6.7811207845807076e-003 + 0.3980278968811035 + 0.5183305740356445 + <_> + + <_> + + + + <_>1 14 18 6 -1. + <_>1 17 18 3 2. + 0 + 0.0111543098464608 + 0.5431231856346130 + 0.4188759922981262 + <_> + + <_> + + + + <_>0 0 10 6 -1. + <_>0 0 5 3 2. + <_>5 3 5 3 2. + 0 + 0.0431624315679073 + 0.4738228023052216 + 0.6522961258888245 + 105.7611007690429700 + 20 + -1 + diff --git a/data/haarcascade_frontalface_alt_gpu.xml b/data/haarcascade_frontalface_alt_gpu.xml new file mode 100644 index 00000000..caa86f6c --- /dev/null +++ b/data/haarcascade_frontalface_alt_gpu.xml @@ -0,0 +1,23550 @@ + + + + + 20 20 + + <_> + + + <_> + + <_> + + + + <_>2 7 16 4 -1. + <_>2 9 16 2 2. + 0 + 4.3272329494357109e-003 + 0.0383819006383419 + 1 + <_> + + + + <_>8 4 3 14 -1. + <_>8 11 3 7 2. + 0 + 0.0130761601030827 + 0.8965256810188294 + 0.2629314064979553 + <_> + + <_> + + + + <_>13 6 1 6 -1. + <_>13 9 1 3 2. + 0 + 5.2434601821005344e-004 + 0.1021663025021553 + 1 + <_> + + + + <_>4 2 12 8 -1. + <_>8 2 4 8 3. + 0 + 4.4573000632226467e-003 + 0.1238401979207993 + 0.6910383105278015 + <_> + + <_> + + + + <_>6 3 1 9 -1. + <_>6 6 1 3 3. + 0 + -9.2708261217921972e-004 + 1 + 0.1953697055578232 + <_> + + + + <_>3 7 14 9 -1. + <_>3 10 14 3 3. + 0 + 3.3989109215326607e-004 + 0.2101441025733948 + 0.8258674740791321 + 0.3506923019886017 + -1 + -1 + <_> + + + <_> + + <_> + + + + <_>4 7 4 4 -1. + <_>4 9 4 2 2. + 0 + 2.3025739938020706e-003 + 0.1018375977873802 + 1 + <_> + + + + <_>9 4 2 16 -1. + <_>9 12 2 8 2. + 0 + 4.4174338690936565e-003 + 0.8219057917594910 + 0.1956554949283600 + <_> + + <_> + + + + <_>1 1 18 5 -1. + <_>7 1 6 5 3. + 0 + 0.0222032107412815 + 0.2205407023429871 + 1 + <_> + + + + <_>4 5 13 8 -1. + <_>4 9 13 4 2. + 0 + -1.7283110355492681e-004 + 0.0732632577419281 + 0.5931484103202820 + <_> + + <_> + + + + <_>1 7 16 9 -1. + <_>1 10 16 3 3. + 0 + 4.3567270040512085e-003 + 0.1844114959239960 + 1 + <_> + + + + <_>2 0 15 4 -1. + <_>2 2 15 2 2. + 0 + -2.6032889727503061e-003 + 0.4032213985919952 + 0.8066521286964417 + <_> + + <_> + + + + <_>7 5 6 4 -1. + <_>9 5 2 4 3. + 0 + 1.7309630056843162e-003 + 0.2548328042030335 + 1 + <_> + + + + <_>6 3 8 9 -1. + <_>6 6 8 3 3. + 0 + -7.8146401792764664e-003 + 0.6057069897651672 + 0.2779063880443573 + <_> + + <_> + + + + <_>8 12 3 8 -1. + <_>8 16 3 4 2. + 0 + -8.7343417108058929e-003 + 0.2889980077743530 + 1 + <_> + + + + <_>3 16 2 2 -1. + <_>3 17 2 1 2. + 0 + 9.4522320432588458e-004 + 0.7616587281227112 + 0.3495643138885498 + <_> + + <_> + + + + <_>14 1 6 12 -1. + <_>14 1 3 12 2. + 0 + 0.0494148582220078 + 1 + 0.8151652812957764 + <_> + + + + <_>4 4 12 6 -1. + <_>8 4 4 6 3. + 0 + 4.4891750440001488e-003 + 0.2808783054351807 + 0.6027774810791016 + <_> + + <_> + + + + <_>0 2 6 15 -1. + <_>3 2 3 15 2. + 0 + 0.0603136196732521 + 1 + 0.7607501745223999 + <_> + + + + <_>5 4 9 6 -1. + <_>5 6 9 2 3. + 0 + -1.0762850288301706e-003 + 0.4444035887718201 + 0.1437312066555023 + <_> + + <_> + + + + <_>13 11 6 3 -1. + <_>13 12 6 1 3. + 0 + -9.5083238556981087e-003 + 1 + 0.5318170189857483 + <_> + + + + <_>12 12 6 4 -1. + <_>12 14 6 2 2. + 0 + 7.6601309701800346e-003 + 0.5411052107810974 + 0.2180687040090561 + <_> + + <_> + + + + <_>1 11 6 3 -1. + <_>1 12 6 1 3. + 0 + 7.6467678882181644e-003 + 1 + 0.1158960014581680 + <_> + + + + <_>2 5 5 8 -1. + <_>2 9 5 4 2. + 0 + -8.4662932204082608e-004 + 0.2340679019689560 + 0.5990381836891174 + 3.4721779823303223 + 0 + -1 + <_> + + + <_> + + <_> + + + + <_>5 4 10 4 -1. + <_>5 6 10 2 2. + 0 + -4.8506218008697033e-003 + 1 + 0.1805496066808701 + <_> + + + + <_>2 4 16 12 -1. + <_>2 8 16 4 3. + 0 + -4.6141650527715683e-003 + 0.2177893966436386 + 0.8018236756324768 + <_> + + <_> + + + + <_>4 5 12 6 -1. + <_>8 5 4 6 3. + 0 + -2.4301309604197741e-003 + 0.1141354963183403 + 1 + <_> + + + + <_>13 7 2 9 -1. + <_>13 10 2 3 3. + 0 + 4.1787960799410939e-004 + 0.1203093975782394 + 0.6108530759811401 + <_> + + <_> + + + + <_>5 7 2 9 -1. + <_>5 10 2 3 3. + 0 + 1.0010929545387626e-003 + 0.2079959958791733 + 1 + <_> + + + + <_>7 1 6 8 -1. + <_>9 1 2 8 3. + 0 + 1.0577100329101086e-003 + 0.3302054107189179 + 0.7511094212532044 + <_> + + <_> + + + + <_>12 0 4 12 -1. + <_>14 0 2 6 2. + <_>12 6 2 6 2. + 0 + 1.2376549420878291e-003 + 1 + 0.2768222093582153 + <_> + + + + <_>5 8 10 2 -1. + <_>5 9 10 1 2. + 0 + 3.5315038985572755e-004 + 0.1668293029069901 + 0.5829476714134216 + <_> + + <_> + + + + <_>5 1 6 4 -1. + <_>7 1 2 4 3. + 0 + -0.0119536602869630 + 0.1508788019418716 + 1 + <_> + + + + <_>0 3 9 12 -1. + <_>3 3 3 12 3. + 0 + 1.4182999730110168e-003 + 0.4391227960586548 + 0.7646595239639282 + <_> + + <_> + + + + <_>9 8 3 12 -1. + <_>9 12 3 4 3. + 0 + 3.4642980899661779e-003 + 1 + 0.2651556134223938 + <_> + + + + <_>0 5 20 15 -1. + <_>0 10 20 5 3. + 0 + -0.0149489501491189 + 0.2298053056001663 + 0.5442165732383728 + <_> + + <_> + + + + <_>2 2 6 8 -1. + <_>2 2 3 4 2. + <_>5 6 3 4 2. + 0 + -1.0506849503144622e-003 + 1 + 0.3622843921184540 + <_> + + + + <_>2 1 6 2 -1. + <_>2 2 6 1 2. + 0 + -4.0782918222248554e-003 + 0.2601259946823120 + 0.7233657836914063 + <_> + + <_> + + + + <_>10 15 6 4 -1. + <_>13 15 3 2 2. + <_>10 17 3 2 2. + 0 + 5.4242828628048301e-004 + 0.3849678933620453 + 1 + <_> + + + + <_>12 14 2 6 -1. + <_>12 16 2 2 3. + 0 + -7.3204059153795242e-003 + 0.2965512871742249 + 0.5480309128761292 + <_> + + <_> + + + + <_>5 15 4 4 -1. + <_>5 15 2 2 2. + <_>7 17 2 2 2. + 0 + 1.1421289527788758e-003 + 0.4104770123958588 + 1 + <_> + + + + <_>7 18 1 2 -1. + <_>7 19 1 1 2. + 0 + 1.1783400550484657e-003 + 0.7239024043083191 + 0.2787283957004547 + <_> + + <_> + + + + <_>4 5 12 10 -1. + <_>10 5 6 5 2. + <_>4 10 6 5 2. + 0 + 0.0440771095454693 + 0.5640516281127930 + 1 + <_> + + + + <_>7 4 8 12 -1. + <_>11 4 4 6 2. + <_>7 10 4 6 2. + 0 + 3.7900090683251619e-003 + 0.5947548151016235 + 0.3312020003795624 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -2.4291418958455324e-003 + 0.6603232026100159 + 1 + <_> + + + + <_>3 3 12 12 -1. + <_>3 3 6 6 2. + <_>9 9 6 6 2. + 0 + 9.4262324273586273e-003 + 0.4680665135383606 + 0.2064338028430939 + <_> + + <_> + + + + <_>15 11 5 3 -1. + <_>15 12 5 1 3. + 0 + 8.0630257725715637e-003 + 0.5298851132392883 + 1 + <_> + + + + <_>10 18 3 2 -1. + <_>11 18 1 2 3. + 0 + 5.2240812219679356e-003 + 0.5281602740287781 + 0.1909549981355667 + <_> + + <_> + + + + <_>0 11 5 3 -1. + <_>0 12 5 1 3. + 0 + -7.0630568079650402e-003 + 0.1380645930767059 + 1 + <_> + + + + <_>7 18 3 2 -1. + <_>8 18 1 2 3. + 0 + 5.6897541508078575e-003 + 0.5490636825561523 + 0.1260281056165695 + <_> + + <_> + + + + <_>2 8 16 2 -1. + <_>2 9 16 1 2. + 0 + 1.2472929665818810e-003 + 0.2372663021087647 + 1 + <_> + + + + <_>9 6 5 12 -1. + <_>9 12 5 6 2. + 0 + 0.0495434887707233 + 0.5240166187286377 + 0.1769216060638428 + 5.9844889640808105 + 1 + -1 + <_> + + + <_> + + <_> + + + + <_>6 3 8 6 -1. + <_>6 6 8 3 2. + 0 + -4.9326149746775627e-003 + 1 + 0.1998064965009689 + <_> + + + + <_>4 7 12 2 -1. + <_>8 7 4 2 3. + 0 + 2.7918140403926373e-005 + 0.2299380004405975 + 0.7393211126327515 + <_> + + <_> + + + + <_>10 9 6 8 -1. + <_>10 13 6 4 2. + 0 + 3.0876200180500746e-003 + 1 + 0.1533840000629425 + <_> + + + + <_>12 5 3 10 -1. + <_>12 10 3 5 2. + 0 + 7.4669660534709692e-006 + 0.2036858946084976 + 0.5854915976524353 + <_> + + <_> + + + + <_>4 6 3 9 -1. + <_>4 9 3 3 3. + 0 + 1.8739729421213269e-003 + 0.2049895972013474 + 1 + <_> + + + + <_>7 4 6 4 -1. + <_>9 4 2 4 3. + 0 + 9.3380251200869679e-004 + 0.3234199881553650 + 0.7323014140129089 + <_> + + <_> + + + + <_>12 3 8 3 -1. + <_>12 3 4 3 2. + 0 + 1.9151850137859583e-003 + 0.3045149147510529 + 1 + <_> + + + + <_>15 0 3 6 -1. + <_>15 3 3 3 2. + 0 + -5.9683797881007195e-003 + 0.2932133972644806 + 0.5621296167373657 + <_> + + <_> + + + + <_>2 12 10 8 -1. + <_>2 12 5 4 2. + <_>7 16 5 4 2. + 0 + -7.2115601506084204e-004 + 0.3658036887645721 + 1 + <_> + + + + <_>5 5 6 8 -1. + <_>5 9 6 4 2. + 0 + -5.9663117863237858e-003 + 0.2712155878543854 + 0.7226334810256958 + <_> + + <_> + + + + <_>12 3 8 3 -1. + <_>12 3 4 3 2. + 0 + 0.0308741796761751 + 0.4419837892055512 + 1 + <_> + + + + <_>15 0 3 6 -1. + <_>15 3 3 3 2. + 0 + -0.0110997101292014 + 0.3612976968288422 + 0.5251451134681702 + <_> + + <_> + + + + <_>0 3 8 3 -1. + <_>4 3 4 3 2. + 0 + 2.1164179779589176e-003 + 0.3628616929054260 + 1 + <_> + + + + <_>2 1 4 4 -1. + <_>2 3 4 2 2. + 0 + -9.4317439943552017e-003 + 0.1601095050573349 + 0.7052276730537415 + <_> + + <_> + + + + <_>10 2 3 2 -1. + <_>11 2 1 2 3. + 0 + -3.5266019403934479e-003 + 0.1301288008689880 + 1 + <_> + + + + <_>10 3 3 1 -1. + <_>11 3 1 1 3. + 0 + -1.6907559474930167e-003 + 0.1786323934793472 + 0.5521529912948608 + <_> + + <_> + + + + <_>7 15 3 4 -1. + <_>7 17 3 2 2. + 0 + 4.6470930101349950e-004 + 0.3487383127212524 + 1 + <_> + + + + <_>4 13 3 6 -1. + <_>4 15 3 2 3. + 0 + -0.0102155702188611 + 0.2673991024494171 + 0.6667919158935547 + <_> + + <_> + + + + <_>10 5 1 14 -1. + <_>10 12 1 7 2. + 0 + 1.2634709710255265e-003 + 1 + 0.3437863886356354 + <_> + + + + <_>5 4 10 6 -1. + <_>5 6 10 2 3. + 0 + -0.0118752997368574 + 0.5995336174964905 + 0.3497717976570129 + <_> + + <_> + + + + <_>5 0 6 3 -1. + <_>7 0 2 3 3. + 0 + -0.0107323396950960 + 0.2150489985942841 + 1 + <_> + + + + <_>6 0 3 5 -1. + <_>7 0 1 5 3. + 0 + 7.1836481802165508e-003 + 0.6271436214447022 + 0.2519541978836060 + <_> + + <_> + + + + <_>7 15 6 5 -1. + <_>9 15 2 5 3. + 0 + -0.0283408891409636 + 0.0824118927121162 + 1 + <_> + + + + <_>9 10 2 6 -1. + <_>9 12 2 2 3. + 0 + -4.5813230099156499e-004 + 0.5910056829452515 + 0.3705201148986816 + <_> + + <_> + + + + <_>8 17 3 2 -1. + <_>9 17 1 2 3. + 0 + 4.2940340936183929e-003 + 1 + 0.1594727933406830 + <_> + + + + <_>1 12 7 6 -1. + <_>1 14 7 2 3. + 0 + 0.0107510797679424 + 0.5980480909347534 + 0.2832508087158203 + <_> + + <_> + + + + <_>9 6 3 7 -1. + <_>10 6 1 7 3. + 0 + 0.0224651191383600 + 1 + 0.7877091169357300 + <_> + + + + <_>16 3 4 9 -1. + <_>16 6 4 3 3. + 0 + -0.0579885393381119 + 0.1555740982294083 + 0.5239657163619995 + <_> + + <_> + + + + <_>8 6 3 7 -1. + <_>9 6 1 7 3. + 0 + 7.2110891342163086e-003 + 1 + 0.6620365977287293 + <_> + + + + <_>0 5 18 8 -1. + <_>0 5 9 4 2. + <_>9 9 9 4 2. + 0 + -0.0483675710856915 + 0.1424719989299774 + 0.4429833889007568 + <_> + + <_> + + + + <_>13 5 2 10 -1. + <_>13 10 2 5 2. + 0 + -0.0144180599600077 + 0.1588540971279144 + 1 + <_> + + + + <_>12 10 2 6 -1. + <_>12 13 2 3 2. + 0 + -0.0231563895940781 + 0.2375798970460892 + 0.5217134952545166 + <_> + + <_> + + + + <_>7 0 3 5 -1. + <_>8 0 1 5 3. + 0 + 7.6985340565443039e-003 + 1 + 0.1941725015640259 + <_> + + + + <_>6 5 8 6 -1. + <_>6 7 8 2 3. + 0 + -5.6248619221150875e-003 + 0.6278405785560608 + 0.3746044933795929 + <_> + + <_> + + + + <_>10 3 6 14 -1. + <_>13 3 3 7 2. + <_>10 10 3 7 2. + 0 + -7.2936748620122671e-004 + 1 + 0.3840922117233276 + <_> + + + + <_>13 5 1 8 -1. + <_>13 9 1 4 2. + 0 + 6.1783898854628205e-004 + 0.3106493055820465 + 0.5537847280502319 + <_> + + <_> + + + + <_>4 3 6 14 -1. + <_>4 3 3 7 2. + <_>7 10 3 7 2. + 0 + -4.5803939428878948e-005 + 1 + 0.3444449007511139 + <_> + + + + <_>6 5 1 8 -1. + <_>6 9 1 4 2. + 0 + -1.4719359569426160e-005 + 0.2729552090167999 + 0.6428951025009155 + 8.5117864608764648 + 2 + -1 + <_> + + + <_> + + <_> + + + + <_>8 1 1 6 -1. + <_>8 3 1 2 3. + 0 + -1.3469370314851403e-003 + 0.1657086014747620 + 1 + <_> + + + + <_>2 0 15 2 -1. + <_>2 1 15 1 2. + 0 + -2.4774789344519377e-003 + 0.2273851037025452 + 0.6989349722862244 + <_> + + <_> + + + + <_>0 7 20 6 -1. + <_>0 9 20 2 3. + 0 + 5.2632777951657772e-003 + 0.1512074023485184 + 1 + <_> + + + + <_>10 10 6 8 -1. + <_>10 14 6 4 2. + 0 + 4.9075339920818806e-003 + 0.5564470291137695 + 0.1605442017316818 + <_> + + <_> + + + + <_>7 1 3 2 -1. + <_>8 1 1 2 3. + 0 + -2.3254349362105131e-003 + 0.1880259066820145 + 1 + <_> + + + + <_>8 1 2 2 -1. + <_>9 1 1 2 2. + 0 + -1.4665479538962245e-003 + 0.3122498989105225 + 0.7165396213531494 + <_> + + <_> + + + + <_>4 3 12 9 -1. + <_>4 6 12 3 3. + 0 + -0.1231169030070305 + 1 + 0.3859583139419556 + <_> + + + + <_>6 5 9 5 -1. + <_>9 5 3 5 3. + 0 + 2.2108340635895729e-003 + 0.2455293983221054 + 0.5695710182189941 + <_> + + <_> + + + + <_>5 5 9 5 -1. + <_>8 5 3 5 3. + 0 + 2.0661531016230583e-003 + 0.2716520130634308 + 1 + <_> + + + + <_>4 6 6 12 -1. + <_>4 10 6 4 3. + 0 + 3.6130280932411551e-004 + 0.2293362021446228 + 0.7208629846572876 + <_> + + <_> + + + + <_>13 0 6 18 -1. + <_>13 0 3 18 2. + 0 + 0.0799578726291656 + 1 + 0.7833620905876160 + <_> + + + + <_>10 8 1 12 -1. + <_>10 12 1 4 3. + 0 + 2.6064720004796982e-003 + 0.5545232295989990 + 0.2550689876079559 + <_> + + <_> + + + + <_>3 2 6 10 -1. + <_>3 2 3 5 2. + <_>6 7 3 5 2. + 0 + 6.5699010156095028e-003 + 1 + 0.1819390058517456 + <_> + + + + <_>1 2 4 6 -1. + <_>3 2 2 6 2. + 0 + 1.6259610420092940e-003 + 0.3529875874519348 + 0.6552819013595581 + <_> + + <_> + + + + <_>9 18 3 2 -1. + <_>10 18 1 2 3. + 0 + 3.6204981151968241e-003 + 0.5462309718132019 + 1 + <_> + + + + <_>10 18 3 2 -1. + <_>11 18 1 2 3. + 0 + -4.4391951523721218e-003 + 0.1359843015670776 + 0.5415815114974976 + <_> + + <_> + + + + <_>2 8 2 6 -1. + <_>2 10 2 2 3. + 0 + -9.0540945529937744e-003 + 0.1115119978785515 + 1 + <_> + + + + <_>7 5 6 6 -1. + <_>7 7 6 2 3. + 0 + -4.6067481162026525e-004 + 0.5846719741821289 + 0.2598348855972290 + <_> + + <_> + + + + <_>7 19 6 1 -1. + <_>9 19 2 1 3. + 0 + -5.6621041148900986e-003 + 0.1610569059848785 + 1 + <_> + + + + <_>10 18 3 2 -1. + <_>11 18 1 2 3. + 0 + 5.1165837794542313e-003 + 0.5376678705215454 + 0.1739455014467239 + <_> + + <_> + + + + <_>8 3 3 1 -1. + <_>9 3 1 1 3. + 0 + -2.1362339612096548e-003 + 0.1902073025703430 + 1 + <_> + + + + <_>2 2 16 2 -1. + <_>2 2 8 1 2. + <_>10 3 8 1 2. + 0 + -5.4809921421110630e-003 + 0.3272008001804352 + 0.6364840865135193 + <_> + + <_> + + + + <_>8 11 5 3 -1. + <_>8 12 5 1 3. + 0 + -8.1061907112598419e-003 + 0.6914852857589722 + 1 + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + 6.0048708692193031e-003 + 0.4327326118946075 + 0.6963843107223511 + <_> + + <_> + + + + <_>0 1 6 15 -1. + <_>2 1 2 15 3. + 0 + -0.0870285481214523 + 0.8594133853912354 + 1 + <_> + + + + <_>2 12 2 3 -1. + <_>2 13 2 1 3. + 0 + -4.7809639945626259e-003 + 0.0973944664001465 + 0.4587030112743378 + <_> + + <_> + + + + <_>16 13 1 3 -1. + <_>16 14 1 1 3. + 0 + -2.2166660055518150e-003 + 0.2554625868797302 + 1 + <_> + + + + <_>13 7 6 4 -1. + <_>16 7 3 2 2. + <_>13 9 3 2 2. + 0 + 1.3642730191349983e-003 + 0.3319090902805328 + 0.5964102745056152 + <_> + + <_> + + + + <_>7 13 3 6 -1. + <_>7 16 3 3 2. + 0 + -9.0077864006161690e-003 + 0.2666594982147217 + 1 + <_> + + + + <_>7 5 1 14 -1. + <_>7 12 1 7 2. + 0 + -0.0154941203072667 + 0.1848185956478119 + 0.6245970726013184 + <_> + + <_> + + + + <_>15 12 2 3 -1. + <_>15 13 2 1 3. + 0 + -4.2165028862655163e-003 + 1 + 0.5379927158355713 + <_> + + + + <_>10 5 3 14 -1. + <_>10 12 3 7 2. + 0 + 0.0432497598230839 + 0.5183029174804688 + 0.2170419991016388 + <_> + + <_> + + + + <_>6 10 2 6 -1. + <_>6 13 2 3 2. + 0 + 2.8786511393263936e-004 + 1 + 0.2613384127616882 + <_> + + + + <_>6 5 1 8 -1. + <_>6 9 1 4 2. + 0 + 1.2373150093480945e-003 + 0.2786532044410706 + 0.5908988118171692 + <_> + + <_> + + + + <_>13 11 2 1 -1. + <_>13 11 1 1 2. + 0 + 1.9528300035744905e-003 + 1 + 0.2612869143486023 + <_> + + + + <_>12 1 6 10 -1. + <_>15 1 3 5 2. + <_>12 6 3 5 2. + 0 + -1.4947060262784362e-003 + 0.5915412902832031 + 0.3455781936645508 + <_> + + <_> + + + + <_>3 12 2 3 -1. + <_>3 13 2 1 3. + 0 + 3.5878680646419525e-003 + 1 + 0.1587052047252655 + <_> + + + + <_>9 18 2 1 -1. + <_>10 18 1 1 2. + 0 + -2.5938691105693579e-003 + 0.1270411014556885 + 0.5979428887367249 + 8.4680156707763672 + 3 + -1 + <_> + + + <_> + + <_> + + + + <_>1 0 17 9 -1. + <_>1 3 17 3 3. + 0 + 3.5810680128633976e-003 + 0.1995104998350143 + 1 + <_> + + + + <_>1 2 8 8 -1. + <_>1 2 4 4 2. + <_>5 6 4 4 2. + 0 + -2.8552350122481585e-003 + 0.7373070120811462 + 0.2921737134456635 + <_> + + <_> + + + + <_>9 5 6 4 -1. + <_>9 5 3 4 2. + 0 + 1.9758539274334908e-003 + 0.1956419944763184 + 1 + <_> + + + + <_>10 9 7 10 -1. + <_>10 14 7 5 2. + 0 + 3.2583118882030249e-003 + 0.5692046880722046 + 0.1839064955711365 + <_> + + <_> + + + + <_>5 5 6 4 -1. + <_>8 5 3 4 2. + 0 + 2.3711679386906326e-004 + 0.2171667069196701 + 1 + <_> + + + + <_>0 7 20 6 -1. + <_>0 9 20 2 3. + 0 + 2.5942500215023756e-003 + 0.2719989120960236 + 0.7150244116783142 + <_> + + <_> + + + + <_>6 5 9 10 -1. + <_>6 10 9 5 2. + 0 + -0.0250324495136738 + 0.1825183928012848 + 1 + <_> + + + + <_>8 4 4 12 -1. + <_>8 10 4 6 2. + 0 + 6.3087949529290199e-003 + 0.5699837803840637 + 0.3509852886199951 + <_> + + <_> + + + + <_>6 6 8 3 -1. + <_>6 7 8 1 3. + 0 + -3.2494920305907726e-003 + 1 + 0.4023926854133606 + <_> + + + + <_>3 13 10 6 -1. + <_>3 13 5 3 2. + <_>8 16 5 3 2. + 0 + -0.0148857301101089 + 0.3604095876216888 + 0.7291995286941528 + <_> + + <_> + + + + <_>15 1 4 11 -1. + <_>15 1 2 11 2. + 0 + 8.0623216927051544e-003 + 1 + 0.6491490006446838 + <_> + + + + <_>5 7 10 10 -1. + <_>10 7 5 5 2. + <_>5 12 5 5 2. + 0 + 0.0274056792259216 + 0.5518993139266968 + 0.2659681141376495 + <_> + + <_> + + + + <_>1 1 4 11 -1. + <_>3 1 2 11 2. + 0 + 0.0343686006963253 + 1 + 0.6712512969970703 + <_> + + + + <_>1 5 8 12 -1. + <_>1 11 8 6 2. + 0 + -0.0272929705679417 + 0.1691378057003021 + 0.4326277971267700 + <_> + + <_> + + + + <_>13 7 6 4 -1. + <_>16 7 3 2 2. + <_>13 9 3 2 2. + 0 + 7.4452121043577790e-004 + 0.3405100107192993 + 1 + <_> + + + + <_>11 10 7 4 -1. + <_>11 12 7 2 2. + 0 + 7.0336280623450875e-004 + 0.5516793131828308 + 0.3311387896537781 + <_> + + <_> + + + + <_>0 4 20 12 -1. + <_>0 4 10 6 2. + <_>10 10 10 6 2. + 0 + -0.1227546036243439 + 0.1675315052270889 + 1 + <_> + + + + <_>1 5 6 15 -1. + <_>1 10 6 5 3. + 0 + 3.2559928949922323e-003 + 0.3615751862525940 + 0.6420782804489136 + <_> + + <_> + + + + <_>11 10 3 8 -1. + <_>11 14 3 4 2. + 0 + -0.0320903994143009 + 0.2921079099178314 + 1 + <_> + + + + <_>11 12 7 6 -1. + <_>11 14 7 2 3. + 0 + 3.2957999501377344e-003 + 0.5613031983375549 + 0.3357860147953033 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -3.2273170072585344e-003 + 0.6970642805099487 + 1 + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 1.1171669466421008e-003 + 0.3541150093078613 + 0.6144006252288818 + <_> + + <_> + + + + <_>3 14 14 4 -1. + <_>10 14 7 2 2. + <_>3 16 7 2 2. + 0 + -0.0172799509018660 + 1 + 0.5537180900573731 + <_> + + + + <_>18 7 2 4 -1. + <_>18 9 2 2 2. + 0 + 0.0117412004619837 + 0.5341957211494446 + 0.2757104933261871 + <_> + + <_> + + + + <_>3 12 6 6 -1. + <_>3 14 6 2 3. + 0 + 4.6405228786170483e-003 + 1 + 0.2489521056413651 + <_> + + + + <_>0 4 3 6 -1. + <_>0 6 3 2 3. + 0 + -0.0169130302965641 + 0.1711928993463516 + 0.5523952841758728 + <_> + + <_> + + + + <_>9 14 3 3 -1. + <_>9 15 3 1 3. + 0 + 0.0100601697340608 + 1 + 0.8273450732231140 + <_> + + + + <_>10 7 10 4 -1. + <_>15 7 5 2 2. + <_>10 9 5 2 2. + 0 + -6.0715491417795420e-004 + 0.3779391050338745 + 0.5476251840591431 + <_> + + <_> + + + + <_>7 2 6 8 -1. + <_>7 6 6 4 2. + 0 + -1.0865400545299053e-003 + 1 + 0.3296540975570679 + <_> + + + + <_>6 3 6 2 -1. + <_>8 3 2 2 3. + 0 + 8.9362077414989471e-003 + 0.6062883734703064 + 0.2434220016002655 + <_> + + <_> + + + + <_>10 6 3 5 -1. + <_>11 6 1 5 3. + 0 + -2.6372660067863762e-004 + 1 + 0.3814094960689545 + <_> + + + + <_>9 0 6 19 -1. + <_>11 0 2 19 3. + 0 + 0.0131100500002503 + 0.5517616271972656 + 0.3726893067359924 + <_> + + <_> + + + + <_>3 12 1 2 -1. + <_>3 13 1 1 2. + 0 + -2.9806280508637428e-003 + 0.1229664012789726 + 1 + <_> + + + + <_>7 14 5 3 -1. + <_>7 15 5 1 3. + 0 + -4.1619571857154369e-003 + 0.7252274751663208 + 0.4973455071449280 + <_> + + <_> + + + + <_>2 1 18 4 -1. + <_>11 1 9 2 2. + <_>2 3 9 2 2. + 0 + 0.0338423289358616 + 0.5348312854766846 + 1 + <_> + + + + <_>10 5 3 8 -1. + <_>11 5 1 8 3. + 0 + -1.2564560165628791e-003 + 0.5851914882659912 + 0.4384166896343231 + <_> + + <_> + + + + <_>0 1 18 4 -1. + <_>0 1 9 2 2. + <_>9 3 9 2 2. + 0 + -0.0196352303028107 + 0.2297834008932114 + 1 + <_> + + + + <_>7 5 3 8 -1. + <_>8 5 1 8 3. + 0 + -9.9625496659427881e-004 + 0.6295937895774841 + 0.4131599068641663 + <_> + + <_> + + + + <_>9 5 2 6 -1. + <_>9 7 2 2 3. + 0 + -0.0231271106749773 + 0.1695459038019180 + 1 + <_> + + + + <_>10 8 5 2 -1. + <_>10 9 5 1 2. + 0 + 0.0235257092863321 + 0.5174130201339722 + 0.0595193915069103 + <_> + + <_> + + + + <_>2 10 15 1 -1. + <_>7 10 5 1 3. + 0 + -0.0193565208464861 + 0.1357247978448868 + 1 + <_> + + + + <_>2 7 2 6 -1. + <_>2 9 2 2 3. + 0 + -4.1787112131714821e-003 + 0.2996628880500794 + 0.5791695117950440 + <_> + + <_> + + + + <_>9 14 3 3 -1. + <_>9 15 3 1 3. + 0 + 3.1488779932260513e-003 + 1 + 0.6592589020729065 + <_> + + + + <_>9 7 4 10 -1. + <_>9 12 4 5 2. + 0 + 7.3972279205918312e-003 + 0.5307171940803528 + 0.3795121014118195 + <_> + + <_> + + + + <_>0 8 8 2 -1. + <_>0 8 4 1 2. + <_>4 9 4 1 2. + 0 + 7.1955118983169086e-006 + 0.3128314912319183 + 1 + <_> + + + + <_>5 9 10 8 -1. + <_>5 9 5 4 2. + <_>10 13 5 4 2. + 0 + 0.0471144095063210 + 0.5537893176078796 + 0.1027309000492096 + <_> + + <_> + + + + <_>9 7 2 4 -1. + <_>9 7 1 4 2. + 0 + 7.2878710925579071e-003 + 0.4660859107971191 + 1 + <_> + + + + <_>9 6 3 4 -1. + <_>10 6 1 4 3. + 0 + -6.1887511983513832e-003 + 0.7158858180046082 + 0.4724448919296265 + <_> + + <_> + + + + <_>8 3 2 1 -1. + <_>9 3 1 1 2. + 0 + 2.9757320880889893e-003 + 1 + 0.0593456886708736 + <_> + + + + <_>8 6 3 4 -1. + <_>9 6 1 4 3. + 0 + -1.8449809867888689e-003 + 0.7027301788330078 + 0.4718731045722961 + <_> + + <_> + + + + <_>12 0 4 14 -1. + <_>14 0 2 7 2. + <_>12 7 2 7 2. + 0 + 1.0239540279144421e-004 + 0.5894734263420105 + 1 + <_> + + + + <_>12 5 6 9 -1. + <_>12 5 3 9 2. + 0 + 2.4277009069919586e-003 + 0.4862355887889862 + 0.5247588157653809 + <_> + + <_> + + + + <_>0 2 6 16 -1. + <_>3 2 3 16 2. + 0 + -0.0647513121366501 + 0.6917471289634705 + 1 + <_> + + + + <_>1 12 4 2 -1. + <_>1 13 4 1 2. + 0 + 3.9380151429213583e-004 + 0.4669617116451263 + 0.2382405996322632 + 12.5784997940063480 + 4 + -1 + <_> + + + <_> + + <_> + + + + <_>7 7 6 1 -1. + <_>9 7 2 1 3. + 0 + 1.4397440245375037e-003 + 0.2773470878601074 + 1 + <_> + + + + <_>8 3 4 9 -1. + <_>8 6 4 3 3. + 0 + -5.4068560712039471e-004 + 0.7427154779434204 + 0.2479735016822815 + <_> + + <_> + + + + <_>12 10 4 6 -1. + <_>12 13 4 3 2. + 0 + -7.1237959673453588e-006 + 1 + 0.2199503034353256 + <_> + + + + <_>8 1 8 16 -1. + <_>12 1 4 8 2. + <_>8 9 4 8 2. + 0 + -2.3661039303988218e-003 + 0.5889989733695984 + 0.2595716118812561 + <_> + + <_> + + + + <_>4 6 3 6 -1. + <_>4 9 3 3 2. + 0 + 1.7343269428238273e-003 + 0.1860125958919525 + 1 + <_> + + + + <_>1 3 6 2 -1. + <_>4 3 3 2 2. + 0 + 1.5874590026214719e-003 + 0.4151870906352997 + 0.7103474140167236 + <_> + + <_> + + + + <_>9 8 3 12 -1. + <_>9 12 3 4 3. + 0 + 3.7285638973116875e-003 + 1 + 0.2527967095375061 + <_> + + + + <_>10 9 7 10 -1. + <_>10 14 7 5 2. + 0 + -0.1288381963968277 + 0.1393000930547714 + 0.5254514813423157 + <_> + + <_> + + + + <_>3 9 7 10 -1. + <_>3 14 7 5 2. + 0 + 7.9412180930376053e-003 + 1 + 0.2487729042768478 + <_> + + + + <_>7 5 1 14 -1. + <_>7 12 1 7 2. + 0 + -0.0126617299392819 + 0.2710700035095215 + 0.6618837714195252 + <_> + + <_> + + + + <_>13 14 1 6 -1. + <_>13 16 1 2 3. + 0 + 3.0146789868013002e-005 + 0.3812825977802277 + 1 + <_> + + + + <_>14 12 3 6 -1. + <_>14 14 3 2 3. + 0 + -0.0163301602005959 + 0.2326432019472122 + 0.5263010859489441 + <_> + + <_> + + + + <_>6 14 1 6 -1. + <_>6 16 1 2 3. + 0 + 1.4622770322603174e-005 + 0.4293332099914551 + 1 + <_> + + + + <_>3 12 3 6 -1. + <_>3 14 3 2 3. + 0 + -0.0208586603403091 + 0.1600403934717178 + 0.6782314777374268 + <_> + + <_> + + + + <_>8 13 5 3 -1. + <_>8 14 5 1 3. + 0 + 2.8194559272378683e-003 + 1 + 0.6679294109344482 + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 3.7899368908256292e-003 + 0.4587705135345459 + 0.7176238894462585 + <_> + + <_> + + + + <_>5 1 10 8 -1. + <_>5 1 5 4 2. + <_>10 5 5 4 2. + 0 + 0.0353446416556835 + 1 + 0.1864075064659119 + <_> + + + + <_>6 4 5 4 -1. + <_>6 6 5 2 2. + 0 + -1.1571600334718823e-003 + 0.5538259744644165 + 0.3150450885295868 + <_> + + <_> + + + + <_>1 10 18 1 -1. + <_>7 10 6 1 3. + 0 + -5.8742752298712730e-003 + 0.2828791141510010 + 1 + <_> + + + + <_>11 10 4 3 -1. + <_>11 10 2 3 2. + 0 + -1.5201780115603469e-005 + 0.5870224237442017 + 0.3704823851585388 + <_> + + <_> + + + + <_>5 11 6 1 -1. + <_>7 11 2 1 3. + 0 + -2.2681879636365920e-004 + 1 + 0.4218930900096893 + <_> + + + + <_>3 13 2 3 -1. + <_>3 14 2 1 3. + 0 + 3.7845689803361893e-003 + 0.6667001247406006 + 0.2461182028055191 + <_> + + <_> + + + + <_>12 12 3 4 -1. + <_>12 14 3 2 2. + 0 + -8.5295992903411388e-005 + 1 + 0.3557587862014771 + <_> + + + + <_>11 10 5 6 -1. + <_>11 12 5 2 3. + 0 + -0.0443948917090893 + 0.1665547043085098 + 0.5234848856925964 + <_> + + <_> + + + + <_>0 8 16 2 -1. + <_>0 9 16 1 2. + 0 + 1.0126030538231134e-003 + 0.2884612977504730 + 1 + <_> + + + + <_>2 1 3 4 -1. + <_>2 3 3 2 2. + 0 + -7.6327780261635780e-003 + 0.2969340085983276 + 0.6080111265182495 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + 4.0330411866307259e-003 + 0.4536390006542206 + 1 + <_> + + + + <_>5 6 12 6 -1. + <_>9 6 4 6 3. + 0 + 0.1367668956518173 + 0.5177264213562012 + 0.1449182033538818 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>9 7 1 3 3. + 0 + -5.0060478970408440e-003 + 0.7616909742355347 + 1 + <_> + + + + <_>3 6 12 6 -1. + <_>7 6 4 6 3. + 0 + -0.0124758398160338 + 0.2159706056118012 + 0.5460187792778015 + <_> + + <_> + + + + <_>10 5 6 5 -1. + <_>12 5 2 5 3. + 0 + -9.4012258341535926e-004 + 1 + 0.3926295936107636 + <_> + + + + <_>5 7 10 2 -1. + <_>5 7 5 2 2. + 0 + -0.0121919801458716 + 0.3478881120681763 + 0.5542662739753723 + <_> + + <_> + + + + <_>4 5 6 5 -1. + <_>6 5 2 5 3. + 0 + -5.4959481349214911e-004 + 0.6064276099205017 + 1 + <_> + + + + <_>9 3 2 10 -1. + <_>9 8 2 5 2. + 0 + -2.1802430273965001e-004 + 0.5697407126426697 + 0.1779713928699493 + <_> + + <_> + + + + <_>3 1 16 2 -1. + <_>11 1 8 1 2. + <_>3 2 8 1 2. + 0 + 6.9115799851715565e-003 + 0.5379372239112854 + 1 + <_> + + + + <_>9 9 3 2 -1. + <_>9 10 3 1 2. + 0 + -9.7631698008626699e-004 + 0.3327839076519013 + 0.5461531281471252 + <_> + + <_> + + + + <_>1 1 16 2 -1. + <_>1 1 8 1 2. + <_>9 2 8 1 2. + 0 + -8.7870173156261444e-003 + 0.2116160988807678 + 1 + <_> + + + + <_>8 14 1 3 -1. + <_>8 15 1 1 3. + 0 + -1.6761029837653041e-003 + 0.6635823249816895 + 0.4365859031677246 + <_> + + <_> + + + + <_>4 5 12 10 -1. + <_>10 5 6 5 2. + <_>4 10 6 5 2. + 0 + -0.0556949488818645 + 1 + 0.5387424826622009 + <_> + + + + <_>7 13 6 6 -1. + <_>10 13 3 3 2. + <_>7 16 3 3 2. + 0 + -0.0198443792760372 + 0.1602804958820343 + 0.5330458879470825 + <_> + + <_> + + + + <_>8 9 3 2 -1. + <_>8 10 3 1 2. + 0 + -7.4751611100509763e-004 + 0.2917476892471314 + 1 + <_> + + + + <_>7 2 6 4 -1. + <_>9 2 2 4 3. + 0 + 0.0230328906327486 + 0.5608124136924744 + 0.1997981071472168 + <_> + + <_> + + + + <_>6 6 9 3 -1. + <_>6 7 9 1 3. + 0 + -3.0700280331075191e-003 + 1 + 0.3938314020633698 + <_> + + + + <_>10 7 6 1 -1. + <_>12 7 2 1 3. + 0 + -1.1636839481070638e-003 + 0.5757436156272888 + 0.4239456951618195 + <_> + + <_> + + + + <_>0 0 18 6 -1. + <_>6 0 6 6 3. + 0 + 0.2246433943510056 + 1 + 0.7676553130149841 + <_> + + + + <_>6 10 2 6 -1. + <_>6 13 2 3 2. + 0 + 1.4412109740078449e-003 + 0.5353866219520569 + 0.2514776885509491 + <_> + + <_> + + + + <_>11 12 3 6 -1. + <_>11 15 3 3 2. + 0 + -0.0300112497061491 + 0.2364903986454010 + 1 + <_> + + + + <_>4 4 12 12 -1. + <_>10 4 6 6 2. + <_>4 10 6 6 2. + 0 + -0.0530789606273174 + 0.2385863959789276 + 0.5414664745330811 + <_> + + <_> + + + + <_>1 2 3 6 -1. + <_>2 2 1 6 3. + 0 + 2.0800929050892591e-003 + 1 + 0.6511614918708801 + <_> + + + + <_>1 5 3 7 -1. + <_>2 5 1 7 3. + 0 + -4.0738182142376900e-003 + 0.6030414104461670 + 0.3587701022624970 + <_> + + <_> + + + + <_>4 13 12 4 -1. + <_>10 13 6 2 2. + <_>4 15 6 2 2. + 0 + -0.0195293705910444 + 1 + 0.5423592925071716 + <_> + + + + <_>3 3 17 12 -1. + <_>3 9 17 6 2. + 0 + -0.0533094704151154 + 0.2360953986644745 + 0.5401757955551148 + <_> + + <_> + + + + <_>3 3 14 12 -1. + <_>3 3 7 6 2. + <_>10 9 7 6 2. + 0 + -0.0348495617508888 + 0.2836985886096954 + 1 + <_> + + + + <_>2 11 16 9 -1. + <_>2 14 16 3 3. + 0 + -0.1265845000743866 + 0.1813516020774841 + 0.5421046018600464 + <_> + + <_> + + + + <_>9 14 3 6 -1. + <_>9 17 3 3 2. + 0 + 7.3325118137290701e-006 + 0.3980365991592407 + 1 + <_> + + + + <_>8 14 4 6 -1. + <_>10 14 2 3 2. + <_>8 17 2 3 2. + 0 + -0.0118438703939319 + 0.2616384923458099 + 0.5237730145454407 + <_> + + <_> + + + + <_>6 2 6 1 -1. + <_>8 2 2 1 3. + 0 + -4.8470678739249706e-003 + 0.2438108026981354 + 1 + <_> + + + + <_>9 5 2 5 -1. + <_>10 5 1 5 2. + 0 + 8.1693977117538452e-003 + 0.5327146053314209 + 0.8190376758575440 + <_> + + <_> + + + + <_>9 8 3 5 -1. + <_>10 8 1 5 3. + 0 + -6.4716790802776814e-003 + 1 + 0.4679693877696991 + <_> + + + + <_>9 12 6 1 -1. + <_>9 12 3 1 2. + 0 + -1.5188479665084742e-005 + 0.5563911795616150 + 0.4367586076259613 + <_> + + <_> + + + + <_>8 8 3 5 -1. + <_>9 8 1 5 3. + 0 + 3.0696711037307978e-003 + 1 + 0.6664348840713501 + <_> + + + + <_>6 10 4 3 -1. + <_>8 10 2 3 2. + 0 + -1.6296720423270017e-004 + 0.5594611167907715 + 0.3042711913585663 + 14.5467500686645510 + 5 + -1 + <_> + + + <_> + + <_> + + + + <_>0 4 20 6 -1. + <_>0 6 20 2 3. + 0 + -9.8275858908891678e-003 + 1 + 0.2116018980741501 + <_> + + + + <_>1 3 8 6 -1. + <_>1 3 4 3 2. + <_>5 6 4 3 2. + 0 + -4.1693858802318573e-003 + 0.6924685239791870 + 0.3043777048587799 + <_> + + <_> + + + + <_>7 15 6 4 -1. + <_>7 17 6 2 2. + 0 + 3.5341319744475186e-004 + 0.3183285892009735 + 1 + <_> + + + + <_>3 10 14 10 -1. + <_>3 15 14 5 2. + 0 + 4.8054549843072891e-003 + 0.5456559062004089 + 0.2522268891334534 + <_> + + <_> + + + + <_>6 4 4 4 -1. + <_>8 4 2 4 2. + 0 + 2.1071180526632816e-004 + 0.2902618050575256 + 1 + <_> + + + + <_>0 4 20 10 -1. + <_>0 9 20 5 2. + 0 + -2.8318869881331921e-003 + 0.3130455911159515 + 0.6884937286376953 + <_> + + <_> + + + + <_>9 4 2 14 -1. + <_>9 11 2 7 2. + 0 + -7.5633679443853907e-006 + 1 + 0.2962465882301331 + <_> + + + + <_>2 0 16 4 -1. + <_>2 2 16 2 2. + 0 + -8.2888139877468348e-004 + 0.3099626004695892 + 0.5752515196800232 + <_> + + <_> + + + + <_>4 12 6 8 -1. + <_>4 12 3 4 2. + <_>7 16 3 4 2. + 0 + 1.6209259629249573e-003 + 0.3993195891380310 + 1 + <_> + + + + <_>0 5 6 7 -1. + <_>3 5 3 7 2. + 0 + 9.1338958591222763e-003 + 0.4827372133731842 + 0.7537832856178284 + <_> + + <_> + + + + <_>10 7 10 4 -1. + <_>15 7 5 2 2. + <_>10 9 5 2 2. + 0 + -4.1212290525436401e-003 + 0.2616927027702332 + 1 + <_> + + + + <_>5 8 12 1 -1. + <_>9 8 4 1 3. + 0 + -2.5447290390729904e-003 + 0.3108702898025513 + 0.5491235852241516 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -6.2652782071381807e-004 + 0.3239691853523254 + 1 + <_> + + + + <_>9 4 2 4 -1. + <_>9 6 2 2 2. + 0 + -3.6596331483451650e-005 + 0.6517410874366760 + 0.4178912043571472 + <_> + + <_> + + + + <_>9 6 3 6 -1. + <_>10 6 1 6 3. + 0 + 0.0138827199116349 + 1 + 0.6771203875541687 + <_> + + + + <_>12 7 6 4 -1. + <_>15 7 3 2 2. + <_>12 9 3 2 2. + 0 + 1.0493700392544270e-003 + 0.4159511029720306 + 0.5652891993522644 + <_> + + <_> + + + + <_>8 6 3 6 -1. + <_>9 6 1 6 3. + 0 + 0.0182153601199389 + 1 + 0.7689601182937622 + <_> + + + + <_>1 6 18 6 -1. + <_>1 6 9 3 2. + <_>10 9 9 3 2. + 0 + -0.0113345803692937 + 0.2873323857784271 + 0.4988932907581329 + <_> + + <_> + + + + <_>9 1 3 3 -1. + <_>10 1 1 3 3. + 0 + -4.1097560897469521e-003 + 1 + 0.5463008284568787 + <_> + + + + <_>10 8 5 2 -1. + <_>10 9 5 1 2. + 0 + 4.2612891411408782e-004 + 0.3631235063076019 + 0.5512552261352539 + <_> + + <_> + + + + <_>8 1 3 3 -1. + <_>9 1 1 3 3. + 0 + 6.0301548801362514e-003 + 1 + 0.1143767014145851 + <_> + + + + <_>5 8 5 2 -1. + <_>5 9 5 1 2. + 0 + 3.3587709185667336e-004 + 0.2891078889369965 + 0.5447341799736023 + <_> + + <_> + + + + <_>8 6 8 8 -1. + <_>12 6 4 4 2. + <_>8 10 4 4 2. + 0 + 6.2279507983475924e-004 + 1 + 0.3023431897163391 + <_> + + + + <_>5 7 10 2 -1. + <_>5 7 5 2 2. + 0 + -0.0258371196687222 + 0.2167005985975266 + 0.5278152823448181 + <_> + + <_> + + + + <_>4 5 12 10 -1. + <_>4 5 6 5 2. + <_>10 10 6 5 2. + 0 + 0.0217749103903770 + 1 + 0.3254834115505219 + <_> + + + + <_>5 5 2 3 -1. + <_>5 6 2 1 3. + 0 + 1.7682299949228764e-003 + 0.5263050794601440 + 0.7526329159736633 + <_> + + <_> + + + + <_>7 14 6 3 -1. + <_>7 15 6 1 3. + 0 + -0.0137938102707267 + 0.7410330176353455 + 1 + <_> + + + + <_>9 14 3 3 -1. + <_>9 15 3 1 3. + 0 + -5.0852829590439796e-003 + 0.6836609840393066 + 0.4579071104526520 + <_> + + <_> + + + + <_>8 14 3 3 -1. + <_>8 15 3 1 3. + 0 + 6.1795017682015896e-003 + 1 + 0.7449936270713806 + <_> + + + + <_>1 10 8 9 -1. + <_>1 13 8 3 3. + 0 + 0.0100303199142218 + 0.4860779941082001 + 0.2361457049846649 + <_> + + <_> + + + + <_>9 7 2 3 -1. + <_>9 8 2 1 3. + 0 + -6.4201927743852139e-003 + 0.1467327028512955 + 1 + <_> + + + + <_>12 3 3 3 -1. + <_>13 3 1 3 3. + 0 + -5.6961281225085258e-003 + 0.2347819954156876 + 0.5323377251625061 + <_> + + <_> + + + + <_>5 3 3 3 -1. + <_>6 3 1 3 3. + 0 + -7.1498160250484943e-003 + 0.1477057039737701 + 1 + <_> + + + + <_>5 6 2 12 -1. + <_>5 10 2 4 3. + 0 + 2.4450740311294794e-003 + 0.3498533964157105 + 0.5803561806678772 + <_> + + <_> + + + + <_>1 11 18 4 -1. + <_>10 11 9 2 2. + <_>1 13 9 2 2. + 0 + -0.0375034101307392 + 1 + 0.5259550809860230 + <_> + + + + <_>7 12 6 2 -1. + <_>7 13 6 1 2. + 0 + 4.7799441381357610e-004 + 0.4362882971763611 + 0.6208922863006592 + <_> + + <_> + + + + <_>6 0 3 6 -1. + <_>7 0 1 6 3. + 0 + -7.0806080475449562e-003 + 0.2039460986852646 + 1 + <_> + + + + <_>0 11 18 4 -1. + <_>0 11 9 2 2. + <_>9 13 9 2 2. + 0 + 0.0328180007636547 + 0.5198358893394470 + 0.1371196061372757 + <_> + + <_> + + + + <_>7 12 6 2 -1. + <_>7 13 6 1 2. + 0 + 6.5188988810405135e-004 + 1 + 0.6323429942131043 + <_> + + + + <_>9 12 3 3 -1. + <_>9 13 3 1 3. + 0 + 4.6485587954521179e-003 + 0.4720163047313690 + 0.6567087173461914 + <_> + + <_> + + + + <_>9 12 2 3 -1. + <_>9 13 2 1 3. + 0 + -1.9827929791063070e-003 + 0.6053060293197632 + 1 + <_> + + + + <_>8 11 4 3 -1. + <_>8 12 4 1 3. + 0 + -1.6011310508474708e-003 + 0.5090519189834595 + 0.3116933107376099 + <_> + + <_> + + + + <_>13 3 4 2 -1. + <_>13 4 4 1 2. + 0 + -3.0539939180016518e-003 + 0.3429804146289825 + 1 + <_> + + + + <_>4 0 12 2 -1. + <_>4 1 12 1 2. + 0 + 4.3212040327489376e-004 + 0.3838402926921845 + 0.5775598287582398 + <_> + + <_> + + + + <_>6 9 8 8 -1. + <_>6 9 4 4 2. + <_>10 13 4 4 2. + 0 + -0.0274521205574274 + 0.2143469005823135 + 1 + <_> + + + + <_>1 11 6 2 -1. + <_>1 12 6 1 2. + 0 + 9.3099439982324839e-004 + 0.5952966213226318 + 0.3760158121585846 + <_> + + <_> + + + + <_>2 5 18 8 -1. + <_>11 5 9 4 2. + <_>2 9 9 4 2. + 0 + 6.7144189961254597e-003 + 0.5692626833915710 + 1 + <_> + + + + <_>7 1 6 10 -1. + <_>7 6 6 5 2. + 0 + -3.3701690845191479e-003 + 0.5784304141998291 + 0.3974282145500183 + <_> + + <_> + + + + <_>0 3 3 6 -1. + <_>0 5 3 2 3. + 0 + -0.0189039595425129 + 0.1818892955780029 + 1 + <_> + + + + <_>4 5 4 3 -1. + <_>4 6 4 1 3. + 0 + -6.5850871615111828e-003 + 0.6849110126495361 + 0.4351584017276764 + <_> + + <_> + + + + <_>19 3 1 6 -1. + <_>19 5 1 2 3. + 0 + 5.8810501359403133e-003 + 1 + 0.2726660966873169 + <_> + + + + <_>6 15 8 2 -1. + <_>6 16 8 1 2. + 0 + 8.0092082498595119e-004 + 0.4236431121826172 + 0.5844675898551941 + <_> + + <_> + + + + <_>0 3 1 6 -1. + <_>0 5 1 2 3. + 0 + 1.8510579830035567e-003 + 1 + 0.3371320962905884 + <_> + + + + <_>5 5 3 3 -1. + <_>5 6 3 1 3. + 0 + 6.3273650594055653e-003 + 0.5270221829414368 + 0.8053650856018066 + <_> + + <_> + + + + <_>8 8 4 3 -1. + <_>8 9 4 1 3. + 0 + -3.3820930402725935e-003 + 0.2866018116474152 + 1 + <_> + + + + <_>10 6 6 3 -1. + <_>12 6 2 3 3. + 0 + -1.9292969955131412e-003 + 0.5888946056365967 + 0.3895787000656128 + <_> + + <_> + + + + <_>8 13 2 6 -1. + <_>8 16 2 3 2. + 0 + 0.0149952201172709 + 1 + 0.2177816927433014 + <_> + + + + <_>9 11 2 8 -1. + <_>9 15 2 4 2. + 0 + -0.0263307504355907 + 0.1775317043066025 + 0.5671470165252686 + <_> + + <_> + + + + <_>10 6 6 3 -1. + <_>12 6 2 3 3. + 0 + -4.1734222322702408e-003 + 1 + 0.4652962088584900 + <_> + + + + <_>5 15 15 5 -1. + <_>10 15 5 5 3. + 0 + 0.0272683501243591 + 0.4768311083316803 + 0.5695238709449768 + <_> + + <_> + + + + <_>2 14 2 2 -1. + <_>2 15 2 1 2. + 0 + 9.8880263976752758e-004 + 1 + 0.3397401869297028 + <_> + + + + <_>4 7 6 2 -1. + <_>6 7 2 2 3. + 0 + -1.0528849670663476e-003 + 0.6250041127204895 + 0.4288412034511566 + <_> + + <_> + + + + <_>8 3 6 1 -1. + <_>10 3 2 1 3. + 0 + 5.2288072183728218e-003 + 0.5347762107849121 + 1 + <_> + + + + <_>1 0 18 12 -1. + <_>7 0 6 12 3. + 0 + 0.0303954593837261 + 0.4115518927574158 + 0.5660753846168518 + <_> + + <_> + + + + <_>0 14 8 6 -1. + <_>4 14 4 6 2. + 0 + -0.0791139304637909 + 0.7881323099136353 + 1 + <_> + + + + <_>0 15 15 5 -1. + <_>5 15 5 5 3. + 0 + 0.0182316694408655 + 0.3604339957237244 + 0.5569505095481873 + <_> + + <_> + + + + <_>8 3 6 1 -1. + <_>10 3 2 1 3. + 0 + 5.2288072183728218e-003 + 0.5416644215583801 + 1 + <_> + + + + <_>11 11 3 6 -1. + <_>11 14 3 3 2. + 0 + 4.3922828626818955e-004 + 0.5507156848907471 + 0.3882277011871338 + <_> + + <_> + + + + <_>6 3 6 1 -1. + <_>8 3 2 1 3. + 0 + -8.6501962505280972e-004 + 0.3185850977897644 + 1 + <_> + + + + <_>6 11 3 6 -1. + <_>6 14 3 3 2. + 0 + 1.0326979681849480e-003 + 0.5578364133834839 + 0.3219245970249176 + <_> + + <_> + + + + <_>9 6 3 4 -1. + <_>10 6 1 4 3. + 0 + -7.2997747920453548e-003 + 0.7073233127593994 + 1 + <_> + + + + <_>12 10 4 7 -1. + <_>12 10 2 7 2. + 0 + -9.3629042385146022e-004 + 0.5558015704154968 + 0.4613842070102692 + <_> + + <_> + + + + <_>8 6 3 4 -1. + <_>9 6 1 4 3. + 0 + -6.0483231209218502e-003 + 0.6869289875030518 + 1 + <_> + + + + <_>4 6 4 7 -1. + <_>6 6 2 7 2. + 0 + 6.7529221996665001e-003 + 0.4870317876338959 + 0.2650370895862579 + <_> + + <_> + + + + <_>10 3 4 12 -1. + <_>10 3 2 12 2. + 0 + 0.0530780293047428 + 0.5281515121459961 + 1 + <_> + + + + <_>10 8 3 4 -1. + <_>11 8 1 4 3. + 0 + -1.0225810110569000e-003 + 0.6085882186889648 + 0.4304867982864380 + <_> + + <_> + + + + <_>1 0 18 14 -1. + <_>7 0 6 14 3. + 0 + 0.0312706492841244 + 1 + 0.5445832014083862 + <_> + + + + <_>2 8 6 11 -1. + <_>5 8 3 11 2. + 0 + -6.3522169366478920e-003 + 0.5328335762023926 + 0.2364324033260346 + 18.5722503662109380 + 6 + -1 + <_> + + + <_> + + <_> + + + + <_>1 4 15 4 -1. + <_>1 6 15 2 2. + 0 + -6.2215630896389484e-003 + 1 + 0.2625581026077271 + <_> + + + + <_>5 5 10 8 -1. + <_>5 9 10 4 2. + 0 + 2.1097389981150627e-003 + 0.1564992964267731 + 0.6792883276939392 + <_> + + <_> + + + + <_>14 2 6 8 -1. + <_>14 2 3 8 2. + 0 + 0.0108458595350385 + 0.3485808968544006 + 1 + <_> + + + + <_>11 6 6 14 -1. + <_>14 6 3 7 2. + <_>11 13 3 7 2. + 0 + 6.4230401767417789e-004 + 0.3698255121707916 + 0.5921658277511597 + <_> + + <_> + + + + <_>9 5 2 12 -1. + <_>9 11 2 6 2. + 0 + 7.3311722371727228e-004 + 1 + 0.3007084131240845 + <_> + + + + <_>3 7 4 6 -1. + <_>3 9 4 2 3. + 0 + 1.0134200565516949e-003 + 0.3624922931194305 + 0.7072426080703735 + <_> + + <_> + + + + <_>14 3 6 6 -1. + <_>14 3 3 6 2. + 0 + 0.0110935596749187 + 0.4416702091693878 + 1 + <_> + + + + <_>15 2 4 4 -1. + <_>15 4 4 2 2. + 0 + -7.9127531498670578e-003 + 0.3028708100318909 + 0.5417376160621643 + <_> + + <_> + + + + <_>0 2 6 7 -1. + <_>3 2 3 7 2. + 0 + 0.0129053099080920 + 0.4374504089355469 + 1 + <_> + + + + <_>3 6 6 14 -1. + <_>3 6 3 7 2. + <_>6 13 3 7 2. + 0 + -4.2430912144482136e-003 + 0.4401589930057526 + 0.7565190792083740 + <_> + + <_> + + + + <_>4 6 16 8 -1. + <_>4 10 16 4 2. + 0 + -2.1304309484548867e-004 + 0.2310786992311478 + 1 + <_> + + + + <_>10 12 2 8 -1. + <_>10 16 2 4 2. + 0 + -2.2308640182018280e-003 + 0.3568195998668671 + 0.5749999284744263 + <_> + + <_> + + + + <_>7 0 6 20 -1. + <_>9 0 2 20 3. + 0 + 2.6400520000606775e-003 + 0.3593688905239105 + 1 + <_> + + + + <_>1 7 16 12 -1. + <_>1 7 8 6 2. + <_>9 13 8 6 2. + 0 + 0.0751010328531265 + 0.6363567709922791 + 0.2327028959989548 + <_> + + <_> + + + + <_>9 11 3 3 -1. + <_>9 12 3 1 3. + 0 + -7.7012968249619007e-003 + 0.7074623703956604 + 1 + <_> + + + + <_>11 9 4 5 -1. + <_>11 9 2 5 2. + 0 + 1.5588370151817799e-003 + 0.5700237154960632 + 0.3590450882911682 + <_> + + <_> + + + + <_>3 3 1 2 -1. + <_>3 4 1 1 2. + 0 + -4.7687938786111772e-004 + 0.2805441021919251 + 1 + <_> + + + + <_>7 17 5 3 -1. + <_>7 18 5 1 3. + 0 + 8.4234727546572685e-004 + 0.4125418961048126 + 0.6177995800971985 + <_> + + <_> + + + + <_>8 12 4 8 -1. + <_>10 12 2 4 2. + <_>8 16 2 4 2. + 0 + -0.0128251099959016 + 1 + 0.5403078198432922 + <_> + + + + <_>7 4 10 12 -1. + <_>12 4 5 6 2. + <_>7 10 5 6 2. + 0 + -6.5156567143276334e-004 + 0.5633643865585327 + 0.3356539011001587 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + -0.0120061598718166 + 0.7109510898590088 + 1 + <_> + + + + <_>5 9 4 5 -1. + <_>7 9 2 5 2. + 0 + 1.3213419588282704e-003 + 0.4903850853443146 + 0.2824583053588867 + <_> + + <_> + + + + <_>9 9 8 2 -1. + <_>9 9 4 2 2. + 0 + -0.0203074403107166 + 0.1891369968652725 + 1 + <_> + + + + <_>14 15 5 2 -1. + <_>14 16 5 1 2. + 0 + 4.0180929936468601e-003 + 0.5377966165542603 + 0.3119494915008545 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 4.5315311290323734e-003 + 1 + 0.7206758260726929 + <_> + + + + <_>1 7 8 4 -1. + <_>1 7 4 2 2. + <_>5 9 4 2 2. + 0 + -4.4381739571690559e-003 + 0.1854667961597443 + 0.4981732964515686 + <_> + + <_> + + + + <_>19 3 1 2 -1. + <_>19 4 1 1 2. + 0 + 1.5692010056227446e-003 + 1 + 0.2638274133205414 + <_> + + + + <_>9 12 2 3 -1. + <_>9 13 2 1 3. + 0 + -4.9516442231833935e-003 + 0.6871067285537720 + 0.4714686870574951 + <_> + + <_> + + + + <_>3 14 14 4 -1. + <_>3 14 7 2 2. + <_>10 16 7 2 2. + 0 + -0.0274296794086695 + 0.1548285037279129 + 1 + <_> + + + + <_>5 0 10 2 -1. + <_>5 1 10 1 2. + 0 + 1.4181969454512000e-003 + 0.4376842975616455 + 0.6327368021011353 + <_> + + <_> + + + + <_>11 14 4 6 -1. + <_>11 16 4 2 3. + 0 + -0.0130789401009679 + 0.3166814148426056 + 1 + <_> + + + + <_>7 14 6 3 -1. + <_>7 15 6 1 3. + 0 + -3.5092779435217381e-003 + 0.6199743747711182 + 0.4379687011241913 + <_> + + <_> + + + + <_>7 13 6 6 -1. + <_>7 13 3 3 2. + <_>10 16 3 3 2. + 0 + 0.0189207307994366 + 1 + 0.1470714062452316 + <_> + + + + <_>0 2 1 6 -1. + <_>0 4 1 2 3. + 0 + 2.1683350205421448e-003 + 0.5809459090232849 + 0.3431949019432068 + <_> + + <_> + + + + <_>6 7 8 2 -1. + <_>6 8 8 1 2. + 0 + 1.6401590546593070e-003 + 0.3959457874298096 + 1 + <_> + + + + <_>9 7 6 1 -1. + <_>9 7 3 1 2. + 0 + 1.4005920093040913e-004 + 0.3240025043487549 + 0.5646647214889526 + <_> + + <_> + + + + <_>7 1 6 10 -1. + <_>7 6 6 5 2. + 0 + -3.3137591090053320e-003 + 1 + 0.4274528026580811 + <_> + + + + <_>0 2 6 2 -1. + <_>0 3 6 1 2. + 0 + -2.9459029901772738e-003 + 0.3341667950153351 + 0.6627960205078125 + <_> + + <_> + + + + <_>11 4 2 4 -1. + <_>11 4 1 4 2. + 0 + 1.3612229668069631e-004 + 0.4046927988529205 + 1 + <_> + + + + <_>11 10 3 6 -1. + <_>11 13 3 3 2. + 0 + 6.0512032359838486e-004 + 0.5484058260917664 + 0.3569940924644470 + <_> + + <_> + + + + <_>3 9 8 2 -1. + <_>7 9 4 2 2. + 0 + -0.0175139904022217 + 0.1824150979518890 + 1 + <_> + + + + <_>0 0 4 6 -1. + <_>2 0 2 6 2. + 0 + -0.0187350306659937 + 0.7971820235252380 + 0.5068569183349609 + <_> + + <_> + + + + <_>7 0 6 2 -1. + <_>9 0 2 2 3. + 0 + 0.0120656499639153 + 1 + 0.2167007029056549 + <_> + + + + <_>9 15 2 3 -1. + <_>9 16 2 1 3. + 0 + -2.6544178836047649e-003 + 0.6584178805351257 + 0.4628243148326874 + <_> + + <_> + + + + <_>3 12 1 2 -1. + <_>3 13 1 1 2. + 0 + 1.4501289697363973e-003 + 1 + 0.2090252041816711 + <_> + + + + <_>4 5 11 3 -1. + <_>4 6 11 1 3. + 0 + 0.0109540196135640 + 0.5112305283546448 + 0.7784575819969177 + <_> + + <_> + + + + <_>11 4 2 4 -1. + <_>11 4 1 4 2. + 0 + 0.0157717093825340 + 0.5132359266281128 + 1 + <_> + + + + <_>8 3 6 3 -1. + <_>10 3 2 3 3. + 0 + -0.0142526896670461 + 0.1742414981126785 + 0.5267148017883301 + <_> + + <_> + + + + <_>7 4 2 4 -1. + <_>8 4 1 4 2. + 0 + 3.0411860279855318e-005 + 0.3418447971343994 + 1 + <_> + + + + <_>6 3 6 3 -1. + <_>8 3 2 3 3. + 0 + 0.0234862994402647 + 0.5631265044212341 + 0.2006393969058991 + <_> + + <_> + + + + <_>11 4 4 3 -1. + <_>11 5 4 1 3. + 0 + 5.2205449901521206e-003 + 1 + 0.6249648928642273 + <_> + + + + <_>11 8 2 8 -1. + <_>11 12 2 4 2. + 0 + -0.0258124303072691 + 0.3203228116035461 + 0.5199329853057861 + <_> + + <_> + + + + <_>8 7 3 5 -1. + <_>9 7 1 5 3. + 0 + -1.9526650430634618e-003 + 0.6140705943107605 + 1 + <_> + + + + <_>9 7 2 5 -1. + <_>10 7 1 5 2. + 0 + -8.1470049917697906e-003 + 0.6592895984649658 + 0.3711124956607819 + <_> + + <_> + + + + <_>14 11 1 6 -1. + <_>14 13 1 2 3. + 0 + 3.2962448894977570e-003 + 1 + 0.2952111959457398 + <_> + + + + <_>8 8 4 3 -1. + <_>8 9 4 1 3. + 0 + -1.3961310032755136e-003 + 0.3320803940296173 + 0.5528414845466614 + <_> + + <_> + + + + <_>0 3 2 2 -1. + <_>0 4 2 1 2. + 0 + -4.1055441834032536e-003 + 0.1710550040006638 + 1 + <_> + + + + <_>4 14 5 6 -1. + <_>4 16 5 2 3. + 0 + -0.0108887795358896 + 0.3359434902667999 + 0.5674905180931091 + <_> + + <_> + + + + <_>11 4 4 3 -1. + <_>11 5 4 1 3. + 0 + -7.6768421567976475e-003 + 1 + 0.4773241877555847 + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -9.7729787230491638e-003 + 0.8081045150756836 + 0.4845828115940094 + <_> + + <_> + + + + <_>5 4 4 3 -1. + <_>5 5 4 1 3. + 0 + 6.0439710505306721e-003 + 1 + 0.6784002184867859 + <_> + + + + <_>5 15 4 2 -1. + <_>7 15 2 2 2. + 0 + -4.6134641161188483e-004 + 0.5514639019966126 + 0.3642359972000122 + <_> + + <_> + + + + <_>15 1 5 9 -1. + <_>15 4 5 3 3. + 0 + 0.0579923614859581 + 1 + 0.1254435032606125 + <_> + + + + <_>9 10 3 3 -1. + <_>9 11 3 1 3. + 0 + 5.9384980704635382e-004 + 0.4424878954887390 + 0.5728461742401123 + <_> + + <_> + + + + <_>1 6 2 6 -1. + <_>1 8 2 2 3. + 0 + -6.2353480607271194e-003 + 0.2805041968822479 + 1 + <_> + + + + <_>2 4 8 15 -1. + <_>2 9 8 5 3. + 0 + -0.0127849299460649 + 0.1950912028551102 + 0.5652924776077271 + <_> + + <_> + + + + <_>9 12 3 2 -1. + <_>9 13 3 1 2. + 0 + 4.1973669431172311e-004 + 1 + 0.6166483759880066 + <_> + + + + <_>9 12 3 3 -1. + <_>9 13 3 1 3. + 0 + 8.0646801507100463e-004 + 0.4526579976081848 + 0.5944486856460571 + <_> + + <_> + + + + <_>7 6 3 5 -1. + <_>8 6 1 5 3. + 0 + -1.6339010326191783e-003 + 1 + 0.4086942076683044 + <_> + + + + <_>5 3 6 2 -1. + <_>7 3 2 2 3. + 0 + -4.8299999907612801e-003 + 0.2793526947498322 + 0.6444935202598572 + <_> + + <_> + + + + <_>6 1 8 10 -1. + <_>10 1 4 5 2. + <_>6 6 4 5 2. + 0 + -6.3992068171501160e-003 + 1 + 0.5671656131744385 + <_> + + + + <_>0 0 20 10 -1. + <_>10 0 10 5 2. + <_>0 5 10 5 2. + 0 + 0.1081919968128204 + 0.5311812162399292 + 0.2614356875419617 + <_> + + <_> + + + + <_>6 3 3 1 -1. + <_>7 3 1 1 3. + 0 + 6.5056560561060905e-004 + 1 + 0.2996774017810822 + <_> + + + + <_>0 2 6 8 -1. + <_>2 2 2 8 3. + 0 + 0.0206112507730722 + 0.4489943087100983 + 0.6888279914855957 + <_> + + <_> + + + + <_>11 10 3 4 -1. + <_>11 12 3 2 2. + 0 + -0.0251290500164032 + 1 + 0.5196864008903503 + <_> + + + + <_>12 6 3 8 -1. + <_>12 10 3 4 2. + 0 + 1.7922939732670784e-003 + 0.3466995954513550 + 0.5533587932586670 + <_> + + <_> + + + + <_>6 10 3 4 -1. + <_>6 12 3 2 2. + 0 + 1.5626220265403390e-003 + 1 + 0.3081440031528473 + <_> + + + + <_>5 6 3 8 -1. + <_>5 10 3 4 2. + 0 + -6.1898730928078294e-004 + 0.2693870961666107 + 0.5544489026069641 + <_> + + <_> + + + + <_>2 6 18 6 -1. + <_>11 6 9 3 2. + <_>2 9 9 3 2. + 0 + 4.8111421056091785e-003 + 0.5587847828865051 + 1 + <_> + + + + <_>7 14 7 3 -1. + <_>7 15 7 1 3. + 0 + 2.2484229411929846e-003 + 0.4672113060951233 + 0.6090825200080872 + <_> + + <_> + + + + <_>0 0 2 12 -1. + <_>1 0 1 12 2. + 0 + -0.0301472395658493 + 0.9027591943740845 + 1 + <_> + + + + <_>1 2 18 16 -1. + <_>1 10 18 8 2. + 0 + 0.2754867970943451 + 0.4719834923744202 + 0.2196920067071915 + <_> + + <_> + + + + <_>9 13 5 3 -1. + <_>9 14 5 1 3. + 0 + 3.6894630175083876e-003 + 1 + 0.6273009181022644 + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 7.2957701049745083e-003 + 0.4839217960834503 + 0.6909062266349793 + <_> + + <_> + + + + <_>0 6 18 6 -1. + <_>0 6 9 3 2. + <_>9 9 9 3 2. + 0 + -0.0562110692262650 + 0.1738487929105759 + 1 + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + -2.6478560175746679e-003 + 0.6304144859313965 + 0.4474301934242249 + <_> + + <_> + + + + <_>17 4 1 3 -1. + <_>17 5 1 1 3. + 0 + -1.4534000074490905e-003 + 1 + 0.5302538275718689 + <_> + + + + <_>12 11 1 9 -1. + <_>12 14 1 3 3. + 0 + 2.8540920466184616e-003 + 0.5338397026062012 + 0.3796882927417755 + <_> + + <_> + + + + <_>2 4 1 3 -1. + <_>2 5 1 1 3. + 0 + 5.8243022067472339e-004 + 1 + 0.3269836902618408 + <_> + + + + <_>5 4 2 3 -1. + <_>5 5 2 1 3. + 0 + 9.2509482055902481e-004 + 0.4554812014102936 + 0.6358348131179810 + 21.5781192779541020 + 7 + -1 + <_> + + + <_> + + <_> + + + + <_>1 2 18 3 -1. + <_>7 2 6 3 3. + 0 + 0.0198064409196377 + 0.2809725105762482 + 1 + <_> + + + + <_>0 1 20 6 -1. + <_>0 3 20 2 3. + 0 + 7.0395611692219973e-004 + 0.3119826018810272 + 0.7090306282043457 + <_> + + <_> + + + + <_>7 5 6 3 -1. + <_>9 5 2 3 3. + 0 + 2.5563780218362808e-003 + 0.2981947958469391 + 1 + <_> + + + + <_>13 7 6 4 -1. + <_>16 7 3 2 2. + <_>13 9 3 2 2. + 0 + 1.0824160417541862e-003 + 0.3020560145378113 + 0.5808811187744141 + <_> + + <_> + + + + <_>3 1 4 10 -1. + <_>3 1 2 5 2. + <_>5 6 2 5 2. + 0 + -9.2893769033253193e-004 + 1 + 0.3738102912902832 + <_> + + + + <_>0 4 19 10 -1. + <_>0 9 19 5 2. + 0 + -0.0180097296833992 + 0.2163126021623612 + 0.6619253754615784 + <_> + + <_> + + + + <_>9 8 3 12 -1. + <_>9 12 3 4 3. + 0 + 2.3500190582126379e-003 + 1 + 0.2910403907299042 + <_> + + + + <_>11 18 5 2 -1. + <_>11 19 5 1 2. + 0 + 8.1822491483762860e-004 + 0.5578622817993164 + 0.3366627991199493 + <_> + + <_> + + + + <_>5 16 6 4 -1. + <_>5 16 3 2 2. + <_>8 18 3 2 2. + 0 + 6.2095321482047439e-004 + 0.4072425961494446 + 1 + <_> + + + + <_>5 18 3 2 -1. + <_>5 19 3 1 2. + 0 + 9.6780969761312008e-004 + 0.6859595775604248 + 0.3105461895465851 + <_> + + <_> + + + + <_>13 11 3 2 -1. + <_>13 12 3 1 2. + 0 + 4.8000211245380342e-004 + 1 + 0.3337332904338837 + <_> + + + + <_>8 5 8 4 -1. + <_>8 5 4 4 2. + 0 + 9.0538640506565571e-005 + 0.3370958864688873 + 0.5451210737228394 + <_> + + <_> + + + + <_>1 2 18 6 -1. + <_>1 2 9 3 2. + <_>10 5 9 3 2. + 0 + -0.0439147986471653 + 0.2625670135021210 + 1 + <_> + + + + <_>3 5 14 6 -1. + <_>3 7 14 2 3. + 0 + -5.6501338258385658e-003 + 0.6050462722778320 + 0.3232415020465851 + <_> + + <_> + + + + <_>18 1 2 6 -1. + <_>18 3 2 2 3. + 0 + 3.8661491125822067e-003 + 1 + 0.3262613117694855 + <_> + + + + <_>9 11 6 1 -1. + <_>11 11 2 1 3. + 0 + -6.3069426687434316e-005 + 0.5817307829856873 + 0.4164389967918396 + <_> + + <_> + + + + <_>0 2 6 11 -1. + <_>3 2 3 11 2. + 0 + 0.0525337383151054 + 1 + 0.7095398902893066 + <_> + + + + <_>4 12 2 3 -1. + <_>4 13 2 1 3. + 0 + 1.3818660518154502e-003 + 0.5292875766754150 + 0.2541388869285584 + <_> + + <_> + + + + <_>6 12 9 2 -1. + <_>9 12 3 2 3. + 0 + -8.9264067355543375e-004 + 1 + 0.4085341095924377 + <_> + + + + <_>9 4 6 15 -1. + <_>9 4 3 15 2. + 0 + 0.0855795070528984 + 0.5263236165046692 + 0.3003202974796295 + <_> + + <_> + + + + <_>5 11 6 1 -1. + <_>7 11 2 1 3. + 0 + -1.8343339615967125e-004 + 1 + 0.4029205143451691 + <_> + + + + <_>5 4 6 15 -1. + <_>8 4 3 15 2. + 0 + -9.7924815490841866e-003 + 0.3521319925785065 + 0.6664004921913147 + <_> + + <_> + + + + <_>14 12 6 7 -1. + <_>14 12 3 7 2. + 0 + 0.0144286202266812 + 0.4593566060066223 + 1 + <_> + + + + <_>18 3 2 9 -1. + <_>18 6 2 3 3. + 0 + -0.0456870011985302 + 0.1474756002426148 + 0.5178632140159607 + <_> + + <_> + + + + <_>8 1 3 1 -1. + <_>9 1 1 1 3. + 0 + -2.5763090234249830e-003 + 0.1837278008460999 + 1 + <_> + + + + <_>0 12 6 7 -1. + <_>3 12 3 7 2. + 0 + -0.0383018590509892 + 0.8082658052444458 + 0.5166687965393066 + <_> + + <_> + + + + <_>13 7 6 4 -1. + <_>16 7 3 2 2. + <_>13 9 3 2 2. + 0 + 2.8978290501981974e-003 + 0.4798013865947723 + 1 + <_> + + + + <_>8 0 10 2 -1. + <_>8 1 10 1 2. + 0 + -2.5165060069411993e-003 + 0.3346295952796936 + 0.5444449186325073 + <_> + + <_> + + + + <_>1 7 6 4 -1. + <_>1 7 3 2 2. + <_>4 9 3 2 2. + 0 + 5.6281982688233256e-004 + 0.3589026927947998 + 1 + <_> + + + + <_>1 2 3 3 -1. + <_>1 3 3 1 3. + 0 + 3.6684391088783741e-003 + 0.5983129739761353 + 0.2983964085578919 + <_> + + <_> + + + + <_>9 13 4 3 -1. + <_>9 14 4 1 3. + 0 + 2.1319789811968803e-003 + 1 + 0.6163223981857300 + <_> + + + + <_>12 13 7 2 -1. + <_>12 14 7 1 2. + 0 + 7.6037310063838959e-003 + 0.5217130184173584 + 0.2054159045219421 + <_> + + <_> + + + + <_>5 12 9 2 -1. + <_>8 12 3 2 3. + 0 + -1.1668079969240353e-004 + 1 + 0.3446668982505798 + <_> + + + + <_>6 10 4 8 -1. + <_>6 14 4 4 2. + 0 + 3.1659509986639023e-003 + 0.5597484707832336 + 0.2673786878585815 + <_> + + <_> + + + + <_>1 0 18 4 -1. + <_>7 0 6 4 3. + 0 + -0.0225694999098778 + 0.6900268197059631 + 1 + <_> + + + + <_>12 0 5 2 -1. + <_>12 1 5 1 2. + 0 + 2.7129601221531630e-004 + 0.4486638903617859 + 0.5508785247802734 + <_> + + <_> + + + + <_>7 7 1 12 -1. + <_>7 13 1 6 2. + 0 + -0.0154344597831368 + 0.2048323005437851 + 1 + <_> + + + + <_>6 2 3 4 -1. + <_>7 2 1 4 3. + 0 + -8.4861656650900841e-003 + 0.1254952996969223 + 0.5060356259346008 + <_> + + <_> + + + + <_>0 13 20 6 -1. + <_>0 15 20 2 3. + 0 + -0.1180747002363205 + 0.0676330626010895 + 1 + <_> + + + + <_>8 5 12 2 -1. + <_>14 5 6 1 2. + <_>8 6 6 1 2. + 0 + -1.2300079688429832e-003 + 0.5660700798034668 + 0.4292201101779938 + <_> + + <_> + + + + <_>8 14 2 3 -1. + <_>8 15 2 1 3. + 0 + -7.0290351286530495e-003 + 0.7136403918266296 + 1 + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 8.9325206354260445e-003 + 0.4338876008987427 + 0.7060875296592712 + <_> + + <_> + + + + <_>12 13 7 6 -1. + <_>12 15 7 2 3. + 0 + -0.0477359816431999 + 1 + 0.5268685221672058 + <_> + + + + <_>6 0 8 12 -1. + <_>10 0 4 6 2. + <_>6 6 4 6 2. + 0 + -0.0441555790603161 + 0.2580580115318298 + 0.5406960844993591 + <_> + + <_> + + + + <_>0 15 9 4 -1. + <_>0 17 9 2 2. + 0 + -0.0259834807366133 + 0.1905054003000259 + 1 + <_> + + + + <_>9 0 2 5 -1. + <_>10 0 1 5 2. + 0 + -4.7885831445455551e-003 + 0.2551892995834351 + 0.5339077115058899 + <_> + + <_> + + + + <_>9 5 2 6 -1. + <_>9 5 1 6 2. + 0 + 6.7423451691865921e-003 + 0.4693309962749481 + 1 + <_> + + + + <_>17 2 3 6 -1. + <_>17 4 3 2 3. + 0 + 0.0116547504439950 + 0.5261964201927185 + 0.3145434856414795 + <_> + + <_> + + + + <_>3 11 2 3 -1. + <_>3 12 2 1 3. + 0 + -5.6982729583978653e-003 + 0.1756853014230728 + 1 + <_> + + + + <_>7 13 3 3 -1. + <_>7 14 3 1 3. + 0 + -7.2983349673449993e-003 + 0.7774729728698731 + 0.5124292969703674 + <_> + + <_> + + + + <_>14 12 5 3 -1. + <_>14 13 5 1 3. + 0 + 7.9091778025031090e-003 + 0.5284559726715088 + 1 + <_> + + + + <_>4 8 14 3 -1. + <_>4 9 14 1 3. + 0 + -1.5874979726504534e-004 + 0.3887802064418793 + 0.5501173734664917 + <_> + + <_> + + + + <_>1 12 5 3 -1. + <_>1 13 5 1 3. + 0 + -6.2235877849161625e-003 + 0.2489829063415527 + 1 + <_> + + + + <_>1 15 12 2 -1. + <_>1 15 6 1 2. + <_>7 16 6 1 2. + 0 + 1.3308860361576080e-003 + 0.4262146055698395 + 0.5935062170028687 + <_> + + <_> + + + + <_>12 11 4 2 -1. + <_>12 12 4 1 2. + 0 + 5.2055278792977333e-003 + 1 + 0.2545222938060761 + <_> + + + + <_>9 8 3 5 -1. + <_>10 8 1 5 3. + 0 + 0.0140651697292924 + 0.4851990044116974 + 0.7021418809890747 + <_> + + <_> + + + + <_>9 5 2 6 -1. + <_>10 5 1 6 2. + 0 + -6.7384149879217148e-003 + 0.7143270969390869 + 1 + <_> + + + + <_>0 2 3 6 -1. + <_>0 4 3 2 3. + 0 + 3.3406780567020178e-003 + 0.5175725221633911 + 0.2808643877506256 + <_> + + <_> + + + + <_>12 11 4 2 -1. + <_>12 12 4 1 2. + 0 + -0.0118806995451450 + 1 + 0.5173221826553345 + <_> + + + + <_>9 7 3 5 -1. + <_>10 7 1 5 3. + 0 + 1.4226379571482539e-003 + 0.4502865970134735 + 0.5795695185661316 + <_> + + <_> + + + + <_>4 11 4 2 -1. + <_>4 12 4 1 2. + 0 + 2.9858129564672709e-003 + 1 + 0.1915116012096405 + <_> + + + + <_>8 8 3 5 -1. + <_>9 8 1 5 3. + 0 + -2.0481580868363380e-003 + 0.6502432227134705 + 0.4559315145015717 + <_> + + <_> + + + + <_>9 3 3 1 -1. + <_>10 3 1 1 3. + 0 + 1.7122729914262891e-003 + 0.5376247167587280 + 1 + <_> + + + + <_>16 5 3 8 -1. + <_>17 5 1 8 3. + 0 + -0.0169808696955442 + 0.7056233286857605 + 0.4914605915546417 + <_> + + <_> + + + + <_>8 3 3 1 -1. + <_>9 3 1 1 3. + 0 + -1.1290470138192177e-003 + 0.2678706049919128 + 1 + <_> + + + + <_>1 5 3 8 -1. + <_>2 5 1 8 3. + 0 + 2.8620059601962566e-003 + 0.4410853981971741 + 0.6368319988250732 + <_> + + <_> + + + + <_>10 1 3 3 -1. + <_>11 1 1 3 3. + 0 + -3.8065758999437094e-003 + 0.2763563990592957 + 1 + <_> + + + + <_>17 5 2 4 -1. + <_>17 5 1 4 2. + 0 + 5.9090270660817623e-003 + 0.4867301881313324 + 0.6728776097297669 + <_> + + <_> + + + + <_>2 8 14 3 -1. + <_>2 9 14 1 3. + 0 + 1.1004370171576738e-003 + 0.4070514142513275 + 1 + <_> + + + + <_>9 7 1 3 -1. + <_>9 8 1 1 3. + 0 + -2.3396299220621586e-003 + 0.2604948878288269 + 0.6154860258102417 + <_> + + <_> + + + + <_>6 1 8 10 -1. + <_>6 6 8 5 2. + 0 + -3.6068160552531481e-003 + 0.5731999874114990 + 1 + <_> + + + + <_>13 0 6 8 -1. + <_>16 0 3 4 2. + <_>13 4 3 4 2. + 0 + 0.0408311896026134 + 0.4973376989364624 + 0.7387006878852844 + <_> + + <_> + + + + <_>1 5 2 4 -1. + <_>2 5 1 4 2. + 0 + -7.1082250215113163e-003 + 0.6984751224517822 + 1 + <_> + + + + <_>4 2 12 2 -1. + <_>4 3 12 1 2. + 0 + -9.3759730225428939e-004 + 0.2691167891025543 + 0.4741779863834381 + <_> + + <_> + + + + <_>8 8 4 4 -1. + <_>8 10 4 2 2. + 0 + -1.6740820137783885e-003 + 0.3551014065742493 + 1 + <_> + + + + <_>5 6 12 4 -1. + <_>9 6 4 4 3. + 0 + 0.0882877036929131 + 0.5244613885879517 + 0.2096650004386902 + <_> + + <_> + + + + <_>1 2 8 1 -1. + <_>5 2 4 1 2. + 0 + 8.2009629113599658e-004 + 0.4131096899509430 + 1 + <_> + + + + <_>1 1 6 10 -1. + <_>3 1 2 10 3. + 0 + -7.6624617213383317e-004 + 0.4620293080806732 + 0.6775410175323486 + <_> + + <_> + + + + <_>8 6 8 2 -1. + <_>8 6 4 2 2. + 0 + 6.5769668435677886e-004 + 1 + 0.5628275275230408 + <_> + + + + <_>10 7 6 6 -1. + <_>12 7 2 6 3. + 0 + -2.1304790861904621e-003 + 0.5576859712600708 + 0.4577650129795075 + <_> + + <_> + + + + <_>4 6 8 2 -1. + <_>8 6 4 2 2. + 0 + -3.7317050737328827e-004 + 1 + 0.4959256052970886 + <_> + + + + <_>4 7 6 6 -1. + <_>6 7 2 6 3. + 0 + -0.0111722303554416 + 0.5625635981559753 + 0.2047107964754105 + <_> + + <_> + + + + <_>3 14 16 4 -1. + <_>3 16 16 2 2. + 0 + 0.0434352196753025 + 1 + 0.2242148071527481 + <_> + + + + <_>8 12 4 2 -1. + <_>8 13 4 1 2. + 0 + 9.6736161503940821e-004 + 0.4533343911170960 + 0.6199932098388672 + <_> + + <_> + + + + <_>8 12 3 3 -1. + <_>8 13 3 1 3. + 0 + -3.1452889088541269e-003 + 0.6662756204605103 + 1 + <_> + + + + <_>5 12 6 1 -1. + <_>8 12 3 1 2. + 0 + 1.5233129961416125e-003 + 0.5007988214492798 + 0.2384992986917496 + <_> + + <_> + + + + <_>18 10 2 3 -1. + <_>18 11 2 1 3. + 0 + 2.0854279864579439e-003 + 1 + 0.3753500878810883 + <_> + + + + <_>16 8 4 6 -1. + <_>16 10 4 2 3. + 0 + 0.0360982008278370 + 0.5177171230316162 + 0.1634493023157120 + <_> + + <_> + + + + <_>8 3 2 1 -1. + <_>9 3 1 1 2. + 0 + 1.6179570229724050e-003 + 1 + 0.2587381899356842 + <_> + + + + <_>7 1 3 9 -1. + <_>8 1 1 9 3. + 0 + -6.2132300809025764e-004 + 0.6299533843994141 + 0.4658789932727814 + <_> + + <_> + + + + <_>5 11 11 6 -1. + <_>5 14 11 3 2. + 0 + 7.1878539165481925e-004 + 1 + 0.3354076147079468 + <_> + + + + <_>12 2 3 14 -1. + <_>12 9 3 7 2. + 0 + -0.0393395200371742 + 0.2154128998517990 + 0.5235713720321655 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>9 7 1 3 3. + 0 + -1.0988829890266061e-003 + 0.6468896865844727 + 1 + <_> + + + + <_>3 5 12 5 -1. + <_>7 5 4 5 3. + 0 + 2.1191420964896679e-003 + 0.2893089056015015 + 0.5254815816879273 + 22.5852909088134770 + 8 + -1 + <_> + + + <_> + + <_> + + + + <_>1 2 6 3 -1. + <_>4 2 3 3 2. + 0 + 5.2359891124069691e-003 + 0.3299711048603058 + 1 + <_> + + + + <_>5 5 6 10 -1. + <_>5 5 3 5 2. + <_>8 10 3 5 2. + 0 + -2.2169889416545630e-003 + 0.7041593194007874 + 0.3235465884208679 + <_> + + <_> + + + + <_>16 18 2 2 -1. + <_>16 18 1 2 2. + 0 + -8.2303592935204506e-003 + 1 + 0.4961170852184296 + <_> + + + + <_>16 18 2 2 -1. + <_>16 18 1 2 2. + 0 + -8.2303592935204506e-003 + 0.7128043174743652 + 0.4961170852184296 + <_> + + <_> + + + + <_>8 4 2 5 -1. + <_>9 4 1 5 2. + 0 + 4.5343261444941163e-004 + 0.3208472132682800 + 1 + <_> + + + + <_>8 4 1 4 -1. + <_>8 6 1 2 2. + 0 + -4.1777061414904892e-004 + 0.6613916754722595 + 0.3551332950592041 + <_> + + <_> + + + + <_>7 15 12 4 -1. + <_>13 15 6 2 2. + <_>7 17 6 2 2. + 0 + 2.7823769487440586e-003 + 0.3710134923458099 + 1 + <_> + + + + <_>11 18 6 2 -1. + <_>11 19 6 1 2. + 0 + -6.0361868236213923e-005 + 0.5746393799781799 + 0.3894880115985870 + <_> + + <_> + + + + <_>7 7 4 10 -1. + <_>7 12 4 5 2. + 0 + 3.5061789676547050e-003 + 1 + 0.3054102957248688 + <_> + + + + <_>5 6 10 8 -1. + <_>5 10 10 4 2. + 0 + 1.7013119941111654e-004 + 0.2885577976703644 + 0.6487745046615601 + <_> + + <_> + + + + <_>11 1 6 12 -1. + <_>14 1 3 6 2. + <_>11 7 3 6 2. + 0 + -2.3378930054605007e-003 + 1 + 0.3174431025981903 + <_> + + + + <_>5 8 12 1 -1. + <_>9 8 4 1 3. + 0 + -2.1369170863181353e-003 + 0.3820919990539551 + 0.5232893228530884 + <_> + + <_> + + + + <_>4 7 3 6 -1. + <_>4 9 3 2 3. + 0 + 1.0250400518998504e-003 + 0.3622795045375824 + 1 + <_> + + + + <_>4 11 3 4 -1. + <_>4 13 3 2 2. + 0 + -4.4726220949087292e-005 + 0.6538959145545960 + 0.4003680944442749 + <_> + + <_> + + + + <_>14 16 2 2 -1. + <_>14 17 2 1 2. + 0 + 5.7102291611954570e-004 + 1 + 0.3893173038959503 + <_> + + + + <_>15 15 2 2 -1. + <_>15 16 2 1 2. + 0 + 5.7743012439459562e-004 + 0.5614532828330994 + 0.3687644004821777 + <_> + + <_> + + + + <_>7 12 6 2 -1. + <_>7 13 6 1 2. + 0 + 7.9692091094329953e-004 + 1 + 0.6443027853965759 + <_> + + + + <_>8 13 4 2 -1. + <_>8 14 4 1 2. + 0 + 3.5945948911830783e-004 + 0.3380852937698364 + 0.5824648141860962 + <_> + + <_> + + + + <_>11 1 6 12 -1. + <_>14 1 3 6 2. + <_>11 7 3 6 2. + 0 + 4.3973900028504431e-004 + 1 + 0.3938767015933991 + <_> + + + + <_>12 2 4 2 -1. + <_>12 3 4 1 2. + 0 + -8.9061429025605321e-004 + 0.3427971005439758 + 0.5515698790550232 + <_> + + <_> + + + + <_>3 10 12 6 -1. + <_>3 10 6 3 2. + <_>9 13 6 3 2. + 0 + 5.4110242053866386e-003 + 1 + 0.3803538084030151 + <_> + + + + <_>3 1 6 12 -1. + <_>3 1 3 6 2. + <_>6 7 3 6 2. + 0 + -8.5764907998964190e-004 + 0.6439505219459534 + 0.4168345928192139 + <_> + + <_> + + + + <_>16 6 4 14 -1. + <_>18 6 2 7 2. + <_>16 13 2 7 2. + 0 + -0.0220006499439478 + 0.6654601097106934 + 1 + <_> + + + + <_>5 1 10 8 -1. + <_>10 1 5 4 2. + <_>5 5 5 4 2. + 0 + -7.8731682151556015e-003 + 0.4182722866535187 + 0.5604724287986755 + <_> + + <_> + + + + <_>0 6 4 14 -1. + <_>0 6 2 7 2. + <_>2 13 2 7 2. + 0 + -0.0274444594979286 + 0.6586862802505493 + 1 + <_> + + + + <_>1 15 12 4 -1. + <_>1 15 6 2 2. + <_>7 17 6 2 2. + 0 + 1.9792269449681044e-003 + 0.3244912028312683 + 0.4882870018482208 + <_> + + <_> + + + + <_>10 17 3 3 -1. + <_>11 17 1 3 3. + 0 + -5.6783691979944706e-003 + 0.2229079008102417 + 1 + <_> + + + + <_>11 2 2 6 -1. + <_>12 2 1 3 2. + <_>11 5 1 3 2. + 0 + 1.5057219570735469e-005 + 0.4107285141944885 + 0.5747591257095337 + <_> + + <_> + + + + <_>7 17 3 3 -1. + <_>8 17 1 3 3. + 0 + -5.4136710241436958e-003 + 0.2065797001123428 + 1 + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + 5.3679239936172962e-003 + 0.4926423132419586 + 0.7139484882354736 + <_> + + <_> + + + + <_>10 15 4 2 -1. + <_>12 15 2 1 2. + <_>10 16 2 1 2. + 0 + -3.1426660716533661e-003 + 0.6780086755752564 + 1 + <_> + + + + <_>13 13 4 3 -1. + <_>13 14 4 1 3. + 0 + 0.0109073901548982 + 0.5214930176734924 + 0.1143995970487595 + <_> + + <_> + + + + <_>3 13 4 3 -1. + <_>3 14 4 1 3. + 0 + 5.8436761610209942e-003 + 1 + 0.1937526017427445 + <_> + + + + <_>7 2 2 6 -1. + <_>7 2 1 3 2. + <_>8 5 1 3 2. + 0 + 9.0507230197545141e-005 + 0.3812577128410339 + 0.5514187812805176 + <_> + + <_> + + + + <_>2 1 16 3 -1. + <_>2 2 16 1 3. + 0 + -0.0163457896560431 + 0.2474023997783661 + 1 + <_> + + + + <_>10 15 4 2 -1. + <_>12 15 2 1 2. + <_>10 16 2 1 2. + 0 + 1.5987500082701445e-003 + 0.4817782938480377 + 0.5923079848289490 + <_> + + <_> + + + + <_>6 15 4 2 -1. + <_>6 15 2 1 2. + <_>8 16 2 1 2. + 0 + -4.0257978253066540e-003 + 0.7508208751678467 + 1 + <_> + + + + <_>3 0 13 3 -1. + <_>3 1 13 1 3. + 0 + -6.7750471644103527e-003 + 0.2879810929298401 + 0.5199695229530335 + <_> + + <_> + + + + <_>0 9 20 3 -1. + <_>0 10 20 1 3. + 0 + -3.2470689620822668e-003 + 0.3044910132884979 + 1 + <_> + + + + <_>6 7 9 2 -1. + <_>6 8 9 1 2. + 0 + 1.5409620245918632e-003 + 0.4063482880592346 + 0.5676562786102295 + <_> + + <_> + + + + <_>8 14 3 6 -1. + <_>9 14 1 6 3. + 0 + -0.0128581197932363 + 0.0967175588011742 + 1 + <_> + + + + <_>9 10 2 2 -1. + <_>9 11 2 1 2. + 0 + -1.4824670506641269e-004 + 0.4537833034992218 + 0.6115375161170960 + <_> + + <_> + + + + <_>9 7 2 5 -1. + <_>9 7 1 5 2. + 0 + -9.0210810303688049e-003 + 1 + 0.4807750880718231 + <_> + + + + <_>5 6 10 3 -1. + <_>5 6 5 3 2. + 0 + -0.0287950299680233 + 0.3403795063495636 + 0.5255529284477234 + <_> + + <_> + + + + <_>9 7 2 5 -1. + <_>10 7 1 5 2. + 0 + 9.0210810303688049e-003 + 1 + 0.7505835890769959 + <_> + + + + <_>5 6 10 3 -1. + <_>10 6 5 3 2. + 0 + 7.4121179059147835e-003 + 0.5455446839332581 + 0.3226068913936615 + <_> + + <_> + + + + <_>13 9 2 2 -1. + <_>13 9 1 2 2. + 0 + -3.7217529024928808e-003 + 0.2311848998069763 + 1 + <_> + + + + <_>4 3 12 11 -1. + <_>8 3 4 11 3. + 0 + 0.1986588984727860 + 0.5271047949790955 + 0.1469929963350296 + <_> + + <_> + + + + <_>7 1 2 7 -1. + <_>8 1 1 7 2. + 0 + 1.5208719560177997e-005 + 0.3678138852119446 + 1 + <_> + + + + <_>7 4 3 8 -1. + <_>8 4 1 8 3. + 0 + -3.9089918136596680e-003 + 0.7131929993629456 + 0.4993866980075836 + <_> + + <_> + + + + <_>13 9 2 2 -1. + <_>13 9 1 2 2. + 0 + 2.5106288958340883e-003 + 0.5312054157257080 + 1 + <_> + + + + <_>11 6 2 2 -1. + <_>12 6 1 1 2. + <_>11 7 1 1 2. + 0 + 2.3921660613268614e-004 + 0.4689378142356873 + 0.5714021921157837 + <_> + + <_> + + + + <_>5 4 2 3 -1. + <_>5 5 2 1 3. + 0 + 6.9443131797015667e-003 + 1 + 0.6948797702789307 + <_> + + + + <_>6 5 1 3 -1. + <_>6 6 1 1 3. + 0 + 1.2065629707649350e-003 + 0.4004504978656769 + 0.5874881744384766 + <_> + + <_> + + + + <_>13 9 2 2 -1. + <_>13 9 1 2 2. + 0 + 2.5106288958340883e-003 + 0.5329571962356567 + 1 + <_> + + + + <_>16 14 3 3 -1. + <_>16 15 3 1 3. + 0 + 1.7514040227979422e-003 + 0.5545849204063416 + 0.3449581861495972 + <_> + + <_> + + + + <_>5 9 2 2 -1. + <_>6 9 1 2 2. + 0 + -4.1978210210800171e-003 + 0.1217183023691177 + 1 + <_> + + + + <_>1 14 3 3 -1. + <_>1 15 3 1 3. + 0 + 1.3092850567772985e-003 + 0.5375049710273743 + 0.3415625095367432 + <_> + + <_> + + + + <_>13 1 1 6 -1. + <_>13 3 1 2 3. + 0 + 6.7396182566881180e-004 + 0.4195179045200348 + 1 + <_> + + + + <_>13 3 7 2 -1. + <_>13 4 7 1 2. + 0 + -0.0105307102203369 + 0.3460753858089447 + 0.5155860185623169 + <_> + + <_> + + + + <_>0 6 20 14 -1. + <_>0 13 20 7 2. + 0 + -0.4067229926586151 + 0.0580656789243221 + 1 + <_> + + + + <_>0 4 3 6 -1. + <_>0 6 3 2 3. + 0 + -0.0263145491480827 + 0.1473449021577835 + 0.5559378266334534 + <_> + + <_> + + + + <_>10 1 9 6 -1. + <_>10 3 9 2 3. + 0 + 2.2557149641215801e-003 + 1 + 0.5477715134620667 + <_> + + + + <_>8 0 12 5 -1. + <_>8 0 6 5 2. + 0 + 0.0121548604220152 + 0.4207791090011597 + 0.5621880888938904 + <_> + + <_> + + + + <_>0 0 18 5 -1. + <_>6 0 6 5 3. + 0 + -0.0184365399181843 + 0.6447147130966187 + 1 + <_> + + + + <_>1 1 9 6 -1. + <_>1 3 9 2 3. + 0 + 5.3676147945225239e-004 + 0.2765127122402191 + 0.4888595938682556 + <_> + + <_> + + + + <_>15 15 2 2 -1. + <_>15 16 2 1 2. + 0 + -2.6265541091561317e-003 + 1 + 0.5264691114425659 + <_> + + + + <_>13 16 3 4 -1. + <_>13 18 3 2 2. + 0 + -5.1119807176291943e-004 + 0.5785310268402100 + 0.4291102886199951 + <_> + + <_> + + + + <_>3 15 2 2 -1. + <_>3 16 2 1 2. + 0 + 4.1454841266386211e-004 + 1 + 0.3455410897731781 + <_> + + + + <_>4 16 3 4 -1. + <_>4 18 3 2 2. + 0 + -5.5028748465701938e-004 + 0.6026918888092041 + 0.4143893122673035 + <_> + + <_> + + + + <_>11 14 1 3 -1. + <_>11 15 1 1 3. + 0 + -1.0347720235586166e-003 + 0.6095293760299683 + 1 + <_> + + + + <_>9 13 5 3 -1. + <_>9 14 5 1 3. + 0 + -3.3966631162911654e-003 + 0.6108282208442688 + 0.4707720875740051 + <_> + + <_> + + + + <_>0 0 3 6 -1. + <_>0 2 3 2 3. + 0 + 3.1795909162610769e-003 + 1 + 0.3244366943836212 + <_> + + + + <_>4 1 6 3 -1. + <_>6 1 2 3 3. + 0 + -1.6528950072824955e-004 + 0.3830757141113281 + 0.5734326243400574 + <_> + + <_> + + + + <_>9 13 4 3 -1. + <_>9 14 4 1 3. + 0 + 8.3725210279226303e-003 + 1 + 0.6610919237136841 + <_> + + + + <_>8 15 5 3 -1. + <_>8 16 5 1 3. + 0 + -2.5799809955060482e-003 + 0.6139307022094727 + 0.4686149954795837 + <_> + + <_> + + + + <_>8 3 3 2 -1. + <_>9 3 1 2 3. + 0 + 9.0194388758391142e-004 + 1 + 0.3520022034645081 + <_> + + + + <_>1 8 18 2 -1. + <_>1 9 18 1 2. + 0 + 3.6952210939489305e-004 + 0.2578754127025604 + 0.5467242002487183 + <_> + + <_> + + + + <_>11 14 1 3 -1. + <_>11 15 1 1 3. + 0 + 9.9746137857437134e-004 + 0.4820146858692169 + 1 + <_> + + + + <_>8 13 6 3 -1. + <_>8 14 6 1 3. + 0 + -3.6688039544969797e-003 + 0.5710150003433228 + 0.4831911027431488 + <_> + + <_> + + + + <_>8 14 1 3 -1. + <_>8 15 1 1 3. + 0 + -8.9501030743122101e-004 + 0.6133679151535034 + 1 + <_> + + + + <_>4 13 12 4 -1. + <_>4 13 6 2 2. + <_>10 15 6 2 2. + 0 + 5.1904921419918537e-003 + 0.4928582906723023 + 0.2581309080123901 + <_> + + <_> + + + + <_>10 7 2 2 -1. + <_>10 7 1 2 2. + 0 + 4.2274440056644380e-004 + 0.4471124112606049 + 1 + <_> + + + + <_>13 4 2 8 -1. + <_>14 4 1 4 2. + <_>13 8 1 4 2. + 0 + 8.5176713764667511e-003 + 0.5161024928092957 + 0.3316533863544464 + <_> + + <_> + + + + <_>0 5 4 6 -1. + <_>0 7 4 2 3. + 0 + -0.0366236083209515 + 0.0926062166690826 + 1 + <_> + + + + <_>8 7 2 2 -1. + <_>9 7 1 2 2. + 0 + -4.1103712283074856e-003 + 0.8522114753723145 + 0.5137907862663269 + <_> + + <_> + + + + <_>13 0 3 7 -1. + <_>14 0 1 7 3. + 0 + -6.6017331555485725e-003 + 1 + 0.5459060072898865 + <_> + + + + <_>11 2 2 14 -1. + <_>11 2 1 14 2. + 0 + 0.0255786404013634 + 0.5219352841377258 + 0.1927185952663422 + <_> + + <_> + + + + <_>4 0 3 7 -1. + <_>5 0 1 7 3. + 0 + 0.0114474399015307 + 1 + 0.1916002035140991 + <_> + + + + <_>5 5 8 12 -1. + <_>5 5 4 6 2. + <_>9 11 4 6 2. + 0 + 7.2427501436322927e-004 + 0.5231571197509766 + 0.3535340130329132 + <_> + + <_> + + + + <_>11 4 6 3 -1. + <_>11 5 6 1 3. + 0 + 9.7127500921487808e-003 + 1 + 0.6464101076126099 + <_> + + + + <_>12 3 4 3 -1. + <_>12 4 4 1 3. + 0 + -0.0113375699147582 + 0.7383037805557251 + 0.4964743852615356 + <_> + + <_> + + + + <_>5 5 10 12 -1. + <_>5 5 5 6 2. + <_>10 11 5 6 2. + 0 + -8.1453882157802582e-003 + 0.3611705899238586 + 1 + <_> + + + + <_>3 6 12 3 -1. + <_>9 6 6 3 2. + 0 + -8.5570756345987320e-003 + 0.3421907126903534 + 0.5943511724472046 + <_> + + <_> + + + + <_>9 6 2 7 -1. + <_>9 6 1 7 2. + 0 + 2.2993308957666159e-003 + 0.4550104141235352 + 1 + <_> + + + + <_>9 5 2 4 -1. + <_>9 5 1 4 2. + 0 + 3.8430930580943823e-003 + 0.4716862142086029 + 0.6656190752983093 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>9 7 1 3 3. + 0 + -9.9116540513932705e-004 + 1 + 0.4592716991901398 + <_> + + + + <_>5 1 6 4 -1. + <_>7 1 2 4 3. + 0 + 0.0254964698106050 + 0.6563401222229004 + 0.1258835047483444 + <_> + + <_> + + + + <_>13 16 7 3 -1. + <_>13 17 7 1 3. + 0 + -0.0157483592629433 + 1 + 0.5239502191543579 + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -0.0180461201816797 + 0.8015851974487305 + 0.5007957816123962 + <_> + + <_> + + + + <_>0 16 7 3 -1. + <_>0 17 7 1 3. + 0 + 0.0103233903646469 + 1 + 0.2274820059537888 + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 1.6452240524813533e-003 + 0.4351946115493774 + 0.5867627859115601 + <_> + + <_> + + + + <_>12 9 8 10 -1. + <_>12 9 4 10 2. + 0 + 0.0158811490982771 + 0.4465051889419556 + 1 + <_> + + + + <_>8 10 12 5 -1. + <_>12 10 4 5 3. + 0 + 0.0105865197256207 + 0.4544458091259003 + 0.5707110762596130 + <_> + + <_> + + + + <_>0 9 8 10 -1. + <_>4 9 4 10 2. + 0 + -0.0215316899120808 + 0.6527643799781799 + 1 + <_> + + + + <_>0 10 12 5 -1. + <_>4 10 4 5 3. + 0 + 5.2480469457805157e-003 + 0.3444727957248688 + 0.5324636101722717 + 25.6093006134033200 + 9 + -1 + <_> + + + <_> + + <_> + + + + <_>2 3 6 2 -1. + <_>5 3 3 2 2. + 0 + 1.8219340126961470e-003 + 0.3108788132667542 + 1 + <_> + + + + <_>0 0 17 9 -1. + <_>0 3 17 3 3. + 0 + 8.1313941627740860e-003 + 0.3133237063884735 + 0.6645867228507996 + <_> + + <_> + + + + <_>4 7 12 2 -1. + <_>8 7 4 2 3. + 0 + 1.7055979697033763e-003 + 0.2640131115913391 + 1 + <_> + + + + <_>10 4 6 4 -1. + <_>12 4 2 4 3. + 0 + -7.4483548814896494e-005 + 0.5647205114364624 + 0.3485372960567474 + <_> + + <_> + + + + <_>0 10 20 4 -1. + <_>0 12 20 2 2. + 0 + 3.8342390325851738e-004 + 1 + 0.3140654861927033 + <_> + + + + <_>4 3 6 5 -1. + <_>6 3 2 5 3. + 0 + 3.1868910882622004e-003 + 0.6489198803901672 + 0.3887729048728943 + <_> + + <_> + + + + <_>1 1 18 4 -1. + <_>7 1 6 4 3. + 0 + 0.1604432016611099 + 1 + 0.7216529846191406 + <_> + + + + <_>13 9 2 3 -1. + <_>13 9 1 3 2. + 0 + -6.7285560071468353e-003 + 0.1653137952089310 + 0.5139825940132141 + <_> + + <_> + + + + <_>6 15 7 4 -1. + <_>6 17 7 2 2. + 0 + 7.2638481469766703e-006 + 0.3140619993209839 + 1 + <_> + + + + <_>3 17 4 2 -1. + <_>3 18 4 1 2. + 0 + 5.5551197146996856e-004 + 0.5993698835372925 + 0.3317398130893707 + <_> + + <_> + + + + <_>9 4 8 10 -1. + <_>9 9 8 5 2. + 0 + -0.0108223203569651 + 0.2652938067913055 + 1 + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + -4.5834020711481571e-003 + 0.1849568933248520 + 0.5313957929611206 + <_> + + <_> + + + + <_>8 2 4 8 -1. + <_>8 6 4 4 2. + 0 + -3.0205070506781340e-003 + 1 + 0.4040099978446960 + <_> + + + + <_>3 4 14 12 -1. + <_>3 4 7 6 2. + <_>10 10 7 6 2. + 0 + 0.0778646171092987 + 0.6158189773559570 + 0.1786486953496933 + <_> + + <_> + + + + <_>7 7 6 4 -1. + <_>9 7 2 4 3. + 0 + 0.0264943800866604 + 0.4511089920997620 + 1 + <_> + + + + <_>6 7 9 4 -1. + <_>6 9 9 2 2. + 0 + 0.0369121097028255 + 0.4528219997882843 + 0.5972282886505127 + <_> + + <_> + + + + <_>2 10 3 3 -1. + <_>2 11 3 1 3. + 0 + 5.7857790961861610e-003 + 1 + 0.2533892095088959 + <_> + + + + <_>4 6 2 9 -1. + <_>4 9 2 3 3. + 0 + 9.3849771656095982e-004 + 0.3410412073135376 + 0.5923643708229065 + <_> + + <_> + + + + <_>9 11 3 3 -1. + <_>9 12 3 1 3. + 0 + -0.0110031999647617 + 0.6958044171333313 + 1 + <_> + + + + <_>3 1 15 2 -1. + <_>3 2 15 1 2. + 0 + -1.1737640015780926e-003 + 0.3851084113121033 + 0.5408189296722412 + <_> + + <_> + + + + <_>9 8 2 3 -1. + <_>9 9 2 1 3. + 0 + -3.6596669815480709e-003 + 0.2009308934211731 + 1 + <_> + + + + <_>9 6 2 5 -1. + <_>10 6 1 5 2. + 0 + -2.4822750128805637e-003 + 0.6295393109321594 + 0.4395040869712830 + <_> + + <_> + + + + <_>9 7 2 3 -1. + <_>9 8 2 1 3. + 0 + -4.4606071896851063e-003 + 0.2405299991369247 + 1 + <_> + + + + <_>4 10 12 10 -1. + <_>4 15 12 5 2. + 0 + -3.5969649907201529e-003 + 0.5450174212455750 + 0.3782357871532440 + <_> + + <_> + + + + <_>0 10 4 2 -1. + <_>0 11 4 1 2. + 0 + -3.6222559865564108e-003 + 0.3033896982669830 + 1 + <_> + + + + <_>5 15 9 2 -1. + <_>5 16 9 1 2. + 0 + 1.2059339787811041e-003 + 0.4633778929710388 + 0.6335952281951904 + <_> + + <_> + + + + <_>8 14 6 3 -1. + <_>8 15 6 1 3. + 0 + 4.3124938383698463e-003 + 1 + 0.6598826050758362 + <_> + + + + <_>8 16 4 3 -1. + <_>8 17 4 1 3. + 0 + -4.4961250387132168e-003 + 0.6621696949005127 + 0.4755246937274933 + <_> + + <_> + + + + <_>8 9 4 2 -1. + <_>8 10 4 1 2. + 0 + -1.3860689941793680e-003 + 0.2801201045513153 + 1 + <_> + + + + <_>3 3 14 2 -1. + <_>3 4 14 1 2. + 0 + -5.1588460337370634e-004 + 0.3829489052295685 + 0.5623626708984375 + <_> + + <_> + + + + <_>11 12 1 2 -1. + <_>11 13 1 1 2. + 0 + 7.0330002927221358e-005 + 0.4536342918872833 + 1 + <_> + + + + <_>4 12 12 1 -1. + <_>8 12 4 1 3. + 0 + -2.0976549421902746e-004 + 0.5608139038085938 + 0.4265779852867127 + <_> + + <_> + + + + <_>0 2 1 2 -1. + <_>0 3 1 1 2. + 0 + 1.3642259873449802e-003 + 1 + 0.2637091875076294 + <_> + + + + <_>7 4 4 6 -1. + <_>9 4 2 6 2. + 0 + 1.5483660390600562e-003 + 0.4170750975608826 + 0.5932987928390503 + <_> + + <_> + + + + <_>0 2 20 14 -1. + <_>10 2 10 7 2. + <_>0 9 10 7 2. + 0 + 0.1917960941791534 + 0.5256764292716980 + 1 + <_> + + + + <_>14 6 1 3 -1. + <_>14 7 1 1 3. + 0 + -4.4776909053325653e-003 + 0.6632621884346008 + 0.4892588853836060 + <_> + + <_> + + + + <_>0 4 20 12 -1. + <_>0 4 10 6 2. + <_>10 10 10 6 2. + 0 + -0.1264917999505997 + 0.1499778926372528 + 1 + <_> + + + + <_>8 12 1 2 -1. + <_>8 13 1 1 2. + 0 + 6.5253327193204314e-005 + 0.4233320057392120 + 0.5756040215492249 + <_> + + <_> + + + + <_>9 18 3 2 -1. + <_>10 18 1 2 3. + 0 + 4.1856421157717705e-003 + 0.5288826823234558 + 1 + <_> + + + + <_>9 17 6 2 -1. + <_>11 17 2 2 3. + 0 + 2.7478230185806751e-004 + 0.4524017870426178 + 0.5604125261306763 + <_> + + <_> + + + + <_>5 6 2 3 -1. + <_>5 7 2 1 3. + 0 + -2.2906810045242310e-003 + 0.5578274130821228 + 1 + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 1.6744500026106834e-003 + 0.3323057889938355 + 0.5558788180351257 + <_> + + <_> + + + + <_>14 15 3 2 -1. + <_>14 16 3 1 2. + 0 + 1.2349759927019477e-003 + 1 + 0.3653947114944458 + <_> + + + + <_>11 3 3 4 -1. + <_>12 3 1 4 3. + 0 + -8.7158754467964172e-003 + 0.1924533993005753 + 0.5313649773597717 + <_> + + <_> + + + + <_>3 15 3 2 -1. + <_>3 16 3 1 2. + 0 + 4.6613621525466442e-003 + 1 + 0.2027730941772461 + <_> + + + + <_>9 12 2 3 -1. + <_>9 13 2 1 3. + 0 + -8.5815992206335068e-003 + 0.7636060118675232 + 0.5140826106071472 + <_> + + <_> + + + + <_>9 13 3 7 -1. + <_>10 13 1 7 3. + 0 + 0.0143521204590797 + 0.5252975821495056 + 1 + <_> + + + + <_>12 12 5 3 -1. + <_>12 13 5 1 3. + 0 + -7.7948719263076782e-003 + 0.2632937133312225 + 0.5328689217567444 + <_> + + <_> + + + + <_>8 18 3 2 -1. + <_>9 18 1 2 3. + 0 + -3.4155680332332850e-003 + 0.2416087985038757 + 1 + <_> + + + + <_>4 7 12 4 -1. + <_>4 7 6 2 2. + <_>10 9 6 2 2. + 0 + -4.2639090679585934e-003 + 0.3936544954776764 + 0.5478742122650147 + <_> + + <_> + + + + <_>6 19 14 1 -1. + <_>6 19 7 1 2. + 0 + 8.7177697569131851e-003 + 0.4788199067115784 + 1 + <_> + + + + <_>16 14 3 2 -1. + <_>16 15 3 1 2. + 0 + -3.2232629600912333e-003 + 0.3631612062454224 + 0.5288316011428833 + <_> + + <_> + + + + <_>1 0 6 10 -1. + <_>1 0 3 5 2. + <_>4 5 3 5 2. + 0 + -0.0421883687376976 + 0.6931139230728149 + 1 + <_> + + + + <_>1 0 4 10 -1. + <_>1 0 2 5 2. + <_>3 5 2 5 2. + 0 + 0.0198757499456406 + 0.4520100057125092 + 0.6855055093765259 + <_> + + <_> + + + + <_>15 3 5 6 -1. + <_>15 5 5 2 3. + 0 + -0.0311345104128122 + 1 + 0.5300424098968506 + <_> + + + + <_>9 5 2 15 -1. + <_>9 10 2 5 3. + 0 + 5.7032387703657150e-003 + 0.5606892108917236 + 0.4230622947216034 + <_> + + <_> + + + + <_>0 3 5 6 -1. + <_>0 5 5 2 3. + 0 + 5.2733682096004486e-003 + 1 + 0.3247228860855103 + <_> + + + + <_>6 0 3 2 -1. + <_>7 0 1 2 3. + 0 + -3.1231069006025791e-003 + 0.1985695958137512 + 0.5349872708320618 + <_> + + <_> + + + + <_>12 8 8 2 -1. + <_>16 8 4 1 2. + <_>12 9 4 1 2. + 0 + 4.6453849063254893e-004 + 0.4207508862018585 + 1 + <_> + + + + <_>5 8 12 1 -1. + <_>9 8 4 1 3. + 0 + 0.0303558893501759 + 0.5153458714485169 + 0.3118101060390472 + <_> + + <_> + + + + <_>3 13 3 3 -1. + <_>3 14 3 1 3. + 0 + -4.2992769740521908e-003 + 0.3274506926536560 + 1 + <_> + + + + <_>5 13 3 2 -1. + <_>5 14 3 1 2. + 0 + 1.9509199773892760e-004 + 0.5953078269958496 + 0.4225521087646484 + <_> + + <_> + + + + <_>9 15 3 3 -1. + <_>9 16 3 1 3. + 0 + -7.7784480527043343e-003 + 0.7211179733276367 + 1 + <_> + + + + <_>7 15 7 3 -1. + <_>7 16 7 1 3. + 0 + 0.0169175993651152 + 0.4936591982841492 + 0.7030277252197266 + <_> + + <_> + + + + <_>3 14 11 6 -1. + <_>3 16 11 2 3. + 0 + -0.0519485697150230 + 0.1425534933805466 + 1 + <_> + + + + <_>0 19 14 1 -1. + <_>7 19 7 1 2. + 0 + -5.4751220159232616e-003 + 0.6059331893920898 + 0.4393995106220245 + <_> + + <_> + + + + <_>9 17 6 2 -1. + <_>11 17 2 2 3. + 0 + 1.5210839592327829e-005 + 0.4488849937915802 + 1 + <_> + + + + <_>12 11 6 2 -1. + <_>14 11 2 2 3. + 0 + 1.0235579684376717e-003 + 0.4256550073623657 + 0.5795438289642334 + <_> + + <_> + + + + <_>5 17 6 2 -1. + <_>7 17 2 2 3. + 0 + -1.0427719826111570e-004 + 0.4246039986610413 + 1 + <_> + + + + <_>0 1 9 10 -1. + <_>3 1 3 10 3. + 0 + 8.7853781878948212e-003 + 0.4958009123802185 + 0.6759430766105652 + <_> + + <_> + + + + <_>10 1 3 3 -1. + <_>11 1 1 3 3. + 0 + 3.4012699034065008e-003 + 0.5423480868339539 + 1 + <_> + + + + <_>9 5 6 4 -1. + <_>9 5 3 4 2. + 0 + 5.8582378551363945e-004 + 0.3636542856693268 + 0.5464348793029785 + <_> + + <_> + + + + <_>7 1 3 3 -1. + <_>8 1 1 3 3. + 0 + -2.2973360028117895e-003 + 0.2548818886280060 + 1 + <_> + + + + <_>0 4 4 11 -1. + <_>2 4 2 11 2. + 0 + -0.0143301896750927 + 0.6587656736373901 + 0.4532802104949951 + <_> + + <_> + + + + <_>9 5 6 4 -1. + <_>9 5 3 4 2. + 0 + 9.8565965890884399e-004 + 0.3822771012783051 + 1 + <_> + + + + <_>6 0 8 10 -1. + <_>10 0 4 5 2. + <_>6 5 4 5 2. + 0 + -0.0466407611966133 + 0.3077321946620941 + 0.5244132876396179 + <_> + + <_> + + + + <_>6 6 5 14 -1. + <_>6 13 5 7 2. + 0 + -0.1190730035305023 + 0.1033862978219986 + 1 + <_> + + + + <_>8 5 4 14 -1. + <_>8 12 4 7 2. + 0 + 0.0193332806229591 + 0.5554745197296143 + 0.3221316933631897 + <_> + + <_> + + + + <_>7 7 6 5 -1. + <_>9 7 2 5 3. + 0 + 0.0314278490841389 + 0.4682379066944122 + 1 + <_> + + + + <_>9 3 3 9 -1. + <_>9 6 3 3 3. + 0 + 2.0082130504306406e-004 + 0.5373070240020752 + 0.3800666928291321 + <_> + + <_> + + + + <_>8 1 3 3 -1. + <_>9 1 1 3 3. + 0 + -6.2584900297224522e-003 + 0.1799207031726837 + 1 + <_> + + + + <_>9 6 2 4 -1. + <_>10 6 1 4 2. + 0 + 8.2861045375466347e-003 + 0.5095068812370300 + 0.7544605135917664 + <_> + + <_> + + + + <_>10 8 6 9 -1. + <_>10 8 3 9 2. + 0 + 2.0529709290713072e-003 + 0.5628644824028015 + 1 + <_> + + + + <_>16 4 3 8 -1. + <_>17 4 1 8 3. + 0 + 3.2524869311600924e-003 + 0.4801689088344574 + 0.5802102088928223 + <_> + + <_> + + + + <_>5 9 10 6 -1. + <_>5 9 5 3 2. + <_>10 12 5 3 2. + 0 + -0.0318849012255669 + 0.1742745041847229 + 1 + <_> + + + + <_>5 5 6 4 -1. + <_>8 5 3 4 2. + 0 + 1.8379340181127191e-003 + 0.3466596901416779 + 0.5107154846191406 + <_> + + <_> + + + + <_>9 8 4 2 -1. + <_>9 9 4 1 2. + 0 + -4.8512680223211646e-004 + 1 + 0.5326086282730103 + <_> + + + + <_>11 7 2 2 -1. + <_>11 7 1 2 2. + 0 + -2.5407879147678614e-003 + 0.6342775225639343 + 0.4992693066596985 + <_> + + <_> + + + + <_>8 12 4 8 -1. + <_>8 12 2 4 2. + <_>10 16 2 4 2. + 0 + -5.1559060811996460e-003 + 0.3433429002761841 + 1 + <_> + + + + <_>0 1 4 9 -1. + <_>0 4 4 3 3. + 0 + -0.0449687503278255 + 0.1868136972188950 + 0.5215464830398560 + <_> + + <_> + + + + <_>9 10 3 3 -1. + <_>9 11 3 1 3. + 0 + 5.8984281495213509e-003 + 1 + 0.6229305267333984 + <_> + + + + <_>8 11 4 2 -1. + <_>8 12 4 1 2. + 0 + 3.2763120252639055e-003 + 0.4935772120952606 + 0.7217944860458374 + <_> + + <_> + + + + <_>7 8 4 2 -1. + <_>7 9 4 1 2. + 0 + -1.0161520185647532e-004 + 1 + 0.5007976293563843 + <_> + + + + <_>7 8 6 1 -1. + <_>9 8 2 1 3. + 0 + -1.6290300118271261e-004 + 0.6024149060249329 + 0.2329508066177368 + <_> + + <_> + + + + <_>16 0 4 9 -1. + <_>16 0 2 9 2. + 0 + 9.0541364625096321e-003 + 0.4510416984558106 + 1 + <_> + + + + <_>16 0 3 6 -1. + <_>16 3 3 3 2. + 0 + 0.0353984907269478 + 0.5141996741294861 + 0.2860291898250580 + <_> + + <_> + + + + <_>0 0 4 9 -1. + <_>2 0 2 9 2. + 0 + 5.6469351984560490e-003 + 0.4704925119876862 + 1 + <_> + + + + <_>1 0 3 6 -1. + <_>1 3 3 3 2. + 0 + -2.4807190056890249e-003 + 0.4179851114749908 + 0.6726647019386292 + <_> + + <_> + + + + <_>9 7 6 9 -1. + <_>11 7 2 9 3. + 0 + -4.1088787838816643e-003 + 0.5809801816940308 + 1 + <_> + + + + <_>10 6 3 6 -1. + <_>11 6 1 6 3. + 0 + -2.0714469719678164e-003 + 0.6074783802032471 + 0.4524059891700745 + <_> + + <_> + + + + <_>1 2 18 2 -1. + <_>1 2 9 1 2. + <_>10 3 9 1 2. + 0 + -2.8939060866832733e-003 + 0.3383519947528839 + 1 + <_> + + + + <_>5 8 6 8 -1. + <_>7 8 2 8 3. + 0 + 1.3467279495671391e-003 + 0.5696910023689270 + 0.3970845043659210 + <_> + + <_> + + + + <_>9 0 6 16 -1. + <_>11 0 2 16 3. + 0 + -0.0907791331410408 + 0.1502701938152313 + 1 + <_> + + + + <_>14 1 6 18 -1. + <_>17 1 3 9 2. + <_>14 10 3 9 2. + 0 + -0.0831717625260353 + 0.7573670744895935 + 0.4936437010765076 + <_> + + <_> + + + + <_>2 9 2 3 -1. + <_>2 10 2 1 3. + 0 + -1.4107000315561891e-003 + 0.3390932977199554 + 1 + <_> + + + + <_>0 1 6 18 -1. + <_>0 1 3 9 2. + <_>3 10 3 9 2. + 0 + 0.0556687600910664 + 0.5025097131729126 + 0.7422083020210266 + <_> + + <_> + + + + <_>11 8 4 12 -1. + <_>11 8 2 12 2. + 0 + 0.0577015392482281 + 0.5197371840476990 + 1 + <_> + + + + <_>2 1 18 18 -1. + <_>2 10 18 9 2. + 0 + -0.4250329136848450 + 0.0973469167947769 + 0.5185739994049072 + <_> + + <_> + + + + <_>6 3 3 1 -1. + <_>7 3 1 1 3. + 0 + -4.4380719191394746e-004 + 0.3649350106716156 + 1 + <_> + + + + <_>4 12 2 2 -1. + <_>4 13 2 1 2. + 0 + 1.7924769781529903e-004 + 0.5619279146194458 + 0.3760297000408173 + <_> + + <_> + + + + <_>8 13 5 3 -1. + <_>8 14 5 1 3. + 0 + 5.0382469780743122e-003 + 1 + 0.6328445076942444 + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 0.0151911703869700 + 0.4936082065105438 + 0.7426524758338928 + <_> + + <_> + + + + <_>3 12 5 3 -1. + <_>3 13 5 1 3. + 0 + -0.0123003898188472 + 0.1389349997043610 + 1 + <_> + + + + <_>6 3 3 4 -1. + <_>7 3 1 4 3. + 0 + 1.5168030513450503e-003 + 0.5091962218284607 + 0.3482648134231567 + <_> + + <_> + + + + <_>11 10 2 2 -1. + <_>12 10 1 1 2. + <_>11 11 1 1 2. + 0 + 9.5754547510296106e-004 + 1 + 0.6036316752433777 + <_> + + + + <_>5 8 12 1 -1. + <_>9 8 4 1 3. + 0 + -0.0189622007310390 + 0.2319173067808151 + 0.5116652846336365 + <_> + + <_> + + + + <_>8 4 4 8 -1. + <_>10 4 2 8 2. + 0 + -0.0222722608596087 + 0.6555022001266480 + 1 + <_> + + + + <_>6 6 8 5 -1. + <_>10 6 4 5 2. + 0 + -0.0251452308148146 + 0.1326071023941040 + 0.4674034118652344 + <_> + + <_> + + + + <_>10 4 6 4 -1. + <_>12 4 2 4 3. + 0 + 0.0195339005440474 + 0.5182027220726013 + 1 + <_> + + + + <_>12 7 2 2 -1. + <_>13 7 1 1 2. + <_>12 8 1 1 2. + 0 + -1.1231349781155586e-003 + 0.6318243145942688 + 0.4825519025325775 + <_> + + <_> + + + + <_>3 5 10 8 -1. + <_>3 9 10 4 2. + 0 + -1.4861139934509993e-003 + 0.2918671071529388 + 1 + <_> + + + + <_>7 1 2 12 -1. + <_>7 7 2 6 2. + 0 + 3.5002888762392104e-004 + 0.5621371269226074 + 0.4249213039875031 + <_> + + <_> + + + + <_>12 7 2 2 -1. + <_>13 7 1 1 2. + <_>12 8 1 1 2. + 0 + -1.1231349781155586e-003 + 1 + 0.4813745021820068 + <_> + + + + <_>11 13 1 6 -1. + <_>11 16 1 3 2. + 0 + 0.0104097397997975 + 0.5184006094932556 + 0.2051223069429398 + <_> + + <_> + + + + <_>5 1 6 15 -1. + <_>7 1 2 15 3. + 0 + -0.0878325626254082 + 0.1179921999573708 + 1 + <_> + + + + <_>6 7 2 2 -1. + <_>6 7 1 1 2. + <_>7 8 1 1 2. + 0 + 1.6584879485890269e-003 + 0.4987811148166657 + 0.6973755955696106 + <_> + + <_> + + + + <_>17 5 2 2 -1. + <_>17 6 2 1 2. + 0 + -2.3008750285953283e-003 + 1 + 0.5339831113815308 + <_> + + + + <_>10 3 4 10 -1. + <_>12 3 2 5 2. + <_>10 8 2 5 2. + 0 + 0.0330261699855328 + 0.5033289194107056 + 0.6851906776428223 + <_> + + <_> + + + + <_>1 5 2 2 -1. + <_>1 6 2 1 2. + 0 + -1.3585069682449102e-003 + 0.3002822101116180 + 1 + <_> + + + + <_>7 10 2 2 -1. + <_>7 10 1 1 2. + <_>8 11 1 1 2. + 0 + 7.8067491995170712e-004 + 0.4593083858489990 + 0.6440045237541199 + <_> + + <_> + + + + <_>3 12 14 4 -1. + <_>10 12 7 2 2. + <_>3 14 7 2 2. + 0 + -0.0180257596075535 + 1 + 0.5311291217803955 + <_> + + + + <_>9 15 3 2 -1. + <_>9 16 3 1 2. + 0 + 1.2354910140857100e-003 + 0.4729106128215790 + 0.5721461176872253 + <_> + + <_> + + + + <_>1 13 3 3 -1. + <_>1 14 3 1 3. + 0 + -9.2583027435466647e-004 + 0.3662332892417908 + 1 + <_> + + + + <_>0 3 1 2 -1. + <_>0 4 1 1 2. + 0 + 8.0123997759073973e-004 + 0.5361989736557007 + 0.3008632957935333 + 32.6471290588378910 + 10 + -1 + <_> + + + <_> + + <_> + + + + <_>7 7 6 1 -1. + <_>9 7 2 1 3. + 0 + 2.4914839304983616e-003 + 0.3422389030456543 + 1 + <_> + + + + <_>0 4 16 6 -1. + <_>0 6 16 2 3. + 0 + -0.0504885986447334 + 0.7703458070755005 + 0.4516390860080719 + <_> + + <_> + + + + <_>9 3 2 14 -1. + <_>9 10 2 7 2. + 0 + -7.7838351717218757e-004 + 1 + 0.3256342113018036 + <_> + + + + <_>12 0 4 3 -1. + <_>12 0 2 3 2. + 0 + 2.3572890495415777e-004 + 0.3406555950641632 + 0.5897027254104614 + <_> + + <_> + + + + <_>4 18 12 2 -1. + <_>8 18 4 2 3. + 0 + 4.5575071126222610e-003 + 0.4306578934192658 + 1 + <_> + + + + <_>4 10 12 4 -1. + <_>8 10 4 4 3. + 0 + 8.1241987645626068e-003 + 0.7149587273597717 + 0.4345684945583344 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -4.4612158671952784e-004 + 0.3295974135398865 + 1 + <_> + + + + <_>14 1 2 8 -1. + <_>15 1 1 4 2. + <_>14 5 1 4 2. + 0 + -2.8972938889637589e-004 + 0.5845620036125183 + 0.3526687920093536 + <_> + + <_> + + + + <_>3 4 9 1 -1. + <_>6 4 3 1 3. + 0 + 7.1604831646254752e-006 + 0.4081954956054688 + 1 + <_> + + + + <_>3 3 4 2 -1. + <_>3 4 4 1 2. + 0 + -3.8497708737850189e-004 + 0.4203113019466400 + 0.6634126901626587 + <_> + + <_> + + + + <_>11 15 2 4 -1. + <_>11 17 2 2 2. + 0 + 1.9489860278554261e-004 + 0.3942466974258423 + 1 + <_> + + + + <_>14 13 2 6 -1. + <_>14 15 2 2 3. + 0 + -0.0170838497579098 + 0.2294072061777115 + 0.5238960981369019 + <_> + + <_> + + + + <_>6 6 1 6 -1. + <_>6 9 1 3 2. + 0 + 8.3513697609305382e-004 + 0.3026031851768494 + 1 + <_> + + + + <_>6 10 8 8 -1. + <_>6 14 8 4 2. + 0 + 7.5499608647078276e-004 + 0.6032196283340454 + 0.3412458896636963 + <_> + + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 8.0216713249683380e-003 + 1 + 0.7306240797042847 + <_> + + + + <_>10 11 4 8 -1. + <_>10 15 4 4 2. + 0 + -0.0389305092394352 + 0.3599325120449066 + 0.5234380960464478 + <_> + + <_> + + + + <_>5 11 6 1 -1. + <_>7 11 2 1 3. + 0 + -7.0348767621908337e-005 + 1 + 0.3493758141994476 + <_> + + + + <_>5 4 6 10 -1. + <_>8 4 3 10 2. + 0 + -8.5350573062896729e-003 + 0.2746109068393707 + 0.5626586079597473 + <_> + + <_> + + + + <_>14 2 6 3 -1. + <_>14 3 6 1 3. + 0 + 0.0108544500544667 + 0.5282226204872131 + 1 + <_> + + + + <_>9 12 3 2 -1. + <_>9 13 3 1 2. + 0 + 4.5329501153901219e-004 + 0.4522049129009247 + 0.6054301857948303 + <_> + + <_> + + + + <_>8 1 4 6 -1. + <_>8 3 4 2 3. + 0 + 1.8117150466423482e-004 + 0.3306862115859985 + 1 + <_> + + + + <_>3 5 13 8 -1. + <_>3 9 13 4 2. + 0 + 4.6641560038551688e-004 + 0.1455000042915344 + 0.5384927988052368 + <_> + + <_> + + + + <_>12 5 5 3 -1. + <_>12 6 5 1 3. + 0 + -8.4854792803525925e-003 + 1 + 0.4814155995845795 + <_> + + + + <_>5 14 15 6 -1. + <_>5 16 15 2 3. + 0 + -0.0189343094825745 + 0.3563741147518158 + 0.5405145287513733 + <_> + + <_> + + + + <_>3 5 5 3 -1. + <_>3 6 5 1 3. + 0 + 4.9814549274742603e-003 + 1 + 0.6957743167877197 + <_> + + + + <_>9 14 2 6 -1. + <_>9 14 1 3 2. + <_>10 17 1 3 2. + 0 + 3.4286780282855034e-003 + 0.5050892829895020 + 0.2316994965076447 + <_> + + <_> + + + + <_>9 12 3 2 -1. + <_>9 13 3 1 2. + 0 + 4.4203791185282171e-004 + 1 + 0.6018581986427307 + <_> + + + + <_>9 13 3 2 -1. + <_>9 14 3 1 2. + 0 + 2.3822550429031253e-004 + 0.4755082130432129 + 0.5585237741470337 + <_> + + <_> + + + + <_>0 2 6 3 -1. + <_>0 3 6 1 3. + 0 + -6.4261639490723610e-003 + 0.2282465994358063 + 1 + <_> + + + + <_>0 1 9 11 -1. + <_>3 1 3 11 3. + 0 + 9.9637769162654877e-003 + 0.4040588140487671 + 0.5650169849395752 + <_> + + <_> + + + + <_>8 13 4 6 -1. + <_>10 13 2 3 2. + <_>8 16 2 3 2. + 0 + 0.0136540504172444 + 0.5267739295959473 + 1 + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + -9.9892877042293549e-003 + 0.6794049739837647 + 0.4797033965587616 + <_> + + <_> + + + + <_>3 12 14 4 -1. + <_>3 12 7 2 2. + <_>10 14 7 2 2. + 0 + 0.0365586318075657 + 1 + 0.0884257331490517 + <_> + + + + <_>7 14 1 4 -1. + <_>7 16 1 2 2. + 0 + 4.8999379941960797e-005 + 0.4020788073539734 + 0.5457332134246826 + <_> + + <_> + + + + <_>8 13 4 6 -1. + <_>10 13 2 3 2. + <_>8 16 2 3 2. + 0 + 0.0136540504172444 + 0.5267612934112549 + 1 + <_> + + + + <_>10 14 1 3 -1. + <_>10 15 1 1 3. + 0 + 1.8802779959514737e-003 + 0.4806052148342133 + 0.6394364833831787 + <_> + + <_> + + + + <_>8 13 4 6 -1. + <_>8 13 2 3 2. + <_>10 16 2 3 2. + 0 + -0.0136540504172444 + 0.1724810004234314 + 1 + <_> + + + + <_>9 14 1 3 -1. + <_>9 15 1 1 3. + 0 + 1.2778700329363346e-003 + 0.4479824006557465 + 0.6310008764266968 + <_> + + <_> + + + + <_>10 15 2 3 -1. + <_>10 16 2 1 3. + 0 + 9.8843395244330168e-004 + 1 + 0.5948169231414795 + <_> + + + + <_>11 16 1 2 -1. + <_>11 17 1 1 2. + 0 + 1.4511500012304168e-005 + 0.4854174852371216 + 0.5309361219406128 + <_> + + <_> + + + + <_>9 0 2 2 -1. + <_>9 1 2 1 2. + 0 + -2.2775429533794522e-004 + 0.3183631896972656 + 1 + <_> + + + + <_>0 1 5 8 -1. + <_>0 5 5 4 2. + 0 + -0.0147537402808666 + 0.3084976077079773 + 0.5352026224136353 + <_> + + <_> + + + + <_>10 14 2 3 -1. + <_>10 15 2 1 3. + 0 + -3.4148250706493855e-003 + 0.6115326881408691 + 1 + <_> + + + + <_>10 13 2 3 -1. + <_>10 14 2 1 3. + 0 + 7.5806681998074055e-003 + 0.4951646029949188 + 0.7061331272125244 + <_> + + <_> + + + + <_>0 3 16 6 -1. + <_>0 6 16 3 2. + 0 + -5.7734688743948936e-003 + 1 + 0.3754220902919769 + <_> + + + + <_>4 1 2 2 -1. + <_>5 1 1 2 2. + 0 + 7.4033669079653919e-005 + 0.4115517139434815 + 0.5889444947242737 + <_> + + <_> + + + + <_>9 7 2 3 -1. + <_>9 8 2 1 3. + 0 + -8.2278084009885788e-003 + 0.0956105664372444 + 1 + <_> + + + + <_>10 8 2 12 -1. + <_>10 12 2 4 3. + 0 + 5.3380909375846386e-003 + 0.5300508737564087 + 0.3961898088455200 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>10 7 1 2 2. + 0 + -2.7049109339714050e-003 + 0.6481869220733643 + 1 + <_> + + + + <_>5 0 6 8 -1. + <_>7 0 2 8 3. + 0 + 7.7341338619589806e-003 + 0.5110440254211426 + 0.3121519088745117 + <_> + + <_> + + + + <_>9 7 3 6 -1. + <_>10 7 1 6 3. + 0 + 0.0108866095542908 + 0.4801428914070129 + 1 + <_> + + + + <_>8 12 10 8 -1. + <_>8 16 10 4 2. + 0 + 0.0110386600717902 + 0.5429710149765015 + 0.4162363111972809 + <_> + + <_> + + + + <_>8 7 3 6 -1. + <_>9 7 1 6 3. + 0 + -0.0100541999563575 + 0.7329335212707520 + 1 + <_> + + + + <_>4 7 12 2 -1. + <_>10 7 6 2 2. + 0 + 7.7072880230844021e-003 + 0.5356872081756592 + 0.3455547094345093 + <_> + + <_> + + + + <_>8 6 8 3 -1. + <_>8 6 4 3 2. + 0 + -5.8278098003938794e-004 + 0.3655022084712982 + 1 + <_> + + + + <_>16 15 3 3 -1. + <_>16 16 3 1 3. + 0 + -2.5739220436662436e-003 + 0.3776760101318359 + 0.5391774773597717 + <_> + + <_> + + + + <_>4 6 12 3 -1. + <_>10 6 6 3 2. + 0 + -7.0167761296033859e-003 + 0.4039304852485657 + 1 + <_> + + + + <_>7 8 3 5 -1. + <_>8 8 1 5 3. + 0 + -1.7727289814502001e-003 + 0.6950443983078003 + 0.4981116950511932 + <_> + + <_> + + + + <_>0 10 20 2 -1. + <_>10 10 10 1 2. + <_>0 11 10 1 2. + 0 + -0.0163182895630598 + 1 + 0.5296732783317566 + <_> + + + + <_>11 16 9 4 -1. + <_>14 16 3 4 3. + 0 + -0.0116630000993609 + 0.5842639803886414 + 0.4789502918720245 + <_> + + <_> + + + + <_>0 5 3 4 -1. + <_>1 5 1 4 3. + 0 + 2.5881489273160696e-003 + 1 + 0.6092178821563721 + <_> + + + + <_>8 15 4 2 -1. + <_>8 15 2 1 2. + <_>10 16 2 1 2. + 0 + -3.7328999023884535e-003 + 0.6721742749214172 + 0.4066894054412842 + <_> + + <_> + + + + <_>1 8 19 3 -1. + <_>1 9 19 1 3. + 0 + -1.4355930034071207e-003 + 0.3585087954998016 + 1 + <_> + + + + <_>15 16 3 3 -1. + <_>15 17 3 1 3. + 0 + 1.8340899841859937e-003 + 0.5371158123016357 + 0.4033507108688355 + <_> + + <_> + + + + <_>0 4 20 10 -1. + <_>0 4 10 5 2. + <_>10 9 10 5 2. + 0 + 0.1228028982877731 + 1 + 0.1547572016716003 + <_> + + + + <_>2 14 7 6 -1. + <_>2 16 7 2 3. + 0 + 0.0502287000417709 + 0.5433843731880188 + 0.0842926725745201 + <_> + + <_> + + + + <_>8 6 6 6 -1. + <_>10 6 2 6 3. + 0 + -0.0214370004832745 + 1 + 0.4860053956508637 + <_> + + + + <_>16 4 4 6 -1. + <_>16 6 4 2 3. + 0 + -0.0310096200555563 + 0.1833010017871857 + 0.5207554101943970 + <_> + + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + -0.0129737202078104 + 0.7048240900039673 + 1 + <_> + + + + <_>7 13 4 3 -1. + <_>7 14 4 1 3. + 0 + 1.5818020328879356e-003 + 0.4170587062835693 + 0.5865163803100586 + <_> + + <_> + + + + <_>13 13 6 2 -1. + <_>13 14 6 1 2. + 0 + -9.7806248813867569e-003 + 1 + 0.5307918190956116 + <_> + + + + <_>14 12 2 3 -1. + <_>14 13 2 1 3. + 0 + 1.1735740117728710e-003 + 0.5522453188896179 + 0.3507165014743805 + <_> + + <_> + + + + <_>1 13 6 2 -1. + <_>1 14 6 1 2. + 0 + 1.4651629608124495e-003 + 1 + 0.3042651116847992 + <_> + + + + <_>4 12 2 3 -1. + <_>4 13 2 1 3. + 0 + 2.3532148916274309e-003 + 0.5339323282241821 + 0.2806236147880554 + <_> + + <_> + + + + <_>17 4 3 5 -1. + <_>18 4 1 5 3. + 0 + -6.1809681355953217e-003 + 0.6410133242607117 + 1 + <_> + + + + <_>5 5 14 8 -1. + <_>12 5 7 4 2. + <_>5 9 7 4 2. + 0 + 6.5688649192452431e-004 + 0.5620871186256409 + 0.4390318989753723 + <_> + + <_> + + + + <_>6 8 6 5 -1. + <_>8 8 2 5 3. + 0 + 0.0262280106544495 + 1 + 0.6445556879043579 + <_> + + + + <_>0 4 4 6 -1. + <_>0 6 4 2 3. + 0 + -0.0179581101983786 + 0.2002713978290558 + 0.4624665081501007 + <_> + + <_> + + + + <_>9 1 3 6 -1. + <_>10 1 1 6 3. + 0 + -7.6468721963465214e-003 + 1 + 0.5263200998306274 + <_> + + + + <_>10 4 6 3 -1. + <_>10 5 6 1 3. + 0 + -2.7482809964567423e-003 + 0.5873981118202210 + 0.4836600124835968 + <_> + + <_> + + + + <_>8 1 3 6 -1. + <_>9 1 1 6 3. + 0 + 0.0138518502935767 + 1 + 0.1566130965948105 + <_> + + + + <_>4 4 6 3 -1. + <_>4 5 6 1 3. + 0 + 2.6369190309196711e-003 + 0.4270178973674774 + 0.5806660056114197 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -3.1513599678874016e-003 + 0.6215866208076477 + 1 + <_> + + + + <_>12 11 4 2 -1. + <_>12 12 4 1 2. + 0 + -1.4788460248382762e-005 + 0.5576642751693726 + 0.4122002124786377 + <_> + + <_> + + + + <_>0 2 20 6 -1. + <_>0 2 10 3 2. + <_>10 5 10 3 2. + 0 + -0.0736769884824753 + 0.1536709964275360 + 1 + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + -3.0912780202925205e-003 + 0.6344268918037415 + 0.4507412016391754 + <_> + + <_> + + + + <_>2 10 16 4 -1. + <_>10 10 8 2 2. + <_>2 12 8 2 2. + 0 + 7.9240966588258743e-003 + 0.5457975268363953 + 1 + <_> + + + + <_>3 10 16 6 -1. + <_>11 10 8 3 2. + <_>3 13 8 3 2. + 0 + 8.5778040811419487e-003 + 0.5401657223701477 + 0.3890799880027771 + <_> + + <_> + + + + <_>1 10 16 6 -1. + <_>1 10 8 3 2. + <_>9 13 8 3 2. + 0 + 5.5403169244527817e-003 + 1 + 0.3555611073970795 + <_> + + + + <_>4 7 2 4 -1. + <_>5 7 1 4 2. + 0 + -1.1886510037584230e-004 + 0.5836750268936157 + 0.4274316132068634 + <_> + + <_> + + + + <_>11 16 9 4 -1. + <_>14 16 3 4 3. + 0 + -0.0184083692729473 + 0.5860440135002136 + 1 + <_> + + + + <_>3 16 14 4 -1. + <_>10 16 7 2 2. + <_>3 18 7 2 2. + 0 + -2.3490579333156347e-003 + 0.4498957991600037 + 0.5498198866844177 + <_> + + <_> + + + + <_>0 16 9 4 -1. + <_>3 16 3 4 3. + 0 + -7.6157399453222752e-003 + 1 + 0.4100992977619171 + <_> + + + + <_>1 14 6 6 -1. + <_>1 14 3 3 2. + <_>4 17 3 3 2. + 0 + -3.3190969843417406e-003 + 0.6701378822326660 + 0.4353001117706299 + <_> + + <_> + + + + <_>9 0 2 1 -1. + <_>9 0 1 1 2. + 0 + -9.4642979092895985e-004 + 1 + 0.5391176939010620 + <_> + + + + <_>6 7 8 10 -1. + <_>10 7 4 5 2. + <_>6 12 4 5 2. + 0 + 8.7858550250530243e-003 + 0.5504050254821777 + 0.3990935087203980 + <_> + + <_> + + + + <_>2 15 1 2 -1. + <_>2 16 1 1 2. + 0 + 1.6395459533669055e-004 + 1 + 0.3592933118343353 + <_> + + + + <_>0 14 7 6 -1. + <_>0 16 7 2 3. + 0 + -2.3508940357714891e-003 + 0.4034172892570496 + 0.5806077122688294 + <_> + + <_> + + + + <_>7 8 6 2 -1. + <_>7 9 6 1 2. + 0 + 7.5449963333085179e-005 + 1 + 0.5412384867668152 + <_> + + + + <_>9 2 2 15 -1. + <_>9 7 2 5 3. + 0 + 0.0270184893161058 + 0.4944922924041748 + 0.5589436292648315 + <_> + + <_> + + + + <_>5 6 2 2 -1. + <_>5 7 2 1 2. + 0 + 8.4561208495870233e-004 + 1 + 0.5809218287467957 + <_> + + + + <_>6 6 8 3 -1. + <_>6 7 8 1 3. + 0 + -1.1687109945341945e-003 + 0.4746957123279572 + 0.2845895886421204 + <_> + + <_> + + + + <_>12 13 5 6 -1. + <_>12 15 5 2 3. + 0 + 0.0228975005447865 + 1 + 0.2414411008358002 + <_> + + + + <_>0 0 20 18 -1. + <_>0 9 20 9 2. + 0 + 0.7087926268577576 + 0.5195764899253845 + 0.1030092015862465 + <_> + + <_> + + + + <_>5 1 6 6 -1. + <_>7 1 2 6 3. + 0 + 0.0374838300049305 + 1 + 0.1814638972282410 + <_> + + + + <_>5 1 4 9 -1. + <_>7 1 2 9 2. + 0 + 1.2827500468119979e-003 + 0.4246071875095367 + 0.5707973241806030 + <_> + + <_> + + + + <_>1 19 18 1 -1. + <_>7 19 6 1 3. + 0 + -5.1718312315642834e-003 + 0.6143323183059692 + 1 + <_> + + + + <_>14 16 5 2 -1. + <_>14 17 5 1 2. + 0 + 2.7545939665287733e-003 + 0.5205671191215515 + 0.4220441877841950 + <_> + + <_> + + + + <_>0 5 15 10 -1. + <_>0 10 15 5 2. + 0 + -3.6072919610887766e-003 + 0.3182592093944550 + 1 + <_> + + + + <_>7 15 4 2 -1. + <_>7 15 2 1 2. + <_>9 16 2 1 2. + 0 + -2.5258748792111874e-004 + 0.5710468292236328 + 0.4226093888282776 + <_> + + <_> + + + + <_>14 11 2 2 -1. + <_>14 12 2 1 2. + 0 + -7.0514748804271221e-003 + 1 + 0.5162829756736755 + <_> + + + + <_>9 8 3 3 -1. + <_>9 9 3 1 3. + 0 + -5.4323761723935604e-003 + 0.2666288912296295 + 0.5214679837226868 + <_> + + <_> + + + + <_>4 11 2 2 -1. + <_>4 12 2 1 2. + 0 + -1.4652940080850385e-005 + 1 + 0.3981761038303375 + <_> + + + + <_>8 8 3 3 -1. + <_>8 9 3 1 3. + 0 + -1.8556920113041997e-003 + 0.3322763144969940 + 0.5705834031105042 + <_> + + <_> + + + + <_>9 10 2 3 -1. + <_>9 11 2 1 3. + 0 + 4.7609540633857250e-003 + 1 + 0.6636558175086975 + <_> + + + + <_>8 8 4 3 -1. + <_>8 9 4 1 3. + 0 + 1.5676260227337480e-003 + 0.5505567789077759 + 0.4420661926269531 + <_> + + <_> + + + + <_>1 9 4 10 -1. + <_>1 9 2 5 2. + <_>3 14 2 5 2. + 0 + 5.4239919409155846e-003 + 1 + 0.5959938168525696 + <_> + + + + <_>0 12 6 8 -1. + <_>2 12 2 8 3. + 0 + -6.4692399464547634e-003 + 0.5369594097137451 + 0.3744339942932129 + <_> + + <_> + + + + <_>9 1 4 2 -1. + <_>11 1 2 1 2. + <_>9 2 2 1 2. + 0 + -7.8038539504632354e-004 + 0.4103595018386841 + 1 + <_> + + + + <_>12 13 7 6 -1. + <_>12 15 7 2 3. + 0 + 0.0450864508748055 + 0.5177506804466248 + 0.1878100037574768 + <_> + + <_> + + + + <_>7 0 2 3 -1. + <_>7 1 2 1 3. + 0 + -5.1405387930572033e-003 + 0.2352892011404038 + 1 + <_> + + + + <_>7 14 6 3 -1. + <_>9 14 2 3 3. + 0 + -0.0212361291050911 + 0.1708751022815704 + 0.5424973964691162 + <_> + + <_> + + + + <_>9 6 6 4 -1. + <_>11 6 2 4 3. + 0 + -2.3763340432196856e-003 + 0.5836530923843384 + 1 + <_> + + + + <_>8 10 8 3 -1. + <_>8 10 4 3 2. + 0 + 0.0541225895285606 + 0.5117433071136475 + 0.1865931004285812 + <_> + + <_> + + + + <_>6 10 4 3 -1. + <_>8 10 2 3 2. + 0 + -5.3492980077862740e-004 + 0.5108693242073059 + 1 + <_> + + + + <_>6 8 3 5 -1. + <_>7 8 1 5 3. + 0 + -5.8454048121348023e-004 + 0.4775491058826447 + 0.2439853996038437 + 30.6721305847167970 + 11 + -1 + <_> + + + <_> + + <_> + + + + <_>0 4 8 1 -1. + <_>4 4 4 1 2. + 0 + 3.0031939968466759e-003 + 0.3349649906158447 + 1 + <_> + + + + <_>8 2 2 6 -1. + <_>8 2 1 3 2. + <_>9 5 1 3 2. + 0 + 6.9161207647994161e-004 + 0.4518367946147919 + 0.7289354205131531 + <_> + + <_> + + + + <_>0 7 20 6 -1. + <_>0 9 20 2 3. + 0 + 0.0112127903848886 + 0.2950800955295563 + 1 + <_> + + + + <_>12 10 3 6 -1. + <_>12 13 3 3 2. + 0 + -7.6108198845759034e-004 + 0.5669054985046387 + 0.2830851078033447 + <_> + + <_> + + + + <_>8 15 1 4 -1. + <_>8 17 1 2 2. + 0 + 1.1984579759882763e-004 + 0.4090577960014343 + 1 + <_> + + + + <_>5 16 2 4 -1. + <_>5 18 2 2 2. + 0 + -1.9725349557120353e-004 + 0.6951494216918945 + 0.4637868106365204 + <_> + + <_> + + + + <_>6 2 8 12 -1. + <_>6 6 8 4 3. + 0 + -5.5180420167744160e-003 + 1 + 0.3167675137519836 + <_> + + + + <_>4 7 12 2 -1. + <_>8 7 4 2 3. + 0 + 1.2148249661549926e-003 + 0.3316706120967865 + 0.5396397709846497 + <_> + + <_> + + + + <_>7 0 6 1 -1. + <_>9 0 2 1 3. + 0 + -4.2497441172599792e-003 + 0.2600573897361755 + 1 + <_> + + + + <_>8 11 3 3 -1. + <_>8 12 3 1 3. + 0 + -9.4915721565485001e-003 + 0.7484294772148132 + 0.5073192119598389 + <_> + + <_> + + + + <_>12 11 3 6 -1. + <_>12 14 3 3 2. + 0 + 6.5378600265830755e-004 + 1 + 0.3952010869979858 + <_> + + + + <_>11 2 6 10 -1. + <_>14 2 3 5 2. + <_>11 7 3 5 2. + 0 + -4.9741100519895554e-004 + 0.5880274772644043 + 0.3552120029926300 + <_> + + <_> + + + + <_>5 7 10 12 -1. + <_>5 7 5 6 2. + <_>10 13 5 6 2. + 0 + -0.0430792495608330 + 0.2434878051280975 + 1 + <_> + + + + <_>4 4 2 10 -1. + <_>4 9 2 5 2. + 0 + -5.1999092102050781e-004 + 0.3195562958717346 + 0.5585454702377319 + <_> + + <_> + + + + <_>9 7 2 3 -1. + <_>9 7 1 3 2. + 0 + -4.5451628975570202e-003 + 1 + 0.4845289885997772 + <_> + + + + <_>11 9 6 2 -1. + <_>11 9 3 2 2. + 0 + -7.9610403627157211e-003 + 0.3801181018352509 + 0.5358511805534363 + <_> + + <_> + + + + <_>4 7 2 2 -1. + <_>5 7 1 2 2. + 0 + -3.1919340835884213e-004 + 1 + 0.4356329143047333 + <_> + + + + <_>0 2 4 6 -1. + <_>0 4 4 2 3. + 0 + -0.0192238893359900 + 0.2613066136837006 + 0.6155496239662170 + <_> + + <_> + + + + <_>10 7 3 4 -1. + <_>11 7 1 4 3. + 0 + -1.3076990144327283e-003 + 0.5942062139511108 + 1 + <_> + + + + <_>9 7 3 5 -1. + <_>10 7 1 5 3. + 0 + 0.0198250394314528 + 0.4945428073406220 + 0.7384855151176453 + <_> + + <_> + + + + <_>9 1 1 3 -1. + <_>9 2 1 1 3. + 0 + -2.2013280540704727e-003 + 0.2214481979608536 + 1 + <_> + + + + <_>0 6 16 6 -1. + <_>0 6 8 3 2. + <_>8 9 8 3 2. + 0 + -7.8596705570816994e-003 + 0.3600977063179016 + 0.5298550128936768 + <_> + + <_> + + + + <_>10 15 3 3 -1. + <_>10 16 3 1 3. + 0 + 1.4142199652269483e-003 + 1 + 0.5776566267013550 + <_> + + + + <_>9 14 4 3 -1. + <_>9 15 4 1 3. + 0 + -0.0112327598035336 + 0.6934456825256348 + 0.4827207028865814 + <_> + + <_> + + + + <_>3 2 6 10 -1. + <_>3 2 3 5 2. + <_>6 7 3 5 2. + 0 + 2.9746301006525755e-003 + 1 + 0.3216677010059357 + <_> + + + + <_>3 0 14 2 -1. + <_>3 1 14 1 2. + 0 + 5.3283828310668468e-004 + 0.3962500095367432 + 0.5680363774299622 + <_> + + <_> + + + + <_>9 14 3 3 -1. + <_>9 15 3 1 3. + 0 + 0.0101052597165108 + 1 + 0.7567418217658997 + <_> + + + + <_>10 15 3 3 -1. + <_>10 16 3 1 3. + 0 + -0.0116536999121308 + 0.6523556709289551 + 0.5027053952217102 + <_> + + <_> + + + + <_>9 13 2 6 -1. + <_>9 16 2 3 2. + 0 + -7.0609981194138527e-003 + 0.2538770139217377 + 1 + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + 2.2343141026794910e-003 + 0.4387277066707611 + 0.6177632212638855 + <_> + + <_> + + + + <_>12 11 3 6 -1. + <_>12 14 3 3 2. + 0 + -0.0298022795468569 + 1 + 0.5201140046119690 + <_> + + + + <_>8 12 5 2 -1. + <_>8 13 5 1 2. + 0 + 1.1611840454861522e-003 + 0.4647909998893738 + 0.6184254884719849 + <_> + + <_> + + + + <_>5 11 3 6 -1. + <_>5 14 3 3 2. + 0 + 9.4824447296559811e-004 + 1 + 0.3040994107723236 + <_> + + + + <_>8 12 3 2 -1. + <_>8 13 3 1 2. + 0 + 4.1284630424343050e-004 + 0.4518808126449585 + 0.6245782971382141 + <_> + + <_> + + + + <_>11 13 7 6 -1. + <_>11 15 7 2 3. + 0 + -0.0312035400420427 + 0.2788935899734497 + 1 + <_> + + + + <_>7 14 6 3 -1. + <_>7 15 6 1 3. + 0 + 2.7652881108224392e-003 + 0.4698500037193298 + 0.6502454280853272 + <_> + + <_> + + + + <_>3 13 14 4 -1. + <_>3 13 7 2 2. + <_>10 15 7 2 2. + 0 + 0.0256447792053223 + 1 + 0.1805171072483063 + <_> + + + + <_>8 14 4 6 -1. + <_>8 14 2 3 2. + <_>10 17 2 3 2. + 0 + -7.5331530533730984e-003 + 0.3208068907260895 + 0.5522022843360901 + <_> + + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + 3.2047149725258350e-003 + 1 + 0.6436933875083923 + <_> + + + + <_>7 16 6 2 -1. + <_>9 16 2 2 3. + 0 + -2.4282479716930538e-004 + 0.5676705241203308 + 0.4509103894233704 + <_> + + <_> + + + + <_>7 7 6 2 -1. + <_>7 8 6 1 2. + 0 + -6.1979342717677355e-004 + 0.3122146129608154 + 1 + <_> + + + + <_>3 9 13 3 -1. + <_>3 10 13 1 3. + 0 + -8.0101029016077518e-004 + 0.2965193986892700 + 0.5230494737625122 + <_> + + <_> + + + + <_>9 8 3 4 -1. + <_>9 10 3 2 2. + 0 + -9.1816839994862676e-004 + 1 + 0.5464711785316467 + <_> + + + + <_>8 10 4 3 -1. + <_>8 11 4 1 3. + 0 + 1.2239529751241207e-003 + 0.4618502855300903 + 0.5679548978805542 + <_> + + <_> + + + + <_>7 7 3 4 -1. + <_>8 7 1 4 3. + 0 + -6.8743730662390590e-004 + 0.5430880188941956 + 1 + <_> + + + + <_>8 7 3 5 -1. + <_>9 7 1 5 3. + 0 + -1.8252469599246979e-003 + 0.5433623194694519 + 0.3385221064090729 + <_> + + <_> + + + + <_>12 3 3 4 -1. + <_>13 3 1 4 3. + 0 + -7.4570789001882076e-003 + 1 + 0.5265594720840454 + <_> + + + + <_>9 7 2 3 -1. + <_>9 7 1 3 2. + 0 + 5.3775748237967491e-003 + 0.4857215881347656 + 0.6815124154090881 + <_> + + <_> + + + + <_>5 3 3 4 -1. + <_>6 3 1 4 3. + 0 + 3.7602309603244066e-003 + 1 + 0.2832160890102387 + <_> + + + + <_>3 7 12 1 -1. + <_>7 7 4 1 3. + 0 + 8.7752222316339612e-004 + 0.3966830968856812 + 0.5512480735778809 + <_> + + <_> + + + + <_>12 5 3 3 -1. + <_>12 6 3 1 3. + 0 + 5.5084479972720146e-003 + 1 + 0.6784620285034180 + <_> + + + + <_>11 2 6 2 -1. + <_>11 3 6 1 2. + 0 + -7.5949047459289432e-004 + 0.3906503021717072 + 0.5457202792167664 + <_> + + <_> + + + + <_>3 2 14 2 -1. + <_>3 2 7 1 2. + <_>10 3 7 1 2. + 0 + 1.6352660022675991e-003 + 1 + 0.3640204071998596 + <_> + + + + <_>6 1 7 14 -1. + <_>6 8 7 7 2. + 0 + -1.2750849418807775e-004 + 0.5829724073410034 + 0.4194979965686798 + <_> + + <_> + + + + <_>8 0 12 5 -1. + <_>8 0 6 5 2. + 0 + 0.0220676101744175 + 0.4606702923774719 + 1 + <_> + + + + <_>1 9 18 1 -1. + <_>7 9 6 1 3. + 0 + -0.0192037895321846 + 0.3261483013629913 + 0.5236080884933472 + <_> + + <_> + + + + <_>0 0 10 5 -1. + <_>5 0 5 5 2. + 0 + -0.0129981096833944 + 0.7022112011909485 + 1 + <_> + + + + <_>2 5 8 15 -1. + <_>2 10 8 5 3. + 0 + -3.1332690268754959e-003 + 0.2870470881462097 + 0.5076476931571960 + <_> + + <_> + + + + <_>12 5 3 3 -1. + <_>12 6 3 1 3. + 0 + -5.2937557920813560e-003 + 1 + 0.4709520936012268 + <_> + + + + <_>13 4 2 3 -1. + <_>13 5 2 1 3. + 0 + 2.1857069805264473e-003 + 0.4708291888237000 + 0.6169841885566711 + <_> + + <_> + + + + <_>2 15 4 3 -1. + <_>2 16 4 1 3. + 0 + -4.5750709250569344e-003 + 0.3114252984523773 + 1 + <_> + + + + <_>5 6 10 3 -1. + <_>10 6 5 3 2. + 0 + -0.0451521389186382 + 0.1851435005664825 + 0.5504814982414246 + <_> + + <_> + + + + <_>11 6 2 2 -1. + <_>12 6 1 1 2. + <_>11 7 1 1 2. + 0 + -2.7783559635281563e-003 + 1 + 0.4937348067760468 + <_> + + + + <_>12 4 4 3 -1. + <_>12 5 4 1 3. + 0 + -2.5752480141818523e-003 + 0.6152948141098023 + 0.4735499918460846 + <_> + + <_> + + + + <_>7 6 2 2 -1. + <_>7 6 1 1 2. + <_>8 7 1 1 2. + 0 + 1.1614130344241858e-003 + 1 + 0.6510571837425232 + <_> + + + + <_>4 4 4 3 -1. + <_>4 5 4 1 3. + 0 + 2.3350189439952374e-003 + 0.4088341891765595 + 0.5684152245521545 + <_> + + <_> + + + + <_>11 4 3 3 -1. + <_>12 4 1 3 3. + 0 + 3.8499289657920599e-003 + 1 + 0.3025828897953033 + <_> + + + + <_>9 3 2 1 -1. + <_>9 3 1 1 2. + 0 + 2.4529630318284035e-003 + 0.5232502818107605 + 0.2017620950937271 + <_> + + <_> + + + + <_>4 5 5 3 -1. + <_>4 6 5 1 3. + 0 + 3.6731390282511711e-003 + 1 + 0.6428425908088684 + <_> + + + + <_>4 6 4 3 -1. + <_>4 7 4 1 3. + 0 + 2.1937100682407618e-003 + 0.4328865110874176 + 0.6420509815216065 + <_> + + <_> + + + + <_>11 4 3 3 -1. + <_>12 4 1 3 3. + 0 + -6.4666871912777424e-003 + 1 + 0.5254065990447998 + <_> + + + + <_>8 8 4 3 -1. + <_>8 9 4 1 3. + 0 + -5.7186251506209373e-003 + 0.2490984052419663 + 0.5287619233131409 + <_> + + <_> + + + + <_>6 4 3 3 -1. + <_>7 4 1 3 3. + 0 + 9.9941878579556942e-004 + 1 + 0.3329795897006989 + <_> + + + + <_>4 14 1 3 -1. + <_>4 15 1 1 3. + 0 + -7.8276498243212700e-004 + 0.3598344922065735 + 0.5498340725898743 + <_> + + <_> + + + + <_>9 7 2 3 -1. + <_>9 7 1 3 2. + 0 + 4.3231188319623470e-003 + 0.4818705022335053 + 1 + <_> + + + + <_>17 0 3 2 -1. + <_>17 1 3 1 2. + 0 + 4.0838290005922318e-003 + 0.5266330242156982 + 0.3105789124965668 + <_> + + <_> + + + + <_>8 10 2 9 -1. + <_>8 13 2 3 3. + 0 + 3.0515898833982646e-004 + 1 + 0.3995291888713837 + <_> + + + + <_>0 8 18 2 -1. + <_>0 9 18 1 2. + 0 + 1.2640280183404684e-003 + 0.3228437900543213 + 0.5819215178489685 + <_> + + <_> + + + + <_>9 15 2 3 -1. + <_>9 16 2 1 3. + 0 + -0.0101526603102684 + 0.8026071190834045 + 1 + <_> + + + + <_>8 7 4 3 -1. + <_>8 8 4 1 3. + 0 + -2.6863690000027418e-003 + 0.3875617086887360 + 0.5466570854187012 + <_> + + <_> + + + + <_>1 14 6 6 -1. + <_>1 14 3 3 2. + <_>4 17 3 3 2. + 0 + -9.0515613555908203e-003 + 1 + 0.4372057914733887 + <_> + + + + <_>0 18 6 2 -1. + <_>0 19 6 1 2. + 0 + -6.3204211182892323e-003 + 0.1126551032066345 + 0.6395416259765625 + <_> + + <_> + + + + <_>12 9 4 3 -1. + <_>12 9 2 3 2. + 0 + 2.6117300149053335e-003 + 0.5423989295959473 + 1 + <_> + + + + <_>9 8 3 8 -1. + <_>10 8 1 8 3. + 0 + 0.0143390195444226 + 0.4979273080825806 + 0.6042236089706421 + <_> + + <_> + + + + <_>4 9 4 3 -1. + <_>6 9 2 3 2. + 0 + 2.8452780097723007e-003 + 1 + 0.3491092026233673 + <_> + + + + <_>4 18 6 1 -1. + <_>6 18 2 1 3. + 0 + 1.4783289771003183e-005 + 0.4195067882537842 + 0.5775966048240662 + <_> + + <_> + + + + <_>9 7 3 2 -1. + <_>10 7 1 2 3. + 0 + 8.1814555451273918e-003 + 0.4885987043380737 + 1 + <_> + + + + <_>6 7 8 12 -1. + <_>10 7 4 6 2. + <_>6 13 4 6 2. + 0 + 6.6321990452706814e-003 + 0.5444468259811401 + 0.4420995116233826 + <_> + + <_> + + + + <_>8 7 3 2 -1. + <_>9 7 1 2 3. + 0 + -2.2483461070805788e-003 + 0.6699792146682739 + 1 + <_> + + + + <_>8 7 3 6 -1. + <_>9 7 1 6 3. + 0 + 0.0123745603486896 + 0.4478605985641480 + 0.6564893722534180 + <_> + + <_> + + + + <_>3 16 14 4 -1. + <_>10 16 7 2 2. + <_>3 18 7 2 2. + 0 + -6.6516688093543053e-003 + 1 + 0.5511878728866577 + <_> + + + + <_>1 14 18 4 -1. + <_>10 14 9 2 2. + <_>1 16 9 2 2. + 0 + -8.5750613361597061e-003 + 0.4017445147037506 + 0.5405536293983460 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>8 8 3 1 3. + 0 + 6.5078441984951496e-003 + 1 + 0.2294393032789230 + <_> + + + + <_>0 4 20 12 -1. + <_>0 4 10 6 2. + <_>10 10 10 6 2. + 0 + 0.0286752097308636 + 0.5177900195121765 + 0.3567756116390228 + <_> + + <_> + + + + <_>5 5 10 12 -1. + <_>10 5 5 6 2. + <_>5 11 5 6 2. + 0 + 7.0673860609531403e-003 + 0.5564699769020081 + 1 + <_> + + + + <_>10 2 4 7 -1. + <_>10 2 2 7 2. + 0 + 1.2367829913273454e-003 + 0.3627698123455048 + 0.5572413802146912 + <_> + + <_> + + + + <_>8 11 4 3 -1. + <_>8 12 4 1 3. + 0 + 7.4818679131567478e-003 + 1 + 0.6784911155700684 + <_> + + + + <_>8 12 3 3 -1. + <_>8 13 3 1 3. + 0 + 4.7109839506447315e-003 + 0.4121252894401550 + 0.6072235703468323 + <_> + + <_> + + + + <_>13 13 5 6 -1. + <_>13 15 5 2 3. + 0 + -6.9405790418386459e-003 + 1 + 0.5459766983985901 + <_> + + + + <_>7 0 6 6 -1. + <_>9 0 2 6 3. + 0 + 0.0333020985126495 + 0.5276706814765930 + 0.2374915927648544 + <_> + + <_> + + + + <_>2 13 5 6 -1. + <_>2 15 5 2 3. + 0 + 0.0361046306788921 + 1 + 0.0724927932024002 + <_> + + + + <_>0 4 2 12 -1. + <_>0 4 1 6 2. + <_>1 10 1 6 2. + 0 + 0.0196746494621038 + 0.4626345932483673 + 0.8208963274955750 + <_> + + <_> + + + + <_>9 19 3 1 -1. + <_>10 19 1 1 3. + 0 + 3.4766150638461113e-003 + 0.5208731889724731 + 1 + <_> + + + + <_>18 0 2 6 -1. + <_>18 2 2 2 3. + 0 + 1.3987369602546096e-003 + 0.5484414100646973 + 0.4230034947395325 + <_> + + <_> + + + + <_>0 3 1 6 -1. + <_>0 5 1 2 3. + 0 + 4.0974249131977558e-003 + 1 + 0.2780553102493286 + <_> + + + + <_>0 0 3 6 -1. + <_>0 2 3 2 3. + 0 + 2.6973790954798460e-003 + 0.5403831005096436 + 0.3790988922119141 + <_> + + <_> + + + + <_>17 2 3 7 -1. + <_>18 2 1 7 3. + 0 + -5.6591699831187725e-003 + 1 + 0.4798336029052734 + <_> + + + + <_>10 3 4 7 -1. + <_>10 3 2 7 2. + 0 + 3.9460969856008887e-004 + 0.3766950070858002 + 0.5429229140281677 + <_> + + <_> + + + + <_>0 2 3 7 -1. + <_>1 2 1 7 3. + 0 + 2.1750570740550756e-003 + 1 + 0.6207162737846375 + <_> + + + + <_>6 2 4 8 -1. + <_>8 2 2 8 2. + 0 + 1.4614439569413662e-003 + 0.3357945084571838 + 0.5142632126808167 + <_> + + <_> + + + + <_>13 0 1 4 -1. + <_>13 2 1 2 2. + 0 + -5.3006567759439349e-004 + 1 + 0.5344640016555786 + <_> + + + + <_>5 1 12 5 -1. + <_>9 1 4 5 3. + 0 + 0.1486930996179581 + 0.5159608125686646 + 0.2561823129653931 + <_> + + <_> + + + + <_>6 0 1 4 -1. + <_>6 2 1 2 2. + 0 + -5.8816498494707048e-005 + 1 + 0.5123091936111450 + <_> + + + + <_>3 1 12 5 -1. + <_>7 1 4 5 3. + 0 + -1.6275369562208652e-003 + 0.6017646193504334 + 0.3109371960163117 + <_> + + <_> + + + + <_>9 12 3 8 -1. + <_>10 12 1 8 3. + 0 + -0.0128818098455668 + 0.2712287008762360 + 1 + <_> + + + + <_>7 13 6 1 -1. + <_>9 13 2 1 3. + 0 + 9.4982917653396726e-004 + 0.5442442297935486 + 0.4028888046741486 + <_> + + <_> + + + + <_>7 14 6 3 -1. + <_>7 15 6 1 3. + 0 + -0.0123159997165203 + 1 + 0.4736065864562988 + <_> + + + + <_>5 16 7 3 -1. + <_>5 17 7 1 3. + 0 + 9.0286601334810257e-003 + 0.7451434731483460 + 0.3487991988658905 + <_> + + <_> + + + + <_>0 12 20 6 -1. + <_>0 14 20 2 3. + 0 + -0.0868761166930199 + 0.2290333062410355 + 1 + <_> + + + + <_>4 18 14 2 -1. + <_>4 19 14 1 2. + 0 + -1.5107560102478601e-005 + 0.5517889857292175 + 0.4393149018287659 + <_> + + <_> + + + + <_>8 12 3 8 -1. + <_>9 12 1 8 3. + 0 + -0.0174576602876186 + 0.0901679024100304 + 1 + <_> + + + + <_>7 13 3 3 -1. + <_>7 14 3 1 3. + 0 + -2.5219470262527466e-003 + 0.6233540177345276 + 0.4789459109306335 + <_> + + <_> + + + + <_>5 5 12 10 -1. + <_>11 5 6 5 2. + <_>5 10 6 5 2. + 0 + 1.0656520025804639e-003 + 0.5489696264266968 + 1 + <_> + + + + <_>8 1 5 10 -1. + <_>8 6 5 5 2. + 0 + -4.2540300637483597e-003 + 0.5579808950424194 + 0.4375877976417542 + <_> + + <_> + + + + <_>5 4 9 12 -1. + <_>5 10 9 6 2. + 0 + -9.0349102392792702e-003 + 0.3579156100749970 + 1 + <_> + + + + <_>7 13 6 6 -1. + <_>7 15 6 2 3. + 0 + -1.5230999561026692e-003 + 0.5613660216331482 + 0.3939043879508972 + <_> + + <_> + + + + <_>8 4 5 16 -1. + <_>8 12 5 8 2. + 0 + 2.8441150207072496e-003 + 1 + 0.3901554942131043 + <_> + + + + <_>8 12 4 6 -1. + <_>8 15 4 3 2. + 0 + -3.2824429217725992e-003 + 0.4528619050979614 + 0.5441343188285828 + <_> + + <_> + + + + <_>7 13 2 2 -1. + <_>7 13 1 1 2. + <_>8 14 1 1 2. + 0 + 3.2161718991119415e-005 + 1 + 0.5803111791610718 + <_> + + + + <_>7 12 2 2 -1. + <_>7 12 1 1 2. + <_>8 13 1 1 2. + 0 + 3.0118400900391862e-005 + 0.3336850106716156 + 0.5504856109619141 + <_> + + <_> + + + + <_>18 0 2 14 -1. + <_>18 0 1 14 2. + 0 + -5.6150099262595177e-003 + 0.6124789118766785 + 1 + <_> + + + + <_>12 11 7 2 -1. + <_>12 12 7 1 2. + 0 + -0.0173892099410295 + 0.0872716307640076 + 0.5204588174819946 + <_> + + <_> + + + + <_>1 18 1 2 -1. + <_>1 19 1 1 2. + 0 + -4.4361080654198304e-005 + 0.3935329020023346 + 1 + <_> + + + + <_>2 18 1 2 -1. + <_>2 19 1 1 2. + 0 + 1.0354899859521538e-004 + 0.5918853878974915 + 0.4119614064693451 + <_> + + <_> + + + + <_>9 7 2 1 -1. + <_>9 7 1 1 2. + 0 + 1.5939630102366209e-003 + 0.4839623868465424 + 1 + <_> + + + + <_>9 6 2 3 -1. + <_>9 6 1 3 2. + 0 + 2.5440789759159088e-003 + 0.4787364900112152 + 0.6360663175582886 + <_> + + <_> + + + + <_>3 1 2 2 -1. + <_>4 1 1 2 2. + 0 + 1.5083180187502876e-005 + 0.4231117069721222 + 1 + <_> + + + + <_>3 0 3 2 -1. + <_>3 1 3 1 2. + 0 + -9.9282202427275479e-005 + 0.4274589121341705 + 0.6094048023223877 + <_> + + <_> + + + + <_>12 10 3 4 -1. + <_>12 12 3 2 2. + 0 + 5.5371708003804088e-004 + 1 + 0.4271987974643707 + <_> + + + + <_>7 7 8 2 -1. + <_>7 8 8 1 2. + 0 + 1.9186759600415826e-003 + 0.4497107863426209 + 0.5549122095108032 + <_> + + <_> + + + + <_>8 8 3 4 -1. + <_>8 10 3 2 2. + 0 + -5.0764222396537662e-004 + 1 + 0.5477195978164673 + <_> + + + + <_>7 12 6 3 -1. + <_>7 13 6 1 3. + 0 + 1.7236480489373207e-003 + 0.2882922887802124 + 0.5615127086639404 + 34.6770782470703120 + 12 + -1 + <_> + + + <_> + + <_> + + + + <_>0 2 10 3 -1. + <_>5 2 5 3 2. + 0 + 0.0130921695381403 + 0.3338870108127594 + 1 + <_> + + + + <_>0 1 20 6 -1. + <_>0 3 20 2 3. + 0 + 4.1446479735895991e-004 + 0.3099352121353149 + 0.6677492260932922 + <_> + + <_> + + + + <_>7 6 6 3 -1. + <_>9 6 2 3 3. + 0 + 0.0218357294797897 + 0.4369049072265625 + 1 + <_> + + + + <_>3 7 14 4 -1. + <_>3 9 14 2 2. + 0 + 0.0483239404857159 + 0.4301724135875702 + 0.6153885126113892 + <_> + + <_> + + + + <_>5 7 3 6 -1. + <_>5 9 3 2 3. + 0 + 1.6091950237751007e-003 + 0.3387326002120972 + 1 + <_> + + + + <_>8 8 3 12 -1. + <_>8 12 3 4 3. + 0 + 1.3469760306179523e-003 + 0.6248713731765747 + 0.3594130873680115 + <_> + + <_> + + + + <_>9 17 6 2 -1. + <_>12 17 3 1 2. + <_>9 18 3 1 2. + 0 + 1.7729059618432075e-004 + 0.3868424892425537 + 1 + <_> + + + + <_>10 17 4 3 -1. + <_>10 18 4 1 3. + 0 + 3.6743620876222849e-004 + 0.4409345090389252 + 0.5476474165916443 + <_> + + <_> + + + + <_>4 2 4 2 -1. + <_>4 3 4 1 2. + 0 + -1.2352119665592909e-003 + 0.3260171115398407 + 1 + <_> + + + + <_>7 3 6 14 -1. + <_>9 3 2 14 3. + 0 + 1.1705530341714621e-003 + 0.4111348986625671 + 0.6088163852691650 + <_> + + <_> + + + + <_>15 13 1 6 -1. + <_>15 16 1 3 2. + 0 + -2.9695429475395940e-005 + 1 + 0.4269422888755798 + <_> + + + + <_>13 14 2 6 -1. + <_>13 16 2 2 3. + 0 + 2.7050738572143018e-004 + 0.4306466877460480 + 0.5810514092445374 + <_> + + <_> + + + + <_>4 11 5 6 -1. + <_>4 14 5 3 2. + 0 + -7.9626210208516568e-005 + 1 + 0.3669143021106720 + <_> + + + + <_>4 17 4 2 -1. + <_>6 17 2 2 2. + 0 + 3.3152441028505564e-004 + 0.4610663950443268 + 0.6290590167045593 + <_> + + <_> + + + + <_>0 6 20 2 -1. + <_>0 6 10 2 2. + 0 + -0.0523058287799358 + 1 + 0.5328689813613892 + <_> + + + + <_>6 5 10 12 -1. + <_>11 5 5 6 2. + <_>6 11 5 6 2. + 0 + 0.0268804691731930 + 0.5213261246681213 + 0.3231219947338104 + <_> + + <_> + + + + <_>4 0 2 12 -1. + <_>4 0 1 6 2. + <_>5 6 1 6 2. + 0 + -2.4203000066336244e-004 + 1 + 0.3568570017814636 + <_> + + + + <_>4 1 6 2 -1. + <_>6 1 2 2 3. + 0 + -1.6424639616161585e-003 + 0.3440661132335663 + 0.5625604987144470 + <_> + + <_> + + + + <_>13 7 2 1 -1. + <_>13 7 1 1 2. + 0 + -2.6830288697965443e-004 + 1 + 0.4561173021793366 + <_> + + + + <_>5 5 15 6 -1. + <_>5 7 15 2 3. + 0 + -2.2649629972875118e-003 + 0.5321351885795593 + 0.3674154877662659 + <_> + + <_> + + + + <_>1 10 18 2 -1. + <_>1 10 9 1 2. + <_>10 11 9 1 2. + 0 + 0.0156272090971470 + 1 + 0.2029353976249695 + <_> + + + + <_>1 6 15 7 -1. + <_>6 6 5 7 3. + 0 + 0.1621132045984268 + 0.5563033223152161 + 0.2618849873542786 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + -3.7391691002994776e-003 + 0.6062194705009460 + 1 + <_> + + + + <_>9 14 3 3 -1. + <_>9 15 3 1 3. + 0 + -2.0878419745713472e-003 + 0.5950763821601868 + 0.4545117020606995 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 2.3334210272878408e-003 + 1 + 0.6435524225234985 + <_> + + + + <_>8 13 3 2 -1. + <_>8 14 3 1 2. + 0 + 6.5116386394947767e-005 + 0.3520734012126923 + 0.5179778933525085 + <_> + + <_> + + + + <_>15 14 5 3 -1. + <_>15 15 5 1 3. + 0 + 7.4625718407332897e-003 + 0.5326688289642334 + 1 + <_> + + + + <_>0 14 20 1 -1. + <_>0 14 10 1 2. + 0 + -0.0220326893031597 + 0.3491981029510498 + 0.5429236888885498 + <_> + + <_> + + + + <_>0 14 6 3 -1. + <_>0 15 6 1 3. + 0 + -8.3081610500812531e-003 + 0.2084023058414459 + 1 + <_> + + + + <_>5 3 4 2 -1. + <_>5 4 4 1 2. + 0 + -4.3259368976578116e-004 + 0.3965272009372711 + 0.5425453782081604 + <_> + + <_> + + + + <_>0 6 20 1 -1. + <_>0 6 10 1 2. + 0 + -0.0322092287242413 + 1 + 0.5306411981582642 + <_> + + + + <_>6 3 10 14 -1. + <_>11 3 5 7 2. + <_>6 10 5 7 2. + 0 + -9.0424838708713651e-004 + 0.5450385808944702 + 0.4256696999073029 + <_> + + <_> + + + + <_>8 12 4 2 -1. + <_>8 13 4 1 2. + 0 + 2.2727500181645155e-003 + 1 + 0.5968611240386963 + <_> + + + + <_>6 3 8 6 -1. + <_>6 3 4 3 2. + <_>10 6 4 3 2. + 0 + 5.9820008464157581e-003 + 0.4758140146732330 + 0.3150944113731384 + <_> + + <_> + + + + <_>13 7 2 1 -1. + <_>13 7 1 1 2. + 0 + -5.8856618124991655e-004 + 1 + 0.4847748875617981 + <_> + + + + <_>6 3 10 14 -1. + <_>11 3 5 7 2. + <_>6 10 5 7 2. + 0 + -8.8227191008627415e-004 + 0.5426316261291504 + 0.4338341057300568 + <_> + + <_> + + + + <_>5 7 2 1 -1. + <_>6 7 1 1 2. + 0 + -7.4473457061685622e-005 + 1 + 0.4287509918212891 + <_> + + + + <_>4 3 10 14 -1. + <_>4 3 5 7 2. + <_>9 10 5 7 2. + 0 + 3.9148979703895748e-004 + 0.6345185041427612 + 0.4101851880550385 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>9 7 1 2 2. + 0 + -3.6939629353582859e-003 + 1 + 0.4849104881286621 + <_> + + + + <_>0 3 20 1 -1. + <_>0 3 10 1 2. + 0 + -0.0112078497186303 + 0.4146336913108826 + 0.5471264123916626 + <_> + + <_> + + + + <_>2 1 10 3 -1. + <_>2 2 10 1 3. + 0 + -0.0103374095633626 + 0.2877183854579926 + 1 + <_> + + + + <_>9 7 2 2 -1. + <_>10 7 1 2 2. + 0 + 3.6883640568703413e-003 + 0.5101901888847351 + 0.7216951251029968 + <_> + + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + -3.8984280545264482e-003 + 1 + 0.5276182293891907 + <_> + + + + <_>9 7 3 6 -1. + <_>10 7 1 6 3. + 0 + -5.9986729174852371e-003 + 0.6618459820747376 + 0.4841631054878235 + <_> + + <_> + + + + <_>8 17 3 2 -1. + <_>9 17 1 2 3. + 0 + 4.5043681748211384e-003 + 1 + 0.1874157935380936 + <_> + + + + <_>8 7 3 6 -1. + <_>9 7 1 6 3. + 0 + 0.0177995301783085 + 0.4616934955120087 + 0.7088965773582459 + <_> + + <_> + + + + <_>16 3 4 6 -1. + <_>16 5 4 2 3. + 0 + -0.0184625703841448 + 0.3001979887485504 + 1 + <_> + + + + <_>15 6 2 12 -1. + <_>16 6 1 6 2. + <_>15 12 1 6 2. + 0 + 1.4931300029275008e-005 + 0.4561808109283447 + 0.5610787868499756 + <_> + + <_> + + + + <_>1 4 18 10 -1. + <_>1 4 9 5 2. + <_>10 9 9 5 2. + 0 + -0.0860212296247482 + 0.2341700941324234 + 1 + <_> + + + + <_>9 4 2 4 -1. + <_>9 6 2 2 2. + 0 + -6.0818758356617764e-005 + 0.5672286152839661 + 0.4199964106082916 + <_> + + <_> + + + + <_>12 5 3 2 -1. + <_>12 6 3 1 2. + 0 + 1.2670679716393352e-003 + 1 + 0.6207482218742371 + <_> + + + + <_>5 12 10 4 -1. + <_>5 14 10 2 2. + 0 + 1.3699879636988044e-003 + 0.5394958853721619 + 0.3823862969875336 + <_> + + <_> + + + + <_>5 5 3 2 -1. + <_>5 6 3 1 2. + 0 + 3.3162781037390232e-003 + 1 + 0.7061681151390076 + <_> + + + + <_>4 6 12 6 -1. + <_>8 6 4 6 3. + 0 + -1.4532039640471339e-003 + 0.3065513074398041 + 0.4827373027801514 + <_> + + <_> + + + + <_>14 4 6 6 -1. + <_>14 6 6 2 3. + 0 + -0.0714920610189438 + 1 + 0.5193122029304504 + <_> + + + + <_>16 0 4 6 -1. + <_>18 0 2 3 2. + <_>16 3 2 3 2. + 0 + 1.9857978913933039e-003 + 0.4642435014247894 + 0.5807694792747498 + <_> + + <_> + + + + <_>0 4 6 6 -1. + <_>0 6 6 2 3. + 0 + 6.2516499310731888e-003 + 1 + 0.2949813902378082 + <_> + + + + <_>0 0 4 6 -1. + <_>0 0 2 3 2. + <_>2 3 2 3 2. + 0 + 2.7005500160157681e-003 + 0.4585886895656586 + 0.6022353768348694 + <_> + + <_> + + + + <_>12 0 8 5 -1. + <_>12 0 4 5 2. + 0 + 0.0111303897574544 + 0.4357841014862061 + 1 + <_> + + + + <_>16 0 4 17 -1. + <_>16 0 2 17 2. + 0 + 0.0150928497314453 + 0.4561539888381958 + 0.6119061708450317 + <_> + + <_> + + + + <_>1 0 18 20 -1. + <_>7 0 6 20 3. + 0 + -0.0279433000832796 + 0.6537144184112549 + 1 + <_> + + + + <_>6 0 2 5 -1. + <_>7 0 1 5 2. + 0 + 4.4036991312168539e-005 + 0.3474723100662231 + 0.5336967706680298 + <_> + + <_> + + + + <_>0 6 20 1 -1. + <_>0 6 10 1 2. + 0 + -0.0122327702119946 + 0.3731676042079926 + 1 + <_> + + + + <_>8 7 6 4 -1. + <_>10 7 2 4 3. + 0 + -6.8591412855312228e-004 + 0.5717229247093201 + 0.4793379008769989 + <_> + + <_> + + + + <_>1 1 16 4 -1. + <_>1 1 8 2 2. + <_>9 3 8 2 2. + 0 + -3.8992990739643574e-003 + 0.4056436121463776 + 1 + <_> + + + + <_>7 2 4 2 -1. + <_>7 2 2 1 2. + <_>9 3 2 1 2. + 0 + 4.9113907152786851e-004 + 0.6174048185348511 + 0.4471754133701325 + <_> + + <_> + + + + <_>7 4 9 3 -1. + <_>7 5 9 1 3. + 0 + 8.2117747515439987e-003 + 1 + 0.6179698109626770 + <_> + + + + <_>10 4 5 12 -1. + <_>10 10 5 6 2. + 0 + -0.0455644801259041 + 0.2285494953393936 + 0.5249565839767456 + <_> + + <_> + + + + <_>3 12 2 3 -1. + <_>3 13 2 1 3. + 0 + -5.3631910122931004e-003 + 0.1784950047731400 + 1 + <_> + + + + <_>8 8 3 5 -1. + <_>9 8 1 5 3. + 0 + -0.0122749703004956 + 0.7261952757835388 + 0.4550398886203766 + <_> + + <_> + + + + <_>13 9 2 3 -1. + <_>13 9 1 3 2. + 0 + 5.4185991175472736e-003 + 0.5252990722656250 + 1 + <_> + + + + <_>15 11 2 2 -1. + <_>15 12 2 1 2. + 0 + 8.1846961984410882e-004 + 0.5445222258567810 + 0.3272218108177185 + <_> + + <_> + + + + <_>5 6 2 3 -1. + <_>5 7 2 1 3. + 0 + 4.1358140297234058e-003 + 1 + 0.7013831734657288 + <_> + + + + <_>2 11 6 2 -1. + <_>2 12 6 1 2. + 0 + 3.9578010910190642e-004 + 0.4965943992137909 + 0.3295598030090332 + <_> + + <_> + + + + <_>15 11 4 3 -1. + <_>15 12 4 1 3. + 0 + 4.6887691132724285e-003 + 0.5362641811370850 + 1 + <_> + + + + <_>16 0 4 17 -1. + <_>16 0 2 17 2. + 0 + -0.0182554405182600 + 0.6496108770370483 + 0.4757137000560761 + <_> + + <_> + + + + <_>1 11 4 3 -1. + <_>1 12 4 1 3. + 0 + -6.2736468389630318e-003 + 0.2343741059303284 + 1 + <_> + + + + <_>9 11 1 3 -1. + <_>9 12 1 1 3. + 0 + 2.4320168886333704e-003 + 0.4620118141174316 + 0.6898419260978699 + <_> + + <_> + + + + <_>10 9 6 7 -1. + <_>10 9 3 7 2. + 0 + -0.0496176294982433 + 0.2100719958543778 + 1 + <_> + + + + <_>8 15 4 2 -1. + <_>8 16 4 1 2. + 0 + 1.1701210169121623e-003 + 0.4621528983116150 + 0.5797135829925537 + <_> + + <_> + + + + <_>4 9 6 7 -1. + <_>7 9 3 7 2. + 0 + -0.0452372916042805 + 0.2118262052536011 + 1 + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 4.7563421539962292e-003 + 0.4884614944458008 + 0.6872498989105225 + <_> + + <_> + + + + <_>0 2 20 2 -1. + <_>10 2 10 1 2. + <_>0 3 10 1 2. + 0 + -0.0148359695449471 + 1 + 0.5275105834007263 + <_> + + + + <_>6 7 8 2 -1. + <_>6 8 8 1 2. + 0 + 7.7436608262360096e-004 + 0.4172320961952210 + 0.5491139888763428 + <_> + + <_> + + + + <_>0 2 20 2 -1. + <_>0 2 10 1 2. + <_>10 3 10 1 2. + 0 + 0.0148359695449471 + 1 + 0.2124876976013184 + <_> + + + + <_>3 1 2 10 -1. + <_>3 1 1 5 2. + <_>4 6 1 5 2. + 0 + -8.0892542609944940e-004 + 0.5495215058326721 + 0.4207795858383179 + <_> + + <_> + + + + <_>13 4 1 10 -1. + <_>13 9 1 5 2. + 0 + 7.7517668250948191e-004 + 0.3321942090988159 + 1 + <_> + + + + <_>9 8 4 3 -1. + <_>9 9 4 1 3. + 0 + -6.7618978209793568e-003 + 0.2212958037853241 + 0.5232653021812439 + <_> + + <_> + + + + <_>2 11 16 4 -1. + <_>2 11 8 2 2. + <_>10 13 8 2 2. + 0 + -0.0401358604431152 + 0.1101796030998230 + 1 + <_> + + + + <_>5 1 3 5 -1. + <_>6 1 1 5 3. + 0 + -3.3651469275355339e-003 + 0.3810100853443146 + 0.5617291927337647 + <_> + + <_> + + + + <_>9 10 2 3 -1. + <_>9 11 2 1 3. + 0 + 7.4713007779791951e-004 + 1 + 0.5795056819915772 + <_> + + + + <_>9 11 2 2 -1. + <_>9 12 2 1 2. + 0 + -4.2727389372885227e-003 + 0.6392269134521484 + 0.4711438119411469 + <_> + + <_> + + + + <_>0 10 20 2 -1. + <_>0 11 20 1 2. + 0 + 3.6202510818839073e-003 + 1 + 0.3409883975982666 + <_> + + + + <_>1 7 6 4 -1. + <_>1 7 3 2 2. + <_>4 9 3 2 2. + 0 + 4.7307618660852313e-004 + 0.3659302890300751 + 0.5388171076774597 + <_> + + <_> + + + + <_>12 0 8 8 -1. + <_>16 0 4 4 2. + <_>12 4 4 4 2. + 0 + 0.0330949090421200 + 1 + 0.7170385718345642 + <_> + + + + <_>14 1 6 4 -1. + <_>16 1 2 4 3. + 0 + -0.0115441195666790 + 0.6386818289756775 + 0.4681304097175598 + <_> + + <_> + + + + <_>6 3 2 14 -1. + <_>6 10 2 7 2. + 0 + -7.4234469793736935e-003 + 0.3263700902462006 + 1 + <_> + + + + <_>6 1 7 12 -1. + <_>6 7 7 6 2. + 0 + -4.2252950370311737e-003 + 0.5767819285392761 + 0.4346418082714081 + <_> + + <_> + + + + <_>5 0 15 5 -1. + <_>10 0 5 5 3. + 0 + 0.0181331094354391 + 0.4697827994823456 + 1 + <_> + + + + <_>15 0 4 10 -1. + <_>15 0 2 10 2. + 0 + 7.0903049781918526e-003 + 0.4437389075756073 + 0.6061668992042542 + <_> + + <_> + + + + <_>1 0 18 3 -1. + <_>7 0 6 3 3. + 0 + -0.0132729401811957 + 0.6558511257171631 + 1 + <_> + + + + <_>0 0 17 2 -1. + <_>0 1 17 1 2. + 0 + 1.4632199599873275e-004 + 0.3376353979110718 + 0.5091655254364014 + <_> + + <_> + + + + <_>10 0 3 3 -1. + <_>11 0 1 3 3. + 0 + -3.5790191031992435e-003 + 0.2947883903980255 + 1 + <_> + + + + <_>10 0 3 12 -1. + <_>11 0 1 12 3. + 0 + -4.6997101162560284e-004 + 0.5556982159614563 + 0.4665456116199493 + <_> + + <_> + + + + <_>1 3 4 16 -1. + <_>1 3 2 8 2. + <_>3 11 2 8 2. + 0 + -0.0481794402003288 + 0.7338355779647827 + 1 + <_> + + + + <_>7 0 3 3 -1. + <_>8 0 1 3 3. + 0 + -9.2581362696364522e-004 + 0.3543871939182282 + 0.5285149812698364 + <_> + + <_> + + + + <_>9 13 2 6 -1. + <_>9 16 2 3 2. + 0 + -0.0147807300090790 + 0.1944441944360733 + 1 + <_> + + + + <_>9 0 6 13 -1. + <_>11 0 2 13 3. + 0 + -0.1002745032310486 + 0.0990492925047874 + 0.5139853954315186 + <_> + + <_> + + + + <_>7 7 3 2 -1. + <_>8 7 1 2 3. + 0 + -9.3848101096227765e-004 + 0.5827109813690186 + 1 + <_> + + + + <_>8 2 1 12 -1. + <_>8 6 1 4 3. + 0 + -2.8861360624432564e-003 + 0.3441427946090698 + 0.5148838758468628 + <_> + + <_> + + + + <_>4 10 12 6 -1. + <_>10 10 6 3 2. + <_>4 13 6 3 2. + 0 + -0.0436827614903450 + 1 + 0.5207998156547546 + <_> + + + + <_>13 5 2 3 -1. + <_>13 6 2 1 3. + 0 + 2.6115700602531433e-003 + 0.4835503101348877 + 0.6322219967842102 + <_> + + <_> + + + + <_>4 10 12 6 -1. + <_>4 10 6 3 2. + <_>10 13 6 3 2. + 0 + 0.0436827614903450 + 1 + 0.1364538073539734 + <_> + + + + <_>5 5 2 3 -1. + <_>5 6 2 1 3. + 0 + 1.7179530113935471e-003 + 0.4537320137023926 + 0.6066750884056091 + <_> + + <_> + + + + <_>8 6 6 7 -1. + <_>10 6 2 7 3. + 0 + -0.0339649096131325 + 1 + 0.4968374967575073 + <_> + + + + <_>9 6 2 4 -1. + <_>9 6 1 4 2. + 0 + -1.0993590112775564e-003 + 0.5831680893898010 + 0.4688239991664887 + <_> + + <_> + + + + <_>6 6 6 7 -1. + <_>8 6 2 7 3. + 0 + 0.0543010793626308 + 1 + 0.7568289041519165 + <_> + + + + <_>9 6 2 4 -1. + <_>10 6 1 4 2. + 0 + 1.0993590112775564e-003 + 0.4330148100852966 + 0.5768468976020813 + <_> + + <_> + + + + <_>12 9 2 3 -1. + <_>12 9 1 3 2. + 0 + -1.4954120160837192e-005 + 1 + 0.4443281888961792 + <_> + + + + <_>0 6 20 1 -1. + <_>0 6 10 1 2. + 0 + 0.0314158685505390 + 0.5274472832679749 + 0.3037855923175812 + <_> + + <_> + + + + <_>5 7 10 2 -1. + <_>10 7 5 2 2. + 0 + 0.0108318496495485 + 1 + 0.3581720888614655 + <_> + + + + <_>1 16 4 3 -1. + <_>1 17 4 1 3. + 0 + 8.6545711383223534e-004 + 0.5937584042549133 + 0.4294629991054535 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + 2.2743160370737314e-003 + 1 + 0.5954576730728149 + <_> + + + + <_>10 3 5 3 -1. + <_>10 4 5 1 3. + 0 + 3.9340821094810963e-003 + 0.4792222976684570 + 0.5856133103370667 + <_> + + <_> + + + + <_>3 9 14 8 -1. + <_>3 9 7 4 2. + <_>10 13 7 4 2. + 0 + 8.1451907753944397e-003 + 1 + 0.3573477864265442 + <_> + + + + <_>6 8 8 10 -1. + <_>6 8 4 5 2. + <_>10 13 4 5 2. + 0 + -5.2763288840651512e-003 + 0.4026022851467133 + 0.5764743089675903 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -8.3787851035594940e-003 + 1 + 0.4981333017349243 + <_> + + + + <_>10 3 5 3 -1. + <_>10 4 5 1 3. + 0 + 1.5621910570189357e-003 + 0.4736588001251221 + 0.5583608150482178 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + 3.2318739686161280e-003 + 1 + 0.6167436838150024 + <_> + + + + <_>5 3 5 3 -1. + <_>5 4 5 1 3. + 0 + 6.6804019734263420e-003 + 0.4131424129009247 + 0.6280695199966431 + <_> + + <_> + + + + <_>13 16 2 3 -1. + <_>13 17 2 1 3. + 0 + -3.3396480139344931e-003 + 0.3446358144283295 + 1 + <_> + + + + <_>0 5 20 6 -1. + <_>0 7 20 2 3. + 0 + -0.2093348056077957 + 0.1038658022880554 + 0.5204489231109619 + <_> + + <_> + + + + <_>3 14 3 3 -1. + <_>3 15 3 1 3. + 0 + 6.3805822283029556e-003 + 1 + 0.2167402058839798 + <_> + + + + <_>7 15 5 3 -1. + <_>7 16 5 1 3. + 0 + -6.0137799009680748e-003 + 0.6738399267196655 + 0.4896650910377502 + <_> + + <_> + + + + <_>12 9 2 3 -1. + <_>12 9 1 3 2. + 0 + -8.1756077706813812e-003 + 1 + 0.5177915096282959 + <_> + + + + <_>15 13 2 6 -1. + <_>15 13 1 6 2. + 0 + 6.3951779156923294e-004 + 0.4819645881652832 + 0.5464438199996948 + <_> + + <_> + + + + <_>6 9 2 3 -1. + <_>7 9 1 3 2. + 0 + 1.0127760469913483e-003 + 1 + 0.3423596024513245 + <_> + + + + <_>3 13 2 6 -1. + <_>4 13 1 6 2. + 0 + 4.9784599104896188e-004 + 0.4488461017608643 + 0.5912671089172363 + <_> + + <_> + + + + <_>11 4 2 4 -1. + <_>11 4 1 4 2. + 0 + 1.3596490316558629e-004 + 1 + 0.5568863153457642 + <_> + + + + <_>13 4 2 5 -1. + <_>13 4 1 5 2. + 0 + 0.0135716600343585 + 0.5161067843437195 + 0.1713000982999802 + <_> + + <_> + + + + <_>7 4 2 4 -1. + <_>8 4 1 4 2. + 0 + 3.0259079721872695e-005 + 1 + 0.4916203916072846 + <_> + + + + <_>5 4 2 5 -1. + <_>6 4 1 5 2. + 0 + -3.2625840976834297e-003 + 0.6404662728309631 + 0.2859084904193878 + <_> + + <_> + + + + <_>19 6 1 2 -1. + <_>19 7 1 1 2. + 0 + -1.9217010412830859e-004 + 1 + 0.5459282994270325 + <_> + + + + <_>12 7 8 13 -1. + <_>12 7 4 13 2. + 0 + 0.0219938792288303 + 0.4715713858604431 + 0.5690075159072876 + <_> + + <_> + + + + <_>0 6 1 2 -1. + <_>0 7 1 1 2. + 0 + 7.8907777788117528e-004 + 1 + 0.3279826939105988 + <_> + + + + <_>6 15 4 3 -1. + <_>6 16 4 1 3. + 0 + 5.0893891602754593e-004 + 0.4302007853984833 + 0.5696045160293579 + <_> + + <_> + + + + <_>11 8 2 2 -1. + <_>11 9 2 1 2. + 0 + 1.1662710312521085e-004 + 1 + 0.5387235283851624 + <_> + + + + <_>11 7 2 4 -1. + <_>11 7 1 4 2. + 0 + 8.0604078248143196e-003 + 0.5021423101425171 + 0.5965322256088257 + <_> + + <_> + + + + <_>4 13 2 3 -1. + <_>4 14 2 1 3. + 0 + 9.5925969071686268e-004 + 1 + 0.3473494052886963 + <_> + + + + <_>0 17 18 3 -1. + <_>6 17 6 3 3. + 0 + -0.0195261295884848 + 0.6475545167922974 + 0.4643782079219818 + 36.7265014648437500 + 13 + -1 + <_> + + + <_> + + <_> + + + + <_>1 0 18 5 -1. + <_>7 0 6 5 3. + 0 + 0.0412424392998219 + 0.3393315076828003 + 1 + <_> + + + + <_>5 7 3 4 -1. + <_>5 9 3 2 2. + 0 + 0.0156267099082470 + 0.5104100108146668 + 0.7772815227508545 + <_> + + <_> + + + + <_>10 6 2 2 -1. + <_>10 6 1 2 2. + 0 + 2.9947189614176750e-004 + 0.3664673864841461 + 1 + <_> + + + + <_>6 4 14 4 -1. + <_>13 4 7 2 2. + <_>6 6 7 2 2. + 0 + -1.0037609608843923e-003 + 0.5405650734901428 + 0.3926205039024353 + <_> + + <_> + + + + <_>5 16 6 4 -1. + <_>5 16 3 2 2. + <_>8 18 3 2 2. + 0 + 6.8128242855891585e-004 + 0.4251519143581390 + 1 + <_> + + + + <_>7 15 2 4 -1. + <_>7 17 2 2 2. + 0 + 1.3098999625071883e-004 + 0.4135144948959351 + 0.6925746202468872 + <_> + + <_> + + + + <_>8 5 5 14 -1. + <_>8 12 5 7 2. + 0 + 3.1696720980107784e-003 + 1 + 0.3455873131752014 + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -2.0587369799613953e-003 + 0.2234193980693817 + 0.5286118984222412 + <_> + + <_> + + + + <_>7 5 3 7 -1. + <_>8 5 1 7 3. + 0 + -4.6395038953050971e-004 + 1 + 0.4206520020961762 + <_> + + + + <_>0 0 3 9 -1. + <_>0 3 3 3 3. + 0 + 3.5089480224996805e-003 + 0.6502981781959534 + 0.4117597937583923 + <_> + + <_> + + + + <_>8 6 8 8 -1. + <_>12 6 4 4 2. + <_>8 10 4 4 2. + 0 + -2.3975980002433062e-003 + 1 + 0.3673301041126251 + <_> + + + + <_>4 8 13 2 -1. + <_>4 9 13 1 2. + 0 + 1.0901279747486115e-003 + 0.2906238138675690 + 0.5445111989974976 + <_> + + <_> + + + + <_>4 3 6 1 -1. + <_>6 3 2 1 3. + 0 + -1.6524370585102588e-004 + 0.4233515858650208 + 1 + <_> + + + + <_>9 1 2 6 -1. + <_>9 3 2 2 3. + 0 + -4.1602319106459618e-004 + 0.3886361122131348 + 0.6269165873527527 + <_> + + <_> + + + + <_>10 5 6 4 -1. + <_>12 5 2 4 3. + 0 + -2.3739910102449358e-004 + 0.5524451136589050 + 1 + <_> + + + + <_>9 5 2 12 -1. + <_>9 9 2 4 3. + 0 + 0.0247397609055042 + 0.4960095882415772 + 0.5373491048812866 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + -0.0153428399935365 + 0.6849405169487000 + 1 + <_> + + + + <_>8 12 4 3 -1. + <_>8 13 4 1 3. + 0 + 0.0115404697135091 + 0.4037235081195831 + 0.6786940097808838 + <_> + + <_> + + + + <_>10 3 6 7 -1. + <_>12 3 2 7 3. + 0 + 6.4230621792376041e-003 + 1 + 0.3814676105976105 + <_> + + + + <_>3 10 16 6 -1. + <_>3 12 16 2 3. + 0 + 0.0129778096452355 + 0.5527058839797974 + 0.3744955956935883 + <_> + + <_> + + + + <_>5 5 3 10 -1. + <_>5 10 3 5 2. + 0 + 1.1063399724662304e-003 + 0.3520928919315338 + 1 + <_> + + + + <_>6 10 3 6 -1. + <_>6 13 3 3 2. + 0 + 1.3743690215051174e-003 + 0.5641903281211853 + 0.3075025975704193 + <_> + + <_> + + + + <_>17 2 2 12 -1. + <_>17 2 1 12 2. + 0 + 0.0162337794899940 + 0.4888828098773956 + 1 + <_> + + + + <_>16 6 2 14 -1. + <_>16 13 2 7 2. + 0 + -8.1519351806491613e-004 + 0.5456321239471436 + 0.4743550121784210 + <_> + + <_> + + + + <_>3 11 12 9 -1. + <_>3 14 12 3 3. + 0 + -0.0907824933528900 + 0.2925248146057129 + 1 + <_> + + + + <_>0 2 4 12 -1. + <_>2 2 2 12 2. + 0 + 0.0116652101278305 + 0.4688454866409302 + 0.6230347752571106 + <_> + + <_> + + + + <_>18 0 2 18 -1. + <_>18 0 1 18 2. + 0 + -0.0232864096760750 + 0.6895843148231506 + 1 + <_> + + + + <_>16 12 3 2 -1. + <_>16 13 3 1 2. + 0 + 2.1559339947998524e-003 + 0.5355802178382874 + 0.3423466086387634 + <_> + + <_> + + + + <_>0 2 2 15 -1. + <_>1 2 1 15 2. + 0 + -4.3167220428586006e-003 + 0.5937076210975647 + 1 + <_> + + + + <_>1 10 2 4 -1. + <_>1 12 2 2 2. + 0 + 1.5610599657520652e-003 + 0.4708659946918488 + 0.2736997008323669 + <_> + + <_> + + + + <_>11 1 2 18 -1. + <_>11 1 1 18 2. + 0 + 0.0140766398981214 + 0.5287156105041504 + 1 + <_> + + + + <_>3 2 14 2 -1. + <_>10 2 7 1 2. + <_>3 3 7 1 2. + 0 + 7.1018589660525322e-003 + 0.5336192846298218 + 0.3224813938140869 + <_> + + <_> + + + + <_>7 1 2 18 -1. + <_>8 1 1 18 2. + 0 + -4.8221647739410400e-003 + 0.2983910143375397 + 1 + <_> + + + + <_>6 1 8 12 -1. + <_>6 7 8 6 2. + 0 + -5.3852899000048637e-003 + 0.5623999238014221 + 0.4295912086963654 + <_> + + <_> + + + + <_>8 14 4 3 -1. + <_>8 15 4 1 3. + 0 + 7.3483278974890709e-003 + 1 + 0.6813961267471314 + <_> + + + + <_>7 14 6 3 -1. + <_>7 15 6 1 3. + 0 + -3.5707519855350256e-003 + 0.5857968926429749 + 0.4603429138660431 + <_> + + <_> + + + + <_>0 13 5 2 -1. + <_>0 14 5 1 2. + 0 + 2.3340100888162851e-003 + 1 + 0.2744851112365723 + <_> + + + + <_>9 0 2 6 -1. + <_>9 0 1 3 2. + <_>10 3 1 3 2. + 0 + 4.7432780265808105e-003 + 0.5047526955604553 + 0.2362741976976395 + <_> + + <_> + + + + <_>9 0 2 6 -1. + <_>10 0 1 3 2. + <_>9 3 1 3 2. + 0 + 6.5055489540100098e-003 + 0.5242248177528381 + 1 + <_> + + + + <_>9 7 3 6 -1. + <_>10 7 1 6 3. + 0 + 0.0125892497599125 + 0.4823690950870514 + 0.6752536892890930 + <_> + + <_> + + + + <_>9 0 2 6 -1. + <_>9 0 1 3 2. + <_>10 3 1 3 2. + 0 + -6.3358368352055550e-003 + 0.1734634935855866 + 1 + <_> + + + + <_>8 7 3 6 -1. + <_>9 7 1 6 3. + 0 + -5.7639651931822300e-003 + 0.6354380846023560 + 0.4587475061416626 + <_> + + <_> + + + + <_>9 6 2 6 -1. + <_>9 6 1 6 2. + 0 + 1.3599749654531479e-003 + 0.4580380916595459 + 1 + <_> + + + + <_>9 4 4 3 -1. + <_>9 4 2 3 2. + 0 + 0.0284042600542307 + 0.5176380872726440 + 0.1204385012388229 + <_> + + <_> + + + + <_>0 4 4 3 -1. + <_>0 5 4 1 3. + 0 + -9.2958156019449234e-003 + 0.2337957024574280 + 1 + <_> + + + + <_>8 7 4 2 -1. + <_>8 8 4 1 2. + 0 + -1.1800320353358984e-003 + 0.3902814090251923 + 0.5652930140495300 + <_> + + <_> + + + + <_>10 6 6 3 -1. + <_>12 6 2 3 3. + 0 + -2.0948140881955624e-003 + 0.5512028932571411 + 1 + <_> + + + + <_>9 6 3 12 -1. + <_>9 10 3 4 3. + 0 + 4.1679958812892437e-003 + 0.5455976128578186 + 0.4798949062824249 + <_> + + <_> + + + + <_>5 4 2 3 -1. + <_>5 5 2 1 3. + 0 + 5.4458891972899437e-003 + 1 + 0.6127086877822876 + <_> + + + + <_>5 6 1 3 -1. + <_>5 7 1 1 3. + 0 + -1.2766510481014848e-003 + 0.5317131876945496 + 0.3850932121276856 + <_> + + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + 5.9404270723462105e-004 + 0.5446437001228333 + 1 + <_> + + + + <_>0 7 20 2 -1. + <_>0 8 20 1 2. + 0 + 0.0423096083104610 + 0.5234643816947937 + 0.2213044017553330 + <_> + + <_> + + + + <_>4 3 6 7 -1. + <_>6 3 2 7 3. + 0 + 5.6189671158790588e-003 + 0.4916197955608368 + 1 + <_> + + + + <_>5 10 6 10 -1. + <_>5 10 3 5 2. + <_>8 15 3 5 2. + 0 + 7.2401198558509350e-003 + 0.1471475958824158 + 0.4852893948554993 + <_> + + <_> + + + + <_>9 17 3 2 -1. + <_>10 17 1 2 3. + 0 + -4.5610670931637287e-003 + 0.2773773968219757 + 1 + <_> + + + + <_>9 10 2 2 -1. + <_>9 11 2 1 2. + 0 + 4.5506159949582070e-005 + 0.4626461863517761 + 0.5768079161643982 + <_> + + <_> + + + + <_>8 17 3 2 -1. + <_>9 17 1 2 3. + 0 + -6.1903791502118111e-003 + 0.1644289940595627 + 1 + <_> + + + + <_>5 6 1 3 -1. + <_>5 7 1 1 3. + 0 + 8.1186462193727493e-004 + 0.4778591096401215 + 0.6261864900588989 + <_> + + <_> + + + + <_>0 1 20 2 -1. + <_>10 1 10 1 2. + <_>0 2 10 1 2. + 0 + 0.0137798096984625 + 0.5257307887077332 + 1 + <_> + + + + <_>14 2 6 9 -1. + <_>14 5 6 3 3. + 0 + 1.1290319962427020e-003 + 0.5498048067092896 + 0.3983106911182404 + <_> + + <_> + + + + <_>5 3 3 2 -1. + <_>5 4 3 1 2. + 0 + -1.0610350000206381e-004 + 0.4033519029617310 + 1 + <_> + + + + <_>5 4 4 2 -1. + <_>7 4 2 2 2. + 0 + 1.6695790691301227e-004 + 0.4149340093135834 + 0.5795341134071350 + <_> + + <_> + + + + <_>14 2 6 9 -1. + <_>14 5 6 3 3. + 0 + 1.1290319962427020e-003 + 1 + 0.3934114873409271 + <_> + + + + <_>0 12 20 6 -1. + <_>0 14 20 2 3. + 0 + -0.1201934963464737 + 0.0734004825353622 + 0.5202586054801941 + <_> + + <_> + + + + <_>2 2 16 4 -1. + <_>2 2 8 2 2. + <_>10 4 8 2 2. + 0 + -0.0152307404205203 + 0.3749505877494812 + 1 + <_> + + + + <_>7 12 5 3 -1. + <_>7 13 5 1 3. + 0 + 3.5759829916059971e-003 + 0.5078150033950806 + 0.6606066226959229 + <_> + + <_> + + + + <_>14 9 6 10 -1. + <_>14 9 3 10 2. + 0 + 0.0134794600307941 + 0.4547711014747620 + 1 + <_> + + + + <_>16 6 3 2 -1. + <_>16 7 3 1 2. + 0 + -2.1162950433790684e-003 + 0.3311006128787994 + 0.5384259223937988 + <_> + + <_> + + + + <_>0 9 6 10 -1. + <_>3 9 3 10 2. + 0 + -0.0178777091205120 + 0.6513252854347229 + 1 + <_> + + + + <_>0 16 5 2 -1. + <_>0 17 5 1 2. + 0 + 1.0931970318779349e-003 + 0.5264765024185181 + 0.3456991016864777 + <_> + + <_> + + + + <_>9 12 2 3 -1. + <_>9 13 2 1 3. + 0 + -3.0553159303963184e-003 + 0.6268613934516907 + 1 + <_> + + + + <_>9 7 2 12 -1. + <_>9 11 2 4 3. + 0 + 3.6365049891173840e-003 + 0.5399212837219238 + 0.4345397055149078 + <_> + + <_> + + + + <_>3 2 6 2 -1. + <_>5 2 2 2 3. + 0 + 9.7896481747739017e-005 + 0.3835605978965759 + 1 + <_> + + + + <_>4 1 1 2 -1. + <_>4 2 1 1 2. + 0 + -3.2714448752813041e-004 + 0.3337667882442474 + 0.5539165735244751 + <_> + + <_> + + + + <_>11 15 1 2 -1. + <_>11 16 1 1 2. + 0 + 4.3425030889920890e-004 + 1 + 0.5788270235061646 + <_> + + + + <_>3 1 16 2 -1. + <_>11 1 8 1 2. + <_>3 2 8 1 2. + 0 + 0.0140055799856782 + 0.5275077819824219 + 0.2701125144958496 + <_> + + <_> + + + + <_>3 6 2 2 -1. + <_>3 6 1 1 2. + <_>4 7 1 1 2. + 0 + -9.2654931358993053e-004 + 0.5852280259132385 + 1 + <_> + + + + <_>5 11 10 6 -1. + <_>5 11 5 3 2. + <_>10 14 5 3 2. + 0 + 3.9504268206655979e-003 + 0.4728336930274963 + 0.3313918113708496 + <_> + + <_> + + + + <_>10 11 4 6 -1. + <_>10 14 4 3 2. + 0 + -5.8086868375539780e-004 + 1 + 0.4258810877799988 + <_> + + + + <_>14 9 6 11 -1. + <_>16 9 2 11 3. + 0 + -0.0120180202648044 + 0.5609787106513977 + 0.4895192086696625 + <_> + + <_> + + + + <_>0 9 6 11 -1. + <_>2 9 2 11 3. + 0 + -0.1452154070138931 + 0.0438944809138775 + 1 + <_> + + + + <_>2 11 16 6 -1. + <_>2 11 8 3 2. + <_>10 14 8 3 2. + 0 + -6.6049019806087017e-003 + 0.4229170978069305 + 0.5616292953491211 + <_> + + <_> + + + + <_>12 0 8 10 -1. + <_>16 0 4 5 2. + <_>12 5 4 5 2. + 0 + -0.0349097512662411 + 1 + 0.4788128137588501 + <_> + + + + <_>14 2 6 4 -1. + <_>16 2 2 4 3. + 0 + 3.7478420417755842e-003 + 0.4800282120704651 + 0.5801389217376709 + <_> + + <_> + + + + <_>0 0 8 10 -1. + <_>0 0 4 5 2. + <_>4 5 4 5 2. + 0 + 0.0330380313098431 + 1 + 0.7078176140785217 + <_> + + + + <_>0 2 6 4 -1. + <_>2 2 2 4 3. + 0 + 3.6872599739581347e-003 + 0.4449624121189117 + 0.5957731008529663 + <_> + + <_> + + + + <_>4 9 15 2 -1. + <_>9 9 5 2 3. + 0 + -4.5311939902603626e-003 + 0.4177047014236450 + 1 + <_> + + + + <_>12 3 4 8 -1. + <_>14 3 2 4 2. + <_>12 7 2 4 2. + 0 + 4.1058510541915894e-003 + 0.5372948050498962 + 0.3736926913261414 + <_> + + <_> + + + + <_>9 2 2 9 -1. + <_>10 2 1 9 2. + 0 + -8.7599847465753555e-003 + 0.6658807992935181 + 1 + <_> + + + + <_>0 2 20 1 -1. + <_>10 2 10 1 2. + 0 + -0.0230033099651337 + 0.2647922039031982 + 0.5101817846298218 + <_> + + <_> + + + + <_>16 1 4 5 -1. + <_>16 1 2 5 2. + 0 + 5.3664818406105042e-003 + 0.4548634886741638 + 1 + <_> + + + + <_>16 0 4 6 -1. + <_>16 3 4 3 2. + 0 + 0.0389717705547810 + 0.5157061815261841 + 0.3436439037322998 + <_> + + <_> + + + + <_>4 3 6 4 -1. + <_>6 3 2 4 3. + 0 + -0.0277671907097101 + 0.2354391068220139 + 1 + <_> + + + + <_>0 0 18 5 -1. + <_>6 0 6 5 3. + 0 + -9.8894089460372925e-003 + 0.6887741088867188 + 0.5111051797866821 + <_> + + <_> + + + + <_>6 2 12 14 -1. + <_>12 2 6 7 2. + <_>6 9 6 7 2. + 0 + -3.2073140610009432e-003 + 0.5438867807388306 + 1 + <_> + + + + <_>11 8 3 5 -1. + <_>12 8 1 5 3. + 0 + -6.7484978353604674e-004 + 0.5451148748397827 + 0.4831353127956390 + <_> + + <_> + + + + <_>5 12 2 2 -1. + <_>5 13 2 1 2. + 0 + -5.1947520114481449e-003 + 0.2113419026136398 + 1 + <_> + + + + <_>5 10 4 3 -1. + <_>7 10 2 3 2. + 0 + -2.6169899501837790e-004 + 0.5273681879043579 + 0.3992587029933929 + <_> + + <_> + + + + <_>4 9 15 2 -1. + <_>9 9 5 2 3. + 0 + 2.2421479225158691e-003 + 0.4688260853290558 + 1 + <_> + + + + <_>10 7 6 2 -1. + <_>12 7 2 2 3. + 0 + -1.2139769969508052e-003 + 0.5504235029220581 + 0.4384871125221252 + <_> + + <_> + + + + <_>1 9 15 2 -1. + <_>6 9 5 2 3. + 0 + -2.9469770379364491e-003 + 0.3892847001552582 + 1 + <_> + + + + <_>5 0 2 10 -1. + <_>5 0 1 5 2. + <_>6 5 1 5 2. + 0 + -3.9291830034926534e-004 + 0.6001722812652588 + 0.4561662971973419 + <_> + + <_> + + + + <_>0 0 20 14 -1. + <_>0 7 20 7 2. + 0 + 0.6255072951316834 + 1 + 0.0681256130337715 + <_> + + + + <_>12 7 8 4 -1. + <_>12 7 4 4 2. + 0 + 9.7744520753622055e-003 + 0.4813025891780853 + 0.5620657205581665 + <_> + + <_> + + + + <_>0 7 8 4 -1. + <_>4 7 4 4 2. + 0 + 0.0943782478570938 + 1 + 0.0666322931647301 + <_> + + + + <_>8 1 3 3 -1. + <_>9 1 1 3 3. + 0 + -1.9560910295695066e-003 + 0.3588232994079590 + 0.5295407176017761 + <_> + + <_> + + + + <_>9 7 3 4 -1. + <_>10 7 1 4 3. + 0 + 9.0652769431471825e-003 + 0.4822688102722168 + 1 + <_> + + + + <_>9 9 3 1 -1. + <_>10 9 1 1 3. + 0 + 4.2138071148656309e-004 + 0.4670332968235016 + 0.5683112740516663 + <_> + + <_> + + + + <_>8 9 3 2 -1. + <_>8 10 3 1 2. + 0 + -4.4220191193744540e-004 + 1 + 0.5360795259475708 + <_> + + + + <_>8 4 2 8 -1. + <_>8 4 1 4 2. + <_>9 8 1 4 2. + 0 + -4.7313501127064228e-003 + 0.6137245893478394 + 0.3188089132308960 + <_> + + <_> + + + + <_>5 8 12 3 -1. + <_>5 9 12 1 3. + 0 + 1.5395509544759989e-003 + 0.4487720131874085 + 1 + <_> + + + + <_>11 14 1 3 -1. + <_>11 15 1 1 3. + 0 + 2.4315000046044588e-003 + 0.4894166886806488 + 0.6716653704643250 + <_> + + <_> + + + + <_>6 10 3 6 -1. + <_>6 12 3 2 3. + 0 + -0.0155816199257970 + 0.3336741924285889 + 1 + <_> + + + + <_>4 17 8 3 -1. + <_>4 18 8 1 3. + 0 + 1.0816920548677444e-003 + 0.4718219935894013 + 0.5960627198219299 + <_> + + <_> + + + + <_>17 6 2 3 -1. + <_>17 7 2 1 3. + 0 + -2.2197659127414227e-003 + 0.3588554859161377 + 1 + <_> + + + + <_>9 12 2 2 -1. + <_>10 12 1 1 2. + <_>9 13 1 1 2. + 0 + -9.3048671260476112e-004 + 0.6218712925910950 + 0.4817300140857697 + <_> + + <_> + + + + <_>9 13 2 4 -1. + <_>9 13 1 2 2. + <_>10 15 1 2 2. + 0 + -4.7418707981705666e-003 + 0.2550027072429657 + 1 + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + -6.2950369901955128e-003 + 0.6728078722953796 + 0.5051063895225525 + <_> + + <_> + + + + <_>5 5 12 10 -1. + <_>11 5 6 5 2. + <_>5 10 6 5 2. + 0 + 3.5216049291193485e-003 + 0.5401909947395325 + 1 + <_> + + + + <_>6 3 12 12 -1. + <_>12 3 6 6 2. + <_>6 9 6 6 2. + 0 + -2.4289379362016916e-003 + 0.5419461727142334 + 0.4347142875194550 + <_> + + <_> + + + + <_>5 7 2 2 -1. + <_>5 7 1 1 2. + <_>6 8 1 1 2. + 0 + -2.5261470582336187e-003 + 0.6970624923706055 + 1 + <_> + + + + <_>4 3 3 2 -1. + <_>5 3 1 2 3. + 0 + -1.4817339833825827e-003 + 0.3263416886329651 + 0.4917873144149780 + <_> + + <_> + + + + <_>6 2 12 14 -1. + <_>12 2 6 7 2. + <_>6 9 6 7 2. + 0 + -0.2247453033924103 + 7.2937291115522385e-003 + 1 + <_> + + + + <_>5 2 12 3 -1. + <_>9 2 4 3 3. + 0 + 2.8342509176582098e-003 + 0.4579229950904846 + 0.5379881262779236 + <_> + + <_> + + + + <_>1 1 18 17 -1. + <_>7 1 6 17 3. + 0 + -0.0208216104656458 + 0.6024088859558106 + 1 + <_> + + + + <_>0 9 10 1 -1. + <_>5 9 5 1 2. + 0 + 1.4896340144332498e-004 + 0.3336144089698792 + 0.4962815940380096 + <_> + + <_> + + + + <_>16 8 4 3 -1. + <_>16 9 4 1 3. + 0 + -3.3524499740451574e-003 + 0.3558751046657562 + 1 + <_> + + + + <_>7 13 6 6 -1. + <_>7 16 6 3 2. + 0 + -0.0372798815369606 + 0.1698562949895859 + 0.5208985805511475 + <_> + + <_> + + + + <_>6 14 1 6 -1. + <_>6 16 1 2 3. + 0 + 1.3896770542487502e-004 + 1 + 0.5590686202049255 + <_> + + + + <_>6 17 4 2 -1. + <_>6 18 4 1 2. + 0 + -3.1912620761431754e-004 + 0.5848733782768250 + 0.3795836865901947 + <_> + + <_> + + + + <_>10 18 6 2 -1. + <_>13 18 3 1 2. + <_>10 19 3 1 2. + 0 + 5.4003461264073849e-004 + 1 + 0.5670288205146790 + <_> + + + + <_>16 8 1 3 -1. + <_>16 9 1 1 3. + 0 + 3.8956850767135620e-003 + 0.5182694792747498 + 0.3327709138393402 + <_> + + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 1.6084529925137758e-003 + 1 + 0.5410485863685608 + <_> + + + + <_>9 15 1 2 -1. + <_>9 16 1 1 2. + 0 + -5.7474587811157107e-004 + 0.6022642254829407 + 0.3644644021987915 + <_> + + <_> + + + + <_>13 0 3 12 -1. + <_>14 0 1 12 3. + 0 + 0.0134350396692753 + 1 + 0.3441281914710999 + <_> + + + + <_>15 11 1 3 -1. + <_>15 12 1 1 3. + 0 + 2.1368139423429966e-003 + 0.5292434096336365 + 0.2747075855731964 + <_> + + <_> + + + + <_>8 15 3 3 -1. + <_>8 16 3 1 3. + 0 + 0.0141576295718551 + 1 + 0.8027868270874023 + <_> + + + + <_>4 0 3 12 -1. + <_>5 0 1 12 3. + 0 + 5.3884391672909260e-003 + 0.5222315192222595 + 0.3586727976799011 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + 8.8013410568237305e-003 + 0.4900386929512024 + 1 + <_> + + + + <_>9 9 3 1 -1. + <_>10 9 1 1 3. + 0 + 3.8858849438838661e-004 + 0.4681056141853333 + 0.5721952915191650 + <_> + + <_> + + + + <_>2 2 12 14 -1. + <_>2 2 6 7 2. + <_>8 9 6 7 2. + 0 + -2.2143588867038488e-003 + 0.5388805866241455 + 1 + <_> + + + + <_>4 2 12 3 -1. + <_>8 2 4 3 3. + 0 + -8.4642972797155380e-003 + 0.6675537824630737 + 0.3448441922664642 + <_> + + <_> + + + + <_>18 18 2 2 -1. + <_>18 18 1 2 2. + 0 + 0.0150443902239203 + 1 + 0.9239614009857178 + <_> + + + + <_>17 2 3 8 -1. + <_>18 2 1 8 3. + 0 + 7.6346402056515217e-003 + 0.4884896874427795 + 0.6306052803993225 + <_> + + <_> + + + + <_>0 18 2 2 -1. + <_>1 18 1 2 2. + 0 + 3.3895121305249631e-004 + 1 + 0.3997431099414825 + <_> + + + + <_>6 11 2 6 -1. + <_>6 14 2 3 2. + 0 + 2.1157610171940178e-004 + 0.5663982033729553 + 0.3972980976104736 + <_> + + <_> + + + + <_>13 10 5 6 -1. + <_>13 12 5 2 3. + 0 + -0.0275149494409561 + 1 + 0.5201063752174377 + <_> + + + + <_>5 8 15 3 -1. + <_>5 9 15 1 3. + 0 + 0.0516030602157116 + 0.5140730142593384 + 0.1245130971074104 + <_> + + <_> + + + + <_>2 10 5 6 -1. + <_>2 12 5 2 3. + 0 + 3.7510651163756847e-003 + 1 + 0.3802095055580139 + <_> + + + + <_>0 8 15 3 -1. + <_>0 9 15 1 3. + 0 + -2.1457639522850513e-003 + 0.3309448063373566 + 0.5474538803100586 + <_> + + <_> + + + + <_>16 2 3 1 -1. + <_>17 2 1 1 3. + 0 + -5.8178009930998087e-004 + 1 + 0.4892601966857910 + <_> + + + + <_>17 4 3 2 -1. + <_>18 4 1 2 3. + 0 + -9.3638541875407100e-004 + 0.5937399268150330 + 0.4664669036865234 + <_> + + <_> + + + + <_>0 8 8 12 -1. + <_>0 8 4 6 2. + <_>4 14 4 6 2. + 0 + 0.0416674911975861 + 1 + 0.7021353244781494 + <_> + + + + <_>1 7 8 6 -1. + <_>1 7 4 3 2. + <_>5 10 4 3 2. + 0 + -6.7763780243694782e-003 + 0.3222751021385193 + 0.5068395137786865 + <_> + + <_> + + + + <_>14 1 6 2 -1. + <_>16 1 2 2 3. + 0 + -2.9170580673962831e-003 + 1 + 0.4717701077461243 + <_> + + + + <_>15 0 4 4 -1. + <_>17 0 2 2 2. + <_>15 2 2 2 2. + 0 + 3.2789530814625323e-004 + 0.4509383141994476 + 0.5651162862777710 + 38.2360382080078130 + 14 + -1 + <_> + + + <_> + + <_> + + + + <_>1 1 4 11 -1. + <_>3 1 2 11 2. + 0 + 0.0117298001423478 + 0.3805224895477295 + 1 + <_> + + + + <_>5 5 1 8 -1. + <_>5 9 1 4 2. + 0 + 1.1712179984897375e-003 + 0.3140017986297607 + 0.6858146190643311 + <_> + + <_> + + + + <_>7 7 6 1 -1. + <_>9 7 2 1 3. + 0 + 9.3555096536874771e-003 + 1 + 0.6834673285484314 + <_> + + + + <_>4 7 12 2 -1. + <_>8 7 4 2 3. + 0 + 1.6570610459893942e-003 + 0.2992472946643829 + 0.5475677847862244 + <_> + + <_> + + + + <_>8 4 4 4 -1. + <_>8 6 4 2 2. + 0 + -1.3387809740379453e-003 + 1 + 0.2941406965255737 + <_> + + + + <_>2 4 9 1 -1. + <_>5 4 3 1 3. + 0 + 1.7580550047568977e-004 + 0.3896977901458740 + 0.5872970819473267 + <_> + + <_> + + + + <_>9 12 2 8 -1. + <_>9 16 2 4 2. + 0 + -2.9473248869180679e-003 + 0.3576571941375732 + 1 + <_> + + + + <_>3 8 14 12 -1. + <_>3 14 14 6 2. + 0 + 8.3220899105072021e-003 + 0.5232400894165039 + 0.3231087923049927 + <_> + + <_> + + + + <_>6 13 7 3 -1. + <_>6 14 7 1 3. + 0 + 7.4366689659655094e-003 + 1 + 0.6715673208236694 + <_> + + + + <_>5 9 6 3 -1. + <_>7 9 2 3 3. + 0 + -2.1322889369912446e-004 + 0.5470541715621948 + 0.3863396048545837 + <_> + + <_> + + + + <_>12 1 6 3 -1. + <_>12 2 6 1 3. + 0 + -7.8024631366133690e-003 + 0.2771460115909576 + 1 + <_> + + + + <_>8 12 6 2 -1. + <_>8 13 6 1 2. + 0 + 5.6611228501424193e-004 + 0.4689136147499085 + 0.5851963758468628 + <_> + + <_> + + + + <_>0 2 18 2 -1. + <_>0 2 9 1 2. + <_>9 3 9 1 2. + 0 + -9.2346500605344772e-003 + 0.2704397141933441 + 1 + <_> + + + + <_>6 10 3 6 -1. + <_>6 13 3 3 2. + 0 + -1.4676499631605111e-005 + 0.5622550249099731 + 0.3579317033290863 + <_> + + <_> + + + + <_>14 0 6 6 -1. + <_>14 0 3 6 2. + 0 + 9.7007937729358673e-003 + 0.4173871874809265 + 1 + <_> + + + + <_>15 0 5 8 -1. + <_>15 4 5 4 2. + 0 + -3.5320650786161423e-003 + 0.4195013046264648 + 0.5549468994140625 + <_> + + <_> + + + + <_>7 16 6 4 -1. + <_>9 16 2 4 3. + 0 + 0.0216164104640484 + 1 + 0.2857390940189362 + <_> + + + + <_>2 11 14 4 -1. + <_>2 11 7 2 2. + <_>9 13 7 2 2. + 0 + 3.4567608963698149e-003 + 0.6024532914161682 + 0.4377507865428925 + <_> + + <_> + + + + <_>14 10 6 10 -1. + <_>14 10 3 10 2. + 0 + 0.0229143202304840 + 0.4689350128173828 + 1 + <_> + + + + <_>9 8 10 12 -1. + <_>14 8 5 6 2. + <_>9 14 5 6 2. + 0 + 3.4328910987824202e-003 + 0.4664604961872101 + 0.5762562155723572 + <_> + + <_> + + + + <_>0 10 6 10 -1. + <_>3 10 3 10 2. + 0 + -8.6510833352804184e-003 + 0.6381739974021912 + 1 + <_> + + + + <_>1 8 10 12 -1. + <_>1 8 5 6 2. + <_>6 14 5 6 2. + 0 + 1.4510039472952485e-003 + 0.3711487948894501 + 0.5530750751495361 + <_> + + <_> + + + + <_>9 3 6 1 -1. + <_>11 3 2 1 3. + 0 + 7.8191719949245453e-003 + 0.5264362096786499 + 1 + <_> + + + + <_>7 4 6 3 -1. + <_>9 4 2 3 3. + 0 + 2.0798550394829363e-004 + 0.3730512857437134 + 0.5445731282234192 + <_> + + <_> + + + + <_>5 3 6 1 -1. + <_>7 3 2 1 3. + 0 + -3.9962218143045902e-003 + 0.2438170015811920 + 1 + <_> + + + + <_>4 5 6 3 -1. + <_>6 5 2 3 3. + 0 + -1.5010139577498194e-005 + 0.5324671268463135 + 0.3682988882064819 + <_> + + <_> + + + + <_>9 16 3 3 -1. + <_>9 17 3 1 3. + 0 + -4.2428788729012012e-003 + 0.6481474041938782 + 1 + <_> + + + + <_>8 14 6 3 -1. + <_>8 15 6 1 3. + 0 + 9.1374982148408890e-003 + 0.4896158874034882 + 0.6558843255043030 + <_> + + <_> + + + + <_>6 0 8 12 -1. + <_>6 0 4 6 2. + <_>10 6 4 6 2. + 0 + 8.8254585862159729e-003 + 1 + 0.3613870143890381 + <_> + + + + <_>4 12 2 3 -1. + <_>4 13 2 1 3. + 0 + 9.4092212384566665e-004 + 0.5502895712852478 + 0.3632518053054810 + <_> + + <_> + + + + <_>12 16 6 3 -1. + <_>12 17 6 1 3. + 0 + -0.0125033501535654 + 0.2261132001876831 + 1 + <_> + + + + <_>7 12 7 2 -1. + <_>7 13 7 1 2. + 0 + 8.6759645491838455e-003 + 0.4987890124320984 + 0.6847196221351624 + <_> + + <_> + + + + <_>2 16 6 3 -1. + <_>2 17 6 1 3. + 0 + -0.0104167601093650 + 0.2446299046278000 + 1 + <_> + + + + <_>0 7 16 6 -1. + <_>0 10 16 3 2. + 0 + 2.7432460337877274e-003 + 0.3511525094509125 + 0.5399826765060425 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + -4.2385691776871681e-003 + 0.6823673248291016 + 1 + <_> + + + + <_>9 7 3 5 -1. + <_>10 7 1 5 3. + 0 + 0.0183258708566427 + 0.4891580045223236 + 0.7135618925094605 + <_> + + <_> + + + + <_>0 5 20 10 -1. + <_>0 5 10 5 2. + <_>10 10 10 5 2. + 0 + -0.0243345405906439 + 0.3522521853446960 + 1 + <_> + + + + <_>3 1 4 2 -1. + <_>5 1 2 2 2. + 0 + 4.6469361404888332e-004 + 0.4049868881702423 + 0.5515825748443604 + <_> + + <_> + + + + <_>7 6 8 10 -1. + <_>11 6 4 5 2. + <_>7 11 4 5 2. + 0 + 3.4260009415447712e-003 + 1 + 0.4126769900321960 + <_> + + + + <_>17 6 3 2 -1. + <_>17 7 3 1 2. + 0 + -2.5827318895608187e-003 + 0.2899428904056549 + 0.5386431813240051 + <_> + + <_> + + + + <_>5 6 8 10 -1. + <_>5 6 4 5 2. + <_>9 11 4 5 2. + 0 + 1.0545699624344707e-003 + 1 + 0.3771344125270844 + <_> + + + + <_>5 12 10 6 -1. + <_>5 14 10 2 3. + 0 + -9.1257691383361816e-004 + 0.5827386975288391 + 0.4267556965351105 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + 2.6589010376483202e-003 + 0.4688124954700470 + 1 + <_> + + + + <_>10 3 2 6 -1. + <_>11 3 1 3 2. + <_>10 6 1 3 2. + 0 + 4.8598358407616615e-003 + 0.4853922128677368 + 0.6163644790649414 + <_> + + <_> + + + + <_>0 4 3 3 -1. + <_>0 5 3 1 3. + 0 + 8.0638676881790161e-003 + 1 + 0.1749195009469986 + <_> + + + + <_>3 16 8 4 -1. + <_>3 16 4 2 2. + <_>7 18 4 2 2. + 0 + -7.5898370705544949e-003 + 0.6826189756393433 + 0.4894070029258728 + <_> + + <_> + + + + <_>8 13 5 2 -1. + <_>8 14 5 1 2. + 0 + 3.6368070868775249e-004 + 0.4614596068859100 + 1 + <_> + + + + <_>8 7 4 12 -1. + <_>8 11 4 4 3. + 0 + 0.0625949501991272 + 0.5183017253875732 + 0.2686696052551270 + <_> + + <_> + + + + <_>5 9 2 2 -1. + <_>6 9 1 2 2. + 0 + -4.9753207713365555e-003 + 0.1758466958999634 + 1 + <_> + + + + <_>9 15 2 3 -1. + <_>9 16 2 1 3. + 0 + -2.0880119409412146e-003 + 0.6369382143020630 + 0.4930044114589691 + <_> + + <_> + + + + <_>13 9 2 3 -1. + <_>13 9 1 3 2. + 0 + 9.5644511748105288e-004 + 1 + 0.4139398932456970 + <_> + + + + <_>14 0 6 17 -1. + <_>16 0 2 17 3. + 0 + -0.0317214615643024 + 0.6045557260513306 + 0.4816364049911499 + <_> + + <_> + + + + <_>5 10 2 2 -1. + <_>6 10 1 2 2. + 0 + 1.2898689601570368e-003 + 0.5450810790061951 + 1 + <_> + + + + <_>2 9 9 1 -1. + <_>5 9 3 1 3. + 0 + 9.8405163735151291e-003 + 0.2924000918865204 + 0.6699606180191040 + <_> + + <_> + + + + <_>9 11 2 3 -1. + <_>9 12 2 1 3. + 0 + 1.2237089686095715e-003 + 1 + 0.6282836794853210 + <_> + + + + <_>7 11 6 3 -1. + <_>7 12 6 1 3. + 0 + -8.4232585504651070e-003 + 0.5986570119857788 + 0.4852580130100250 + <_> + + <_> + + + + <_>0 6 3 2 -1. + <_>0 7 3 1 2. + 0 + -7.2726322105154395e-004 + 0.3340049088001251 + 1 + <_> + + + + <_>7 0 6 1 -1. + <_>9 0 2 1 3. + 0 + 4.6842931769788265e-003 + 0.5168923735618591 + 0.2679480016231537 + <_> + + <_> + + + + <_>9 16 3 3 -1. + <_>9 17 3 1 3. + 0 + -1.0379579616710544e-003 + 0.5925791859626770 + 1 + <_> + + + + <_>2 13 17 6 -1. + <_>2 16 17 3 2. + 0 + 9.1342730447649956e-003 + 0.5437728166580200 + 0.4346800148487091 + <_> + + <_> + + + + <_>1 3 3 7 -1. + <_>2 3 1 7 3. + 0 + 1.4971119817346334e-003 + 0.4129500985145569 + 1 + <_> + + + + <_>1 1 6 4 -1. + <_>3 1 2 4 3. + 0 + 1.5762320253998041e-003 + 0.4522874057292938 + 0.6556292176246643 + <_> + + <_> + + + + <_>14 1 6 5 -1. + <_>14 1 3 5 2. + 0 + 8.7496247142553329e-003 + 0.4532034099102020 + 1 + <_> + + + + <_>13 2 3 2 -1. + <_>13 3 3 1 2. + 0 + -8.5103599121794105e-004 + 0.3785983920097351 + 0.5416975021362305 + <_> + + <_> + + + + <_>0 1 6 5 -1. + <_>3 1 3 5 2. + 0 + -0.0173255708068609 + 0.6884248256683350 + 1 + <_> + + + + <_>2 3 2 6 -1. + <_>2 5 2 2 3. + 0 + -8.3266440778970718e-003 + 0.3091326057910919 + 0.5243654847145081 + <_> + + <_> + + + + <_>9 10 3 2 -1. + <_>9 11 3 1 2. + 0 + 1.5157909729168750e-005 + 0.4765793979167938 + 1 + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 1.8041470320895314e-003 + 0.4725385904312134 + 0.5716555118560791 + <_> + + <_> + + + + <_>6 3 3 1 -1. + <_>7 3 1 1 3. + 0 + 3.0691560823470354e-003 + 1 + 0.2143359929323196 + <_> + + + + <_>8 2 3 12 -1. + <_>8 6 3 4 3. + 0 + -5.2225510444259271e-005 + 0.5653210282325745 + 0.4385111033916473 + <_> + + <_> + + + + <_>11 12 1 2 -1. + <_>11 13 1 1 2. + 0 + 1.0072169970953837e-004 + 1 + 0.5924776196479797 + <_> + + + + <_>11 12 2 2 -1. + <_>12 12 1 1 2. + <_>11 13 1 1 2. + 0 + 1.3573700562119484e-004 + 0.4573448896408081 + 0.5769382715225220 + <_> + + <_> + + + + <_>5 5 2 2 -1. + <_>5 6 2 1 2. + 0 + 9.2137878527864814e-004 + 1 + 0.5992609262466431 + <_> + + + + <_>5 4 1 3 -1. + <_>5 5 1 1 3. + 0 + 3.0316581251099706e-004 + 0.3610081076622009 + 0.5049325823783875 + <_> + + <_> + + + + <_>3 11 16 4 -1. + <_>11 11 8 2 2. + <_>3 13 8 2 2. + 0 + 0.0395824797451496 + 1 + 0.1538489013910294 + <_> + + + + <_>0 10 20 3 -1. + <_>0 11 20 1 3. + 0 + 0.0475196801126003 + 0.5216140747070313 + 0.1428391039371491 + <_> + + <_> + + + + <_>1 11 16 4 -1. + <_>1 11 8 2 2. + <_>9 13 8 2 2. + 0 + 0.0188717599958181 + 1 + 0.2825506925582886 + <_> + + + + <_>4 2 4 2 -1. + <_>4 3 4 1 2. + 0 + -3.9876459049992263e-004 + 0.4035016894340515 + 0.5437793135643005 + <_> + + <_> + + + + <_>12 6 2 2 -1. + <_>13 6 1 1 2. + <_>12 7 1 1 2. + 0 + 4.6556600136682391e-004 + 0.4668996930122376 + 1 + <_> + + + + <_>12 11 6 6 -1. + <_>12 13 6 2 3. + 0 + 6.7090610973536968e-003 + 0.5331354737281799 + 0.4136571884155273 + <_> + + <_> + + + + <_>6 6 2 2 -1. + <_>6 6 1 1 2. + <_>7 7 1 1 2. + 0 + -1.8931160448119044e-003 + 0.7155163288116455 + 1 + <_> + + + + <_>6 4 4 16 -1. + <_>8 4 2 16 2. + 0 + -0.0130569497123361 + 0.3117899894714356 + 0.5208439826965332 + <_> + + <_> + + + + <_>11 18 3 2 -1. + <_>11 19 3 1 2. + 0 + -1.9484119547996670e-004 + 1 + 0.4637658894062042 + <_> + + + + <_>9 17 6 2 -1. + <_>12 17 3 1 2. + <_>9 18 3 1 2. + 0 + 1.5093220099515747e-005 + 0.4561653137207031 + 0.5445234179496765 + <_> + + <_> + + + + <_>2 13 5 2 -1. + <_>2 14 5 1 2. + 0 + -7.1617960202274844e-006 + 1 + 0.4193108081817627 + <_> + + + + <_>3 15 2 2 -1. + <_>3 16 2 1 2. + 0 + 3.0164679628796875e-004 + 0.5966237783432007 + 0.4100500047206879 + <_> + + <_> + + + + <_>9 7 3 3 -1. + <_>10 7 1 3 3. + 0 + 4.4195181690156460e-003 + 0.4845055937767029 + 1 + <_> + + + + <_>9 6 2 6 -1. + <_>9 6 1 6 2. + 0 + -7.3984181508421898e-003 + 0.6206846237182617 + 0.4931209087371826 + <_> + + <_> + + + + <_>1 14 7 6 -1. + <_>1 16 7 2 3. + 0 + -7.8031201846897602e-003 + 1 + 0.5282462835311890 + <_> + + + + <_>8 1 2 11 -1. + <_>9 1 1 11 2. + 0 + -0.0107314297929406 + 0.9104834198951721 + 0.3455922007560730 + <_> + + <_> + + + + <_>9 7 2 4 -1. + <_>9 7 1 4 2. + 0 + 1.4246780192479491e-003 + 0.4708554148674011 + 1 + <_> + + + + <_>11 10 2 1 -1. + <_>11 10 1 1 2. + 0 + -8.2717568147927523e-005 + 0.5651623010635376 + 0.4731023907661438 + <_> + + <_> + + + + <_>0 3 3 9 -1. + <_>1 3 1 9 3. + 0 + 4.4803409837186337e-003 + 1 + 0.6175886988639832 + <_> + + + + <_>0 3 3 6 -1. + <_>0 5 3 2 3. + 0 + 3.0789140146225691e-003 + 0.5139533281326294 + 0.3423087894916534 + <_> + + <_> + + + + <_>11 15 2 2 -1. + <_>12 15 1 1 2. + <_>11 16 1 1 2. + 0 + -1.1310289846733212e-003 + 1 + 0.4918282032012940 + <_> + + + + <_>11 14 2 2 -1. + <_>12 14 1 1 2. + <_>11 15 1 1 2. + 0 + -1.0410690447315574e-003 + 0.5942087173461914 + 0.4923042953014374 + <_> + + <_> + + + + <_>7 15 2 2 -1. + <_>7 15 1 1 2. + <_>8 16 1 1 2. + 0 + 1.1648540385067463e-003 + 1 + 0.6405271887779236 + <_> + + + + <_>7 14 2 2 -1. + <_>7 14 1 1 2. + <_>8 15 1 1 2. + 0 + 9.0057362103834748e-004 + 0.4504396915435791 + 0.6192076802253723 + <_> + + <_> + + + + <_>8 13 4 6 -1. + <_>10 13 2 3 2. + <_>8 16 2 3 2. + 0 + 6.8781538866460323e-003 + 0.5374813079833984 + 1 + <_> + + + + <_>2 14 16 4 -1. + <_>10 14 8 2 2. + <_>2 16 8 2 2. + 0 + -0.0352839007973671 + 0.2247101068496704 + 0.5217170715332031 + <_> + + <_> + + + + <_>9 8 2 2 -1. + <_>9 9 2 1 2. + 0 + -1.3320200378075242e-003 + 0.2554703056812286 + 1 + <_> + + + + <_>7 7 5 3 -1. + <_>7 8 5 1 3. + 0 + -2.3177571129053831e-003 + 0.3792515993118286 + 0.5243226885795593 + <_> + + <_> + + + + <_>7 5 6 2 -1. + <_>9 5 2 2 3. + 0 + 2.1332940377760679e-004 + 0.3860337138175964 + 1 + <_> + + + + <_>9 1 6 18 -1. + <_>11 1 2 18 3. + 0 + 0.0134679004549980 + 0.5380687713623047 + 0.4178363978862763 + <_> + + <_> + + + + <_>8 6 3 4 -1. + <_>9 6 1 4 3. + 0 + -1.2829169863834977e-003 + 0.6133623123168945 + 1 + <_> + + + + <_>8 5 2 4 -1. + <_>8 5 1 2 2. + <_>9 7 1 2 2. + 0 + 5.1571638323366642e-004 + 0.4028537869453430 + 0.5536851882934570 + <_> + + <_> + + + + <_>9 13 2 6 -1. + <_>10 13 1 3 2. + <_>9 16 1 3 2. + 0 + 3.9254198782145977e-003 + 0.5279921293258667 + 1 + <_> + + + + <_>11 0 3 18 -1. + <_>12 0 1 18 3. + 0 + -0.0337805896997452 + 0.2334675043821335 + 0.5175911784172058 + <_> + + <_> + + + + <_>6 0 3 18 -1. + <_>7 0 1 18 3. + 0 + -0.0378537215292454 + 0.1074853017926216 + 1 + <_> + + + + <_>5 15 4 2 -1. + <_>7 15 2 2 2. + 0 + -4.0752900531515479e-004 + 0.5345929861068726 + 0.4198938012123108 + <_> + + <_> + + + + <_>1 9 18 1 -1. + <_>7 9 6 1 3. + 0 + -3.1193809118121862e-003 + 0.3855825066566467 + 1 + <_> + + + + <_>0 0 20 3 -1. + <_>0 1 20 1 3. + 0 + -0.0157149694859982 + 0.3335190117359161 + 0.5263202190399170 + <_> + + <_> + + + + <_>9 6 2 4 -1. + <_>10 6 1 4 2. + 0 + -7.8525702701881528e-004 + 0.5860397219657898 + 1 + <_> + + + + <_>6 10 6 2 -1. + <_>8 10 2 2 3. + 0 + -2.8750501223839819e-004 + 0.5437784790992737 + 0.3716104924678803 + <_> + + <_> + + + + <_>0 7 20 1 -1. + <_>0 7 10 1 2. + 0 + 0.0280168596655130 + 1 + 0.3330754935741425 + <_> + + + + <_>11 3 5 4 -1. + <_>11 5 5 2 2. + 0 + -1.9018839811906219e-003 + 0.5366597771644592 + 0.4693793952465057 + <_> + + <_> + + + + <_>5 7 10 1 -1. + <_>10 7 5 1 2. + 0 + 0.0206475593149662 + 1 + 0.1006956025958061 + <_> + + + + <_>8 10 3 3 -1. + <_>8 11 3 1 3. + 0 + 4.3002571910619736e-003 + 0.4816035926342011 + 0.6215677261352539 + <_> + + <_> + + + + <_>2 0 16 8 -1. + <_>10 0 8 4 2. + <_>2 4 8 4 2. + 0 + 0.0134591404348612 + 0.5461953878402710 + 1 + <_> + + + + <_>11 0 9 10 -1. + <_>11 5 9 5 2. + 0 + -0.0103200403973460 + 0.4578453004360199 + 0.5419309735298157 + <_> + + <_> + + + + <_>0 2 8 18 -1. + <_>4 2 4 18 2. + 0 + 0.3199074864387512 + 1 + 0.2008046954870224 + <_> + + + + <_>0 0 2 6 -1. + <_>0 2 2 2 3. + 0 + 9.2198798665776849e-004 + 0.5193281173706055 + 0.3912194073200226 + <_> + + <_> + + + + <_>6 0 9 2 -1. + <_>6 1 9 1 2. + 0 + 4.1852539288811386e-004 + 0.4299744069576263 + 1 + <_> + + + + <_>4 1 12 2 -1. + <_>4 2 12 1 2. + 0 + 3.5891108564101160e-004 + 0.4344502985477448 + 0.5531973838806152 + <_> + + <_> + + + + <_>2 1 16 14 -1. + <_>2 8 16 7 2. + 0 + -0.2099243998527527 + 0.1075721010565758 + 1 + <_> + + + + <_>5 1 8 12 -1. + <_>5 7 8 6 2. + 0 + -4.9328152090311050e-003 + 0.5762796998023987 + 0.4574643969535828 + <_> + + <_> + + + + <_>9 11 2 2 -1. + <_>9 12 2 1 2. + 0 + 2.3409130517393351e-003 + 1 + 0.7476807832717896 + <_> + + + + <_>9 10 5 6 -1. + <_>9 12 5 2 3. + 0 + 4.7120270319283009e-003 + 0.5261765122413635 + 0.4505550861358643 + <_> + + <_> + + + + <_>3 0 13 8 -1. + <_>3 4 13 4 2. + 0 + 0.0287131909281015 + 0.4407103061676025 + 1 + <_> + + + + <_>6 7 5 8 -1. + <_>6 11 5 4 2. + 0 + -2.6156550738960505e-003 + 0.4244270920753479 + 0.6892976760864258 + <_> + + <_> + + + + <_>9 5 2 3 -1. + <_>9 6 2 1 3. + 0 + -0.0135589698329568 + 0.1252267956733704 + 1 + <_> + + + + <_>6 8 8 3 -1. + <_>6 9 8 1 3. + 0 + -3.0331799644045532e-004 + 0.4077791869640350 + 0.5442817807197571 + <_> + + <_> + + + + <_>2 2 7 6 -1. + <_>2 5 7 3 2. + 0 + -5.5601762142032385e-004 + 0.5378003716468811 + 1 + <_> + + + + <_>2 1 14 4 -1. + <_>2 1 7 2 2. + <_>9 3 7 2 2. + 0 + 2.4025330785661936e-003 + 0.3166579902172089 + 0.5285738110542297 + <_> + + <_> + + + + <_>11 14 1 3 -1. + <_>11 15 1 1 3. + 0 + -3.4089901018887758e-003 + 1 + 0.4905214905738831 + <_> + + + + <_>6 15 8 2 -1. + <_>6 16 8 1 2. + 0 + 8.0019602319225669e-004 + 0.4522736072540283 + 0.5580614209175110 + <_> + + <_> + + + + <_>8 14 1 3 -1. + <_>8 15 1 1 3. + 0 + 2.1901070140302181e-003 + 1 + 0.6612681746482849 + <_> + + + + <_>8 11 2 8 -1. + <_>8 15 2 4 2. + 0 + 3.3745369873940945e-003 + 0.5107765197753906 + 0.3386929929256439 + <_> + + <_> + + + + <_>6 15 8 2 -1. + <_>6 16 8 1 2. + 0 + 8.0019602319225669e-004 + 1 + 0.5707560181617737 + <_> + + + + <_>7 16 8 3 -1. + <_>7 17 8 1 3. + 0 + 0.0173460692167282 + 0.5016021132469177 + 0.6306459903717041 + <_> + + <_> + + + + <_>0 16 2 2 -1. + <_>0 17 2 1 2. + 0 + -1.9568449351936579e-003 + 0.3017806112766266 + 1 + <_> + + + + <_>1 16 8 4 -1. + <_>1 16 4 2 2. + <_>5 18 4 2 2. + 0 + -0.0112290196120739 + 0.6293851137161255 + 0.4520488977432251 + <_> + + <_> + + + + <_>2 9 16 3 -1. + <_>2 10 16 1 3. + 0 + -2.6608388870954514e-003 + 0.3344007134437561 + 1 + <_> + + + + <_>13 11 2 4 -1. + <_>13 11 1 4 2. + 0 + -0.0116151003167033 + 0.2825379073619843 + 0.5150970816612244 + <_> + + <_> + + + + <_>0 13 16 6 -1. + <_>0 15 16 2 3. + 0 + -0.0952486023306847 + 0.1398265063762665 + 1 + <_> + + + + <_>5 11 2 4 -1. + <_>6 11 1 4 2. + 0 + 7.3701781220734119e-003 + 0.5293998718261719 + 0.2331728041172028 + <_> + + <_> + + + + <_>18 2 2 18 -1. + <_>19 2 1 9 2. + <_>18 11 1 9 2. + 0 + -0.0149539001286030 + 1 + 0.4940465986728668 + <_> + + + + <_>19 7 1 9 -1. + <_>19 10 1 3 3. + 0 + 5.7038792874664068e-004 + 0.5466570854187012 + 0.4626767933368683 + <_> + + <_> + + + + <_>0 2 2 18 -1. + <_>0 2 1 9 2. + <_>1 11 1 9 2. + 0 + 5.8516198769211769e-003 + 1 + 0.6270040869712830 + <_> + + + + <_>0 7 1 9 -1. + <_>0 10 1 3 3. + 0 + 2.1150549582671374e-004 + 0.5508140921592712 + 0.4061872959136963 + <_> + + <_> + + + + <_>14 12 2 2 -1. + <_>14 13 2 1 2. + 0 + -6.9679190346505493e-006 + 1 + 0.4096567928791046 + <_> + + + + <_>11 14 2 3 -1. + <_>11 15 2 1 3. + 0 + -7.9677387839183211e-004 + 0.5615556836128235 + 0.4666886031627655 + <_> + + <_> + + + + <_>7 8 6 2 -1. + <_>7 9 6 1 2. + 0 + 0.0194594804197550 + 1 + 0.2311480939388275 + <_> + + + + <_>7 12 4 6 -1. + <_>7 12 2 3 2. + <_>9 15 2 3 2. + 0 + -0.0111608300358057 + 0.3087011873722076 + 0.5514662265777588 + <_> + + <_> + + + + <_>8 13 5 3 -1. + <_>8 14 5 1 3. + 0 + 0.0140561498701572 + 1 + 0.7005056142807007 + <_> + + + + <_>12 14 2 2 -1. + <_>13 14 1 1 2. + <_>12 15 1 1 2. + 0 + -3.2958350493572652e-004 + 0.5797485709190369 + 0.4691650867462158 + <_> + + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + -5.4636420682072639e-003 + 0.5928595066070557 + 1 + <_> + + + + <_>7 13 5 2 -1. + <_>7 14 5 1 2. + 0 + 5.8881669247057289e-005 + 0.3741397857666016 + 0.5170168876647949 + <_> + + <_> + + + + <_>2 10 16 4 -1. + <_>10 10 8 2 2. + <_>2 12 8 2 2. + 0 + 6.6343429498374462e-003 + 0.5414987802505493 + 1 + <_> + + + + <_>7 0 6 6 -1. + <_>9 0 2 6 3. + 0 + 0.0452634096145630 + 0.5180327296257019 + 0.1529684066772461 + <_> + + <_> + + + + <_>7 1 6 3 -1. + <_>7 2 6 1 3. + 0 + -8.0646127462387085e-003 + 0.2515468001365662 + 1 + <_> + + + + <_>0 12 6 2 -1. + <_>0 13 6 1 2. + 0 + 4.7389548853971064e-004 + 0.5121998786926270 + 0.3725948929786682 + <_> + + <_> + + + + <_>6 3 11 2 -1. + <_>6 4 11 1 2. + 0 + 1.4877359717502259e-005 + 1 + 0.5532435774803162 + <_> + + + + <_>12 0 8 6 -1. + <_>16 0 4 3 2. + <_>12 3 4 3 2. + 0 + 0.0243211593478918 + 0.4960766136646271 + 0.5983315110206604 + <_> + + <_> + + + + <_>8 12 1 2 -1. + <_>8 13 1 1 2. + 0 + 6.9931396865285933e-005 + 0.4163953065872192 + 1 + <_> + + + + <_>8 8 1 12 -1. + <_>8 12 1 4 3. + 0 + 2.6287760119885206e-003 + 0.5880144834518433 + 0.3399662971496582 + <_> + + <_> + + + + <_>11 11 2 2 -1. + <_>12 11 1 1 2. + <_>11 12 1 1 2. + 0 + 3.8190539926290512e-003 + 1 + 0.7846621274948120 + <_> + + + + <_>12 7 3 13 -1. + <_>13 7 1 13 3. + 0 + -0.0259891506284475 + 0.3288114070892334 + 0.5155087709426880 + <_> + + <_> + + + + <_>7 11 2 2 -1. + <_>7 11 1 1 2. + <_>8 12 1 1 2. + 0 + 1.2062400346621871e-003 + 0.4596059918403626 + 1 + <_> + + + + <_>3 13 1 3 -1. + <_>3 14 1 1 3. + 0 + -1.5557400183752179e-003 + 0.3126986920833588 + 0.7183399200439453 + <_> + + <_> + + + + <_>10 18 3 2 -1. + <_>11 18 1 2 3. + 0 + -2.2691930644214153e-003 + 1 + 0.5274006128311157 + <_> + + + + <_>11 11 2 1 -1. + <_>11 11 1 1 2. + 0 + 2.3287249496206641e-004 + 0.4878666102886200 + 0.5615152716636658 + <_> + + <_> + + + + <_>1 10 5 9 -1. + <_>1 13 5 3 3. + 0 + -5.5999699980020523e-003 + 1 + 0.5160812139511108 + <_> + + + + <_>4 8 6 4 -1. + <_>6 8 2 4 3. + 0 + -0.0104961898177862 + 0.5701614022254944 + 0.3204850852489471 + <_> + + <_> + + + + <_>13 12 1 4 -1. + <_>13 14 1 2 2. + 0 + -1.4814930182183161e-005 + 0.5538837909698486 + 1 + <_> + + + + <_>11 3 4 14 -1. + <_>13 3 2 7 2. + <_>11 10 2 7 2. + 0 + -6.4287078566849232e-004 + 0.5349429249763489 + 0.4472151100635529 + <_> + + <_> + + + + <_>6 12 1 4 -1. + <_>6 14 1 2 2. + 0 + -1.8891949730459601e-004 + 0.5012837052345276 + 1 + <_> + + + + <_>5 3 4 14 -1. + <_>5 3 2 7 2. + <_>7 10 2 7 2. + 0 + -9.0413521975278854e-003 + 0.2562935948371887 + 0.4503383040428162 + <_> + + <_> + + + + <_>10 18 3 2 -1. + <_>11 18 1 2 3. + 0 + 7.9534705728292465e-003 + 1 + 0.2630499899387360 + <_> + + + + <_>9 12 3 3 -1. + <_>9 13 3 1 3. + 0 + -2.7908999472856522e-003 + 0.5756508708000183 + 0.4854863882064819 + <_> + + <_> + + + + <_>2 2 12 6 -1. + <_>2 2 6 3 2. + <_>8 5 6 3 2. + 0 + 3.2857100013643503e-003 + 1 + 0.4084751904010773 + <_> + + + + <_>6 6 6 2 -1. + <_>9 6 3 2 2. + 0 + 7.7063008211553097e-004 + 0.4073356091976166 + 0.5920240879058838 + 44.6829681396484380 + 15 + -1 + <_> + + + <_> + + <_> + + + + <_>1 0 18 12 -1. + <_>7 0 6 12 3. + 0 + 0.0630219429731369 + 0.3419382870197296 + 1 + <_> + + + + <_>5 7 6 4 -1. + <_>5 7 3 2 2. + <_>8 9 3 2 2. + 0 + -2.8374609537422657e-003 + 0.6829563975334168 + 0.4404523074626923 + <_> + + <_> + + + + <_>5 7 10 4 -1. + <_>5 9 10 2 2. + 0 + 0.0464619509875774 + 0.4391745030879974 + 1 + <_> + + + + <_>7 7 6 4 -1. + <_>9 7 2 4 3. + 0 + 0.0291525404900312 + 0.4601063132286072 + 0.6357936859130859 + <_> + + <_> + + + + <_>9 5 2 2 -1. + <_>9 6 2 1 2. + 0 + -1.4000290320836939e-005 + 1 + 0.3730010092258453 + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -1.2757079675793648e-003 + 0.3093824088573456 + 0.5901370048522949 + <_> + + <_> + + + + <_>6 17 8 3 -1. + <_>6 18 8 1 3. + 0 + 1.3596529606729746e-003 + 0.4337565004825592 + 1 + <_> + + + + <_>9 17 6 2 -1. + <_>12 17 3 1 2. + <_>9 18 3 1 2. + 0 + 1.7991929780691862e-004 + 0.4217503964900971 + 0.5846847891807556 + <_> + + <_> + + + + <_>4 12 2 2 -1. + <_>4 13 2 1 2. + 0 + -1.4166639630275313e-005 + 1 + 0.4084691107273102 + <_> + + + + <_>3 12 9 2 -1. + <_>3 13 9 1 2. + 0 + 6.0252390539972112e-005 + 0.5087286829948425 + 0.7277184128761292 + <_> + + <_> + + + + <_>8 3 6 1 -1. + <_>10 3 2 1 3. + 0 + 6.4320368692278862e-003 + 1 + 0.2967903017997742 + <_> + + + + <_>9 3 4 6 -1. + <_>11 3 2 3 2. + <_>9 6 2 3 2. + 0 + 4.6682319953106344e-004 + 0.4110462963581085 + 0.5581219792366028 + <_> + + <_> + + + + <_>0 3 6 5 -1. + <_>3 3 3 5 2. + 0 + 5.7436279021203518e-003 + 0.4287309944629669 + 1 + <_> + + + + <_>2 0 2 18 -1. + <_>2 6 2 6 3. + 0 + 3.2019240316003561e-003 + 0.4266195893287659 + 0.6444045901298523 + <_> + + <_> + + + + <_>14 2 4 9 -1. + <_>14 5 4 3 3. + 0 + -5.7637941790744662e-004 + 1 + 0.4084824919700623 + <_> + + + + <_>10 18 3 2 -1. + <_>11 18 1 2 3. + 0 + -3.7901920732110739e-003 + 0.3181920945644379 + 0.5230693221092224 + <_> + + <_> + + + + <_>2 2 4 9 -1. + <_>2 5 4 3 3. + 0 + 4.8914109356701374e-003 + 1 + 0.3548356890678406 + <_> + + + + <_>7 18 3 2 -1. + <_>8 18 1 2 3. + 0 + 4.6459292061626911e-003 + 0.5610597729682922 + 0.2693848907947540 + <_> + + <_> + + + + <_>10 14 3 3 -1. + <_>10 15 3 1 3. + 0 + -6.8799369037151337e-003 + 0.6235408186912537 + 1 + <_> + + + + <_>10 12 2 6 -1. + <_>10 15 2 3 2. + 0 + -0.0181474704295397 + 0.2861981987953186 + 0.5226848125457764 + <_> + + <_> + + + + <_>7 5 3 6 -1. + <_>7 7 3 2 3. + 0 + 1.1409220314817503e-004 + 1 + 0.3257833123207092 + <_> + + + + <_>3 3 6 2 -1. + <_>3 4 6 1 2. + 0 + -5.4334272863343358e-004 + 0.3882969021797180 + 0.5341166257858276 + <_> + + <_> + + + + <_>8 4 7 3 -1. + <_>8 5 7 1 3. + 0 + -2.7602489572018385e-003 + 0.6353965997695923 + 1 + <_> + + + + <_>13 6 2 3 -1. + <_>13 7 2 1 3. + 0 + -1.9730569329112768e-003 + 0.5880761146545410 + 0.4593090116977692 + <_> + + <_> + + + + <_>8 8 2 12 -1. + <_>8 12 2 4 3. + 0 + 2.4565239436924458e-003 + 1 + 0.3134010136127472 + <_> + + + + <_>5 4 8 14 -1. + <_>5 4 4 7 2. + <_>9 11 4 7 2. + 0 + 1.9392010290175676e-004 + 0.5277131795883179 + 0.3604106903076172 + <_> + + <_> + + + + <_>0 1 20 8 -1. + <_>10 1 10 4 2. + <_>0 5 10 4 2. + 0 + 0.0786430165171623 + 0.5290341973304749 + 1 + <_> + + + + <_>4 0 12 2 -1. + <_>4 1 12 1 2. + 0 + 6.5276869572699070e-003 + 0.4654479920864105 + 0.6044905185699463 + <_> + + <_> + + + + <_>0 1 20 8 -1. + <_>0 1 10 4 2. + <_>10 5 10 4 2. + 0 + -0.0787167996168137 + 0.2541126906871796 + 1 + <_> + + + + <_>4 0 12 2 -1. + <_>4 1 12 1 2. + 0 + 5.7298499159514904e-003 + 0.4366919100284576 + 0.5822886228561401 + <_> + + <_> + + + + <_>9 5 6 3 -1. + <_>9 5 3 3 2. + 0 + 6.2386557692661881e-004 + 1 + 0.5472692251205444 + <_> + + + + <_>8 13 10 6 -1. + <_>8 15 10 2 3. + 0 + -0.0852672308683395 + 0.1461607962846756 + 0.5181810855865479 + <_> + + <_> + + + + <_>5 5 6 3 -1. + <_>8 5 3 3 2. + 0 + 0.0409811101853848 + 1 + 0.1270135045051575 + <_> + + + + <_>6 3 6 1 -1. + <_>8 3 2 1 3. + 0 + 7.7135749161243439e-003 + 0.4832684993743897 + 0.2223578989505768 + <_> + + <_> + + + + <_>11 18 9 2 -1. + <_>14 18 3 2 3. + 0 + -6.8663940764963627e-003 + 0.5918928980827332 + 1 + <_> + + + + <_>13 11 6 7 -1. + <_>13 11 3 7 2. + 0 + 0.0145596396178007 + 0.4761506915092468 + 0.5727223753929138 + <_> + + <_> + + + + <_>4 6 12 10 -1. + <_>4 6 6 5 2. + <_>10 11 6 5 2. + 0 + -0.0100643103942275 + 0.3636730909347534 + 1 + <_> + + + + <_>8 17 3 3 -1. + <_>9 17 1 3 3. + 0 + 3.6274080630391836e-003 + 0.5271731019020081 + 0.2740525007247925 + <_> + + <_> + + + + <_>11 18 9 2 -1. + <_>14 18 3 2 3. + 0 + -2.3421540390700102e-003 + 0.5497784018516541 + 1 + <_> + + + + <_>13 11 6 8 -1. + <_>13 11 3 8 2. + 0 + -0.0246864091604948 + 0.6059895157814026 + 0.4960314035415649 + <_> + + <_> + + + + <_>4 16 2 2 -1. + <_>4 17 2 1 2. + 0 + 1.9456120207905769e-004 + 1 + 0.3769465088844299 + <_> + + + + <_>7 15 4 4 -1. + <_>7 17 4 2 2. + 0 + 3.1714211218059063e-004 + 0.4062362015247345 + 0.5668215155601502 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + 2.0793990697711706e-003 + 0.4618656933307648 + 1 + <_> + + + + <_>13 6 2 3 -1. + <_>13 7 2 1 3. + 0 + 1.7982709687203169e-003 + 0.4867505133152008 + 0.6518449783325195 + <_> + + <_> + + + + <_>5 11 6 1 -1. + <_>7 11 2 1 3. + 0 + -2.2287059982772917e-004 + 0.5677595734596252 + 1 + <_> + + + + <_>7 10 3 1 -1. + <_>8 10 1 1 3. + 0 + 3.2623921288177371e-004 + 0.3710733950138092 + 0.5676605105400085 + <_> + + <_> + + + + <_>0 12 20 4 -1. + <_>0 14 20 2 2. + 0 + -0.0667926818132401 + 0.2511521875858307 + 1 + <_> + + + + <_>10 2 3 2 -1. + <_>10 3 3 1 2. + 0 + -1.4869889710098505e-003 + 0.3886750936508179 + 0.5262253880500794 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + -5.0454870797693729e-003 + 0.6557472944259644 + 1 + <_> + + + + <_>5 5 4 3 -1. + <_>5 6 4 1 3. + 0 + -4.8297587782144547e-003 + 0.5934106111526489 + 0.4285922050476074 + <_> + + <_> + + + + <_>8 8 4 3 -1. + <_>8 9 4 1 3. + 0 + -1.0722599690780044e-003 + 1 + 0.5426058769226074 + <_> + + + + <_>10 4 2 12 -1. + <_>10 8 2 4 3. + 0 + 8.7901195511221886e-003 + 0.5351303219795227 + 0.4834277927875519 + <_> + + <_> + + + + <_>0 3 4 3 -1. + <_>0 4 4 1 3. + 0 + -7.1750381030142307e-003 + 0.2067168951034546 + 1 + <_> + + + + <_>1 3 2 3 -1. + <_>1 4 2 1 3. + 0 + 1.1251230025663972e-003 + 0.5112252235412598 + 0.3468714058399200 + <_> + + <_> + + + + <_>16 1 4 11 -1. + <_>16 1 2 11 2. + 0 + 0.0106347100809217 + 0.4479008018970490 + 1 + <_> + + + + <_>18 2 2 16 -1. + <_>19 2 1 8 2. + <_>18 10 1 8 2. + 0 + -0.0117632197216153 + 0.6253901720046997 + 0.4968987107276917 + <_> + + <_> + + + + <_>1 8 6 12 -1. + <_>3 8 2 12 3. + 0 + 0.0923240631818771 + 1 + 0.2031303942203522 + <_> + + + + <_>7 2 6 2 -1. + <_>7 2 3 1 2. + <_>10 3 3 1 2. + 0 + 1.8991080578416586e-003 + 0.5618721842765808 + 0.4046572148799896 + <_> + + <_> + + + + <_>12 4 8 2 -1. + <_>16 4 4 1 2. + <_>12 5 4 1 2. + 0 + -0.0105103403329849 + 1 + 0.4943264126777649 + <_> + + + + <_>10 6 6 2 -1. + <_>12 6 2 2 3. + 0 + -7.4531312566250563e-004 + 0.5613427758216858 + 0.3845331966876984 + <_> + + <_> + + + + <_>0 4 8 2 -1. + <_>0 4 4 1 2. + <_>4 5 4 1 2. + 0 + 8.0041000619530678e-003 + 1 + 0.7759842276573181 + <_> + + + + <_>1 3 3 5 -1. + <_>2 3 1 5 3. + 0 + 5.8110528625547886e-003 + 0.4624733030796051 + 0.6286277174949646 + <_> + + <_> + + + + <_>16 3 4 6 -1. + <_>16 5 4 2 3. + 0 + -0.0279185809195042 + 0.2409314066171646 + 1 + <_> + + + + <_>8 6 4 3 -1. + <_>8 7 4 1 3. + 0 + 2.1739399526268244e-003 + 0.5345504879951477 + 0.3507958054542542 + <_> + + <_> + + + + <_>8 14 1 3 -1. + <_>8 15 1 1 3. + 0 + -4.0639587678015232e-003 + 0.6647101044654846 + 1 + <_> + + + + <_>4 11 1 2 -1. + <_>4 12 1 1 2. + 0 + 6.0017139185220003e-004 + 0.4998509883880615 + 0.3022165000438690 + <_> + + <_> + + + + <_>8 14 6 3 -1. + <_>8 15 6 1 3. + 0 + 1.9214770291000605e-003 + 1 + 0.5919150710105896 + <_> + + + + <_>7 15 7 3 -1. + <_>7 16 7 1 3. + 0 + -0.0138608301058412 + 0.6351767778396606 + 0.4993310868740082 + <_> + + <_> + + + + <_>9 12 2 8 -1. + <_>9 16 2 4 2. + 0 + 0.0230068508535624 + 1 + 0.1902336031198502 + <_> + + + + <_>4 6 6 2 -1. + <_>6 6 2 2 3. + 0 + -1.3857929734513164e-003 + 0.5253369212150574 + 0.3985860049724579 + <_> + + <_> + + + + <_>12 7 4 2 -1. + <_>12 8 4 1 2. + 0 + 1.2637410545721650e-003 + 0.4666104018688202 + 1 + <_> + + + + <_>5 3 13 10 -1. + <_>5 8 13 5 2. + 0 + -0.0146752102300525 + 0.3823164999485016 + 0.5326632857322693 + <_> + + <_> + + + + <_>4 7 4 2 -1. + <_>4 8 4 1 2. + 0 + -2.9535070061683655e-003 + 0.7063655853271484 + 1 + <_> + + + + <_>0 8 16 2 -1. + <_>0 8 8 1 2. + <_>8 9 8 1 2. + 0 + -1.7189770005643368e-003 + 0.3813462853431702 + 0.5246735215187073 + <_> + + <_> + + + + <_>11 8 2 5 -1. + <_>11 8 1 5 2. + 0 + -4.2484089499339461e-004 + 1 + 0.4791638851165772 + <_> + + + + <_>10 0 6 13 -1. + <_>10 0 3 13 2. + 0 + -8.5248658433556557e-004 + 0.4491218030452728 + 0.5370901226997376 + <_> + + <_> + + + + <_>1 6 4 2 -1. + <_>1 7 4 1 2. + 0 + 8.9034568518400192e-003 + 1 + 0.2076473981142044 + <_> + + + + <_>4 3 2 1 -1. + <_>5 3 1 1 2. + 0 + 1.4895649655954912e-005 + 0.4447635114192963 + 0.5667163133621216 + <_> + + <_> + + + + <_>11 8 2 5 -1. + <_>11 8 1 5 2. + 0 + -4.7091601300053298e-004 + 0.5465071201324463 + 1 + <_> + + + + <_>12 10 4 8 -1. + <_>12 10 2 8 2. + 0 + 4.3084810022264719e-004 + 0.5493261814117432 + 0.4580708146095276 + <_> + + <_> + + + + <_>7 8 2 5 -1. + <_>8 8 1 5 2. + 0 + -6.3893961487337947e-004 + 0.5501571893692017 + 1 + <_> + + + + <_>4 10 4 8 -1. + <_>6 10 2 8 2. + 0 + -7.3733746830839664e-005 + 0.5085790753364563 + 0.3305698037147522 + <_> + + <_> + + + + <_>6 7 9 12 -1. + <_>9 7 3 12 3. + 0 + -8.8991485536098480e-003 + 0.4276469051837921 + 1 + <_> + + + + <_>11 13 2 3 -1. + <_>11 13 1 3 2. + 0 + -0.0102533502504230 + 0.1123218014836311 + 0.5152723193168640 + <_> + + <_> + + + + <_>7 10 6 10 -1. + <_>10 10 3 10 2. + 0 + -0.0596374906599522 + 0.7386772036552429 + 1 + <_> + + + + <_>8 11 4 8 -1. + <_>8 11 2 4 2. + <_>10 15 2 4 2. + 0 + 0.0217071995139122 + 0.4996291995048523 + 0.1339413970708847 + <_> + + <_> + + + + <_>16 1 4 11 -1. + <_>16 1 2 11 2. + 0 + 9.9107045680284500e-003 + 0.4679012000560761 + 1 + <_> + + + + <_>18 2 2 4 -1. + <_>18 2 1 4 2. + 0 + -0.0109983002766967 + 0.6928656101226807 + 0.5012068152427673 + <_> + + <_> + + + + <_>5 6 6 2 -1. + <_>5 6 3 1 2. + <_>8 7 3 1 2. + 0 + 7.4608891736716032e-004 + 1 + 0.5833582282066345 + <_> + + + + <_>5 4 1 3 -1. + <_>5 5 1 1 3. + 0 + 2.9539171373471618e-004 + 0.3826391100883484 + 0.5566350817680359 + <_> + + <_> + + + + <_>11 1 4 14 -1. + <_>11 1 2 14 2. + 0 + 0.0500541292130947 + 1 + 0.3002721071243286 + <_> + + + + <_>4 2 12 3 -1. + <_>8 2 4 3 3. + 0 + -7.2330660186707973e-003 + 0.5908042788505554 + 0.5000870823860169 + <_> + + <_> + + + + <_>5 1 4 14 -1. + <_>7 1 2 14 2. + 0 + -2.6863380335271358e-003 + 0.3975034952163696 + 1 + <_> + + + + <_>7 3 6 2 -1. + <_>9 3 2 2 3. + 0 + -1.0195849463343620e-003 + 0.3697685897350311 + 0.5756192803382874 + <_> + + <_> + + + + <_>2 0 18 4 -1. + <_>8 0 6 4 3. + 0 + -0.0202049203217030 + 0.6375268101692200 + 1 + <_> + + + + <_>9 5 2 10 -1. + <_>9 10 2 5 2. + 0 + 2.1340379025787115e-003 + 0.5363265872001648 + 0.4433170855045319 + <_> + + <_> + + + + <_>8 6 3 4 -1. + <_>9 6 1 4 3. + 0 + -1.8348889425396919e-003 + 0.5828999280929565 + 1 + <_> + + + + <_>5 5 9 11 -1. + <_>8 5 3 11 3. + 0 + -5.9489468112587929e-003 + 0.2680670917034149 + 0.4642885923385620 + <_> + + <_> + + + + <_>10 6 3 5 -1. + <_>11 6 1 5 3. + 0 + -2.3030120064504445e-004 + 0.5475320219993591 + 1 + <_> + + + + <_>8 9 6 5 -1. + <_>8 9 3 5 2. + 0 + 5.0581009127199650e-003 + 0.5320833921432495 + 0.4646492898464203 + <_> + + <_> + + + + <_>7 6 3 5 -1. + <_>8 6 1 5 3. + 0 + -5.1950011402368546e-004 + 0.5232744812965393 + 1 + <_> + + + + <_>6 10 6 3 -1. + <_>9 10 3 3 2. + 0 + -6.8620947422459722e-004 + 0.4935086071491242 + 0.3103117942810059 + <_> + + <_> + + + + <_>10 0 3 7 -1. + <_>11 0 1 7 3. + 0 + -7.4936267919838428e-003 + 0.2883046865463257 + 1 + <_> + + + + <_>0 3 20 12 -1. + <_>0 9 20 6 2. + 0 + -0.0156829301267862 + 0.3640313148498535 + 0.5368754863739014 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>10 7 1 2 2. + 0 + -3.2649750355631113e-003 + 0.6468631029129028 + 1 + <_> + + + + <_>5 9 4 1 -1. + <_>7 9 2 1 2. + 0 + 3.8463930832222104e-004 + 0.5259659886360169 + 0.3831427991390228 + <_> + + <_> + + + + <_>13 13 3 2 -1. + <_>13 14 3 1 2. + 0 + 4.4492390006780624e-003 + 1 + 0.2086818963289261 + <_> + + + + <_>16 9 4 6 -1. + <_>16 9 2 6 2. + 0 + 0.0231183208525181 + 0.4978533089160919 + 0.5961257219314575 + <_> + + <_> + + + + <_>7 15 6 3 -1. + <_>7 16 6 1 3. + 0 + 2.0835159812122583e-003 + 1 + 0.5746421813964844 + <_> + + + + <_>6 16 7 3 -1. + <_>6 17 7 1 3. + 0 + 1.1513150529935956e-003 + 0.3586845099925995 + 0.5363473892211914 + <_> + + <_> + + + + <_>11 14 9 6 -1. + <_>11 16 9 2 3. + 0 + 0.0361047089099884 + 1 + 0.2833136916160584 + <_> + + + + <_>19 14 1 3 -1. + <_>19 15 1 1 3. + 0 + 3.6256198654882610e-004 + 0.5477722287178040 + 0.4110532104969025 + <_> + + <_> + + + + <_>0 9 6 6 -1. + <_>3 9 3 6 2. + 0 + -3.4635469783097506e-003 + 0.5990386009216309 + 1 + <_> + + + + <_>0 19 9 1 -1. + <_>3 19 3 1 3. + 0 + -2.8796829283237457e-003 + 0.5725253224372864 + 0.4149512052536011 + <_> + + <_> + + + + <_>11 14 9 6 -1. + <_>11 16 9 2 3. + 0 + -8.1119500100612640e-003 + 1 + 0.5396351814270020 + <_> + + + + <_>12 12 6 6 -1. + <_>12 14 6 2 3. + 0 + 4.5932079665362835e-003 + 0.5379704236984253 + 0.3891302943229675 + <_> + + <_> + + + + <_>1 14 8 6 -1. + <_>1 16 8 2 3. + 0 + 7.0014740340411663e-003 + 1 + 0.3714671134948731 + <_> + + + + <_>8 1 3 2 -1. + <_>9 1 1 2 3. + 0 + 8.0169539432972670e-004 + 0.5529567003250122 + 0.3755804896354675 + <_> + + <_> + + + + <_>18 2 2 4 -1. + <_>18 2 1 4 2. + 0 + -8.6652329191565514e-003 + 1 + 0.5025773048400879 + <_> + + + + <_>14 0 6 3 -1. + <_>16 0 2 3 3. + 0 + -2.7315050829201937e-003 + 0.5850322246551514 + 0.4617573916912079 + <_> + + <_> + + + + <_>0 2 2 4 -1. + <_>1 2 1 4 2. + 0 + 1.3301590224727988e-003 + 1 + 0.5937700867652893 + <_> + + + + <_>0 0 6 3 -1. + <_>2 0 2 3 3. + 0 + -4.2648240923881531e-003 + 0.5645368099212647 + 0.3937624990940094 + <_> + + <_> + + + + <_>9 0 3 2 -1. + <_>10 0 1 2 3. + 0 + 6.3251499086618423e-003 + 0.5182105898857117 + 1 + <_> + + + + <_>12 1 2 2 -1. + <_>12 1 1 2 2. + 0 + -3.0753740575164557e-003 + 0.3007416129112244 + 0.5196403861045837 + <_> + + <_> + + + + <_>8 0 3 2 -1. + <_>9 0 1 2 3. + 0 + -7.3622138006612659e-004 + 0.3697580099105835 + 1 + <_> + + + + <_>6 1 2 2 -1. + <_>7 1 1 2 2. + 0 + 3.0082479497650638e-005 + 0.4327593147754669 + 0.5715808868408203 + <_> + + <_> + + + + <_>10 8 2 3 -1. + <_>10 9 2 1 3. + 0 + -3.8722730241715908e-003 + 0.3473713099956513 + 1 + <_> + + + + <_>13 15 6 2 -1. + <_>13 16 6 1 2. + 0 + 6.2879058532416821e-004 + 0.5438259243965149 + 0.4453906118869782 + <_> + + <_> + + + + <_>8 12 2 2 -1. + <_>8 12 1 1 2. + <_>9 13 1 1 2. + 0 + 1.3411579420790076e-003 + 1 + 0.6511713862419128 + <_> + + + + <_>8 15 3 5 -1. + <_>9 15 1 5 3. + 0 + -8.3681922405958176e-003 + 0.1443295031785965 + 0.4888199865818024 + <_> + + <_> + + + + <_>8 6 4 12 -1. + <_>8 12 4 6 2. + 0 + 9.3305751215666533e-004 + 1 + 0.3951109051704407 + <_> + + + + <_>7 6 7 8 -1. + <_>7 10 7 4 2. + 0 + -1.0746510233730078e-003 + 0.3910265862941742 + 0.5349503755569458 + <_> + + <_> + + + + <_>0 11 8 2 -1. + <_>0 12 8 1 2. + 0 + -0.0186100509017706 + 0.1275743991136551 + 1 + <_> + + + + <_>8 11 2 2 -1. + <_>8 11 1 1 2. + <_>9 12 1 1 2. + 0 + 1.3651419430971146e-003 + 0.5038288831710815 + 0.6951304078102112 + <_> + + <_> + + + + <_>7 7 12 1 -1. + <_>11 7 4 1 3. + 0 + 7.3744421824812889e-003 + 0.5253443121910095 + 1 + <_> + + + + <_>10 8 3 2 -1. + <_>11 8 1 2 3. + 0 + 8.4163323044776917e-003 + 0.5011243820190430 + 0.7311332821846008 + <_> + + <_> + + + + <_>1 7 12 1 -1. + <_>5 7 4 1 3. + 0 + 5.1413988694548607e-003 + 0.4953536093235016 + 1 + <_> + + + + <_>6 5 8 2 -1. + <_>6 5 4 1 2. + <_>10 6 4 1 2. + 0 + 4.5847031287848949e-003 + 0.2535555958747864 + 0.6462442874908447 + <_> + + <_> + + + + <_>9 10 3 10 -1. + <_>10 10 1 10 3. + 0 + 0.0285652391612530 + 1 + 0.2330722063779831 + <_> + + + + <_>16 0 2 4 -1. + <_>16 0 1 4 2. + 0 + 4.3958800961263478e-004 + 0.4702244102954865 + 0.5544549226760864 + <_> + + <_> + + + + <_>8 10 3 10 -1. + <_>9 10 1 10 3. + 0 + 0.0314594581723213 + 1 + 0.0336896888911724 + <_> + + + + <_>9 10 2 3 -1. + <_>9 11 2 1 3. + 0 + 5.6011630222201347e-003 + 0.4787121117115021 + 0.6338351964950562 + <_> + + <_> + + + + <_>8 9 4 2 -1. + <_>10 9 2 1 2. + <_>8 10 2 1 2. + 0 + 7.1835669223219156e-004 + 0.5431486964225769 + 1 + <_> + + + + <_>12 14 7 6 -1. + <_>12 16 7 2 3. + 0 + -5.5303089320659637e-003 + 0.4105832874774933 + 0.5403990745544434 + <_> + + <_> + + + + <_>6 1 3 1 -1. + <_>7 1 1 1 3. + 0 + 1.4129279879853129e-003 + 1 + 0.3105539977550507 + <_> + + + + <_>2 0 2 4 -1. + <_>3 0 1 4 2. + 0 + 2.5530709535814822e-004 + 0.4254471957683563 + 0.5447154045104981 + <_> + + <_> + + + + <_>11 11 2 2 -1. + <_>12 11 1 1 2. + <_>11 12 1 1 2. + 0 + 3.1966410460881889e-004 + 1 + 0.6118361949920654 + <_> + + + + <_>12 12 6 6 -1. + <_>12 14 6 2 3. + 0 + 5.0411392003297806e-003 + 0.5290042161941528 + 0.4224787056446075 + <_> + + <_> + + + + <_>1 0 6 10 -1. + <_>1 0 3 5 2. + <_>4 5 3 5 2. + 0 + 7.7617880888283253e-003 + 0.4315345883369446 + 1 + <_> + + + + <_>3 0 2 9 -1. + <_>3 3 2 3 3. + 0 + 2.9374631121754646e-003 + 0.6629263162612915 + 0.3028964996337891 + <_> + + <_> + + + + <_>14 13 3 2 -1. + <_>14 14 3 1 2. + 0 + -1.6497720498591661e-003 + 1 + 0.5491852760314941 + <_> + + + + <_>15 2 3 2 -1. + <_>15 3 3 1 2. + 0 + -5.8834417723119259e-003 + 0.3188554048538208 + 0.5184289216995239 + <_> + + <_> + + + + <_>2 13 5 2 -1. + <_>2 14 5 1 2. + 0 + 8.7459187489002943e-004 + 1 + 0.3328830897808075 + <_> + + + + <_>3 4 12 10 -1. + <_>3 4 6 5 2. + <_>9 9 6 5 2. + 0 + -0.0153087796643376 + 0.3923608064651489 + 0.5235139131546021 + <_> + + <_> + + + + <_>5 1 14 6 -1. + <_>5 3 14 2 3. + 0 + 0.0322924517095089 + 1 + 0.5977646708488464 + <_> + + + + <_>15 3 3 2 -1. + <_>15 4 3 1 2. + 0 + -4.3842519517056644e-004 + 0.4541687965393066 + 0.5369428992271423 + <_> + + <_> + + + + <_>7 11 2 2 -1. + <_>7 11 1 1 2. + <_>8 12 1 1 2. + 0 + 1.5429529594257474e-003 + 1 + 0.6318141222000122 + <_> + + + + <_>2 14 6 6 -1. + <_>2 16 6 2 3. + 0 + -2.4733028840273619e-003 + 0.3490633070468903 + 0.4759024977684021 + <_> + + <_> + + + + <_>6 13 8 3 -1. + <_>6 14 8 1 3. + 0 + 2.0994939841330051e-003 + 1 + 0.5887197852134705 + <_> + + + + <_>1 19 18 1 -1. + <_>7 19 6 1 3. + 0 + -5.7541108690202236e-003 + 0.5961331725120544 + 0.4841983020305634 + <_> + + <_> + + + + <_>8 12 1 6 -1. + <_>8 15 1 3 2. + 0 + -0.0102331303060055 + 0.1705404072999954 + 1 + <_> + + + + <_>0 0 14 15 -1. + <_>0 5 14 5 3. + 0 + 0.2255450934171677 + 0.4779379963874817 + 0.0978796631097794 + <_> + + <_> + + + + <_>3 0 16 8 -1. + <_>3 4 16 4 2. + 0 + 0.0296665597707033 + 1 + 0.5822224020957947 + <_> + + + + <_>6 1 8 12 -1. + <_>6 7 8 6 2. + 0 + -2.8518449980765581e-003 + 0.5459626913070679 + 0.4610066115856171 + <_> + + <_> + + + + <_>5 3 3 3 -1. + <_>6 3 1 3 3. + 0 + 9.7465328872203827e-004 + 1 + 0.3670322895050049 + <_> + + + + <_>5 1 3 4 -1. + <_>6 1 1 4 3. + 0 + 1.4044740055396687e-005 + 0.4302386045455933 + 0.5691710710525513 + <_> + + <_> + + + + <_>15 14 4 6 -1. + <_>17 14 2 3 2. + <_>15 17 2 3 2. + 0 + -0.0175794307142496 + 0.6917321085929871 + 1 + <_> + + + + <_>12 11 6 8 -1. + <_>15 11 3 4 2. + <_>12 15 3 4 2. + 0 + -0.0523816794157028 + 0.7110040187835693 + 0.5060154795646668 + <_> + + <_> + + + + <_>8 7 2 4 -1. + <_>9 7 1 4 2. + 0 + -0.0112421102821827 + 0.8769189119338989 + 1 + <_> + + + + <_>6 11 3 1 -1. + <_>7 11 1 1 3. + 0 + -3.6728400737047195e-003 + 0.6519191861152649 + 0.4546068906784058 + <_> + + <_> + + + + <_>12 3 2 14 -1. + <_>12 3 1 14 2. + 0 + 3.5082760732620955e-003 + 0.5329865813255310 + 1 + <_> + + + + <_>12 11 6 2 -1. + <_>15 11 3 1 2. + <_>12 12 3 1 2. + 0 + 6.1679710634052753e-003 + 0.5220459103584290 + 0.2953518927097321 + <_> + + <_> + + + + <_>0 2 5 2 -1. + <_>0 3 5 1 2. + 0 + -9.7009900491684675e-004 + 1 + 0.5048633217811585 + <_> + + + + <_>0 0 15 1 -1. + <_>5 0 5 1 3. + 0 + -0.0109570100903511 + 0.5837358236312866 + 0.3020085990428925 + <_> + + <_> + + + + <_>12 11 6 2 -1. + <_>15 11 3 1 2. + <_>12 12 3 1 2. + 0 + -8.3272513002157211e-003 + 0.3158063888549805 + 1 + <_> + + + + <_>10 5 2 2 -1. + <_>10 5 1 2 2. + 0 + 2.9798380637657829e-005 + 0.4386389851570129 + 0.5443211197853088 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>10 7 1 2 2. + 0 + 2.8244039276614785e-004 + 1 + 0.5625395774841309 + <_> + + + + <_>9 0 2 10 -1. + <_>9 0 1 5 2. + <_>10 5 1 5 2. + 0 + -8.1364117795601487e-004 + 0.5281198024749756 + 0.3401407897472382 + <_> + + <_> + + + + <_>18 14 2 2 -1. + <_>18 15 2 1 2. + 0 + 1.8008040497079492e-003 + 1 + 0.3471659123897553 + <_> + + + + <_>13 11 4 9 -1. + <_>13 14 4 3 3. + 0 + -6.9944779388606548e-003 + 0.4481697082519531 + 0.5385770201683044 + <_> + + <_> + + + + <_>8 13 2 2 -1. + <_>8 13 1 1 2. + <_>9 14 1 1 2. + 0 + 4.5625398342963308e-005 + 0.4492512941360474 + 1 + <_> + + + + <_>7 8 4 3 -1. + <_>7 9 4 1 3. + 0 + -7.3189922841265798e-004 + 0.4167312085628510 + 0.6021102070808411 + <_> + + <_> + + + + <_>8 9 4 2 -1. + <_>8 10 4 1 2. + 0 + -2.9980219551362097e-004 + 0.4148428142070770 + 1 + <_> + + + + <_>13 12 4 2 -1. + <_>13 13 4 1 2. + 0 + -2.9060940505587496e-005 + 0.5592089891433716 + 0.4073210954666138 + <_> + + <_> + + + + <_>6 14 2 2 -1. + <_>6 14 1 1 2. + <_>7 15 1 1 2. + 0 + -5.9742690064013004e-004 + 0.6088914275169373 + 1 + <_> + + + + <_>0 14 2 2 -1. + <_>0 15 2 1 2. + 0 + 1.4831830048933625e-004 + 0.5298305153846741 + 0.3761950135231018 + <_> + + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + -2.9441029764711857e-003 + 1 + 0.4716084897518158 + <_> + + + + <_>7 9 10 6 -1. + <_>7 11 10 2 3. + 0 + 0.1374121010303497 + 0.5101336836814880 + 0.0467468015849590 + <_> + + <_> + + + + <_>2 9 12 4 -1. + <_>6 9 4 4 3. + 0 + -0.0884141772985458 + 0.1181868985295296 + 1 + <_> + + + + <_>7 9 6 11 -1. + <_>10 9 3 11 2. + 0 + 0.0706102773547173 + 0.5119063258171082 + 0.7778441905975342 + <_> + + <_> + + + + <_>9 7 2 3 -1. + <_>9 8 2 1 3. + 0 + -7.7188978902995586e-003 + 0.1874134987592697 + 1 + <_> + + + + <_>9 14 4 3 -1. + <_>9 15 4 1 3. + 0 + 0.0151153998449445 + 0.4980027973651886 + 0.7005817890167236 + <_> + + <_> + + + + <_>2 3 3 17 -1. + <_>3 3 1 17 3. + 0 + 1.0671879863366485e-003 + 0.4482238888740540 + 1 + <_> + + + + <_>0 11 6 3 -1. + <_>0 12 6 1 3. + 0 + 7.0487911580130458e-004 + 0.6265752911567688 + 0.4402655065059662 + 47.7634506225585940 + 16 + -1 + <_> + + + <_> + + <_> + + + + <_>4 3 11 9 -1. + <_>4 6 11 3 3. + 0 + -0.0986907333135605 + 1 + 0.3999474942684174 + <_> + + + + <_>0 2 6 11 -1. + <_>3 2 3 11 2. + 0 + 0.0623734183609486 + 0.5247784852981567 + 0.8193575739860535 + <_> + + <_> + + + + <_>13 0 4 5 -1. + <_>13 0 2 5 2. + 0 + 1.9496519817039371e-003 + 0.3529816865921021 + 1 + <_> + + + + <_>9 7 6 4 -1. + <_>12 7 3 2 2. + <_>9 9 3 2 2. + 0 + -8.9139147894456983e-004 + 0.5852727890014648 + 0.3245978057384491 + <_> + + <_> + + + + <_>5 7 8 2 -1. + <_>9 7 4 2 2. + 0 + -5.5150408297777176e-004 + 0.3892816901206970 + 1 + <_> + + + + <_>1 8 15 1 -1. + <_>6 8 5 1 3. + 0 + -1.1721949558705091e-003 + 0.4335052073001862 + 0.6520624160766602 + <_> + + <_> + + + + <_>4 12 12 2 -1. + <_>8 12 4 2 3. + 0 + -7.4480642797425389e-004 + 1 + 0.4041135013103485 + <_> + + + + <_>13 0 4 10 -1. + <_>15 0 2 5 2. + <_>13 5 2 5 2. + 0 + -2.6264840271323919e-003 + 0.5624982118606567 + 0.3967525064945221 + <_> + + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + -3.9712688885629177e-004 + 0.3856112062931061 + 1 + <_> + + + + <_>3 9 6 2 -1. + <_>6 9 3 2 2. + 0 + 3.5984949208796024e-003 + 0.5997889041900635 + 0.4241614043712616 + <_> + + <_> + + + + <_>8 17 4 3 -1. + <_>8 18 4 1 3. + 0 + 5.3080618381500244e-003 + 1 + 0.6660168766975403 + <_> + + + + <_>8 3 9 2 -1. + <_>11 3 3 2 3. + 0 + 9.6319877775385976e-004 + 0.4481379091739655 + 0.5583487749099731 + <_> + + <_> + + + + <_>3 3 9 2 -1. + <_>6 3 3 2 3. + 0 + 5.0776469288393855e-004 + 0.3535459041595459 + 1 + <_> + + + + <_>5 0 9 14 -1. + <_>8 0 3 14 3. + 0 + 3.6223160568624735e-003 + 0.3409807085990906 + 0.5420687794685364 + <_> + + <_> + + + + <_>7 3 7 10 -1. + <_>7 8 7 5 2. + 0 + -0.0620614103972912 + 0.1934083998203278 + 1 + <_> + + + + <_>4 8 13 3 -1. + <_>4 9 13 1 3. + 0 + 6.4387189922854304e-004 + 0.4083626866340637 + 0.5490221977233887 + <_> + + <_> + + + + <_>3 12 14 4 -1. + <_>3 12 7 2 2. + <_>10 14 7 2 2. + 0 + 0.0262399092316628 + 1 + 0.2285708039999008 + <_> + + + + <_>8 12 4 2 -1. + <_>8 13 4 1 2. + 0 + 8.1940297968685627e-004 + 0.4648667871952057 + 0.6017355918884277 + <_> + + <_> + + + + <_>6 10 9 8 -1. + <_>6 14 9 4 2. + 0 + 2.3833119485061616e-004 + 1 + 0.3598038852214813 + <_> + + + + <_>9 12 2 8 -1. + <_>9 16 2 4 2. + 0 + -1.5869759954512119e-003 + 0.4259651005268097 + 0.5476434826850891 + <_> + + <_> + + + + <_>8 12 3 3 -1. + <_>8 13 3 1 3. + 0 + -6.7263417877256870e-003 + 0.6507238149642944 + 1 + <_> + + + + <_>5 5 4 10 -1. + <_>7 5 2 10 2. + 0 + 0.0110061103478074 + 0.5149409770965576 + 0.3362984955310822 + <_> + + <_> + + + + <_>14 15 3 3 -1. + <_>14 16 3 1 3. + 0 + 7.1445819921791553e-003 + 1 + 0.2672930061817169 + <_> + + + + <_>4 6 13 3 -1. + <_>4 7 13 1 3. + 0 + -4.7233798541128635e-003 + 0.5652182102203369 + 0.4298144876956940 + <_> + + <_> + + + + <_>3 15 3 3 -1. + <_>3 16 3 1 3. + 0 + 9.8437406122684479e-003 + 1 + 0.1151885986328125 + <_> + + + + <_>3 9 4 2 -1. + <_>3 9 2 1 2. + <_>5 10 2 1 2. + 0 + 1.5124640412977897e-005 + 0.4373598098754883 + 0.5612128973007202 + <_> + + <_> + + + + <_>0 11 20 4 -1. + <_>10 11 10 2 2. + <_>0 13 10 2 2. + 0 + 0.0399088710546494 + 0.5204648971557617 + 1 + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + 5.3903679363429546e-003 + 0.4813467860221863 + 0.6361209154129028 + <_> + + <_> + + + + <_>0 11 20 4 -1. + <_>0 11 10 2 2. + <_>10 13 10 2 2. + 0 + -0.0399088710546494 + 0.1506870985031128 + 1 + <_> + + + + <_>8 15 4 3 -1. + <_>8 16 4 1 3. + 0 + 5.3903679363429546e-003 + 0.4581694900989533 + 0.6200240850448608 + <_> + + <_> + + + + <_>10 13 1 6 -1. + <_>10 16 1 3 2. + 0 + 6.7005190066993237e-003 + 1 + 0.3432235121726990 + <_> + + + + <_>2 1 18 2 -1. + <_>11 1 9 1 2. + <_>2 2 9 1 2. + 0 + -0.0126237897202373 + 0.3088226914405823 + 0.5226737856864929 + <_> + + <_> + + + + <_>8 14 3 3 -1. + <_>8 15 3 1 3. + 0 + 0.0118066100403667 + 1 + 0.7187939286231995 + <_> + + + + <_>4 1 6 1 -1. + <_>6 1 2 1 3. + 0 + -3.4257229417562485e-003 + 0.3120814859867096 + 0.5065844058990479 + <_> + + <_> + + + + <_>11 13 1 3 -1. + <_>11 14 1 1 3. + 0 + 3.9385299896821380e-004 + 0.4754584133625031 + 1 + <_> + + + + <_>13 5 2 12 -1. + <_>13 11 2 6 2. + 0 + 0.0343881882727146 + 0.5261657834053040 + 0.3350174129009247 + <_> + + <_> + + + + <_>1 14 18 6 -1. + <_>1 16 18 2 3. + 0 + -0.0750099867582321 + 0.1713480949401856 + 1 + <_> + + + + <_>8 13 1 3 -1. + <_>8 14 1 1 3. + 0 + 4.9022492021322250e-004 + 0.4725801944732666 + 0.5956469178199768 + <_> + + <_> + + + + <_>7 13 6 3 -1. + <_>7 14 6 1 3. + 0 + -8.5525289177894592e-003 + 0.6558222770690918 + 1 + <_> + + + + <_>9 10 3 2 -1. + <_>9 11 3 1 2. + 0 + 1.3135520566720515e-004 + 0.4835400879383087 + 0.5586913824081421 + <_> + + <_> + + + + <_>5 1 3 3 -1. + <_>6 1 1 3 3. + 0 + 4.7948658466339111e-003 + 1 + 0.2645705938339233 + <_> + + + + <_>5 5 6 5 -1. + <_>8 5 3 5 2. + 0 + 2.0124691072851419e-003 + 0.3657945096492767 + 0.5124772191047669 + <_> + + <_> + + + + <_>7 5 6 14 -1. + <_>7 12 6 7 2. + 0 + -0.1178547963500023 + 0.2385654002428055 + 1 + <_> + + + + <_>7 16 6 2 -1. + <_>9 16 2 2 3. + 0 + 1.5575019642710686e-003 + 0.5490474104881287 + 0.4274747967720032 + <_> + + <_> + + + + <_>0 2 2 12 -1. + <_>1 2 1 12 2. + 0 + -0.0155737595632672 + 0.6938900947570801 + 1 + <_> + + + + <_>1 0 5 3 -1. + <_>1 1 5 1 3. + 0 + -2.1854790393263102e-003 + 0.3645988106727600 + 0.5092526078224182 + <_> + + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + 2.9272339306771755e-003 + 0.4685808122158051 + 1 + <_> + + + + <_>12 6 3 3 -1. + <_>12 7 3 1 3. + 0 + 6.4663668163120747e-003 + 0.4973410069942474 + 0.7726097106933594 + <_> + + <_> + + + + <_>5 4 3 3 -1. + <_>5 5 3 1 3. + 0 + -7.6140360906720161e-003 + 0.6877465844154358 + 1 + <_> + + + + <_>5 6 3 3 -1. + <_>5 7 3 1 3. + 0 + 4.1512572206556797e-003 + 0.4788525104522705 + 0.6921657919883728 + <_> + + <_> + + + + <_>8 12 4 8 -1. + <_>10 12 2 4 2. + <_>8 16 2 4 2. + 0 + 2.7711640577763319e-003 + 0.5481839776039124 + 1 + <_> + + + + <_>2 17 18 2 -1. + <_>11 17 9 1 2. + <_>2 18 9 1 2. + 0 + -0.0128361098468304 + 0.3800162971019745 + 0.5204492807388306 + <_> + + <_> + + + + <_>9 3 2 2 -1. + <_>9 4 2 1 2. + 0 + -2.4380050599575043e-003 + 0.2582435011863709 + 1 + <_> + + + + <_>8 5 4 6 -1. + <_>8 7 4 2 3. + 0 + 2.1713329479098320e-003 + 0.4961163103580475 + 0.3215202987194061 + <_> + + <_> + + + + <_>9 0 8 6 -1. + <_>9 2 8 2 3. + 0 + 6.2800728483125567e-004 + 1 + 0.5460423827171326 + <_> + + + + <_>1 0 18 4 -1. + <_>7 0 6 4 3. + 0 + -9.7982389852404594e-003 + 0.6046543717384338 + 0.4939922094345093 + <_> + + <_> + + + + <_>0 0 4 8 -1. + <_>2 0 2 8 2. + 0 + 7.3543828912079334e-003 + 1 + 0.5291094183921814 + <_> + + + + <_>0 4 6 9 -1. + <_>2 4 2 9 3. + 0 + -0.0146650401875377 + 0.5446122884750366 + 0.3567362129688263 + <_> + + <_> + + + + <_>1 4 18 2 -1. + <_>7 4 6 2 3. + 0 + 0.0302445106208324 + 0.5518329143524170 + 1 + <_> + + + + <_>8 16 12 4 -1. + <_>14 16 6 2 2. + <_>8 18 6 2 2. + 0 + -0.0566602088510990 + 0.6930978894233704 + 0.5093387961387634 + <_> + + <_> + + + + <_>0 0 18 2 -1. + <_>0 0 9 1 2. + <_>9 1 9 1 2. + 0 + -5.6967479176819324e-003 + 0.3201526105403900 + 1 + <_> + + + + <_>3 0 3 18 -1. + <_>4 0 1 18 3. + 0 + 0.0308067705482244 + 0.4989246129989624 + 0.2277054041624069 + <_> + + <_> + + + + <_>14 9 4 7 -1. + <_>14 9 2 7 2. + 0 + 2.2748769260942936e-003 + 0.4810931086540222 + 1 + <_> + + + + <_>15 14 2 2 -1. + <_>15 15 2 1 2. + 0 + 2.0436900667846203e-003 + 0.5283867120742798 + 0.3255924880504608 + <_> + + <_> + + + + <_>2 9 4 7 -1. + <_>4 9 2 7 2. + 0 + -8.6277956143021584e-003 + 0.6266536116600037 + 1 + <_> + + + + <_>3 14 2 2 -1. + <_>3 15 2 1 2. + 0 + 6.5113382879644632e-004 + 0.5097137093544006 + 0.3191910088062286 + <_> + + <_> + + + + <_>11 0 6 6 -1. + <_>11 2 6 2 3. + 0 + 8.8188261725008488e-004 + 0.4549585878849030 + 1 + <_> + + + + <_>14 0 2 6 -1. + <_>15 0 1 3 2. + <_>14 3 1 3 2. + 0 + -0.0145949097350240 + 0.2645038962364197 + 0.5153868198394775 + <_> + + <_> + + + + <_>7 11 2 2 -1. + <_>7 11 1 1 2. + <_>8 12 1 1 2. + 0 + -1.2304580304771662e-003 + 0.6197584867477417 + 1 + <_> + + + + <_>7 10 2 2 -1. + <_>8 10 1 2 2. + 0 + -2.1867299801670015e-004 + 0.5469198822975159 + 0.4206855893135071 + <_> + + <_> + + + + <_>9 14 2 6 -1. + <_>9 17 2 3 2. + 0 + -1.0909959673881531e-003 + 0.4140760004520416 + 1 + <_> + + + + <_>12 18 4 2 -1. + <_>12 19 4 1 2. + 0 + 3.5210378700867295e-004 + 0.5476608872413635 + 0.4155021011829376 + <_> + + <_> + + + + <_>8 17 4 3 -1. + <_>8 18 4 1 3. + 0 + -7.2563779540359974e-003 + 0.7160469293594360 + 1 + <_> + + + + <_>2 18 8 2 -1. + <_>2 19 8 1 2. + 0 + 1.4701850013807416e-003 + 0.5240808129310608 + 0.3729662895202637 + <_> + + <_> + + + + <_>2 9 16 3 -1. + <_>2 10 16 1 3. + 0 + 1.1472719779703766e-004 + 0.4033798873424530 + 1 + <_> + + + + <_>9 9 2 2 -1. + <_>9 10 2 1 2. + 0 + 3.0506469774991274e-003 + 0.5263985991477966 + 0.3560093045234680 + <_> + + <_> + + + + <_>5 14 2 4 -1. + <_>5 14 1 2 2. + <_>6 16 1 2 2. + 0 + 2.6269949739798903e-004 + 0.4569799900054932 + 1 + <_> + + + + <_>8 9 4 2 -1. + <_>8 9 2 1 2. + <_>10 10 2 1 2. + 0 + -3.6365550477057695e-003 + 0.3042570948600769 + 0.5868253707885742 + <_> + + <_> + + + + <_>9 5 2 5 -1. + <_>9 5 1 5 2. + 0 + -8.4893293678760529e-003 + 1 + 0.4914157092571259 + <_> + + + + <_>9 9 3 2 -1. + <_>10 9 1 2 3. + 0 + 5.8107408694922924e-003 + 0.4918529987335205 + 0.6266962885856628 + <_> + + <_> + + + + <_>8 9 3 2 -1. + <_>9 9 1 2 3. + 0 + 7.5583951547741890e-004 + 1 + 0.5633236169815064 + <_> + + + + <_>8 8 3 6 -1. + <_>9 8 1 6 3. + 0 + -2.2017690353095531e-003 + 0.5553916096687317 + 0.3827646076679230 + <_> + + <_> + + + + <_>8 12 4 8 -1. + <_>10 12 2 4 2. + <_>8 16 2 4 2. + 0 + 2.7908938936889172e-003 + 0.5498697757720947 + 1 + <_> + + + + <_>2 17 16 2 -1. + <_>10 17 8 1 2. + <_>2 18 8 1 2. + 0 + -1.8228569533675909e-003 + 0.4382283091545105 + 0.5424032807350159 + <_> + + <_> + + + + <_>8 12 3 8 -1. + <_>9 12 1 8 3. + 0 + -7.2495508939027786e-003 + 0.2888121902942658 + 1 + <_> + + + + <_>3 10 1 3 -1. + <_>3 11 1 1 3. + 0 + -6.8744522286579013e-004 + 0.3472655117511749 + 0.5076370835304260 + <_> + + <_> + + + + <_>9 14 10 6 -1. + <_>14 14 5 3 2. + <_>9 17 5 3 2. + 0 + 2.5174440816044807e-003 + 0.4661205112934113 + 1 + <_> + + + + <_>14 13 3 6 -1. + <_>14 15 3 2 3. + 0 + -0.0101513797417283 + 0.3744775056838989 + 0.5294001102447510 + <_> + + <_> + + + + <_>1 19 18 1 -1. + <_>7 19 6 1 3. + 0 + -4.1399952024221420e-003 + 1 + 0.4660485088825226 + <_> + + + + <_>2 10 15 2 -1. + <_>7 10 5 2 3. + 0 + -4.7078551724553108e-003 + 0.4175061881542206 + 0.6916306018829346 + <_> + + <_> + + + + <_>4 17 16 3 -1. + <_>4 18 16 1 3. + 0 + 0.0419810414314270 + 1 + 0.2018215060234070 + <_> + + + + <_>8 6 4 9 -1. + <_>8 9 4 3 3. + 0 + -0.0142729999497533 + 0.7511197924613953 + 0.5032083988189697 + <_> + + <_> + + + + <_>9 16 2 4 -1. + <_>9 16 1 2 2. + <_>10 18 1 2 2. + 0 + 4.0869521908462048e-003 + 1 + 0.2504513859748840 + <_> + + + + <_>5 5 10 8 -1. + <_>5 9 10 4 2. + 0 + 1.7606799956411123e-003 + 0.3301401138305664 + 0.5218337178230286 + <_> + + <_> + + + + <_>13 1 4 2 -1. + <_>13 1 2 2 2. + 0 + 1.2550549581646919e-004 + 0.4614442884922028 + 1 + <_> + + + + <_>14 0 3 6 -1. + <_>14 2 3 2 3. + 0 + -2.9503209516406059e-003 + 0.4619950056076050 + 0.5247030258178711 + <_> + + <_> + + + + <_>6 7 2 2 -1. + <_>6 7 1 1 2. + <_>7 8 1 1 2. + 0 + -1.1312420247122645e-003 + 0.6314368247985840 + 1 + <_> + + + + <_>7 1 6 1 -1. + <_>9 1 2 1 3. + 0 + -1.6983180539682508e-003 + 0.3401306867599487 + 0.5055527091026306 + <_> + + <_> + + + + <_>9 11 3 3 -1. + <_>9 12 3 1 3. + 0 + -0.0114578204229474 + 1 + 0.4939996004104614 + <_> + + + + <_>12 9 3 3 -1. + <_>13 9 1 3 3. + 0 + -8.4962565451860428e-003 + 0.2965450882911682 + 0.5194367766380310 + <_> + + <_> + + + + <_>8 11 3 3 -1. + <_>8 12 3 1 3. + 0 + 0.0119190895929933 + 1 + 0.7886998057365418 + <_> + + + + <_>5 9 3 3 -1. + <_>6 9 1 3 3. + 0 + 6.4416420646011829e-003 + 0.5106986761093140 + 0.2967146039009094 + <_> + + <_> + + + + <_>10 11 1 3 -1. + <_>10 12 1 1 3. + 0 + -8.7857811013236642e-004 + 0.5714371204376221 + 1 + <_> + + + + <_>7 9 6 4 -1. + <_>10 9 3 2 2. + <_>7 11 3 2 2. + 0 + -2.0312711130827665e-003 + 0.4481200873851776 + 0.5384911894798279 + <_> + + <_> + + + + <_>4 7 2 2 -1. + <_>4 7 1 1 2. + <_>5 8 1 1 2. + 0 + -1.5262430533766747e-003 + 0.6193568706512451 + 1 + <_> + + + + <_>5 7 3 1 -1. + <_>6 7 1 1 3. + 0 + 4.2860880494117737e-003 + 0.4339885115623474 + 0.7697299122810364 + <_> + + <_> + + + + <_>18 3 2 3 -1. + <_>18 4 2 1 3. + 0 + 3.5010920837521553e-003 + 1 + 0.3171389102935791 + <_> + + + + <_>13 1 4 2 -1. + <_>13 1 2 2 2. + 0 + 0.0125876702368259 + 0.5246698856353760 + 0.4241208136081696 + <_> + + <_> + + + + <_>3 1 4 2 -1. + <_>5 1 2 2 2. + 0 + 2.6207490009255707e-004 + 0.4231899976730347 + 1 + <_> + + + + <_>3 0 5 2 -1. + <_>3 1 5 1 2. + 0 + 4.4701730075757951e-005 + 0.4174138903617859 + 0.5919603705406189 + <_> + + <_> + + + + <_>14 7 6 4 -1. + <_>17 7 3 2 2. + <_>14 9 3 2 2. + 0 + 7.8084698179736733e-004 + 0.4277389049530029 + 1 + <_> + + + + <_>4 8 16 2 -1. + <_>4 9 16 1 2. + 0 + 8.8851212058216333e-004 + 0.3720161020755768 + 0.5226818919181824 + <_> + + <_> + + + + <_>2 11 5 6 -1. + <_>2 13 5 2 3. + 0 + 2.3369069676846266e-003 + 0.5478066802024841 + 1 + <_> + + + + <_>5 16 2 4 -1. + <_>5 16 1 2 2. + <_>6 18 1 2 2. + 0 + 1.6688359901309013e-003 + 0.3628678917884827 + 0.6150004863739014 + <_> + + <_> + + + + <_>15 6 2 12 -1. + <_>16 6 1 6 2. + <_>15 12 1 6 2. + 0 + 3.0844469438306987e-004 + 0.4747075140476227 + 1 + <_> + + + + <_>13 3 6 16 -1. + <_>15 3 2 16 3. + 0 + 3.4617560449987650e-003 + 0.4580138027667999 + 0.5585681796073914 + <_> + + <_> + + + + <_>4 5 12 12 -1. + <_>4 5 6 6 2. + <_>10 11 6 6 2. + 0 + 0.0189613103866577 + 0.5298801064491272 + 1 + <_> + + + + <_>5 1 10 13 -1. + <_>10 1 5 13 2. + 0 + 0.1734731048345566 + 0.3698385059833527 + 0.8498619794845581 + <_> + + <_> + + + + <_>11 5 2 2 -1. + <_>12 5 1 1 2. + <_>11 6 1 1 2. + 0 + 2.0020549709443003e-004 + 1 + 0.5565661787986755 + <_> + + + + <_>13 5 1 3 -1. + <_>13 6 1 1 3. + 0 + 1.0967060225084424e-003 + 0.4795713126659393 + 0.6286259889602661 + <_> + + <_> + + + + <_>7 4 2 4 -1. + <_>7 4 1 2 2. + <_>8 6 1 2 2. + 0 + 1.5107099898159504e-004 + 0.4052405953407288 + 1 + <_> + + + + <_>7 5 6 4 -1. + <_>10 5 3 4 2. + 0 + -3.4463501069694757e-003 + 0.6173015236854553 + 0.4414263963699341 + <_> + + <_> + + + + <_>12 4 4 6 -1. + <_>14 4 2 3 2. + <_>12 7 2 3 2. + 0 + 8.5176620632410049e-003 + 1 + 0.3570570945739746 + <_> + + + + <_>12 11 7 6 -1. + <_>12 13 7 2 3. + 0 + -0.0358121097087860 + 0.3151328861713409 + 0.5252702832221985 + <_> + + <_> + + + + <_>5 6 6 6 -1. + <_>7 6 2 6 3. + 0 + -0.0211554002016783 + 0.6124721169471741 + 1 + <_> + + + + <_>9 8 2 2 -1. + <_>9 9 2 1 2. + 0 + 8.9890940580517054e-004 + 0.5169975757598877 + 0.3596271872520447 + <_> + + <_> + + + + <_>15 6 2 2 -1. + <_>16 6 1 1 2. + <_>15 7 1 1 2. + 0 + -1.5613760333508253e-003 + 1 + 0.4914987981319428 + <_> + + + + <_>14 7 4 4 -1. + <_>16 7 2 2 2. + <_>14 9 2 2 2. + 0 + 6.7120860330760479e-004 + 0.4546211063861847 + 0.5395811796188355 + <_> + + <_> + + + + <_>5 5 6 2 -1. + <_>7 5 2 2 3. + 0 + -0.0215970296412706 + 0.1903133988380432 + 1 + <_> + + + + <_>1 19 18 1 -1. + <_>7 19 6 1 3. + 0 + -0.0249472297728062 + 0.6974077224731445 + 0.4967716038227081 + <_> + + <_> + + + + <_>12 3 3 3 -1. + <_>12 4 3 1 3. + 0 + 1.8725979607552290e-003 + 0.4748947918415070 + 1 + <_> + + + + <_>16 0 2 3 -1. + <_>16 1 2 1 3. + 0 + 6.3912719488143921e-003 + 0.5180178284645081 + 0.2924321889877319 + <_> + + <_> + + + + <_>5 3 3 3 -1. + <_>5 4 3 1 3. + 0 + -9.1552399098873138e-003 + 0.7665870189666748 + 1 + <_> + + + + <_>2 0 2 3 -1. + <_>2 1 2 1 3. + 0 + 2.1715660113841295e-003 + 0.5215551257133484 + 0.3365719020366669 + <_> + + <_> + + + + <_>15 6 2 2 -1. + <_>16 6 1 1 2. + <_>15 7 1 1 2. + 0 + 1.2330369791015983e-003 + 1 + 0.6260957717895508 + <_> + + + + <_>10 13 1 6 -1. + <_>10 16 1 3 2. + 0 + -4.0785901364870369e-004 + 0.4533509910106659 + 0.5386489033699036 + <_> + + <_> + + + + <_>0 7 10 2 -1. + <_>0 7 5 1 2. + <_>5 8 5 1 2. + 0 + 4.6437609125860035e-004 + 0.4103496074676514 + 1 + <_> + + + + <_>3 10 6 2 -1. + <_>3 11 6 1 2. + 0 + -1.1600199650274590e-004 + 0.5830391049385071 + 0.4304105937480927 + <_> + + <_> + + + + <_>12 18 4 2 -1. + <_>12 19 4 1 2. + 0 + -0.0127187203615904 + 0.2132582962512970 + 1 + <_> + + + + <_>12 18 2 2 -1. + <_>13 18 1 1 2. + <_>12 19 1 1 2. + 0 + 8.9431880041956902e-005 + 0.4872891008853912 + 0.5458915233612061 + <_> + + <_> + + + + <_>6 19 2 1 -1. + <_>7 19 1 1 2. + 0 + -3.3913689549081028e-004 + 0.3974364995956421 + 1 + <_> + + + + <_>0 4 2 16 -1. + <_>0 4 1 8 2. + <_>1 12 1 8 2. + 0 + -0.0180263407528400 + 0.7568550705909729 + 0.5045611858367920 + <_> + + <_> + + + + <_>16 1 4 9 -1. + <_>16 4 4 3 3. + 0 + 6.9179181009531021e-003 + 1 + 0.3966299891471863 + <_> + + + + <_>10 2 1 2 -1. + <_>10 3 1 1 2. + 0 + -1.1839679791592062e-004 + 0.4198082983493805 + 0.5435804128646851 + <_> + + <_> + + + + <_>4 14 4 6 -1. + <_>4 14 2 3 2. + <_>6 17 2 3 2. + 0 + -3.9474181830883026e-003 + 0.6369457840919495 + 1 + <_> + + + + <_>4 15 1 4 -1. + <_>4 17 1 2 2. + 0 + 6.0050919273635373e-005 + 0.5269566774368286 + 0.3812243044376373 + <_> + + <_> + + + + <_>0 2 20 4 -1. + <_>10 2 10 2 2. + <_>0 4 10 2 2. + 0 + 9.1423643752932549e-003 + 1 + 0.4156762957572937 + <_> + + + + <_>14 5 2 8 -1. + <_>14 9 2 4 2. + 0 + 2.1305440168362111e-004 + 0.3523533046245575 + 0.5349454283714294 + <_> + + <_> + + + + <_>5 12 4 5 -1. + <_>7 12 2 5 2. + 0 + -2.0855850016232580e-004 + 1 + 0.4403322041034699 + <_> + + + + <_>0 13 9 6 -1. + <_>0 15 9 2 3. + 0 + 1.3130389852449298e-003 + 0.6058161258697510 + 0.4468218982219696 + <_> + + <_> + + + + <_>9 14 11 3 -1. + <_>9 15 11 1 3. + 0 + -2.9134768992662430e-003 + 1 + 0.4825705885887146 + <_> + + + + <_>7 14 7 3 -1. + <_>7 15 7 1 3. + 0 + 2.9645769391208887e-003 + 0.4835998117923737 + 0.6039277911186218 + <_> + + <_> + + + + <_>3 6 2 2 -1. + <_>3 6 1 1 2. + <_>4 7 1 1 2. + 0 + 1.7772549763321877e-003 + 1 + 0.6871827244758606 + <_> + + + + <_>6 7 2 7 -1. + <_>7 7 1 7 2. + 0 + -7.7136349864304066e-003 + 0.2842220962047577 + 0.5145428180694580 + <_> + + <_> + + + + <_>14 5 1 3 -1. + <_>14 6 1 1 3. + 0 + 5.1027478184551001e-004 + 1 + 0.6024426221847534 + <_> + + + + <_>13 4 4 3 -1. + <_>13 5 4 1 3. + 0 + 1.7460630042478442e-003 + 0.4756610095500946 + 0.5721154212951660 + <_> + + <_> + + + + <_>2 7 4 4 -1. + <_>2 7 2 2 2. + <_>4 9 2 2 2. + 0 + 3.8068278809078038e-004 + 1 + 0.4931069016456604 + <_> + + + + <_>2 9 13 6 -1. + <_>2 12 13 3 2. + 0 + 2.8228890150785446e-003 + 0.3311698138713837 + 0.6227598190307617 + <_> + + <_> + + + + <_>10 1 3 4 -1. + <_>11 1 1 4 3. + 0 + -5.3000478073954582e-003 + 1 + 0.5232092738151550 + <_> + + + + <_>9 8 5 2 -1. + <_>9 9 5 1 2. + 0 + 4.4951299059903249e-005 + 0.3995231986045837 + 0.5314797759056091 + <_> + + <_> + + + + <_>0 14 11 3 -1. + <_>0 15 11 1 3. + 0 + 3.2752458937466145e-003 + 0.4481619894504547 + 1 + <_> + + + + <_>8 11 2 8 -1. + <_>8 15 2 4 2. + 0 + -2.8162579983472824e-003 + 0.3907971978187561 + 0.6671640872955322 + <_> + + <_> + + + + <_>5 11 10 6 -1. + <_>5 14 10 3 2. + 0 + 1.4112279750406742e-003 + 0.5357010960578919 + 1 + <_> + + + + <_>5 13 15 5 -1. + <_>10 13 5 5 3. + 0 + 8.3062034100294113e-003 + 0.4770965874195099 + 0.5570099949836731 + <_> + + <_> + + + + <_>8 10 1 10 -1. + <_>8 15 1 5 2. + 0 + 2.2164839319884777e-003 + 0.4947124123573303 + 1 + <_> + + + + <_>4 14 6 2 -1. + <_>6 14 2 2 3. + 0 + -4.9868631176650524e-003 + 0.5241307020187378 + 0.2512654960155487 + <_> + + <_> + + + + <_>7 14 7 3 -1. + <_>7 15 7 1 3. + 0 + -3.6664260551333427e-003 + 1 + 0.4619553983211517 + <_> + + + + <_>7 16 9 3 -1. + <_>7 17 9 1 3. + 0 + -0.0105812298133969 + 0.6301718950271606 + 0.4973031878471375 + <_> + + <_> + + + + <_>8 7 3 3 -1. + <_>8 8 3 1 3. + 0 + 7.3366491124033928e-003 + 1 + 0.2870970070362091 + <_> + + + + <_>3 5 1 6 -1. + <_>3 8 1 3 2. + 0 + -3.9318940252996981e-004 + 0.4252805113792419 + 0.5579246878623962 + <_> + + <_> + + + + <_>6 5 11 2 -1. + <_>6 6 11 1 2. + 0 + -8.1375334411859512e-003 + 0.5747315883636475 + 1 + <_> + + + + <_>9 0 3 2 -1. + <_>10 0 1 2 3. + 0 + 2.4809150490909815e-003 + 0.5203374028205872 + 0.3903566896915436 + <_> + + <_> + + + + <_>5 5 1 3 -1. + <_>5 6 1 1 3. + 0 + 8.8749779388308525e-004 + 1 + 0.5534321069717407 + <_> + + + + <_>8 7 3 2 -1. + <_>9 7 1 2 3. + 0 + -4.2194919660687447e-004 + 0.5338044166564941 + 0.3925840854644775 + <_> + + <_> + + + + <_>5 2 10 6 -1. + <_>10 2 5 3 2. + <_>5 5 5 3 2. + 0 + -7.9790111631155014e-003 + 0.4144316017627716 + 1 + <_> + + + + <_>8 4 6 4 -1. + <_>8 4 3 4 2. + 0 + 1.1439629597589374e-003 + 0.4701372981071472 + 0.5281736254692078 + <_> + + <_> + + + + <_>8 16 3 4 -1. + <_>9 16 1 4 3. + 0 + 7.5542130507528782e-003 + 1 + 0.2527256011962891 + <_> + + + + <_>9 13 2 6 -1. + <_>9 13 1 3 2. + <_>10 16 1 3 2. + 0 + 1.0288399644196033e-003 + 0.5605146288871765 + 0.4297856092453003 + <_> + + <_> + + + + <_>9 8 3 1 -1. + <_>10 8 1 1 3. + 0 + -1.7234670231118798e-003 + 1 + 0.4839682877063751 + <_> + + + + <_>2 5 18 15 -1. + <_>2 10 18 5 3. + 0 + 0.5758669972419739 + 0.5110502839088440 + 0.0804893299937248 + 44.2512817382812500 + 17 + -1 + <_> + + + <_> + + <_> + + + + <_>1 3 6 2 -1. + <_>4 3 3 2 2. + 0 + 6.6640521399676800e-003 + 0.3828920125961304 + 1 + <_> + + + + <_>7 6 6 2 -1. + <_>9 6 2 2 3. + 0 + 8.9905522763729095e-003 + 0.4858429133892059 + 0.7354959249496460 + <_> + + <_> + + + + <_>8 17 4 3 -1. + <_>8 18 4 1 3. + 0 + 5.7154200039803982e-003 + 1 + 0.6723223924636841 + <_> + + + + <_>10 13 2 3 -1. + <_>10 14 2 1 3. + 0 + 1.1257929727435112e-003 + 0.4429577887058258 + 0.6070777773857117 + <_> + + <_> + + + + <_>0 10 20 4 -1. + <_>0 12 20 2 2. + 0 + -9.1789010912179947e-004 + 1 + 0.3076345026493073 + <_> + + + + <_>5 7 6 4 -1. + <_>5 7 3 2 2. + <_>8 9 3 2 2. + 0 + -1.0492859873920679e-003 + 0.5593643784523010 + 0.3651022911071777 + <_> + + <_> + + + + <_>11 12 1 2 -1. + <_>11 13 1 1 2. + 0 + 3.5453929740469903e-005 + 0.4277968108654022 + 1 + <_> + + + + <_>10 10 2 3 -1. + <_>10 11 2 1 3. + 0 + 2.9015709878876805e-004 + 0.4583545029163361 + 0.5284683108329773 + <_> + + <_> + + + + <_>9 5 2 2 -1. + <_>9 6 2 1 2. + 0 + 1.6071660502348095e-004 + 1 + 0.3798192143440247 + <_> + + + + <_>4 4 1 10 -1. + <_>4 9 1 5 2. + 0 + -5.2961107576265931e-004 + 0.3850437104701996 + 0.5939688086509705 + <_> + + <_> + + + + <_>11 18 4 2 -1. + <_>11 18 2 2 2. + 0 + 2.6682569296099246e-004 + 0.4123024940490723 + 1 + <_> + + + + <_>12 18 3 2 -1. + <_>12 19 3 1 2. + 0 + -1.3492540165316314e-004 + 0.5760599970817566 + 0.4237645864486694 + <_> + + <_> + + + + <_>0 6 16 6 -1. + <_>0 6 8 3 2. + <_>8 9 8 3 2. + 0 + -0.0108416797593236 + 0.3929921090602875 + 1 + <_> + + + + <_>7 6 4 12 -1. + <_>7 12 4 6 2. + 0 + 0.0120778298005462 + 0.5761923193931580 + 0.2780444920063019 + <_> + + <_> + + + + <_>11 18 4 2 -1. + <_>11 18 2 2 2. + 0 + 2.2128869313746691e-003 + 0.4794507026672363 + 1 + <_> + + + + <_>12 18 3 2 -1. + <_>12 19 3 1 2. + 0 + -0.0152661902830005 + 0.0740558803081512 + 0.5153577923774719 + <_> + + <_> + + + + <_>8 12 1 2 -1. + <_>8 13 1 1 2. + 0 + 6.7929533543065190e-005 + 1 + 0.5858737826347351 + <_> + + + + <_>8 13 1 3 -1. + <_>8 14 1 1 3. + 0 + 1.7633590323384851e-004 + 0.3567610979080200 + 0.5598962903022766 + <_> + + <_> + + + + <_>11 18 4 2 -1. + <_>11 18 2 2 2. + 0 + 8.1311381654813886e-004 + 1 + 0.5346850752830505 + <_> + + + + <_>14 12 4 6 -1. + <_>14 12 2 6 2. + 0 + 3.2630451023578644e-003 + 0.4782536923885346 + 0.5456753969192505 + <_> + + <_> + + + + <_>6 0 3 4 -1. + <_>7 0 1 4 3. + 0 + -3.9503918960690498e-003 + 0.2831811904907227 + 1 + <_> + + + + <_>4 0 2 8 -1. + <_>4 0 1 4 2. + <_>5 4 1 4 2. + 0 + -3.9864578866399825e-004 + 0.5485215783119202 + 0.4159697890281677 + <_> + + <_> + + + + <_>11 17 9 3 -1. + <_>14 17 3 3 3. + 0 + -0.0114325201138854 + 0.5639101266860962 + 1 + <_> + + + + <_>16 2 4 5 -1. + <_>16 2 2 5 2. + 0 + 5.3339172154664993e-003 + 0.4596984088420868 + 0.5931242704391480 + <_> + + <_> + + + + <_>0 2 5 9 -1. + <_>0 5 5 3 3. + 0 + 8.3193257451057434e-003 + 1 + 0.3230620026588440 + <_> + + + + <_>7 2 3 2 -1. + <_>8 2 1 2 3. + 0 + -4.2479918920435011e-004 + 0.3795293867588043 + 0.5408611297607422 + <_> + + <_> + + + + <_>11 17 9 3 -1. + <_>14 17 3 3 3. + 0 + -0.1118943020701408 + 0.1132297962903976 + 1 + <_> + + + + <_>16 2 4 5 -1. + <_>16 2 2 5 2. + 0 + -7.5553781352937222e-003 + 0.6339370012283325 + 0.4838770925998688 + <_> + + <_> + + + + <_>0 17 9 3 -1. + <_>3 17 3 3 3. + 0 + -7.0337029173970222e-003 + 0.5665255188941956 + 1 + <_> + + + + <_>0 2 4 5 -1. + <_>2 2 2 5 2. + 0 + -0.0148336803540587 + 0.6751418113708496 + 0.4140945076942444 + <_> + + <_> + + + + <_>5 11 10 9 -1. + <_>5 14 10 3 3. + 0 + 8.7506724521517754e-003 + 1 + 0.3561258912086487 + <_> + + + + <_>9 6 3 3 -1. + <_>9 7 3 1 3. + 0 + 1.6645010327920318e-003 + 0.5347279906272888 + 0.3649779856204987 + <_> + + <_> + + + + <_>3 17 5 3 -1. + <_>3 18 5 1 3. + 0 + 9.4900820404291153e-003 + 1 + 0.2754656076431274 + <_> + + + + <_>7 5 4 7 -1. + <_>9 5 2 7 2. + 0 + 1.1133110383525491e-003 + 0.4225992858409882 + 0.5629178881645203 + <_> + + <_> + + + + <_>9 8 2 5 -1. + <_>9 8 1 5 2. + 0 + 9.4940755516290665e-003 + 0.4906036853790283 + 1 + <_> + + + + <_>2 2 18 2 -1. + <_>2 3 18 1 2. + 0 + -1.5396620146930218e-003 + 0.4007051885128021 + 0.5380709171295166 + <_> + + <_> + + + + <_>2 8 15 6 -1. + <_>7 8 5 6 3. + 0 + 0.1343495994806290 + 1 + 0.2214671969413757 + <_> + + + + <_>9 8 2 5 -1. + <_>10 8 1 5 2. + 0 + -9.4940755516290665e-003 + 0.7353156208992004 + 0.5005033016204834 + <_> + + <_> + + + + <_>12 10 4 6 -1. + <_>12 12 4 2 3. + 0 + 0.0200117900967598 + 1 + 0.3327906131744385 + <_> + + + + <_>14 3 6 2 -1. + <_>14 4 6 1 2. + 0 + -1.8875009845942259e-003 + 0.3915289044380188 + 0.5401849746704102 + <_> + + <_> + + + + <_>5 5 2 3 -1. + <_>5 6 2 1 3. + 0 + 7.1842782199382782e-003 + 1 + 0.7176604866981506 + <_> + + + + <_>4 6 3 3 -1. + <_>4 7 3 1 3. + 0 + 1.6976969782263041e-003 + 0.4526978135108948 + 0.6076912879943848 + <_> + + <_> + + + + <_>14 12 3 3 -1. + <_>14 13 3 1 3. + 0 + 4.9219978973269463e-003 + 1 + 0.2569833993911743 + <_> + + + + <_>6 12 11 3 -1. + <_>6 13 11 1 3. + 0 + 0.0118031995370984 + 0.4999637901782990 + 0.5958228111267090 + <_> + + <_> + + + + <_>1 2 3 6 -1. + <_>1 4 3 2 3. + 0 + -9.7703449428081512e-003 + 0.3459093868732452 + 1 + <_> + + + + <_>1 0 4 7 -1. + <_>3 0 2 7 2. + 0 + 2.1174899302423000e-003 + 0.4515126943588257 + 0.5829715728759766 + <_> + + <_> + + + + <_>9 8 3 4 -1. + <_>10 8 1 4 3. + 0 + 9.4801411032676697e-003 + 0.4807392060756683 + 1 + <_> + + + + <_>10 9 2 2 -1. + <_>10 10 2 1 2. + 0 + -2.6078789960592985e-003 + 0.3462216854095459 + 0.5201594829559326 + <_> + + <_> + + + + <_>8 8 3 4 -1. + <_>9 8 1 4 3. + 0 + -5.7252747938036919e-003 + 0.6599853038787842 + 1 + <_> + + + + <_>4 4 10 10 -1. + <_>4 9 10 5 2. + 0 + -8.2325618714094162e-003 + 0.2821828126907349 + 0.5125284790992737 + <_> + + <_> + + + + <_>9 10 3 2 -1. + <_>10 10 1 2 3. + 0 + 8.9571950957179070e-004 + 0.4883818924427033 + 1 + <_> + + + + <_>9 10 3 2 -1. + <_>9 11 3 1 2. + 0 + -1.5021569561213255e-004 + 0.4829918146133423 + 0.5428717136383057 + <_> + + <_> + + + + <_>8 10 3 2 -1. + <_>9 10 1 2 3. + 0 + 4.8489659093320370e-004 + 0.4434598982334137 + 1 + <_> + + + + <_>2 4 14 12 -1. + <_>2 4 7 6 2. + <_>9 10 7 6 2. + 0 + -0.0961926504969597 + 0.2256636023521423 + 0.5956227779388428 + <_> + + <_> + + + + <_>10 12 1 6 -1. + <_>10 15 1 3 2. + 0 + -1.1053519556298852e-003 + 0.4527224004268646 + 1 + <_> + + + + <_>7 3 8 16 -1. + <_>11 3 4 8 2. + <_>7 11 4 8 2. + 0 + -0.1021504029631615 + 0.2844349145889282 + 0.5186452865600586 + <_> + + <_> + + + + <_>5 6 8 10 -1. + <_>5 6 4 5 2. + <_>9 11 4 5 2. + 0 + 3.0147889629006386e-003 + 1 + 0.3808999061584473 + <_> + + + + <_>6 2 8 8 -1. + <_>6 2 4 4 2. + <_>10 6 4 4 2. + 0 + 7.6131648384034634e-003 + 0.5718699097633362 + 0.4262563884258270 + <_> + + <_> + + + + <_>10 5 4 2 -1. + <_>12 5 2 1 2. + <_>10 6 2 1 2. + 0 + 1.5197630273178220e-003 + 1 + 0.5942718982696533 + <_> + + + + <_>12 4 3 3 -1. + <_>12 5 3 1 3. + 0 + -0.0141972796991467 + 0.7731103897094727 + 0.4997653961181641 + <_> + + <_> + + + + <_>4 19 12 1 -1. + <_>8 19 4 1 3. + 0 + -0.0138188796117902 + 0.6681138277053833 + 1 + <_> + + + + <_>8 2 3 1 -1. + <_>9 2 1 1 3. + 0 + -5.0701329018920660e-004 + 0.3305608034133911 + 0.4749974906444550 + <_> + + <_> + + + + <_>13 17 4 3 -1. + <_>13 18 4 1 3. + 0 + -9.3537531793117523e-003 + 0.2860932946205139 + 1 + <_> + + + + <_>7 14 6 3 -1. + <_>7 15 6 1 3. + 0 + -9.4771059229969978e-003 + 0.6188883185386658 + 0.4842100143432617 + <_> + + <_> + + + + <_>9 14 2 3 -1. + <_>9 15 2 1 3. + 0 + 1.6923650400713086e-003 + 1 + 0.6070249080657959 + <_> + + + + <_>7 15 6 3 -1. + <_>7 16 6 1 3. + 0 + 5.8652542065829039e-004 + 0.3782689869403839 + 0.5368196964263916 + <_> + + <_> + + + + <_>10 18 3 2 -1. + <_>11 18 1 2 3. + 0 + -2.5826620403677225e-003 + 0.3690209984779358 + 1 + <_> + + + + <_>14 12 2 3 -1. + <_>14 13 2 1 3. + 0 + -2.7307639829814434e-003 + 0.3857114911079407 + 0.5318108797073364 + <_> + + <_> + + + + <_>4 10 4 6 -1. + <_>4 12 4 2 3. + 0 + 0.0218715704977512 + 1 + 0.2327008992433548 + <_> + + + + <_>4 13 3 2 -1. + <_>4 14 3 1 2. + 0 + -1.5010299648565706e-005 + 0.5560722947120667 + 0.4301410019397736 + <_> + + <_> + + + + <_>9 16 2 3 -1. + <_>9 17 2 1 3. + 0 + 5.3583700209856033e-003 + 1 + 0.6767637729644775 + <_> + + + + <_>10 18 3 2 -1. + <_>11 18 1 2 3. + 0 + 5.0057549960911274e-003 + 0.5194904208183289 + 0.3612853884696960 + <_> + + <_> + + + + <_>7 18 3 2 -1. + <_>8 18 1 2 3. + 0 + -1.9030070398002863e-003 + 0.3237845003604889 + 1 + <_> + + + + <_>1 10 4 2 -1. + <_>1 11 4 1 2. + 0 + -7.8506693243980408e-003 + 0.1194851994514465 + 0.4991723895072937 + <_> + + <_> + + + + <_>12 4 6 3 -1. + <_>12 5 6 1 3. + 0 + -2.7093670796602964e-003 + 1 + 0.4854960143566132 + <_> + + + + <_>14 4 1 3 -1. + <_>14 5 1 1 3. + 0 + 1.4138079714030027e-003 + 0.4872322976589203 + 0.5903577804565430 + <_> + + <_> + + + + <_>2 4 6 3 -1. + <_>2 5 6 1 3. + 0 + 9.0300198644399643e-003 + 1 + 0.6547315716743469 + <_> + + + + <_>5 4 1 3 -1. + <_>5 5 1 1 3. + 0 + -9.7925681620836258e-004 + 0.5849273204803467 + 0.4554230868816376 + <_> + + <_> + + + + <_>14 12 3 3 -1. + <_>14 13 3 1 3. + 0 + 1.3984439428895712e-003 + 1 + 0.4064626097679138 + <_> + + + + <_>15 12 2 3 -1. + <_>15 13 2 1 3. + 0 + 8.3372107474133372e-004 + 0.5399543046951294 + 0.4152809977531433 + <_> + + <_> + + + + <_>3 16 4 3 -1. + <_>3 17 4 1 3. + 0 + 0.0105510596185923 + 1 + 0.1796680986881256 + <_> + + + + <_>8 0 4 2 -1. + <_>8 1 4 1 2. + 0 + 8.8344102550763637e-005 + 0.4251863062381744 + 0.5413522720336914 + <_> + + <_> + + + + <_>0 0 20 1 -1. + <_>0 0 10 1 2. + 0 + -0.0410223081707954 + 1 + 0.5228124856948853 + <_> + + + + <_>9 7 3 4 -1. + <_>10 7 1 4 3. + 0 + 7.5065628625452518e-003 + 0.4853743016719818 + 0.6093444228172302 + <_> + + <_> + + + + <_>0 0 20 1 -1. + <_>10 0 10 1 2. + 0 + 0.0410223081707954 + 1 + 0.2205024063587189 + <_> + + + + <_>8 7 3 4 -1. + <_>9 7 1 4 3. + 0 + -5.3961377125233412e-004 + 0.5692731738090515 + 0.4468756914138794 + <_> + + <_> + + + + <_>1 6 19 3 -1. + <_>1 7 19 1 3. + 0 + -0.0686960369348526 + 0.1483314037322998 + 1 + <_> + + + + <_>12 7 4 2 -1. + <_>12 8 4 1 2. + 0 + -1.8447940237820148e-003 + 0.6211283802986145 + 0.4966601133346558 + <_> + + <_> + + + + <_>7 8 3 3 -1. + <_>7 9 3 1 3. + 0 + -6.0959919355809689e-003 + 0.2294671982526779 + 1 + <_> + + + + <_>7 7 3 3 -1. + <_>8 7 1 3 3. + 0 + -4.2068301700055599e-003 + 0.6407091021537781 + 0.4748562872409821 + <_> + + <_> + + + + <_>2 9 16 3 -1. + <_>2 10 16 1 3. + 0 + -7.1332789957523346e-004 + 1 + 0.5354936122894287 + <_> + + + + <_>9 4 2 12 -1. + <_>9 8 2 4 3. + 0 + 0.1175677999854088 + 0.5136978030204773 + 0.0105957398191094 + <_> + + <_> + + + + <_>7 3 2 5 -1. + <_>8 3 1 5 2. + 0 + 5.9354289987822995e-005 + 0.3711803853511810 + 1 + <_> + + + + <_>9 7 2 3 -1. + <_>9 8 2 1 3. + 0 + -6.3173691742122173e-003 + 0.1712073981761932 + 0.5061758160591126 + <_> + + <_> + + + + <_>9 14 4 3 -1. + <_>9 15 4 1 3. + 0 + 0.0149414995685220 + 1 + 0.6729118824005127 + <_> + + + + <_>7 8 6 4 -1. + <_>10 8 3 2 2. + <_>7 10 3 2 2. + 0 + -2.0789399277418852e-003 + 0.4410645961761475 + 0.5444027781486511 + <_> + + <_> + + + + <_>9 7 2 2 -1. + <_>10 7 1 2 2. + 0 + -7.0736219640821218e-004 + 0.5568910837173462 + 1 + <_> + + + + <_>5 5 6 6 -1. + <_>7 5 2 6 3. + 0 + -3.1247111037373543e-003 + 0.5023869276046753 + 0.3562405109405518 + <_> + + <_> + + + + <_>9 1 3 6 -1. + <_>10 1 1 6 3. + 0 + -7.8919378574937582e-004 + 1 + 0.5456786155700684 + <_> + + + + <_>4 5 12 2 -1. + <_>8 5 4 2 3. + 0 + 0.0101795801892877 + 0.5545138716697693 + 0.4622310996055603 + <_> + + <_> + + + + <_>4 2 6 4 -1. + <_>6 2 2 4 3. + 0 + -2.7506109327077866e-003 + 1 + 0.4942536056041718 + <_> + + + + <_>4 7 8 2 -1. + <_>4 8 8 1 2. + 0 + 0.0106013296172023 + 0.2961233854293823 + 0.5964338779449463 + <_> + + <_> + + + + <_>3 6 14 6 -1. + <_>10 6 7 3 2. + <_>3 9 7 3 2. + 0 + 5.1466780714690685e-003 + 0.5495228767395020 + 1 + <_> + + + + <_>3 6 14 3 -1. + <_>3 6 7 3 2. + 0 + 0.0763211473822594 + 0.5173959136009216 + 0.2940216958522797 + <_> + + <_> + + + + <_>0 5 2 2 -1. + <_>0 6 2 1 2. + 0 + -1.5027689514681697e-003 + 0.3106299936771393 + 1 + <_> + + + + <_>8 13 4 3 -1. + <_>8 14 4 1 3. + 0 + 0.0122666703537107 + 0.4651150107383728 + 0.6846613883972168 + <_> + + <_> + + + + <_>13 0 3 20 -1. + <_>14 0 1 20 3. + 0 + -0.0311185792088509 + 1 + 0.5226057171821594 + <_> + + + + <_>10 8 10 3 -1. + <_>10 9 10 1 3. + 0 + 0.0289055891335011 + 0.5182244181632996 + 0.2705428004264832 + <_> + + <_> + + + + <_>4 0 3 20 -1. + <_>5 0 1 20 3. + 0 + 0.0475983805954456 + 1 + 0.1109512001276016 + <_> + + + + <_>0 8 10 3 -1. + <_>0 9 10 1 3. + 0 + 0.0308085493743420 + 0.4938625097274780 + 0.1404110938310623 + <_> + + <_> + + + + <_>12 5 3 4 -1. + <_>13 5 1 4 3. + 0 + -2.1277810446918011e-004 + 1 + 0.4392356872558594 + <_> + + + + <_>6 7 12 4 -1. + <_>10 7 4 4 3. + 0 + 0.0789699628949165 + 0.5216552019119263 + 0.2294113934040070 + <_> + + <_> + + + + <_>1 14 6 6 -1. + <_>1 14 3 3 2. + <_>4 17 3 3 2. + 0 + -0.0102579500526190 + 0.6176652908325195 + 1 + <_> + + + + <_>1 17 6 2 -1. + <_>1 18 6 1 2. + 0 + 1.2604889925569296e-003 + 0.5236222743988037 + 0.3328965902328491 + <_> + + <_> + + + + <_>14 8 6 12 -1. + <_>17 8 3 6 2. + <_>14 14 3 6 2. + 0 + -0.0334904603660107 + 1 + 0.4866186976432800 + <_> + + + + <_>18 5 2 2 -1. + <_>18 6 2 1 2. + 0 + -5.9202767442911863e-004 + 0.4116407036781311 + 0.5395640134811401 + <_> + + <_> + + + + <_>3 16 4 2 -1. + <_>3 16 2 1 2. + <_>5 17 2 1 2. + 0 + 3.0320750738610514e-005 + 1 + 0.5610736012458801 + <_> + + + + <_>2 16 6 2 -1. + <_>4 16 2 2 3. + 0 + -5.4369680583477020e-004 + 0.5621389150619507 + 0.3461203873157501 + <_> + + <_> + + + + <_>14 8 6 12 -1. + <_>17 8 3 6 2. + <_>14 14 3 6 2. + 0 + -0.0334904603660107 + 1 + 0.4896762073040009 + <_> + + + + <_>18 5 2 2 -1. + <_>18 6 2 1 2. + 0 + -5.9202767442911863e-004 + 0.4305404126644135 + 0.5340713858604431 + <_> + + <_> + + + + <_>5 16 9 2 -1. + <_>8 16 3 2 3. + 0 + 2.0550889894366264e-003 + 0.5544999837875366 + 1 + <_> + + + + <_>3 14 6 6 -1. + <_>3 14 3 3 2. + <_>6 17 3 3 2. + 0 + -4.4353571720421314e-003 + 0.6038540005683899 + 0.3746592998504639 + <_> + + <_> + + + + <_>14 8 6 12 -1. + <_>17 8 3 6 2. + <_>14 14 3 6 2. + 0 + -0.0841704234480858 + 1 + 0.5007348060607910 + <_> + + + + <_>11 7 2 12 -1. + <_>11 11 2 4 3. + 0 + 6.7419027909636497e-003 + 0.5298097133636475 + 0.4716145098209381 + <_> + + <_> + + + + <_>0 8 6 12 -1. + <_>0 8 3 6 2. + <_>3 14 3 6 2. + 0 + 0.0102781504392624 + 1 + 0.6269375085830689 + <_> + + + + <_>7 7 2 12 -1. + <_>7 11 2 4 3. + 0 + 5.8800862170755863e-003 + 0.5154827833175659 + 0.3813040852546692 + <_> + + <_> + + + + <_>14 12 1 2 -1. + <_>14 13 1 1 2. + 0 + -6.9679190346505493e-006 + 1 + 0.4440239965915680 + <_> + + + + <_>12 13 8 1 -1. + <_>12 13 4 1 2. + 0 + 8.2419527461752295e-004 + 0.4697534143924713 + 0.5485504269599915 + <_> + + <_> + + + + <_>0 3 16 6 -1. + <_>0 6 16 3 2. + 0 + -5.5268318392336369e-003 + 0.5513604879379273 + 1 + <_> + + + + <_>1 4 8 2 -1. + <_>1 4 4 1 2. + <_>5 5 4 1 2. + 0 + 9.6128671430051327e-004 + 0.3618639111518860 + 0.5838456749916077 + <_> + + <_> + + + + <_>14 12 1 2 -1. + <_>14 13 1 1 2. + 0 + 2.4810510221868753e-003 + 1 + 0.2523222863674164 + <_> + + + + <_>15 12 2 3 -1. + <_>15 13 2 1 3. + 0 + -1.0480589699000120e-003 + 0.4117257893085480 + 0.5392996072769165 + <_> + + <_> + + + + <_>8 16 3 3 -1. + <_>8 17 3 1 3. + 0 + -6.1287907883524895e-003 + 0.6726329922676086 + 1 + <_> + + + + <_>5 12 1 2 -1. + <_>5 13 1 1 2. + 0 + 1.1682329932227731e-004 + 0.5041192770004273 + 0.3607729077339172 + <_> + + <_> + + + + <_>13 4 3 15 -1. + <_>14 4 1 15 3. + 0 + -0.0399094782769680 + 0.1563739031553268 + 1 + <_> + + + + <_>17 3 2 6 -1. + <_>18 3 1 3 2. + <_>17 6 1 3 2. + 0 + 1.5859459526836872e-003 + 0.4891980886459351 + 0.5779845118522644 + <_> + + <_> + + + + <_>4 4 3 15 -1. + <_>5 4 1 15 3. + 0 + -0.0226902291178703 + 0.2186879068613052 + 1 + <_> + + + + <_>1 3 2 6 -1. + <_>1 3 1 3 2. + <_>2 6 1 3 2. + 0 + 2.0916070789098740e-003 + 0.4771577119827271 + 0.6099231243133545 + <_> + + <_> + + + + <_>7 15 12 4 -1. + <_>7 17 12 2 2. + 0 + -0.0247154198586941 + 0.3463996946811676 + 1 + <_> + + + + <_>1 0 19 3 -1. + <_>1 1 19 1 3. + 0 + -0.0134194502606988 + 0.3630692958831787 + 0.5252196192741394 + <_> + + <_> + + + + <_>3 17 10 2 -1. + <_>3 17 5 1 2. + <_>8 18 5 1 2. + 0 + -6.0629472136497498e-003 + 0.6666321754455566 + 1 + <_> + + + + <_>2 5 10 15 -1. + <_>2 10 10 5 3. + 0 + -2.0921030081808567e-003 + 0.3399547040462494 + 0.5035697817802429 + <_> + + <_> + + + + <_>13 8 3 4 -1. + <_>13 10 3 2 2. + 0 + 0.0259618591517210 + 0.5036802887916565 + 1 + <_> + + + + <_>19 13 1 2 -1. + <_>19 14 1 1 2. + 0 + 1.7908669542521238e-004 + 0.5418530702590942 + 0.4318976998329163 + <_> + + <_> + + + + <_>4 8 3 4 -1. + <_>4 10 3 2 2. + 0 + -3.1546850223094225e-003 + 0.7221025228500366 + 1 + <_> + + + + <_>0 13 1 2 -1. + <_>0 14 1 1 2. + 0 + -1.1397759662941098e-003 + 0.3320972919464111 + 0.5024433732032776 + <_> + + <_> + + + + <_>12 7 2 12 -1. + <_>12 13 2 6 2. + 0 + -0.0478402115404606 + 0.1938765048980713 + 1 + <_> + + + + <_>14 7 2 2 -1. + <_>15 7 1 1 2. + <_>14 8 1 1 2. + 0 + 4.1577088995836675e-004 + 0.4802188873291016 + 0.5730714797973633 + <_> + + <_> + + + + <_>5 3 8 2 -1. + <_>5 4 8 1 2. + 0 + -4.4247039477340877e-004 + 0.4262515008449554 + 1 + <_> + + + + <_>0 2 2 6 -1. + <_>0 4 2 2 3. + 0 + 1.4479350065812469e-003 + 0.5719171166419983 + 0.4064153134822846 + <_> + + <_> + + + + <_>18 2 2 12 -1. + <_>19 2 1 6 2. + <_>18 8 1 6 2. + 0 + 0.0157015100121498 + 0.4995726048946381 + 1 + <_> + + + + <_>18 1 1 2 -1. + <_>18 2 1 1 2. + 0 + 2.7805729769170284e-004 + 0.5289286971092224 + 0.4581728875637054 + <_> + + <_> + + + + <_>0 2 2 12 -1. + <_>0 2 1 6 2. + <_>1 8 1 6 2. + 0 + -2.9010509606450796e-003 + 0.6012148261070252 + 1 + <_> + + + + <_>1 1 1 2 -1. + <_>1 2 1 1 2. + 0 + 2.0830519497394562e-004 + 0.5057976841926575 + 0.3599432110786438 + <_> + + <_> + + + + <_>16 4 4 14 -1. + <_>18 4 2 7 2. + <_>16 11 2 7 2. + 0 + -0.0515300296247005 + 1 + 0.4991796910762787 + <_> + + + + <_>10 14 1 6 -1. + <_>10 17 1 3 2. + 0 + 1.7163449956569821e-004 + 0.4675469994544983 + 0.5374773144721985 + <_> + + <_> + + + + <_>0 4 4 14 -1. + <_>0 4 2 7 2. + <_>2 11 2 7 2. + 0 + 0.0236142799258232 + 1 + 0.6586478948593140 + <_> + + + + <_>9 14 1 6 -1. + <_>9 17 1 3 2. + 0 + -5.6427798699587584e-004 + 0.3853296041488648 + 0.5196040272712708 + <_> + + <_> + + + + <_>9 14 4 3 -1. + <_>9 15 4 1 3. + 0 + 6.6903959959745407e-003 + 1 + 0.6004235744476318 + <_> + + + + <_>4 7 12 2 -1. + <_>8 7 4 2 3. + 0 + -4.8789530992507935e-003 + 0.3293227851390839 + 0.5245236754417419 + <_> + + <_> + + + + <_>0 8 4 3 -1. + <_>0 9 4 1 3. + 0 + -6.8537332117557526e-003 + 0.2565914094448090 + 1 + <_> + + + + <_>4 7 2 2 -1. + <_>4 7 1 1 2. + <_>5 8 1 1 2. + 0 + 9.9893810693174601e-004 + 0.4615494012832642 + 0.5942432284355164 + <_> + + <_> + + + + <_>13 7 2 1 -1. + <_>13 7 1 1 2. + 0 + -1.3354700058698654e-004 + 0.5487375855445862 + 1 + <_> + + + + <_>11 4 4 5 -1. + <_>11 4 2 5 2. + 0 + 1.0165109997615218e-003 + 0.4578359127044678 + 0.5426927804946899 + <_> + + <_> + + + + <_>4 8 3 3 -1. + <_>5 8 1 3 3. + 0 + 9.1216771397739649e-004 + 1 + 0.3939461112022400 + <_> + + + + <_>0 3 8 1 -1. + <_>4 3 4 1 2. + 0 + 1.0080259526148438e-003 + 0.4049789905548096 + 0.5520703792572022 + <_> + + <_> + + + + <_>13 7 2 1 -1. + <_>13 7 1 1 2. + 0 + -1.3102490629535168e-004 + 1 + 0.4879088997840881 + <_> + + + + <_>14 7 3 2 -1. + <_>15 7 1 2 3. + 0 + 5.5228749988600612e-004 + 0.4844943881034851 + 0.5512825846672058 + <_> + + <_> + + + + <_>5 7 2 1 -1. + <_>6 7 1 1 2. + 0 + -1.2130969844292849e-004 + 1 + 0.4367971122264862 + <_> + + + + <_>3 7 3 2 -1. + <_>4 7 1 2 3. + 0 + -1.5112989785848185e-005 + 0.6425955295562744 + 0.4881826937198639 + <_> + + <_> + + + + <_>18 5 2 2 -1. + <_>18 6 2 1 2. + 0 + -4.0125829400494695e-004 + 1 + 0.5372099280357361 + <_> + + + + <_>12 14 2 2 -1. + <_>13 14 1 1 2. + <_>12 15 1 1 2. + 0 + -6.5766851184889674e-004 + 0.5834553241729736 + 0.4869078099727631 + <_> + + <_> + + + + <_>0 5 2 2 -1. + <_>0 6 2 1 2. + 0 + 6.2220421386882663e-004 + 1 + 0.3824636936187744 + <_> + + + + <_>6 14 2 2 -1. + <_>6 14 1 1 2. + <_>7 15 1 1 2. + 0 + 1.4663359615951777e-003 + 0.4813488125801086 + 0.6966739296913147 + <_> + + <_> + + + + <_>7 12 6 5 -1. + <_>9 12 2 5 3. + 0 + -0.0495477095246315 + 0.0539276599884033 + 1 + <_> + + + + <_>12 17 5 2 -1. + <_>12 18 5 1 2. + 0 + 1.3017569435760379e-003 + 0.5337455868721008 + 0.4160748124122620 + <_> + + <_> + + + + <_>1 11 6 3 -1. + <_>4 11 3 3 2. + 0 + -4.4914530590176582e-003 + 0.5997437238693237 + 1 + <_> + + + + <_>1 9 6 3 -1. + <_>4 9 3 3 2. + 0 + 1.6592369647696614e-003 + 0.3727185130119324 + 0.5115634202957153 + <_> + + <_> + + + + <_>12 7 2 12 -1. + <_>12 13 2 6 2. + 0 + 6.4695458859205246e-003 + 0.5252035260200501 + 1 + <_> + + + + <_>8 7 5 3 -1. + <_>8 8 5 1 3. + 0 + 4.9810269847512245e-003 + 0.5256717801094055 + 0.3934406042098999 + <_> + + <_> + + + + <_>6 7 2 12 -1. + <_>6 13 2 6 2. + 0 + -0.0385369807481766 + 0.2061924934387207 + 1 + <_> + + + + <_>1 2 9 18 -1. + <_>4 2 3 18 3. + 0 + -0.2827565073966980 + 0.0618832111358643 + 0.4925057888031006 + <_> + + <_> + + + + <_>12 17 5 2 -1. + <_>12 18 5 1 2. + 0 + -9.0301828458905220e-003 + 0.3157590031623840 + 1 + <_> + + + + <_>4 7 12 2 -1. + <_>4 7 6 2 2. + 0 + -0.0438662692904472 + 0.2033682018518448 + 0.5164769887924194 + <_> + + <_> + + + + <_>6 7 6 1 -1. + <_>8 7 2 1 3. + 0 + -4.5701069757342339e-003 + 0.6611183285713196 + 1 + <_> + + + + <_>7 3 3 2 -1. + <_>8 3 1 2 3. + 0 + -2.3362410720437765e-003 + 0.2807789146900177 + 0.4962876141071320 + <_> + + <_> + + + + <_>9 4 3 1 -1. + <_>10 4 1 1 3. + 0 + 5.3960331715643406e-003 + 0.5146387815475464 + 1 + <_> + + + + <_>11 11 3 1 -1. + <_>12 11 1 1 3. + 0 + -2.6297608856111765e-003 + 0.6284487843513489 + 0.4955588877201080 + <_> + + <_> + + + + <_>8 4 3 1 -1. + <_>9 4 1 1 3. + 0 + -3.8577478844672441e-003 + 0.1486748009920120 + 1 + <_> + + + + <_>6 11 3 1 -1. + <_>7 11 1 1 3. + 0 + 1.3963800156489015e-003 + 0.4701338112354279 + 0.6320971846580505 + <_> + + <_> + + + + <_>12 13 6 6 -1. + <_>12 15 6 2 3. + 0 + -8.8699469342827797e-003 + 1 + 0.5286818146705627 + <_> + + + + <_>14 13 1 6 -1. + <_>14 15 1 2 3. + 0 + -7.0626288652420044e-004 + 0.4648370146751404 + 0.5333210229873657 + <_> + + <_> + + + + <_>2 13 6 6 -1. + <_>2 15 6 2 3. + 0 + 4.2645810171961784e-003 + 0.5084878206253052 + 1 + <_> + + + + <_>1 5 18 1 -1. + <_>7 5 6 1 3. + 0 + 0.0615721009671688 + 0.3629625141620636 + 0.8757156729698181 + <_> + + <_> + + + + <_>4 7 12 2 -1. + <_>10 7 6 1 2. + <_>4 8 6 1 2. + 0 + -4.5381980016827583e-003 + 1 + 0.4856696128845215 + <_> + + + + <_>6 1 8 10 -1. + <_>10 1 4 5 2. + <_>6 6 4 5 2. + 0 + -4.0877899155020714e-003 + 0.4584116041660309 + 0.5420240759849548 + <_> + + <_> + + + + <_>3 13 4 3 -1. + <_>3 14 4 1 3. + 0 + 6.4308601431548595e-003 + 1 + 0.2707302868366242 + <_> + + + + <_>6 13 4 3 -1. + <_>6 14 4 1 3. + 0 + 7.0455260574817657e-003 + 0.5057486891746521 + 0.7026523947715759 + <_> + + <_> + + + + <_>9 14 4 3 -1. + <_>9 15 4 1 3. + 0 + -2.3246440105140209e-003 + 1 + 0.4827278852462769 + <_> + + + + <_>12 9 2 3 -1. + <_>12 10 2 1 3. + 0 + 6.0276601288933307e-005 + 0.4247249066829681 + 0.5508763194084168 + <_> + + <_> + + + + <_>7 14 4 3 -1. + <_>7 15 4 1 3. + 0 + 0.0180845595896244 + 1 + 0.8104801177978516 + <_> + + + + <_>9 0 2 1 -1. + <_>10 0 1 1 2. + 0 + 8.4693520329892635e-004 + 0.5154619216918945 + 0.3514379858970642 + <_> + + <_> + + + + <_>5 0 10 5 -1. + <_>5 0 5 5 2. + 0 + -0.0269310399889946 + 1 + 0.4886888861656189 + <_> + + + + <_>6 6 8 7 -1. + <_>6 6 4 7 2. + 0 + -4.2346641421318054e-003 + 0.4622378051280975 + 0.5382478237152100 + <_> + + <_> + + + + <_>5 0 10 5 -1. + <_>10 0 5 5 2. + 0 + 0.0269471108913422 + 1 + 0.6366596221923828 + <_> + + + + <_>6 6 8 7 -1. + <_>10 6 4 7 2. + 0 + 4.6446882188320160e-003 + 0.5368506908416748 + 0.3765429854393005 + <_> + + <_> + + + + <_>5 9 10 8 -1. + <_>10 9 5 4 2. + <_>5 13 5 4 2. + 0 + -6.9577661342918873e-003 + 0.4234687089920044 + 1 + <_> + + + + <_>10 0 4 10 -1. + <_>12 0 2 5 2. + <_>10 5 2 5 2. + 0 + 8.7609712500125170e-004 + 0.4672406017780304 + 0.5350683927536011 + <_> + + <_> + + + + <_>1 4 8 3 -1. + <_>1 5 8 1 3. + 0 + 1.6103329835459590e-003 + 1 + 0.5732762813568115 + <_> + + + + <_>4 4 8 3 -1. + <_>4 5 8 1 3. + 0 + -1.2848590267822146e-003 + 0.5481799244880676 + 0.3784593045711517 + <_> + + <_> + + + + <_>9 7 4 3 -1. + <_>9 8 4 1 3. + 0 + 0.0102435396984220 + 0.5155907273292542 + 1 + <_> + + + + <_>12 8 3 12 -1. + <_>12 14 3 6 2. + 0 + 2.6889349101111293e-004 + 0.5353189706802368 + 0.4387153983116150 + <_> + + <_> + + + + <_>7 7 4 3 -1. + <_>7 8 4 1 3. + 0 + 3.7903659977018833e-003 + 0.5032002925872803 + 1 + <_> + + + + <_>5 8 3 12 -1. + <_>5 14 3 6 2. + 0 + -0.0293696802109480 + 0.5873538851737976 + 0.2215445041656494 + <_> + + <_> + + + + <_>10 0 7 6 -1. + <_>10 2 7 2 3. + 0 + 6.0743088833987713e-003 + 1 + 0.5417029857635498 + <_> + + + + <_>2 1 18 1 -1. + <_>8 1 6 1 3. + 0 + -0.0127107203006744 + 0.6056511998176575 + 0.4985181987285614 + <_> + + <_> + + + + <_>5 0 3 8 -1. + <_>6 0 1 8 3. + 0 + -5.9445449151098728e-003 + 0.3352069854736328 + 1 + <_> + + + + <_>4 7 4 2 -1. + <_>4 8 4 1 2. + 0 + -2.8927479870617390e-003 + 0.6929240822792053 + 0.4778220057487488 + 53.7555694580078130 + 18 + -1 + diff --git a/data/lbpcascade_frontalcatface.xml b/data/lbpcascade_frontalcatface.xml new file mode 100644 index 00000000..4d8d8299 --- /dev/null +++ b/data/lbpcascade_frontalcatface.xml @@ -0,0 +1,3336 @@ + + + + + BOOST + LBP + 24 + 24 + + GAB + 9.9900001287460327e-01 + 5.0000000000000000e-01 + 9.4999999999999996e-01 + 1 + 100 + + 256 + 1 + 15 + + + <_> + 12 + -1.7687875032424927e+00 + + <_> + + 0 -1 102 391095182 -138018897 -1311235414 -134348801 + -10637363 1363472332 -168428565 -170000676 + + -3.8902848958969116e-01 7.1630239486694336e-01 + <_> + + 0 -1 266 135269620 1065172957 761273949 1068766640 + -285409281 -1075109889 -1073808385 -1073741825 + + -5.0905084609985352e-01 4.4736129045486450e-01 + <_> + + 0 -1 248 -882714626 -11077637 -2105857 -5255203 1594642431 + -536896039 -540028929 266295295 + + -4.0175846219062805e-01 4.7943404316902161e-01 + <_> + + 0 -1 5 -617089137 -547883529 1911919584 -2239534 1530067199 + 1140914475 -1092824836 1892022980 + + -4.2830348014831543e-01 4.3316614627838135e-01 + <_> + + 0 -1 103 251265151 2145342812 1501453661 1046368729 + -1975908196 -1105592134 -1897996802 -88470342 + + -3.9837184548377991e-01 4.3966090679168701e-01 + <_> + + 0 -1 249 653255651 -1427184958 -736368649 -1052429 + 1722766161 -455896464 1155912595 -167811855 + + -3.9872139692306519e-01 3.9076396822929382e-01 + <_> + + 0 -1 98 -147601648 452990736 522407185 1599686417 1169689768 + 407507112 -1762308210 1599803223 + + -4.5285862684249878e-01 3.3382070064544678e-01 + <_> + + 0 -1 300 805836816 1351616140 -1629160611 -1696006160 + 2133143824 -1418430667 -1093085224 -91160647 + + -5.1765918731689453e-01 2.8637027740478516e-01 + <_> + + 0 -1 206 771753813 1072999924 -637907073 1072594908 + 1022435188 -1073874507 -1076936836 -1141628556 + + -4.5144259929656982e-01 3.3236411213874817e-01 + <_> + + 0 -1 188 -1493176369 712675187 -55120016 -1570308126 + 1845183255 -34048033 -1090533504 -386469418 + + -3.6836385726928711e-01 4.1354060173034668e-01 + <_> + + 0 -1 84 1876927247 -103435857 821334050 -202379046 + -607136374 354198146 1878387370 -455740474 + + -3.8681995868682861e-01 3.9221677184104919e-01 + <_> + + 0 -1 85 70388767 580795691 -83467 1051082410 -287417474 + -1076176594 -57439237 -1430597793 + + -4.1789534687995911e-01 3.5533955693244934e-01 + + <_> + 13 + -1.3504111766815186e+00 + + <_> + + 0 -1 52 -582353192 453631753 -1189740547 490856223 + -1064974120 -1927684129 1413925631 151519071 + + -2.2373910248279572e-01 6.7752838134765625e-01 + <_> + + 0 -1 213 -576729857 454575443 -1996943617 536547583 + 206047452 -1088734277 210521343 264241151 + + -3.7819463014602661e-01 5.2549731731414795e-01 + <_> + + 0 -1 275 -249562832 -1181502479 -174589519 -1112427119 + -1189167448 -1081345300 -1534158677 -1431310669 + + -3.6486798524856567e-01 4.7923672199249268e-01 + <_> + + 0 -1 125 -1405482952 -15924365 -1147527681 -10535319 + -1345282310 -1103133 698354938 -1073790989 + + -4.9668836593627930e-01 3.3489266037940979e-01 + <_> + + 0 -1 82 2135911182 -553255561 -1835761112 -744206088 + 1443360719 1427151980 -208273409 -136971281 + + -4.9673599004745483e-01 2.9186215996742249e-01 + <_> + + 0 -1 64 750650461 -1141224741 228524031 1066678329 + -392530945 -1119829 -389633282 -1909948481 + + -4.4474920630455017e-01 3.3087861537933350e-01 + <_> + + 0 -1 80 -8364 961050640 -337450 -170150085 -4518372 + 1480613384 -270925857 -203948193 + + -3.6774283647537231e-01 3.8125535845756531e-01 + <_> + + 0 -1 304 -1279559723 488853328 894958865 523048208 + -1111801861 -1113625095 -1410843652 -1615113099 + + -3.8107365369796753e-01 3.7617510557174683e-01 + <_> + + 0 -1 27 -1038891372 866262272 -1124866827 -7307515 2556056 + -1947784189 145625549 -537934001 + + -3.3774635195732117e-01 4.1467228531837463e-01 + <_> + + 0 -1 214 1313841735 674152170 -1368464720 -1597048870 + 759309825 -295860621 1709856085 -587729545 + + -4.4100293517112732e-01 3.1954705715179443e-01 + <_> + + 0 -1 310 -1432731787 -1219055176 -42533035 -1126253868 + -2038280772 -55715078 -2000923144 -1936931520 + + -4.3541839718818665e-01 3.1401738524436951e-01 + <_> + + 0 -1 180 232552309 -537305729 -3104297 -67617446 -1211085572 + -20391173 -1968567044 -1392871087 + + -3.7881413102149963e-01 3.5767501592636108e-01 + <_> + + 0 -1 46 -36984309 904630143 823414970 -188744006 1900770270 + 1399711367 -473188378 1969748707 + + -4.0620720386505127e-01 3.2759186625480652e-01 + + <_> + 19 + -1.3998974561691284e+00 + + <_> + + 0 -1 128 -236980233 16777207 -520752904 15793139 -168428203 + 1979187191 -33554947 -251920389 + + -1.7629407346248627e-01 6.5313565731048584e-01 + <_> + + 0 -1 230 -871825409 -580752385 -713042433 -540061189 + 1549092351 -587761733 1607687679 1577014783 + + -3.1553706526756287e-01 4.9262753129005432e-01 + <_> + + 0 -1 79 -545306406 -547422721 474111600 -570360321 -507816 + 1599364180 -11379845 -12845089 + + -3.5872745513916016e-01 4.0607807040214539e-01 + <_> + + 0 -1 123 -252337502 -658267397 7348400 821935103 1377280435 + 47000107 -169347101 939467707 + + -5.1070415973663330e-01 2.8583043813705444e-01 + <_> + + 0 -1 45 645859107 708031411 -168346241 -1330581136 81734679 + 783767351 -45193 -34341517 + + -4.4308465719223022e-01 2.9009637236595154e-01 + <_> + + 0 -1 241 -154214396 268437506 -680474855 864167714 684199820 + 204876327 -52122180 -262209 + + -4.1140288114547729e-01 2.9478433728218079e-01 + <_> + + 0 -1 265 -1365070662 -380938 -1139629826 -35735556 49021040 + 1020949984 219416278 -293 + + -3.9993125200271606e-01 2.9704034328460693e-01 + <_> + + 0 -1 295 217001265 -1346379851 1862205053 -1342447907 + 30277700 -1360008036 -1988349004 -287317952 + + -3.9956006407737732e-01 2.8518736362457275e-01 + <_> + + 0 -1 72 290390927 534606847 534719466 -100668033 1607942091 + 1499327373 -101712435 -187324532 + + -3.0478826165199280e-01 3.7477290630340576e-01 + <_> + + 0 -1 136 -285336459 2110655990 -2013274145 2143051605 + -1124443700 -9506961 -604210584 -1161806512 + + -4.0837058424949646e-01 2.7444043755531311e-01 + <_> + + 0 -1 55 -62093618 -581362746 -141373441 -10940834 -840543755 + -638181765 1859448799 996361303 + + -3.7610772252082825e-01 3.0961802601814270e-01 + <_> + + 0 -1 110 -404233212 134685696 -2016460609 -1379932177 + -540018825 -2163729 806790835 607646519 + + -4.3601146340370178e-01 2.5886246562004089e-01 + <_> + + 0 -1 288 -907025790 1474249959 -806494209 -10763 -283444824 + -364917254 -828244229 -1968201565 + + -2.6032009720802307e-01 4.3652611970901489e-01 + <_> + + 0 -1 229 -18370769 -757680277 788372142 -2072580242 + -273678553 745365463 -134222107 -229310606 + + -3.0938607454299927e-01 3.5719990730285645e-01 + <_> + + 0 -1 14 -1603048865 578088863 -390533121 140676846 + -495489499 -42082971 -4194586 -26017865 + + -3.1977957487106323e-01 3.4310647845268250e-01 + <_> + + 0 -1 249 1643111394 -1211240000 1172894578 -641010466 + 1181712375 -2068614428 1433624934 -671119917 + + -3.3919364213943481e-01 3.4504517912864685e-01 + <_> + + 0 -1 164 1606136599 587595301 -21521312 1079307891 62912316 + 2136471350 -285346140 -201854089 + + -3.1577944755554199e-01 3.4307131171226501e-01 + <_> + + 0 -1 152 785525471 1052180799 1060533999 2120755670 + 1316621908 -270833354 -73736274 -361439920 + + -3.4840318560600281e-01 3.2924604415893555e-01 + <_> + + 0 -1 47 1824524292 1056221828 -268623876 -1615033532 + -2092452655 144493033 502744181 -571159100 + + -4.5537719130516052e-01 2.4885603785514832e-01 + + <_> + 17 + -1.6478537321090698e+00 + + <_> + + 0 -1 99 1126020910 939511791 -137494546 -134218002 928378510 + 667815688 -131090 -21878 + + -1.9173553586006165e-01 6.1490827798843384e-01 + <_> + + 0 -1 277 1066647483 -1078215472 -1078199809 -515 -1078280194 + -1079276888 -1112801281 -1077956952 + + -2.5890102982521057e-01 6.0596489906311035e-01 + <_> + + 0 -1 280 -1347239939 -1078263848 -6291491 -1073954860 + -1883246595 -1075838997 -1346850307 -1393015372 + + -3.5419720411300659e-01 3.9201220870018005e-01 + <_> + + 0 -1 148 -16582767 990936848 -15337711 1024534289 522275741 + 530061615 1786740027 2132761183 + + -4.0790781378746033e-01 3.3604335784912109e-01 + <_> + + 0 -1 33 -1024790785 -33673381 -715534345 -5787889 -721957121 + -17850629 -654587205 -27048190 + + -3.0084383487701416e-01 4.4991242885589600e-01 + <_> + + 0 -1 173 779038223 578498431 -26263553 -1430717601 + 1426011767 1870118397 -726064396 -184550929 + + -4.3469619750976562e-01 2.9388919472694397e-01 + <_> + + 0 -1 207 11804501 -1074249744 2143289343 -1359077380 + 2074886065 -262692 -1075003396 -1431820272 + + -4.1263562440872192e-01 2.8357046842575073e-01 + <_> + + 0 -1 263 -620104768 -83232282 -548406795 -1074143767 + -828717122 -21770245 251698105 68943602 + + -3.8648277521133423e-01 3.0467325448989868e-01 + <_> + + 0 -1 161 1391411790 41936415 -228930992 1892677067 + 1987802112 1480885434 -1362 -219942962 + + -3.7596645951271057e-01 3.1412878632545471e-01 + <_> + + 0 -1 308 248452913 1071429554 -251663105 -538972499 + -1928628395 -1346437645 -1745150348 -33596064 + + -3.9380916953086853e-01 2.8952071070671082e-01 + <_> + + 0 -1 182 626985985 930297719 -286325569 -147866829 + -692197027 2138802865 -117701012 -118164992 + + -3.5818240046501160e-01 3.2363671064376831e-01 + <_> + + 0 -1 60 -1361623937 -1149491078 5825754 508056955 -88210408 + -655077264 -1174209542 -33408130 + + -3.4054177999496460e-01 3.2592311501502991e-01 + <_> + + 0 -1 184 1311738415 -1375274001 1726672390 -829228034 + 2070837764 1208920803 -67308591 -419954764 + + -3.7184986472129822e-01 2.8876912593841553e-01 + <_> + + 0 -1 1 -566173704 -81765536 -328487245 -545227007 8650948 + -1342492099 8915104 -307505157 + + -3.2362362742424011e-01 3.4028744697570801e-01 + <_> + + 0 -1 223 787644405 1052643324 -671622145 1060113936 + -1543669260 -621052931 497506684 -1094759403 + + -3.8580575585365295e-01 2.8625565767288208e-01 + <_> + + 0 -1 90 -754941560 -598092101 -1244290303 281751211 + 1463866633 1153550863 -806946917 38740739 + + -4.4092047214508057e-01 2.5595286488533020e-01 + <_> + + 0 -1 167 184294525 -9037826 -21186597 -1497857980 + -1372058532 -1233225231 -341673474 -1099675796 + + -3.7506091594696045e-01 2.9585087299346924e-01 + + <_> + 21 + -1.4008288383483887e+00 + + <_> + + 0 -1 233 -814746846 -2111111254 -553913104 -2097922 + 2004869959 1141046786 1970763104 -134744334 + + -2.1097929775714874e-01 5.7671958208084106e-01 + <_> + + 0 -1 75 -8396836 -538976473 -16384001 -10879489 -8397857 + -10498599 -45416465 1595899679 + + -3.1942996382713318e-01 4.6969848871231079e-01 + <_> + + 0 -1 4 -824512541 -524299 -344077 -72323247 206048519 + -1409589837 -84975873 -805875917 + + -3.0280569195747375e-01 4.2180880904197693e-01 + <_> + + 0 -1 290 -1086615304 956872912 223108216 496889077 + -1097860099 956429808 1601034749 -538976769 + + -3.5371550917625427e-01 3.6481952667236328e-01 + <_> + + 0 -1 146 -85985781 1914665473 1351604943 269482959 + -118967717 -264571342 -71633409 -1574764609 + + -3.5075160861015320e-01 3.4602758288383484e-01 + <_> + + 0 -1 81 -579450864 489695248 -568994533 -671905287 + 1484394168 -21040594 -1132978498 -4358 + + -3.6514815688133240e-01 3.3418157696723938e-01 + <_> + + 0 -1 300 -1071640576 -1794071852 -589571267 -622299971 + -128680624 -107152175 -1128604712 -93782371 + + -4.3749809265136719e-01 2.3641848564147949e-01 + <_> + + 0 -1 43 1347789474 278788859 1078009887 1450704633 755482275 + -890279806 1601682923 1145430595 + + -4.5889991521835327e-01 2.1458856761455536e-01 + <_> + + 0 -1 58 -67811136 507778012 2090770170 940627838 -547680164 + -564395008 -1507362 -15533189 + + -3.4613710641860962e-01 2.9729354381561279e-01 + <_> + + 0 -1 40 708451453 915939127 2086399799 -1364049961 + -111247856 -278977 -562528515 -1432293672 + + -4.1620507836341858e-01 2.4089127779006958e-01 + <_> + + 0 -1 279 -1423966541 177905074 -199210 -1914114123 + 1966529760 -2068908586 -574294864 -841165576 + + -3.1373840570449829e-01 3.2040333747863770e-01 + <_> + + 0 -1 198 1848585743 -1940984369 1618804030 -285289836 + 1994084869 67912305 -4262128 -303498266 + + -3.6098247766494751e-01 2.7308923006057739e-01 + <_> + + 0 -1 83 -34593 -42134437 83156217 534796439 -206958426 + -542489456 -301270341 -1910021 + + -2.1900075674057007e-01 4.6534782648086548e-01 + <_> + + 0 -1 255 -732498730 808132612 -1694705650 637674514 + -856846932 790002977 -1523128100 -5768257 + + -3.0635869503021240e-01 3.2308223843574524e-01 + <_> + + 0 -1 142 -272658653 -2039881873 -1093759223 -295772198 + 316478038 1219928242 1542411604 -523960875 + + -4.1005435585975647e-01 2.4376337230205536e-01 + <_> + + 0 -1 314 -1886651248 233035768 -579887888 -644481803 + -1924527808 72215888 -813972012 -838860849 + + -3.2710522413253784e-01 3.0177840590476990e-01 + <_> + + 0 -1 109 -626385315 -541893255 -289637249 -2982538 + -285318128 -335644678 -934750724 -1937614 + + -3.0264344811439514e-01 3.4333297610282898e-01 + <_> + + 0 -1 127 -675308008 858262544 -546392130 -86565344 889738476 + 1024209296 -539034113 -17892421 + + -3.0164864659309387e-01 3.2610884308815002e-01 + <_> + + 0 -1 76 289874895 1574889454 356325874 -1257339986 + 2013148111 1523362314 -209587256 -51584276 + + -3.0728715658187866e-01 3.2666257023811340e-01 + <_> + + 0 -1 191 207364212 -1629723097 -69798913 180098791 445713016 + -1342538933 -112443395 -1436022512 + + -4.8653569817543030e-01 2.1469378471374512e-01 + <_> + + 0 -1 316 -1891992271 534502897 -709725931 -1133905467 + -1625325679 -1098169635 -1377993223 -1175556795 + + -3.6775574088096619e-01 2.6944977045059204e-01 + + <_> + 20 + -1.6370692253112793e+00 + + <_> + + 0 -1 246 -544546902 -40378434 1166794751 -553126475 + 1124863438 -6684681 252464271 252663279 + + -1.7677198350429535e-01 5.9283459186553955e-01 + <_> + + 0 -1 105 -1688231254 -136322578 542408738 -167781650 + -284181590 88186882 -74646534 -254480182 + + -4.8250266909599304e-01 3.2293373346328735e-01 + <_> + + 0 -1 291 -1087113223 -1153788752 923893117 -40019499 + -1444151361 -1145394000 520297981 -7610887 + + -2.7269113063812256e-01 4.6762999892234802e-01 + <_> + + 0 -1 163 1431698391 477399807 5291197 215258107 2097218267 + 1070271552 1347764095 1497759739 + + -3.6439743638038635e-01 3.3937779068946838e-01 + <_> + + 0 -1 49 -494878000 -1408572168 -1216184843 -570753839 + -1385631492 -1572929 -37698091 -140075 + + -3.4019106626510620e-01 3.2104432582855225e-01 + <_> + + 0 -1 101 -15196934 2140689563 1546672602 1591347871 + 1544035576 488135152 2142261182 -4259841 + + -3.7342280149459839e-01 2.8317087888717651e-01 + <_> + + 0 -1 195 -357586129 70201151 -292424585 -1468006937 + 1163158101 45494091 -492310284 -184618257 + + -4.2928436398506165e-01 2.4182404577732086e-01 + <_> + + 0 -1 219 -346034385 -1509510400 -590396300 -56691898 + -2013314811 -11148442 -790137804 -17301901 + + -3.2902050018310547e-01 3.1380781531333923e-01 + <_> + + 0 -1 276 51573280 869252567 856020959 2136817673 -1825854798 + 1786292453 1863958011 51070032 + + -4.4989612698554993e-01 2.3105476796627045e-01 + <_> + + 0 -1 239 221945781 -1351824656 -369627303 -1616906768 + 180205816 -1398111810 986511580 -2002860624 + + -3.3374428749084473e-01 3.0387389659881592e-01 + <_> + + 0 -1 88 -12577 1384049145 -1464090918 -265274512 1423314444 + -330608884 -134684970 -95228557 + + -2.9424193501472473e-01 3.4667330980300903e-01 + <_> + + 0 -1 215 -349179217 304152230 -725813534 -44849422 206658671 + 1343674791 1143817582 1414000887 + + -3.5459104180335999e-01 2.8464645147323608e-01 + <_> + + 0 -1 44 2135942447 398828943 961557154 -85264382 -9441329 + 191609019 -135559186 1155988198 + + -3.9276805520057678e-01 2.5532895326614380e-01 + <_> + + 0 -1 322 792354069 -1442292348 -725922817 -1075650752 + -1345299339 -270808291 1585978709 -1363456899 + + -4.0223011374473572e-01 2.3934543132781982e-01 + <_> + + 0 -1 51 -963985190 526195161 -632047017 -13433768 -170216210 + -584509261 -1147462405 2122007633 + + -3.5836115479469299e-01 2.7841308712959290e-01 + <_> + + 0 -1 69 1282640527 -221028405 -1115770991 -1312815327 + 518459295 -5010698 -8421409 -52340448 + + -3.0360385775566101e-01 3.3305782079696655e-01 + <_> + + 0 -1 63 240090463 1543015448 1657994909 1376934782 + 2121953054 -3393448 774963198 -364875945 + + -3.1514179706573486e-01 3.1063860654830933e-01 + <_> + + 0 -1 149 -117441008 272437552 -2011728848 808844177 + -115035003 901066096 -392587048 829815772 + + -4.1897901892662048e-01 2.3548045754432678e-01 + <_> + + 0 -1 41 -285250029 -1342531469 -1337688454 76061301 + 2140621344 -26490526 -230505742 -498673325 + + -3.7328067421913147e-01 2.7277800440788269e-01 + <_> + + 0 -1 186 197109511 113539807 -1663738276 652405614 + 2079664708 -1381909716 -83887277 -340414799 + + -3.5890376567840576e-01 2.7977034449577332e-01 + + <_> + 24 + -1.3530069589614868e+00 + + <_> + + 0 -1 231 -607125512 -203956738 -146407939 -549587593 + 2106032085 -7015967 1296916047 1465901007 + + -1.2551400065422058e-01 6.0037857294082642e-01 + <_> + + 0 -1 126 -12041 289127191 -1961178373 858913587 -452995643 + -573056619 -184946437 811859443 + + -3.1659016013145447e-01 4.0386086702346802e-01 + <_> + + 0 -1 305 -4456453 -1079345488 1601271281 1566430416 + -1145044997 -1363497544 -807547663 -846209539 + + -2.4047850072383881e-01 4.9467754364013672e-01 + <_> + + 0 -1 205 -422843738 730826189 -93007646 -1561338070 + 1156254860 82792447 -359691576 -318767125 + + -4.0942522883415222e-01 2.8118029236793518e-01 + <_> + + 0 -1 130 286242991 1430640951 -1315388758 -5384739 + 1897658847 1435892732 -241122312 -190447622 + + -3.6675310134887695e-01 2.7747273445129395e-01 + <_> + + 0 -1 155 -360711817 1044065557 -202645505 -1078462473 + -554253058 -123796300 -991681292 -117447077 + + -2.2938863933086395e-01 4.3152013421058655e-01 + <_> + + 0 -1 33 -486546689 -38568697 -114385161 -1078244605 + -1398768130 -16859405 -387455605 -95221245 + + -2.5292310118675232e-01 4.0669292211532593e-01 + <_> + + 0 -1 197 -347108861 707787566 -271712714 -286066182 + 1660625669 23327763 -118368650 -16781581 + + -3.2693040370941162e-01 2.9912397265434265e-01 + <_> + + 0 -1 48 44773155 -1400496480 -2013315201 -2130179 1928269391 + 2146108387 1871512017 -2109991 + + -3.1153312325477600e-01 3.0730357766151428e-01 + <_> + + 0 -1 277 817397681 -4651712 -1074593921 -4489223 -1464975366 + -1080350544 1068207931 -1414856608 + + -2.7505692839622498e-01 3.4677764773368835e-01 + <_> + + 0 -1 158 -805311870 -1362548369 -186736224 -220270666 + 1742698308 1147947264 -251792176 -789512618 + + -3.9942753314971924e-01 2.4047489464282990e-01 + <_> + + 0 -1 65 -700036014 -675626240 648044818 -69944464 -389395237 + -215288017 -1719763715 -12588054 + + -3.1749448180198669e-01 3.0149078369140625e-01 + <_> + + 0 -1 319 765664309 -1401170476 -22282241 -1880818860 + -1688316571 -52824373 -1730200112 -889291499 + + -3.5558241605758667e-01 2.6557549834251404e-01 + <_> + + 0 -1 272 -1164201800 -1716289100 -378039852 -1409579788 + -1121338919 -1880520559 932112367 -1869871980 + + -3.6485251784324646e-01 2.5734969973564148e-01 + <_> + + 0 -1 22 -21049601 -25866473 325725 1043995470 1592678894 + -269259937 -971837858 -8913089 + + -2.2092992067337036e-01 4.2716163396835327e-01 + <_> + + 0 -1 138 763233167 2004741991 -277961986 -35997914 897543679 + 1741158903 -50331667 -1578882304 + + -3.0084916949272156e-01 3.0936580896377563e-01 + <_> + + 0 -1 92 66036611 -2133412515 2136683646 -184645734 + 1604280073 202711897 -1379383 -186590399 + + -3.7059250473976135e-01 2.4178710579872131e-01 + <_> + + 0 -1 196 -326382376 361846096 -2045590179 1068964371 + 705563792 -1156488704 1208497115 994048507 + + -3.2299432158470154e-01 2.8366291522979736e-01 + <_> + + 0 -1 70 -412097022 -1568018524 -1342448718 -1253932 + -1260185663 1258275150 -2067820288 -138937659 + + -3.5679051280021667e-01 2.6213440299034119e-01 + <_> + + 0 -1 193 -714615533 270672129 -306258157 -1758339253 + 47808742 -1902768889 -1941903362 -893526249 + + -2.5351437926292419e-01 3.6361116170883179e-01 + <_> + + 0 -1 165 -318796273 1227399022 -1369769360 -675875878 + -344383672 1582766693 -86017024 -344793116 + + -3.1456202268600464e-01 3.0873265862464905e-01 + <_> + + 0 -1 93 -1045815078 -235892117 -571835429 -3460789 + -108525848 -1332172392 -1503517894 -1300229375 + + -3.5038644075393677e-01 2.6677846908569336e-01 + <_> + + 0 -1 15 -1976677263 3726998 -392242219 214976380 -1048834204 + -44384235 -81855380 -1434428367 + + -4.1762107610702515e-01 2.1475161612033844e-01 + <_> + + 0 -1 166 209059956 2146573530 1933758719 -1670893344 + -1206231472 -538281424 -605128624 -88975308 + + -4.3403875827789307e-01 2.1460674703121185e-01 + + <_> + 26 + -1.3850060701370239e+00 + + <_> + + 0 -1 250 1118499839 -796332098 -134253196 -6424581 259721215 + -1671186434 100533499 1170700287 + + -1.3170924782752991e-01 5.9910702705383301e-01 + <_> + + 0 -1 94 1570566140 2106702270 -577478657 -9625925 -36328709 + -75449636 -394325 1071454459 + + -3.8424813747406006e-01 3.6834198236465454e-01 + <_> + + 0 -1 278 -136315975 -1187792752 1568109937 -571788877 + -86048838 -1433673030 -1190563400 -1984968261 + + -2.4970491230487823e-01 4.7245621681213379e-01 + <_> + + 0 -1 155 -25692619 573911103 -1090519553 -1074266633 + -1124204292 -1199619017 -387151619 -1363171157 + + -2.7256563305854797e-01 4.0413850545883179e-01 + <_> + + 0 -1 299 270536720 -82027755 -542052353 -744834006 + -172433515 -36839897 -2048335877 -1356137589 + + -3.7769773602485657e-01 2.3510186374187469e-01 + <_> + + 0 -1 102 133774 1573843455 290464424 -173151905 771865036 + 1430562872 -109382744 -246039832 + + -4.7037139534950256e-01 2.0533446967601776e-01 + <_> + + 0 -1 127 -618460144 -1256386552 -1618575940 1972721552 + 469800920 504635776 -846791686 -69254485 + + -3.5127875208854675e-01 2.5741419196128845e-01 + <_> + + 0 -1 85 150343455 40910711 -1248068641 -1430372421 + -1895949361 -21272033 -331755522 -1431642114 + + -3.7984871864318848e-01 2.3182238638401031e-01 + <_> + + 0 -1 286 -13916067 -237157163 1069283741 -7496371 + -1771992641 -17192227 -1383805025 -2004252467 + + -2.1929037570953369e-01 3.8296228647232056e-01 + <_> + + 0 -1 206 9705301 508957948 -71469059 431911901 2041834229 + -1141023756 -38047748 -1432742364 + + -3.4404903650283813e-01 2.3727993667125702e-01 + <_> + + 0 -1 162 -28187574 1457201967 -1799949806 542855772 + -22592508 347566595 -86051214 -254279713 + + -3.3773353695869446e-01 2.3899486660957336e-01 + <_> + + 0 -1 78 1353317010 -353449217 14955059 233737419 1113314227 + 1272002592 2140215167 200230499 + + -3.5864931344985962e-01 2.1981315314769745e-01 + <_> + + 0 -1 50 -592281584 1487966200 -1782854276 -34165307 + -911392552 -588393496 -86945955 -302569115 + + -2.9026558995246887e-01 2.8104048967361450e-01 + <_> + + 0 -1 301 -14053072 -2064062200 -928567823 -983051523 + 201916593 150423153 -1859132687 -1929383993 + + -3.2115238904953003e-01 2.5486564636230469e-01 + <_> + + 0 -1 79 -607531822 2133030428 1045592120 922799991 + -1958080364 -631876516 -551887109 -116138161 + + -2.5716596841812134e-01 3.1999784708023071e-01 + <_> + + 0 -1 7 -1897370238 2088280021 -27542220 955523029 143789824 + -1732421377 -270311431 -319465097 + + -3.7310892343521118e-01 2.2297158837318420e-01 + <_> + + 0 -1 151 2117994623 -596493511 -42869249 2123389533 + -102873516 -1194255940 -1077870956 -1369933454 + + -3.2065725326538086e-01 2.5838941335678101e-01 + <_> + + 0 -1 141 -402659162 81777018 894353956 -1095917410 + 1470100164 1429538625 -675679616 22405077 + + -3.9470222592353821e-01 2.1365866065025330e-01 + <_> + + 0 -1 306 371408657 -1390197839 -610304075 -1084394735 + 740911518 -1442850385 1025329500 -1085287308 + + -3.5310438275337219e-01 2.2878694534301758e-01 + <_> + + 0 -1 96 1411399848 1607023650 2118667161 2115963630 + 825267416 -1300086616 866705067 1593838595 + + -3.7212049961090088e-01 2.1682462096214294e-01 + <_> + + 0 -1 236 -1023751505 1654647882 654289424 -221611870 + 1142643327 2865238 1353434162 -218116589 + + -3.0895259976387024e-01 2.7360698580741882e-01 + <_> + + 0 -1 25 263714691 -1500250442 -572970029 1029922655 + 461194497 -1384691616 902512981 -831890189 + + -2.8019675612449646e-01 2.8230005502700806e-01 + <_> + + 0 -1 157 -1009275158 703439343 1881063906 1407643120 + 1357622212 1698779727 -175905592 -799737222 + + -3.0597987771034241e-01 2.6828068494796753e-01 + <_> + + 0 -1 24 -655102849 1007864659 -1544094705 -1540313220 + -574699 -47065227 -1091975362 -278732953 + + -2.5672450661659241e-01 3.1667667627334595e-01 + <_> + + 0 -1 103 347621596 1037305260 358617181 753140063 -61713220 + -610393186 -1106322953 -1350956022 + + -3.4445220232009888e-01 2.3471401631832123e-01 + <_> + + 0 -1 36 -923349290 256096042 219291806 -1155987134 + 2086406828 1508909094 -2007541485 1887403703 + + -3.4530115127563477e-01 2.3805907368659973e-01 + + <_> + 25 + -1.2224140167236328e+00 + + <_> + + 0 -1 252 -22088450 -5325374 -33282 -258 12993776 67429556 + 1976988926 2005923583 + + -1.9573126733303070e-01 5.5536717176437378e-01 + <_> + + 0 -1 216 -941896961 288549683 -965260547 1902502507 + 1287981311 723742655 1157582079 1173354239 + + -3.0669313669204712e-01 3.6197665333747864e-01 + <_> + + 0 -1 62 -571494657 -2099490 -25243649 -1082480054 2115633354 + -130996 -329130274 -67419570 + + -2.4500623345375061e-01 4.3682980537414551e-01 + <_> + + 0 -1 19 -704647185 2113917365 -428522838 -141168226 + 2123362255 2006664827 -254348594 1459088068 + + -3.4159252047538757e-01 2.9353541135787964e-01 + <_> + + 0 -1 285 -138414285 -168045645 -550635909 -240708569 + -36728913 -33554641 -890270582 -2069142366 + + -2.8817924857139587e-01 3.4106674790382385e-01 + <_> + + 0 -1 77 -220544510 -184926009 2147213135 -209757985 + -1177821558 -139002180 845151099 -8701317 + + -2.2831186652183533e-01 3.8085940480232239e-01 + <_> + + 0 -1 256 12976195 569051735 -1044464777 -2131832853 + -1863693873 -889525281 -1060633090 -1024468017 + + -3.4035223722457886e-01 2.4870637059211731e-01 + <_> + + 0 -1 225 243431285 -1342397538 -1074439183 -198404 + -1147339787 -1950366979 -1176535299 -1346857836 + + -2.9916274547576904e-01 2.7878564596176147e-01 + <_> + + 0 -1 188 -389107962 -1496674445 -1433293856 1650520822 + -808004780 -340166498 -270808076 -327882656 + + -3.6523097753524780e-01 2.3002453148365021e-01 + <_> + + 0 -1 249 -1561660693 -1964116758 -433068176 -674252332 + 76465114 -86789644 1441781719 -167788045 + + -2.6452550292015076e-01 3.1857562065124512e-01 + <_> + + 0 -1 30 83758542 1352905533 -25477260 888412977 1174342621 + -581240613 -1877419 954559493 + + -3.9430552721023560e-01 2.1380217373371124e-01 + <_> + + 0 -1 291 1060338993 -1618339632 1411411797 -1111518927 + 1038801631 -1171216200 431569585 -1627714192 + + -3.1174781918525696e-01 2.5848281383514404e-01 + <_> + + 0 -1 174 1272433155 241160959 -187054076 -1428167714 + 1656705620 178680903 -188744156 -92279086 + + -3.5104271769523621e-01 2.4124261736869812e-01 + <_> + + 0 -1 100 276007552 1448970891 1624277552 1433388541 + -144262781 203467264 -747113541 1187367471 + + -4.3640381097793579e-01 2.0373314619064331e-01 + <_> + + 0 -1 265 514492090 -1084506382 802327294 -574652997 + -1951495942 -1115800400 -1734105369 -745080833 + + -2.6869311928749084e-01 3.1262946128845215e-01 + <_> + + 0 -1 238 975568369 -1078429260 -1073778819 -1246039248 + -566763547 -574710393 -1879731715 -1363518280 + + -2.5506082177162170e-01 3.2470330595970154e-01 + <_> + + 0 -1 116 -197130578 -69435407 25570034 -1282381057 + -736477475 1078203406 1072176808 -224107914 + + -3.3984503149986267e-01 2.3857665061950684e-01 + <_> + + 0 -1 170 2006936207 2046780255 -906124674 -571018634 + 465548283 1995414095 -469838166 -53152636 + + -2.3337669670581818e-01 3.4638467431068420e-01 + <_> + + 0 -1 261 -1993607757 -1984171376 -1964620068 -1377319864 + -878651982 2100351409 -540935193 -846344047 + + -2.5745591521263123e-01 3.1530505418777466e-01 + <_> + + 0 -1 129 -585119904 520350737 -1602237728 387020659 + -316697172 -809628610 -341521253 1937239575 + + -3.0576938390731812e-01 2.6786401867866516e-01 + <_> + + 0 -1 303 -48760835 -1382112048 1192391029 185356020 + 783760374 -1402171184 959454513 -1431708544 + + -2.8466665744781494e-01 3.0237734317779541e-01 + <_> + + 0 -1 321 700150833 -1366030659 -590225483 -1393138060 + -1364311531 -1142207587 2140558729 -1370849424 + + -3.7198981642723083e-01 2.3002536594867706e-01 + <_> + + 0 -1 228 -1054166 -201341212 1923367016 1916986952 + 1992519431 1213361995 1174402160 -1068174746 + + -3.4979847073554993e-01 2.4561876058578491e-01 + <_> + + 0 -1 106 -1907696549 -268565315 -1342514689 336742770 + -1439790339 -1301623122 -1342275841 -1440064298 + + -2.6577013731002808e-01 3.1544610857963562e-01 + <_> + + 0 -1 210 -257776636 1915752044 -1649103180 -1095126373 + 1422147805 210473965 2022068463 1660109363 + + -3.7758591771125793e-01 2.2004681825637817e-01 + + <_> + 28 + -1.3550500869750977e+00 + + <_> + + 0 -1 273 1595195384 1608363967 1595766713 -572674083 + 1226391547 -44180227 2111155631 531574527 + + -1.6430117189884186e-01 5.4418802261352539e-01 + <_> + + 0 -1 39 -5377 -57601 538639103 -347397 -17301286 -4259105 + -79502593 -77380901 + + -1.8002209067344666e-01 5.2194720506668091e-01 + <_> + + 0 -1 177 1566441471 2103287797 492075325 500554077 + 1998422011 -155652 192249721 1565917179 + + -2.7448469400405884e-01 3.6767318844795227e-01 + <_> + + 0 -1 3 -524550921 -1669383407 -574620225 -33590459 143458441 + 256708119 -805314577 -6324385 + + -2.3465685546398163e-01 4.0192386507987976e-01 + <_> + + 0 -1 71 -846691120 1439476212 -690689 -2237091 -67570179 + -36374787 -2105923 -143907 + + -2.7146762609481812e-01 3.2002952694892883e-01 + <_> + + 0 -1 294 263139089 -581452515 2010774399 -2106799 477955253 + -72357417 267875276 -1097712 + + -3.5161617398262024e-01 2.3248630762100220e-01 + <_> + + 0 -1 302 -15214854 -1884686344 167600312 -581052707 37857013 + 202028220 1305828853 -840957953 + + -2.6214873790740967e-01 3.0466583371162415e-01 + <_> + + 0 -1 169 613396271 2003697295 1738141229 -35000540 + 2147446463 2131993840 -10096690 1690603136 + + -3.2117179036140442e-01 2.4732810258865356e-01 + <_> + + 0 -1 281 -1355025965 -1961980240 -671219723 -283264688 + -1936837383 -1952736320 -908474131 -875701004 + + -2.4713008105754852e-01 3.1776627898216248e-01 + <_> + + 0 -1 232 -894441054 -1880167002 -853281294 -338827028 + 1348301603 877440640 1936192066 -135400158 + + -3.2655048370361328e-01 2.4388861656188965e-01 + <_> + + 0 -1 288 -553260894 -155221559 -13927175 -570440513 + -23332102 -93644167 -1079190789 -1431330575 + + -2.4785453081130981e-01 3.1448525190353394e-01 + <_> + + 0 -1 190 672423253 -570534469 -174826505 -1074210146 + -1158800264 -67208458 802954712 -1079507880 + + -3.1213754415512085e-01 2.4356111884117126e-01 + <_> + + 0 -1 120 -656932646 -651487779 -956164148 2064599515 + -136440708 -588512112 -1232981444 -1979159765 + + -3.0449146032333374e-01 2.5301957130432129e-01 + <_> + + 0 -1 243 1649084931 672964650 -1105808049 713205535 + 2036285460 -666148121 -55162040 -18875393 + + -3.4271252155303955e-01 2.1502359211444855e-01 + <_> + + 0 -1 11 -152656190 868356183 -501591426 -201146046 + -546953661 1982915527 -759837225 -751304729 + + -3.6129125952720642e-01 2.0629832148551941e-01 + <_> + + 0 -1 107 -537765384 1060665394 2014012895 -1179616664 + -22202433 -1074072677 -147975202 -1147076845 + + -2.9889339208602905e-01 2.5862032175064087e-01 + <_> + + 0 -1 199 -328257785 -858932225 -530764942 -826874930 + -82742922 -1671853892 -218380796 -169018736 + + -3.1055119633674622e-01 2.3958165943622589e-01 + <_> + + 0 -1 154 494120195 870143859 -1647046746 -36192340 + 2139319279 803383587 -332148852 -175859072 + + -2.8900969028472900e-01 2.5575104355812073e-01 + <_> + + 0 -1 282 -811560420 827561735 -12914945 -80101505 + -1361111928 -1185616587 -1407676420 -16973965 + + -2.4221476912498474e-01 3.2213848829269409e-01 + <_> + + 0 -1 28 -1807515438 -1923894982 -1525713421 -149168351 + 240714426 -1418935881 419048443 426584671 + + -3.4787160158157349e-01 2.1293328702449799e-01 + <_> + + 0 -1 147 -67165120 453708801 -1303483468 895300097 + 1246742261 -70442158 -982536969 1920335427 + + -3.4275433421134949e-01 2.1697193384170532e-01 + <_> + + 0 -1 84 1234906919 2103279727 -1846517728 -34739694 + 2067706763 1171293376 -104744214 -776609560 + + -3.1936296820640564e-01 2.2989478707313538e-01 + <_> + + 0 -1 203 -148968905 1008481713 788164595 781877169 240125438 + -1348980802 1087673598 -1963666822 + + -2.6340115070343018e-01 2.8225165605545044e-01 + <_> + + 0 -1 292 1837891345 -1365117008 931935797 254075285 + 1304075707 781882527 284906609 -1998401051 + + -3.0138608813285828e-01 2.5070127844810486e-01 + <_> + + 0 -1 31 -2141011328 549559667 -576755279 -1989065165 + -1471060704 -1108160073 -825160949 47662087 + + -4.3011611700057983e-01 1.7580580711364746e-01 + <_> + + 0 -1 244 -747375089 -747702293 -219779522 1890186598 + -335684346 1718484847 1643894306 -206110753 + + -2.3109740018844604e-01 3.2786485552787781e-01 + <_> + + 0 -1 26 -1784488175 -36553927 -1031147589 -369559501 + 125374437 -1648822347 8863969 -1498451769 + + -2.3490820825099945e-01 3.1162357330322266e-01 + <_> + + 0 -1 259 -1071476830 -1095595629 -1920078129 -1444498449 + 810365109 -21630982 -290653569 -392299569 + + -2.5611433386802673e-01 2.9074308276176453e-01 + + <_> + 30 + -1.3058989048004150e+00 + + <_> + + 0 -1 262 -270610434 -134359075 -811399758 -681603633 + -286489698 -45513244 -1344862513 227476639 + + -1.0025274008512497e-01 5.5719470977783203e-01 + <_> + + 0 -1 104 -2097187 353744664 -1074283233 962461525 -17042946 + 2132074456 -185611768 173014862 + + -2.9774430394172668e-01 3.4969726204872131e-01 + <_> + + 0 -1 192 -201591309 322053939 -66051 -1150042305 -1967374172 + 720309079 -1929450275 -9437249 + + -2.2600507736206055e-01 3.8218078017234802e-01 + <_> + + 0 -1 290 -1690568520 1023449340 21823732 -1646306859 + -661660161 529059241 -845261571 -536871425 + + -2.8739321231842041e-01 2.8658962249755859e-01 + <_> + + 0 -1 253 -894497022 101363498 -1468636304 174491490 + 1306476909 100485583 -17240860 -50397265 + + -4.0346711874008179e-01 1.7318421602249146e-01 + <_> + + 0 -1 83 -318927617 2139044223 -1908122241 779509119 + -1159705360 -13892400 239132095 -1357193897 + + -2.4370998144149780e-01 3.1787887215614319e-01 + <_> + + 0 -1 240 -1372487695 -1464797736 -608961161 -539484303 + -1347732485 -1107560232 -1770177028 -1397928683 + + -2.9030051827430725e-01 2.7010890841484070e-01 + <_> + + 0 -1 162 -77617562 1723582851 -388105926 10740970 2075870464 + 2001443802 -264144166 1912602619 + + -3.6183983087539673e-01 2.2234350442886353e-01 + <_> + + 0 -1 209 1737993987 575323583 570599958 -1593901402 + -537396969 800103342 -218367233 -210440396 + + -3.0187138915061951e-01 2.5218242406845093e-01 + <_> + + 0 -1 115 -3692022 -33948459 -1481085416 -169476374 + -243802706 1464294676 -138677344 -135135404 + + -2.6393750309944153e-01 2.8237256407737732e-01 + <_> + + 0 -1 38 652099711 -1564843973 104523854 704662580 2126923816 + -548581264 -351211922 -63803885 + + -3.4199714660644531e-01 2.2430206835269928e-01 + <_> + + 0 -1 42 -1969279581 -1481414863 -1376914049 -1163909120 + 207957301 -1456248013 -347640417 -358126493 + + -3.2226172089576721e-01 2.3534862697124481e-01 + <_> + + 0 -1 97 -721363152 486579872 1882454289 1434257045 + 1611566751 1289487287 996045691 1005540351 + + -3.4691241383552551e-01 2.1465319395065308e-01 + <_> + + 0 -1 146 -613203450 1931612930 -221388928 2357067 -95798262 + -1633004965 -1206355046 -1305281858 + + -3.5142555832862854e-01 2.2679552435874939e-01 + <_> + + 0 -1 53 726466699 -783429313 -1320406822 -3624870 1498638047 + 293610405 -545215571 -171145013 + + -2.8053104877471924e-01 2.5749957561492920e-01 + <_> + + 0 -1 258 -96033630 1940556686 -497037664 -252647058 + 703265613 1079474790 -142103350 1089273046 + + -3.5805869102478027e-01 1.9770637154579163e-01 + <_> + + 0 -1 29 801058311 -1581801242 219502516 -808469412 264711475 + -2031926289 805127380 -840973936 + + -3.1421071290969849e-01 2.3023897409439087e-01 + <_> + + 0 -1 172 -431184122 -2146638145 -899408814 -320144615 + -413827291 -936008940 -1376277757 -856306909 + + -3.3034646511077881e-01 2.2980070114135742e-01 + <_> + + 0 -1 296 -1934886608 -1103642657 -1616127841 2141970916 + 12401112 -606080117 -28750412 -975218195 + + -3.0468633770942688e-01 2.4846823513507843e-01 + <_> + + 0 -1 137 1828669055 -890173322 1056472031 1383623540 + -356497848 -275776488 -319784148 -45023438 + + -2.7311590313911438e-01 2.6826277375221252e-01 + <_> + + 0 -1 9 1255206898 -1667881507 -10989766 54528930 1868912080 + 1497103356 -1096470729 195839511 + + -3.6629125475883484e-01 2.0582148432731628e-01 + <_> + + 0 -1 221 -374953039 110804926 -627248196 1059075576 + -271092824 -1449292838 -306539616 -1950680360 + + -2.7446079254150391e-01 2.6614543795585632e-01 + <_> + + 0 -1 77 1079656456 1450316376 -44560086 -86675865 821811859 + -203750610 1644870683 862142514 + + -4.1938367486000061e-01 1.8087086081504822e-01 + <_> + + 0 -1 0 -290783281 -303164749 -1470447878 -1487432078 + 916915428 -88877852 1774133328 -992512778 + + -2.6362594962120056e-01 2.8109744191169739e-01 + <_> + + 0 -1 234 -756036050 839304974 -287378334 -278205702 + 1541888379 252445922 1089229910 1534066638 + + -3.4634828567504883e-01 2.1581955254077911e-01 + <_> + + 0 -1 276 855880616 863230344 1428139679 995299387 + -1190999286 -2031656420 -1089224709 393285777 + + -3.6159241199493408e-01 2.0310276746749878e-01 + <_> + + 0 -1 311 -1512047005 -894771811 -1683823949 -598542090 + 1995129382 -1899059137 1498537061 -838863787 + + -2.8326958417892456e-01 2.6241222023963928e-01 + <_> + + 0 -1 315 -1885077515 -1147345968 765009497 190991824 + -1880224543 -1444116296 170661041 -1880099595 + + -2.7807191014289856e-01 2.6050725579261780e-01 + <_> + + 0 -1 135 -678450904 253998378 1239066322 -181932174 + 1262701314 1057893524 -413531308 -638649353 + + -3.3198201656341553e-01 2.2709015011787415e-01 + <_> + + 0 -1 34 -581179905 -1848462196 1945061311 -5371768 + -323621137 -1263209313 1589634526 -1983639545 + + -2.1172577142715454e-01 3.3727011084556580e-01 + + <_> + 28 + -1.5291974544525146e+00 + + <_> + + 0 -1 118 1460139419 453084545 822327865 822292283 352929169 + 417272919 135004047 924844031 + + -8.1135094165802002e-02 5.6568491458892822e-01 + <_> + + 0 -1 80 -715128994 1934810962 -672407682 -201597282 + -35692578 809635668 -268435489 2147483551 + + -3.0913391709327698e-01 3.3743736147880554e-01 + <_> + + 0 -1 247 1122941951 1555757531 -694977567 -540019318 + 137302463 470541003 1136607934 1306525407 + + -3.1006491184234619e-01 3.1824222207069397e-01 + <_> + + 0 -1 260 -720124792 -536901237 1570357663 -1650861895 + -552270619 -68301133 1302024703 79667599 + + -3.3839857578277588e-01 2.5523734092712402e-01 + <_> + + 0 -1 17 -8193062 -6097966 -1548746898 -379066394 143198346 + -645407521 12583050 -472923985 + + -2.4971115589141846e-01 3.2822373509407043e-01 + <_> + + 0 -1 237 -825768185 724487963 -390073602 -330379374 + 1107247415 83879931 -993921692 -452988933 + + -3.0709245800971985e-01 2.5717419385910034e-01 + <_> + + 0 -1 58 -824653104 303085300 -1502438950 676395390 + 1255626832 486565974 -815202689 -79167553 + + -3.6309060454368591e-01 2.1628698706626892e-01 + <_> + + 0 -1 67 1465723394 105884335 67529631 1199566589 -1622165645 + 1811892772 1549268950 1652352758 + + -4.2343840003013611e-01 1.6860494017601013e-01 + <_> + + 0 -1 185 148088327 717657079 -1158484046 -2098532510 + 1870465024 1417516115 -834205 -218760204 + + -3.6911985278129578e-01 2.0653814077377319e-01 + <_> + + 0 -1 300 -461242368 1477725653 -1215242820 -90145126 + 1009057732 -704735 -1141055496 -1162708353 + + -3.3464974164962769e-01 2.3336097598075867e-01 + <_> + + 0 -1 293 -1423237359 -1789315824 -574109707 -1107438219 + -1363603597 -872691976 -1657075536 -1933638287 + + -3.1273457407951355e-01 2.2250117361545563e-01 + <_> + + 0 -1 194 -144708057 1699343849 -1838157252 -177211402 + -159396385 625472608 -135793676 -521076854 + + -2.3151670396327972e-01 3.2311838865280151e-01 + <_> + + 0 -1 168 -1931608011 913325143 -171254849 266627963 + -2035524252 -69309961 -81258276 -98535933 + + -2.9178491234779358e-01 2.4896363914012909e-01 + <_> + + 0 -1 91 1087671428 82841500 -823391220 -1623396996 + -102804027 1314177621 -1141613796 -1074263479 + + -3.8546600937843323e-01 1.7542295157909393e-01 + <_> + + 0 -1 159 -933240178 -1878596882 1715175556 -1194366298 + 411894039 268454833 -470873276 719547915 + + -3.2228979468345642e-01 2.1430800855159760e-01 + <_> + + 0 -1 220 -939528673 -1404420134 -369182724 1002367802 + 15711733 -1410089155 1960793528 -2001995142 + + -2.3454265296459198e-01 3.0028054118156433e-01 + <_> + + 0 -1 113 536155908 470828324 -1369532674 -1364256937 + 965751798 -35376543 78916068 750088039 + + -4.0617641806602478e-01 1.7761451005935669e-01 + <_> + + 0 -1 35 -2071666137 -5603018 -1985288769 -1434200 1335921899 + -1427144213 -1685518963 -1157538765 + + -2.4697369337081909e-01 2.9498186707496643e-01 + <_> + + 0 -1 229 -288895194 586300718 -1428684760 -123278042 + -121959099 946274053 -1125681616 1348531058 + + -4.4196075201034546e-01 1.6939437389373779e-01 + <_> + + 0 -1 21 -1431908781 2021291639 -1130434561 980837616 + 575372375 -335353565 -1127443082 -8913481 + + -2.6150795817375183e-01 2.7675113081932068e-01 + <_> + + 0 -1 68 -1163937995 319737271 1308060341 -1120611591 + 215961812 -849912353 -825672464 -121636649 + + -2.0028464496135712e-01 3.5346552729606628e-01 + <_> + + 0 -1 112 -1550874873 68414247 420172119 -1144260794 + -508579405 -134226281 -772565676 -204480722 + + -2.3316873610019684e-01 3.1222426891326904e-01 + <_> + + 0 -1 218 -541341454 531709016 -1735251873 1326185481 + -1933801064 801776562 1154066423 1474264822 + + -2.6953682303428650e-01 2.8109839558601379e-01 + <_> + + 0 -1 181 1280835701 -19635873 -1961789445 -282569314 + 2036092788 -1093054601 -151512323 -1347805666 + + -2.9192847013473511e-01 2.4838224053382874e-01 + <_> + + 0 -1 95 -311496552 764872328 -498934241 504728371 + -1669213988 -1084285404 -22094113 977657810 + + -3.2798394560813904e-01 2.1226845681667328e-01 + <_> + + 0 -1 309 -830243037 -455709770 -1109557600 -394303915 + 1283690960 229296318 285572161 -1936864027 + + -2.9578369855880737e-01 2.4679656326770782e-01 + <_> + + 0 -1 202 -353374409 -1910657629 -153750156 -291312600 + -824232155 -1323582188 -1830135484 -1029119357 + + -3.0753603577613831e-01 2.2499974071979523e-01 + <_> + + 0 -1 150 1861152279 336385887 -1598237261 1532541780 + 717032533 845016530 -1129812228 -567126192 + + -2.7896767854690552e-01 2.5912684202194214e-01 + + <_> + 32 + -1.3275781869888306e+00 + + <_> + + 0 -1 235 -9764865 -604078086 -173773889 -2987398 1279545343 + -557388648 1149200335 1195863143 + + -2.8027681633830070e-02 5.9074550867080688e-01 + <_> + + 0 -1 55 -715992866 -553046580 -170277985 -572962233 + -202911505 -562080269 -271361 2136426523 + + -2.9094350337982178e-01 3.2474684715270996e-01 + <_> + + 0 -1 2 -285213773 -97321424 -537973381 -1342251019 249102355 + 186786323 -1879110913 -269489669 + + -2.4952219426631927e-01 3.3645749092102051e-01 + <_> + + 0 -1 274 -5251811 -46589657 -577170147 -1649982203 -147523 + -67650657 -307360312 -1945170545 + + -2.2803187370300293e-01 3.6403229832649231e-01 + <_> + + 0 -1 132 1587350780 -6418628 -1073864867 -604037841 + -21053701 -1195406672 784076557 -1342501334 + + -2.9213908314704895e-01 2.7659067511558533e-01 + <_> + + 0 -1 176 -826544217 -1431112397 -488065488 540212786 + -722778748 1157429871 -270294508 -520884270 + + -3.5402128100395203e-01 2.1517892181873322e-01 + <_> + + 0 -1 87 712975879 79833691 -1361412946 686460060 -691335585 + -125978095 -285512546 -1430258133 + + -3.1391125917434692e-01 2.2734560072422028e-01 + <_> + + 0 -1 200 -976172866 286760680 6735455 198928110 1074026973 + 990905122 10809743 255401983 + + -3.5261881351470947e-01 2.0989060401916504e-01 + <_> + + 0 -1 224 774125429 -1154154632 -439675595 -1111523364 + 1012643517 -1454645 798207228 -1128575640 + + -2.6199585199356079e-01 2.7558091282844543e-01 + <_> + + 0 -1 251 -487657822 48661756 -659241758 -135899942 + 1153834238 10993310 1170301815 1424455655 + + -4.2886912822723389e-01 1.5836857259273529e-01 + <_> + + 0 -1 61 721311231 -1653716997 -1990311447 531501487 + -1965404323 -67478251 171464059 184576600 + + -3.8873490691184998e-01 1.7470200359821320e-01 + <_> + + 0 -1 57 327418278 390873324 -1341550100 -1277569843 + 890828715 1352696428 762946218 871965384 + + -4.1405329108238220e-01 1.7622730135917664e-01 + <_> + + 0 -1 313 1356549140 -1631210850 -1129431843 -1204505275 + -93539215 -1074227267 -386080853 -84902083 + + -2.7681437134742737e-01 2.4316167831420898e-01 + <_> + + 0 -1 157 -488643058 180875078 -329274718 -236520514 + -1068514035 1145270019 1940253924 1625680036 + + -3.7754905223846436e-01 1.7737720906734467e-01 + <_> + + 0 -1 318 1568653099 -1486684233 -270730127 -320215680 + -1480112719 -1448552587 444420880 -859837569 + + -2.4140998721122742e-01 2.7932175993919373e-01 + <_> + + 0 -1 189 -17905025 1950769147 -402672769 2131932059 + 251095909 -1377736845 -268624424 1935896624 + + -2.4894605576992035e-01 2.6565098762512207e-01 + <_> + + 0 -1 56 -229980658 1379962893 -378530289 -1286386082 + 541532620 -136587009 1094085135 657713951 + + -2.9520252346992493e-01 2.2449728846549988e-01 + <_> + + 0 -1 271 -383212128 -6160449 -283244184 -1365334076 + 762609077 1768025015 -304497187 -1344499269 + + -2.8447866439819336e-01 2.4520753324031830e-01 + <_> + + 0 -1 212 -823677149 33812366 63268002 -1196492664 759909893 + 73716507 -306223978 -151718043 + + -3.2939437031745911e-01 2.0377136766910553e-01 + <_> + + 0 -1 312 -1374019853 713820810 -669067463 -2043769806 + -847767619 -1963069954 1575449037 -450464140 + + -3.0366918444633484e-01 2.2024095058441162e-01 + <_> + + 0 -1 114 -470316922 717621094 -923928028 -172110089 + -175398463 2009855399 -194461440 -243275802 + + -2.6190644502639771e-01 2.6647549867630005e-01 + <_> + + 0 -1 140 1951769299 1434447053 -1336849665 -721425681 + -78677193 -2902011 2045245095 -24300714 + + -2.2465880215167999e-01 3.1657159328460693e-01 + <_> + + 0 -1 267 -861210968 688568240 -1004941864 -35890713 + -662335344 8503434 1128813796 1162868189 + + -4.0748140215873718e-01 1.7012281715869904e-01 + <_> + + 0 -1 8 1909956778 -958730002 73759065 117326543 -170462666 + -1638796928 -144999309 1180628626 + + -3.5050147771835327e-01 1.8371912837028503e-01 + <_> + + 0 -1 156 -1007695481 -1609761269 -218186094 -1297941718 + 1501545350 1348355905 -785383567 -535441850 + + -2.8428241610527039e-01 2.3429898917675018e-01 + <_> + + 0 -1 277 -1088815371 1060734832 -4223497 1069000375 + -1138325508 -23580996 -1751106129 -1447097814 + + -2.0420564711093903e-01 3.2137596607208252e-01 + <_> + + 0 -1 10 1861672606 -668397946 1208024407 1141008467 + 793079834 440603748 -705639574 -48042237 + + -2.7496239542961121e-01 2.4548499286174774e-01 + <_> + + 0 -1 283 -992769979 767790999 -48337487 2140880143 215229748 + 418870965 -320966916 1188940671 + + -2.7034837007522583e-01 2.4777430295944214e-01 + <_> + + 0 -1 254 -1532809423 -1493812843 -1351098395 -172312296 + -515160205 -1498547284 268291320 -1426238432 + + -2.8834709525108337e-01 2.2686660289764404e-01 + <_> + + 0 -1 298 -3221657 908227842 -305164460 942829106 -357061387 + -1565722789 -9463718 -360710886 + + -2.2364138066768646e-01 3.1509658694267273e-01 + <_> + + 0 -1 93 -735960950 -170126554 1909113855 -23709394 + -1542321238 -737632549 -361625941 867181313 + + -3.6416807770729065e-01 1.8943277001380920e-01 + <_> + + 0 -1 297 -1427114189 -1498618581 -224896028 -1392720912 + -1096677881 -972078302 -136092556 -1000345005 + + -3.1630918383598328e-01 2.1302369236946106e-01 + + <_> + 36 + -1.3241410255432129e+00 + + <_> + + 0 -1 264 -1886982258 -671648799 -570864297 -606221228 + -1899852152 -3292975 236208719 1600077909 + + -7.9810082912445068e-02 5.2391374111175537e-01 + <_> + + 0 -1 226 -85990657 570624531 -67109121 992976191 -386251554 + -1965159927 -83923475 -1048581 + + -1.8287384510040283e-01 4.4005623459815979e-01 + <_> + + 0 -1 278 -37758029 -1146357328 -206212751 -572669447 + -3147333 -1147409733 -67110471 -1714697285 + + -2.0388080179691315e-01 4.2895537614822388e-01 + <_> + + 0 -1 145 -183247173 1023475216 1027163441 1527839249 + 1017224859 1738217629 1060840379 1065315199 + + -3.3740916848182678e-01 2.1529236435890198e-01 + <_> + + 0 -1 103 481318143 -134278060 -1749526563 -1078064995 + -1372435270 -1162474278 -358945793 -1431173974 + + -2.8765675425529480e-01 2.5110965967178345e-01 + <_> + + 0 -1 268 -805831759 -302189077 -591401807 -305135631 + 144606625 -1936723969 -992408563 -855769927 + + -2.2018201649188995e-01 3.1721305847167969e-01 + <_> + + 0 -1 20 -534756686 1380106992 -2462279 -33757488 28591869 + -456875269 -1610624779 -1051657 + + -2.6303508877754211e-01 2.5412750244140625e-01 + <_> + + 0 -1 175 1342137858 36560521 -895533800 683603905 1263879488 + 1146407324 -1450126 -537788681 + + -3.6383235454559326e-01 1.9057570397853851e-01 + <_> + + 0 -1 66 1340125183 -134742145 -692979981 -1214109056 + 1289101223 -4839633 -21061633 -369409502 + + -2.0452670753002167e-01 3.3919993042945862e-01 + <_> + + 0 -1 269 193720319 100840569 -303833102 763156184 978053077 + 531299573 -839056136 -1929622308 + + -2.7057421207427979e-01 2.3806059360504150e-01 + <_> + + 0 -1 73 1437966890 -129122561 1958795834 1556596447 + 1598142386 1074702522 -272384141 1205144459 + + -3.8338547945022583e-01 1.6122914850711823e-01 + <_> + + 0 -1 171 1115680527 115249619 895027446 -92284851 1599078213 + 1735769988 -537445018 1689910980 + + -3.6433032155036926e-01 1.7980493605136871e-01 + <_> + + 0 -1 144 1900011604 2069139451 1149891166 -1061030506 + 1967646922 -937402003 -1292100642 838974267 + + -3.2297107577323914e-01 1.9990013539791107e-01 + <_> + + 0 -1 86 1216302162 1437731410 -1922152432 -586510344 + -937599750 1065827099 -621007040 -86024589 + + -2.9406809806823730e-01 2.1769714355468750e-01 + <_> + + 0 -1 288 34597026 -688274366 1187213567 -671108889 + -1508901182 -1308638469 -559091031 247438496 + + -3.2822206616401672e-01 1.8776336312294006e-01 + <_> + + 0 -1 207 103046517 133606652 1733190463 -1346628911 + -1148684048 -22091807 901613945 -1460139888 + + -3.3780130743980408e-01 1.9073766469955444e-01 + <_> + + 0 -1 111 -746085629 -676994367 1095924655 -1122388257 + -212397823 -202506293 -205057719 -208672818 + + -1.8210665881633759e-01 3.4192490577697754e-01 + <_> + + 0 -1 74 -425549783 -371579759 -351371857 -575060349 + -1214609473 -88295489 419684031 -1624088569 + + -2.2647747397422791e-01 2.7878209948539734e-01 + <_> + + 0 -1 208 -894491986 -219288836 1075036258 -1764754717 + -573582558 -1807733298 1383817634 -196806592 + + -2.9377350211143494e-01 2.1309736371040344e-01 + <_> + + 0 -1 201 -2106874097 -931096794 1687396770 -828052004 + 2015982962 -126682795 -294764796 -323961156 + + -3.2405611872673035e-01 1.9604462385177612e-01 + <_> + + 0 -1 222 -2042653379 1051606960 500611353 1069291288 + -1453967943 -1919900749 -547038872 -1414655812 + + -2.6115354895591736e-01 2.3542492091655731e-01 + <_> + + 0 -1 314 -588537600 -844176924 1464154596 -637687780 + 487338116 68063409 -1978163723 -840968737 + + -2.7114504575729370e-01 2.3290830850601196e-01 + <_> + + 0 -1 317 120290097 -1288032431 1651243885 -76200631 + -2068365766 -1346655489 246316733 -1108265899 + + -3.0526432394981384e-01 2.0446150004863739e-01 + <_> + + 0 -1 16 -822121865 -768454985 -352395443 -367512593 + -1091080379 -202815919 -279024202 -28119438 + + -2.4680423736572266e-01 2.5303974747657776e-01 + <_> + + 0 -1 39 -624497410 423430210 168884479 707847256 -901496725 + 2133000198 -1135412149 1936933458 + + -3.1653416156768799e-01 2.0023956894874573e-01 + <_> + + 0 -1 242 1650942474 1345050478 886355088 1168828219 + 1112207884 1231876612 1550108076 1951460330 + + -3.2898175716400146e-01 1.8093948066234589e-01 + <_> + + 0 -1 124 369300756 891056133 -1916674564 -1374783349 + 996154237 -1145226207 -5607004 744775764 + + -3.2225444912910461e-01 1.9573701918125153e-01 + <_> + + 0 -1 211 205577554 1071184148 -1263948549 1998946051 + 1260935961 -304903199 -606843718 1677159567 + + -3.0931469798088074e-01 2.0338173210620880e-01 + <_> + + 0 -1 143 -591418226 177508317 -1342069760 -4867939 + 1927953629 272683209 -1222155904 1886512754 + + -3.4405741095542908e-01 1.8495233356952667e-01 + <_> + + 0 -1 265 -21049686 -28131359 1073478397 -34340880 + -2075882246 -1093124168 -64807690 -1243108611 + + -2.2883313894271851e-01 2.9109308123588562e-01 + <_> + + 0 -1 307 781346419 639805680 -546181353 -1174989674 + -1555551183 -893031525 -2006836811 -1392561707 + + -3.0891278386116028e-01 2.1537151932716370e-01 + <_> + + 0 -1 134 -26563529 576995058 1442217478 -1427177744 + -68769859 -1241776649 -424779152 -285805586 + + -2.3855516314506531e-01 2.6137462258338928e-01 + <_> + + 0 -1 178 -491860352 1783772447 -1761018371 989361018 + 2037451840 -988741302 2128769468 1865931536 + + -3.3605426549911499e-01 1.9781108200550079e-01 + <_> + + 0 -1 59 -1359078146 -21349537 1081098827 794979703 147593312 + -343136234 308281456 -1121813221 + + -3.4179690480232239e-01 1.8693566322326660e-01 + <_> + + 0 -1 131 -467418588 607934740 -510185553 -839002645 + 2000942967 1793376114 710533396 209909344 + + -3.9927759766578674e-01 1.5319514274597168e-01 + <_> + + 0 -1 6 -251463749 -1087866735 954640701 -1345720208 + 257393053 -1721918337 71237772 -522239782 + + -2.0329028367996216e-01 3.1257370114326477e-01 + + <_> + 36 + -1.3515049219131470e+00 + + <_> + + 0 -1 121 -583157832 -41345124 -1667477754 -47472728 + -1631649861 -192782657 -1106464817 1060048799 + + -6.6292375326156616e-02 5.3096652030944824e-01 + <_> + + 0 -1 250 -961874181 -589629441 -202714187 -33687726 + 246352127 -1125919869 1090470655 1441756927 + + -2.9468271136283875e-01 2.9257065057754517e-01 + <_> + + 0 -1 284 -219161456 1561959797 -1157910723 -644253203 + -37769852 -1175163461 -358812998 -1146105857 + + -2.2191908955574036e-01 3.5355353355407715e-01 + <_> + + 0 -1 133 -1395773932 -19337 -872592385 -1082417169 + -268501000 -203988001 -1360523750 -1430265925 + + -2.6642906665802002e-01 2.7330449223518372e-01 + <_> + + 0 -1 89 937245647 533051903 22876957 837784063 -113164289 + 1593942211 1207413693 1942338443 + + -3.1208184361457825e-01 2.1690289676189423e-01 + <_> + + 0 -1 245 -135270614 1911454511 -694266878 1894711038 + 1380414469 1078062543 -200939772 1616172018 + + -3.7340530753135681e-01 2.0424529910087585e-01 + <_> + + 0 -1 79 -673199910 2132653981 -1105191310 -1622098985 + -279161640 1874615084 2066898922 -82575381 + + -2.7581161260604858e-01 2.3679631948471069e-01 + <_> + + 0 -1 108 -88609193 -764250339 -21964208 1785903000 + -705804525 -281542881 -17301633 -29425689 + + -2.1142585575580597e-01 3.1125506758689880e-01 + <_> + + 0 -1 287 2117156824 2142892795 -1715733421 -1118208017 + 1981329130 -1132205343 -531030662 218086646 + + -3.1311789155006409e-01 2.2028388082981110e-01 + <_> + + 0 -1 217 657173799 1208409516 -304231172 -319884740 + 829234695 822389124 -1816709292 -725510 + + -3.4273931384086609e-01 1.9222305715084076e-01 + <_> + + 0 -1 270 -102301694 -135807070 -1880672401 -253298777 + -354657254 -100668629 2011055773 -155453461 + + -2.4226696789264679e-01 2.7088710665702820e-01 + <_> + + 0 -1 191 215240020 -1148310119 -707214049 -1112003969 + 1860719544 -6638593 -4317491 -1414921888 + + -3.1184914708137512e-01 2.1366736292839050e-01 + <_> + + 0 -1 18 -873476105 -30229647 -168296643 -1682912767 + 161284371 -1972125919 -12305 -268965957 + + -2.1284404397010803e-01 3.0867013335227966e-01 + <_> + + 0 -1 289 -449986302 74968807 2145360303 20911369 1088274818 + 1642837031 -1026366551 53429507 + + -3.2960832118988037e-01 1.9843052327632904e-01 + <_> + + 0 -1 187 -294473945 1289282231 -69736418 -366809570 + 585961254 -894112782 -352349116 -857431116 + + -3.4131202101707458e-01 1.7822383344173431e-01 + <_> + + 0 -1 117 -260075316 810653599 -307212416 -1090154618 + 1085218542 2014454434 -889360754 840974879 + + -2.8617727756500244e-01 2.1801990270614624e-01 + <_> + + 0 -1 32 683352887 144804986 883838777 -470815534 749351701 + -1376201987 -1007927147 -269498899 + + -2.7213591337203979e-01 2.3029308021068573e-01 + <_> + + 0 -1 160 -221779237 2055449126 1356126973 1739434813 + -69756111 -78052576 -724205593 927834891 + + -2.1148133277893066e-01 2.9901567101478577e-01 + <_> + + 0 -1 139 -327161337 -541288917 -1074706625 2069214763 + 1422886542 -570618263 1425911455 1965665867 + + -1.9790525734424591e-01 3.1719624996185303e-01 + <_> + + 0 -1 12 -286652406 -1499051796 -2055991469 557910223 + 226286607 -307013288 537285247 1340571263 + + -3.5588899254798889e-01 1.8802331387996674e-01 + <_> + + 0 -1 204 -440754172 -1969605175 -11230786 -1369112738 + -164163787 -439228643 -440438364 -855854880 + + -3.3756810426712036e-01 1.8606249988079071e-01 + <_> + + 0 -1 54 -2103276886 1587028506 -1920974049 -382890163 + -50953603 -625169247 -75998374 847320848 + + -3.3854812383651733e-01 1.8501213192939758e-01 + <_> + + 0 -1 149 -912264192 1437763456 -117442116 1477965101 + -109596288 -782313675 -520249859 -174065925 + + -2.3874689638614655e-01 2.6692461967468262e-01 + <_> + + 0 -1 179 -74761 -1193108610 -1627717634 -1141359812 + -1350594860 -1212204947 -1900803076 -68466436 + + -1.8434369564056396e-01 3.4898519515991211e-01 + <_> + + 0 -1 320 -806388957 -1603323478 -319904391 -1889144109 + -1427144299 -1074553867 -1577597820 -822218338 + + -1.9554206728935242e-01 3.1441712379455566e-01 + <_> + + 0 -1 13 -495530405 -1200567737 -562818530 1426283955 + -646798267 -42047966 -283939201 -15210669 + + -2.0684894919395447e-01 3.0842429399490356e-01 + <_> + + 0 -1 227 -204473205 -111677525 1659697788 -168822810 + 164468462 95878471 1418323918 -705698930 + + -1.5447042882442474e-01 4.0702703595161438e-01 + <_> + + 0 -1 122 332207055 1368372207 1371537916 1541155303 + 1377022927 1195687084 -845629564 -191055413 + + -2.6908680796623230e-01 2.3349469900131226e-01 + <_> + + 0 -1 183 2095555624 -1858958714 880848550 -1086881165 + 1278302507 2017585116 -2100032289 83174071 + + -3.3865603804588318e-01 1.8762224912643433e-01 + <_> + + 0 -1 257 -1599264894 1347540775 548331985 566406079 + -490018643 2125284619 -542620802 -507647254 + + -2.4964332580566406e-01 2.5305619835853577e-01 + <_> + + 0 -1 153 -928904029 -73474081 -431055591 -1365072480 + 1082731439 -1163105435 -401696790 -331068832 + + -2.4641251564025879e-01 2.5806349515914917e-01 + <_> + + 0 -1 261 -1551324256 227211248 -139191220 -1912739520 + 1712117749 1864425601 1605297047 232734801 + + -3.6956688761711121e-01 1.7259617149829865e-01 + <_> + + 0 -1 37 2062683840 -1171226870 -634334626 -42988729 + -177907627 1819501884 -1554858149 -81568901 + + -2.8280401229858398e-01 2.3210345208644867e-01 + <_> + + 0 -1 101 -52896752 2073648803 -104703392 -1877326687 + 1482183868 486564792 -1181155586 -1078764545 + + -2.6182973384857178e-01 2.4921841919422150e-01 + <_> + + 0 -1 119 931876834 -1689820513 -175925869 295803187 + 1288847768 -1394638455 -527053926 -1609099725 + + -2.8890526294708252e-01 2.2244787216186523e-01 + <_> + + 0 -1 23 674383927 640705886 -1980567045 775069703 941246324 + -1074502869 821615185 -1439559299 + + -3.7707689404487610e-01 1.7476500570774078e-01 + + <_> + + 0 0 2 2 + <_> + + 0 0 3 4 + <_> + + 0 0 5 3 + <_> + + 0 0 5 4 + <_> + + 0 0 6 3 + <_> + + 0 0 8 1 + <_> + + 0 1 2 3 + <_> + + 0 1 6 4 + <_> + + 0 2 8 5 + <_> + + 0 7 6 2 + <_> + + 0 9 2 2 + <_> + + 0 9 3 1 + <_> + + 0 9 5 3 + <_> + + 0 14 3 3 + <_> + + 0 15 2 2 + <_> + + 0 16 1 2 + <_> + + 0 17 2 2 + <_> + + 1 0 2 4 + <_> + + 1 0 5 3 + <_> + + 1 0 7 1 + <_> + + 1 6 2 1 + <_> + + 1 9 1 1 + <_> + + 1 9 2 2 + <_> + + 1 15 1 2 + <_> + + 1 16 2 2 + <_> + + 2 0 2 2 + <_> + + 2 0 2 3 + <_> + + 2 0 3 4 + <_> + + 2 1 3 7 + <_> + + 2 4 1 1 + <_> + + 2 4 5 2 + <_> + + 2 4 5 4 + <_> + + 2 5 1 1 + <_> + + 2 6 2 2 + <_> + + 2 7 1 1 + <_> + + 2 7 2 1 + <_> + + 2 8 3 3 + <_> + + 2 9 1 1 + <_> + + 2 10 1 1 + <_> + + 2 10 2 1 + <_> + + 2 15 1 2 + <_> + + 2 19 2 1 + <_> + + 3 0 4 3 + <_> + + 3 0 6 6 + <_> + + 3 0 7 1 + <_> + + 3 2 4 2 + <_> + + 3 2 6 1 + <_> + + 3 4 2 2 + <_> + + 3 5 1 1 + <_> + + 3 6 1 1 + <_> + + 3 6 2 1 + <_> + + 3 6 2 3 + <_> + + 3 6 3 3 + <_> + + 3 6 6 1 + <_> + + 3 7 2 1 + <_> + + 3 7 2 2 + <_> + + 3 8 1 1 + <_> + + 3 8 6 1 + <_> + + 3 9 1 1 + <_> + + 3 9 1 2 + <_> + + 3 10 1 1 + <_> + + 3 10 1 2 + <_> + + 3 10 2 1 + <_> + + 3 11 1 1 + <_> + + 3 11 1 3 + <_> + + 3 13 3 3 + <_> + + 4 0 4 2 + <_> + + 4 0 6 7 + <_> + + 4 1 1 1 + <_> + + 4 1 4 3 + <_> + + 4 4 2 1 + <_> + + 4 6 1 1 + <_> + + 4 6 5 1 + <_> + + 4 6 5 4 + <_> + + 4 7 1 1 + <_> + + 4 7 2 2 + <_> + + 4 7 5 1 + <_> + + 4 8 1 1 + <_> + + 4 8 5 4 + <_> + + 4 9 1 1 + <_> + + 4 9 2 1 + <_> + + 4 9 3 5 + <_> + + 4 9 5 1 + <_> + + 4 10 1 1 + <_> + + 4 10 5 1 + <_> + + 4 12 1 2 + <_> + + 4 14 3 3 + <_> + + 4 15 1 1 + <_> + + 4 18 2 1 + <_> + + 5 2 5 3 + <_> + + 5 3 4 4 + <_> + + 5 6 1 1 + <_> + + 5 6 4 1 + <_> + + 5 7 1 1 + <_> + + 5 7 1 2 + <_> + + 5 7 2 2 + <_> + + 5 8 1 1 + <_> + + 5 8 3 4 + <_> + + 5 8 3 5 + <_> + + 5 8 5 1 + <_> + + 5 8 5 3 + <_> + + 5 9 1 1 + <_> + + 5 9 5 1 + <_> + + 5 10 1 1 + <_> + + 5 10 2 1 + <_> + + 5 10 5 1 + <_> + + 5 11 1 1 + <_> + + 5 13 1 3 + <_> + + 5 16 1 1 + <_> + + 5 18 1 2 + <_> + + 6 0 6 5 + <_> + + 6 1 1 2 + <_> + + 6 3 1 1 + <_> + + 6 3 6 3 + <_> + + 6 4 1 1 + <_> + + 6 5 1 1 + <_> + + 6 5 1 2 + <_> + + 6 6 2 2 + <_> + + 6 6 2 4 + <_> + + 6 6 3 3 + <_> + + 6 7 1 1 + <_> + + 6 7 1 2 + <_> + + 6 7 4 1 + <_> + + 6 7 4 4 + <_> + + 6 7 6 1 + <_> + + 6 8 1 4 + <_> + + 6 8 2 2 + <_> + + 6 9 1 1 + <_> + + 6 9 2 1 + <_> + + 6 9 2 2 + <_> + + 6 9 5 1 + <_> + + 6 9 6 2 + <_> + + 6 10 1 1 + <_> + + 6 11 1 1 + <_> + + 6 13 1 1 + <_> + + 6 13 2 1 + <_> + + 6 18 1 2 + <_> + + 6 20 1 1 + <_> + + 7 0 3 1 + <_> + + 7 2 1 3 + <_> + + 7 3 4 5 + <_> + + 7 5 1 1 + <_> + + 7 5 2 1 + <_> + + 7 6 1 1 + <_> + + 7 7 1 2 + <_> + + 7 7 2 4 + <_> + + 7 8 1 1 + <_> + + 7 8 1 2 + <_> + + 7 8 2 4 + <_> + + 7 9 1 1 + <_> + + 7 16 1 1 + <_> + + 7 21 1 1 + <_> + + 7 21 2 1 + <_> + + 8 0 2 1 + <_> + + 8 0 3 1 + <_> + + 8 0 5 3 + <_> + + 8 3 1 1 + <_> + + 8 4 1 1 + <_> + + 8 5 1 1 + <_> + + 8 5 1 2 + <_> + + 8 7 3 4 + <_> + + 8 8 1 1 + <_> + + 8 9 1 1 + <_> + + 8 9 3 5 + <_> + + 8 11 1 1 + <_> + + 8 14 1 1 + <_> + + 8 19 1 1 + <_> + + 8 20 1 1 + <_> + + 8 21 1 1 + <_> + + 9 0 2 3 + <_> + + 9 1 2 1 + <_> + + 9 5 2 1 + <_> + + 9 5 2 3 + <_> + + 9 5 4 1 + <_> + + 9 7 1 1 + <_> + + 9 9 1 1 + <_> + + 9 11 1 1 + <_> + + 9 12 2 4 + <_> + + 9 15 1 1 + <_> + + 9 17 1 1 + <_> + + 9 18 1 2 + <_> + + 9 20 1 1 + <_> + + 10 0 2 2 + <_> + + 10 6 3 3 + <_> + + 10 7 1 1 + <_> + + 10 8 1 1 + <_> + + 10 9 1 1 + <_> + + 10 11 1 1 + <_> + + 10 12 1 1 + <_> + + 10 15 1 1 + <_> + + 10 20 1 1 + <_> + + 10 21 1 1 + <_> + + 11 0 4 4 + <_> + + 11 1 4 4 + <_> + + 11 3 1 1 + <_> + + 11 4 3 1 + <_> + + 11 6 3 6 + <_> + + 11 7 1 1 + <_> + + 11 8 1 1 + <_> + + 11 9 1 1 + <_> + + 11 9 2 3 + <_> + + 11 10 1 1 + <_> + + 11 11 1 1 + <_> + + 11 12 2 3 + <_> + + 11 13 1 1 + <_> + + 11 15 3 1 + <_> + + 11 20 1 1 + <_> + + 11 21 1 1 + <_> + + 12 3 1 1 + <_> + + 12 5 1 1 + <_> + + 12 5 2 3 + <_> + + 12 5 3 3 + <_> + + 12 6 1 1 + <_> + + 12 7 2 4 + <_> + + 12 8 1 1 + <_> + + 12 8 2 2 + <_> + + 12 8 2 3 + <_> + + 12 9 1 1 + <_> + + 12 10 2 3 + <_> + + 12 11 1 1 + <_> + + 12 16 1 1 + <_> + + 12 17 1 1 + <_> + + 12 18 1 1 + <_> + + 12 18 1 2 + <_> + + 12 20 1 1 + <_> + + 12 21 1 1 + <_> + + 13 0 3 3 + <_> + + 13 3 1 1 + <_> + + 13 4 1 1 + <_> + + 13 5 1 1 + <_> + + 13 6 2 3 + <_> + + 13 7 3 2 + <_> + + 13 8 1 1 + <_> + + 13 9 1 1 + <_> + + 13 10 1 1 + <_> + + 13 10 2 1 + <_> + + 13 11 1 1 + <_> + + 13 13 1 1 + <_> + + 13 19 1 1 + <_> + + 13 20 1 1 + <_> + + 13 21 1 1 + <_> + + 14 0 3 4 + <_> + + 14 3 1 2 + <_> + + 14 3 2 1 + <_> + + 14 4 1 1 + <_> + + 14 5 1 1 + <_> + + 14 6 2 3 + <_> + + 14 7 1 3 + <_> + + 14 7 2 2 + <_> + + 14 8 1 1 + <_> + + 14 8 1 2 + <_> + + 14 9 1 1 + <_> + + 14 9 2 1 + <_> + + 14 13 1 1 + <_> + + 14 21 1 1 + <_> + + 15 0 3 4 + <_> + + 15 1 1 2 + <_> + + 15 2 1 2 + <_> + + 15 5 1 1 + <_> + + 15 6 2 1 + <_> + + 15 6 2 2 + <_> + + 15 7 1 1 + <_> + + 15 7 1 2 + <_> + + 15 7 2 2 + <_> + + 15 8 1 1 + <_> + + 15 9 1 1 + <_> + + 15 9 1 5 + <_> + + 15 9 2 1 + <_> + + 15 15 3 3 + <_> + + 15 17 1 1 + <_> + + 16 4 1 1 + <_> + + 16 6 1 1 + <_> + + 16 7 1 1 + <_> + + 16 7 1 2 + <_> + + 16 7 2 1 + <_> + + 16 7 2 2 + <_> + + 16 8 1 1 + <_> + + 16 10 1 1 + <_> + + 16 10 2 1 + <_> + + 16 17 1 1 + <_> + + 16 17 1 2 + <_> + + 16 18 1 1 + <_> + + 17 4 2 2 + <_> + + 17 5 1 1 + <_> + + 17 6 2 1 + <_> + + 17 6 2 2 + <_> + + 17 7 1 1 + <_> + + 17 7 1 2 + <_> + + 17 8 1 1 + <_> + + 17 8 2 1 + <_> + + 17 9 1 1 + <_> + + 17 10 1 1 + <_> + + 17 10 2 2 + <_> + + 17 11 1 1 + <_> + + 17 12 1 2 + <_> + + 17 13 1 2 + <_> + + 17 13 1 3 + <_> + + 17 21 2 1 + <_> + + 18 0 2 2 + <_> + + 18 4 1 2 + <_> + + 18 6 1 1 + <_> + + 18 8 2 2 + <_> + + 18 9 1 1 + <_> + + 18 9 1 2 + <_> + + 18 9 1 3 + <_> + + 18 10 1 1 + <_> + + 18 11 1 2 + <_> + + 18 12 1 1 + <_> + + 18 13 1 2 + <_> + + 18 17 2 2 + <_> + + 18 18 1 2 + <_> + + 18 19 2 1 + <_> + + 19 0 1 1 + <_> + + 19 6 1 1 + <_> + + 19 9 1 1 + <_> + + 19 9 1 2 + <_> + + 19 10 1 4 + <_> + + 19 12 1 2 + <_> + + 20 10 1 1 + <_> + + 20 15 1 2 + <_> + + 21 10 1 1 + <_> + + 21 14 1 2 + <_> + + 21 15 1 3 + diff --git a/detectors/CMakeLists.txt b/detectors/CMakeLists.txt index e58544ac..00ad1808 100644 --- a/detectors/CMakeLists.txt +++ b/detectors/CMakeLists.txt @@ -1,4 +1,14 @@ -add_subdirectory(local2D) -add_subdirectory(global2D) -add_subdirectory(global3D) -add_subdirectory(misc) +set(DETECTORS_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(DETECTORS_INCLUDE_DIR ${DETECTORS_DIR}/include) +set(DETECTORS_IMPL_DIR ${DETECTORS_DIR}/impl) + +#Add in parent scope to build examples +set(DETECTORS_INCLUDE_DIR ${DETECTORS_DIR}/include PARENT_SCOPE) +set(DETECTORS_IMPL_DIR ${DETECTORS_DIR}/impl PARENT_SCOPE) + +add_subdirectory("src/local2D") +add_subdirectory("src/global2D") +add_subdirectory("src/global3D") +add_subdirectory("src/misc") + +install(DIRECTORY ${DETECTORS_INCLUDE_DIR}/od DESTINATION ${OD_INSTALL_INCLUDE_DIR}) diff --git a/detectors/global2D/CMakeLists.txt b/detectors/global2D/CMakeLists.txt deleted file mode 100644 index e240743c..00000000 --- a/detectors/global2D/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -set(SUBSYS_NAME global_image_detector) -set(LIB_NAME od_${SUBSYS_NAME}) -set(SUBSYS_DESC "global feature based detection in 2D images") - -set(SUBSYS_DEPS od_common ${OpenCV_LIBS} od_svmlight) - - -set(build TRUE) -#PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -#PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS}) - - -if(build) - - set(incs - "ODFaceRecognizer.h" - "detection/ODHOGDetector.h" - "detection/ODCascadeDetector.h" - - - "training/ODHOGTrainer.h" - ) - - set(impl_incs - ) - - set(srcs - ODFaceRecognizer.cpp - "detection/ODHOGDetector.cpp" - "detection/ODCascadeDetector.cpp" - "training/ODHOGTrainer.cpp" - ) - - - OD_ADD_LIBRARY_ALL("${SUBSYS_NAME}" SRCS ${srcs} INCS ${incs} ${impl_incs}) - install(FILES ${incs} DESTINATION ${OD_INSTALL_INCLUDE_DIR}/${SUBSYS_NAME} COMPONENT ${LIB_NAME}) - - if(SUBSYS_DEPS) - target_link_libraries("${LIB_NAME}" ${SUBSYS_DEPS}) - endif(SUBSYS_DEPS) - - #PCL_MAKE_PKGCONFIG("${LIB_NAME}" "${SUBSYS_NAME}" "${SUBSYS_DESC}" "${SUBSYS_DEPS}" "" "" "" "") - - -endif(build) \ No newline at end of file diff --git a/detectors/global2D/ODFaceRecognizer.cpp b/detectors/global2D/ODFaceRecognizer.cpp deleted file mode 100644 index cc88097b..00000000 --- a/detectors/global2D/ODFaceRecognizer.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 16.07.15. -// - -#include "ODFaceRecognizer.h" - -using namespace cv; -using namespace std; - -namespace od -{ - namespace g2d - { - void ODFaceRecognizer::init() - { - switch(recogtype_) - { - case OD_FACE_FISCHER: - cvrecognizer_ = cv::face::createFisherFaceRecognizer(num_components_, threshold_); - break; - case OD_FACE_EIGEN: - cvrecognizer_ = cv::face::createEigenFaceRecognizer(num_components_, threshold_); - break; - default: - std::cout << "FATAL: FACETYPE NOT FOUND!"; - } - } - - void ODFaceRecognizer::initTrainer() - { - init(); - } - - void ODFaceRecognizer::initDetector() - { - if(!trained_) - { - init(); - - //get models in the directory - std::vector files; - FileUtils::getFilesInDirectoryRec(getSpecificTrainingDataLocation(), TRAINED_DATA_EXT_, files); - - if (files.size() == 0) - { - std::cout << "FATAL: Trained data not found" << endl; - exit(1); - } - - //choose the first - cvrecognizer_->load(files[0]); - } - } - - int ODFaceRecognizer::train() - { - vector images; - vector labels; - try - { - read_csv(training_input_location_, images, labels); - } catch(cv::Exception &e) - { - cerr << "Error opening file \"" << training_input_location_ << "\". Reason: " << e.msg << endl; - exit(1); - } - cvrecognizer_->train(images, labels); - FileUtils::createTrainingDir(getSpecificTrainingDataLocation()); - - cvrecognizer_->save(getSpecificTrainingDataLocation() + "/trained." + TRAINED_DATA_EXT_); - trained_ = true; - - //the training set has atleast one image - im_width_ = images[0].cols; - im_height_ = images[0].rows; - } - - ODDetections *ODFaceRecognizer::detect(ODSceneImage *scene) - { - cv::Mat face_edited; - cvtColor(scene->getCVImage(), face_edited, CV_BGR2GRAY); - - if(trained_) - { - cv::resize(face_edited.clone(), face_edited, cv::Size(im_width_, im_height_), 1.0, 1.0, cv::INTER_CUBIC); - } - - int label = 100; - double confidence; - cvrecognizer_->predict(face_edited, label, confidence); - - //fill in the detection - ODDetection2D *detection = new ODDetection2D(ODDetection::OD_DETECTION_CLASS, toString(label), confidence); - ODDetections2D *detections = new ODDetections2D; - detections->push_back(detection); - return detections; - } - - - void ODFaceRecognizer::read_csv(const string &filename, vector &images, vector &labels, char separator) - { - std::ifstream file(filename.c_str(), ifstream::in); - if(!file) - { - string error_message = "No valid input file was given, please check the given filename."; - CV_Error(CV_StsBadArg, error_message); - } - string line, path, classlabel; - while(getline(file, line)) - { - stringstream liness(line); - getline(liness, path, separator); - getline(liness, classlabel); - if(!path.empty() && !classlabel.empty()) - { - images.push_back(cv::imread(path, 0)); - labels.push_back(atoi(classlabel.c_str())); - } - } - } - - } -} \ No newline at end of file diff --git a/detectors/global2D/ODFaceRecognizer.h b/detectors/global2D/ODFaceRecognizer.h deleted file mode 100644 index 2237f794..00000000 --- a/detectors/global2D/ODFaceRecognizer.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 16.06.15. -// - -#ifndef OPENDETECTION_ODPOINTCLOUDGLOBALMATCHING_H -#define OPENDETECTION_ODPOINTCLOUDGLOBALMATCHING_H - -#include -#include -#include - -#include "opencv2/core.hpp" -#include "opencv2/face.hpp" -#include "opencv2/highgui.hpp" -#include "opencv2/imgproc.hpp" -#include "opencv2/objdetect.hpp" - - - -namespace od -{ - namespace g2d - { - - - /** \brief A facerecognizer based on EigenFace and FischerFace algorithms. - * - * Currently it just supports detection on fixed scene (detect()) and does not support multiscale detection. This is due to the fact that class for cascade classifier - - * ODCascadeDetector supports multiscale detection and can be easily integrated with this recognizer - first by finding face using the Cascade and then applying this recognizer on that detected window. - * This is faster than trying to perform recognition on each multiscale window. - * - * \author Kripasindhu Sarkar - * - */ - - class ODFaceRecognizer : public ObjectDetector - { - public: - - OD_DEFINE_ENUM_WITH_STRING_CONVERSIONS(FaceRecogType, (OD_FACE_FISCHER)(OD_FACE_EIGEN)) - - ODFaceRecognizer(FaceRecogType recogtype = OD_FACE_EIGEN, int num_components = 0, double threshold = DBL_MAX) - : recogtype_(recogtype), num_components_(num_components), threshold_(threshold), im_height_(0), im_width_(0) - { - TRAINED_DATA_IDENTIFIER_ = "FACERECOG"; - TRAINED_DATA_EXT_ = "facerec.xml"; - } - - void init(); - - void initTrainer(); - - void initDetector(); - - int train(); - - ODDetections *detect(ODSceneImage *scene); - - - FaceRecogType const &getRecogtype() const - { - return recogtype_; - } - - void setRecogtype(FaceRecogType const &recogtype_) - { - ODFaceRecognizer::recogtype_ = recogtype_; - } - - int getThreshold() const - { - return threshold_; - } - - void setThreshold(int threshold_) - { - ODFaceRecognizer::threshold_ = threshold_; - } - - int getNumComponents() const - { - return num_components_; - } - - void setNumComponents(int num_components_) - { - ODFaceRecognizer::num_components_ = num_components_; - } - - protected: - cv::Ptr cvrecognizer_; - FaceRecogType recogtype_; - - int im_width_; - int im_height_; - int num_components_; - double threshold_; - - - private: - static void read_csv(const std::string &filename, std::vector &images, std::vector &labels, char separator = ';'); - - }; - /** \example objectdetector/od_image_facerecog.cpp - */ - } -} -#endif //OPENDETECTION_ODPOINTCLOUDGLOBALMATCHING_H diff --git a/detectors/global2D/detection/ODCascadeDetector.cpp b/detectors/global2D/detection/ODCascadeDetector.cpp deleted file mode 100644 index 5bbd23c0..00000000 --- a/detectors/global2D/detection/ODCascadeDetector.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 17.07.15. -// - -#include "ODCascadeDetector.h" - -using namespace cv; -using namespace std; - -namespace od -{ - - namespace g2d - { - ODDetections2D *ODCascadeDetector::detectOmni(ODSceneImage *scene) - { - Mat gray; - cvtColor(scene->getCVImage(), gray, CV_BGR2GRAY); - // Find the faces in the frame: - vector > faces; - haar_cascade_->detectMultiScale(gray, faces, scaleFactor_, minNeighbors_, 0, minSize_, maxSize_); - - //always create detections - ODDetections2D *detections = new ODDetections2D; - cv::Mat viz = scene->getCVImage().clone(); - - for(int i = 0; i < faces.size(); i++) - { - // Process face by face: - Rect face_i = faces[i]; - - ODDetection2D *detection2D = new ODDetection2D(ODDetection::OD_DETECTION_CLASS, "FACE", 1); - detection2D->setBoundingBox(face_i); - detections->push_back(detection2D); - - if(metainfo_) - { - rectangle(viz, face_i, CV_RGB(0, 255, 0), 1); - } - } - detections->setMetainfoImage(viz); - - return detections; - } - - ODDetections* ODCascadeDetector::detect(ODSceneImage *scene) - { - //always create detections - ODDetections *detections = new ODDetections; - - Mat gray; - cvtColor(scene->getCVImage(), gray, CV_BGR2GRAY); - // Find the faces in the frame: - vector > faces; - - - cv::Size imsize = gray.size(); - //hack for single detection, - //note: maxsize = minsize = size of input image for single window detection - //todo: implement in some other way of fast single detection; currently this will work, but maynot be fast - haar_cascade_->detectMultiScale(gray, faces, 5, minNeighbors_, 0, gray.size(), gray.size()); - if (faces.size() > 0) - { - ODDetection *detection = new ODDetection(ODDetection::OD_DETECTION_CLASS, "FACE", 1); - detections->push_back(detection); - } - return detections; - } - - } -} \ No newline at end of file diff --git a/detectors/global2D/detection/ODHOGDetector.cpp b/detectors/global2D/detection/ODHOGDetector.cpp deleted file mode 100644 index 75e8902a..00000000 --- a/detectors/global2D/detection/ODHOGDetector.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 15.07.15. -// - -#include "ODHOGDetector.h" - -using namespace std; - -namespace od -{ - namespace g2d - { - - void ODHOGDetector::init() - { - - switch(svmtype_) - { - case OD_DEFAULT_PEOPLE: - hog_.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector()); - cout << "HOG TYPE: OpenCV Default People" << endl; - //hog_.save(getSpecificTrainingDataLocation() + "/defaultpeople." + TRAINED_DATA_EXT_); - break; - case OD_DAIMLER_PEOPLE: - hog_.winSize = cv::Size(48, 96); - hitThreshold =1.2; - hog_.setSVMDetector(cv::HOGDescriptor::getDaimlerPeopleDetector()); - cout << "HOG TYPE: OpenCV Daimler People" << endl; - //hog_.save(getSpecificTrainingDataLocation() + "/daimlerpeople." + TRAINED_DATA_EXT_); - break; - case OD_FILE: - string hogfile = FileUtils::getFirstFile(getSpecificTrainingDataLocation(), TRAINED_DATA_ID_); - load(hogfile); - cout << "HOG TYPE: Custom HOG features loaded from: " << hogfile << endl; - break; - //dont set anything for custom, it is to be set by the user by setSVMDetector - } - - printParameters(); - } - - void ODHOGDetector::load(std::string filename) - { - cv::FileStorage fs(filename, cv::FileStorage::READ); - fs["hitThreshold"] >> hitThreshold; - cv::FileNode fn = fs[cv::FileStorage::getDefaultObjectName(filename)]; - hog_.read(fn); - } - - ODDetections2D *ODHOGDetector::detectOmni(ODSceneImage *scene) - { - //always create a detection - ODDetections2D *detections = new ODDetections2D; - - - vector found, found_filtered; - hog_.detectMultiScale(scene->getCVImage(), found, hitThreshold, cv::Size(8, 8), cv::Size(32, 32), 1.05, 2); - - - cv::Mat viz = scene->getCVImage().clone(); - for(int i = 0; i < found.size(); i++) - { - ODDetection2D *detection2D = new ODDetection2D; - detection2D->setBoundingBox(found[i]); - detection2D->setId("PEOPLE"); - detection2D->setType(ODDetection::OD_DETECTION_CLASS); - detections->push_back(detection2D); - - - if(metainfo_) - { - cv::Rect r = found[i]; - r.x += cvRound(r.width * 0.1); - r.width = cvRound(r.width * 0.8); - r.y += cvRound(r.height * 0.06); - r.height = cvRound(r.height * 0.9); - rectangle(viz, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2); - } - } - detections->setMetainfoImage(viz); - - return detections; - } - - ODDetections *ODHOGDetector::detect(ODSceneImage *scene) - { - //always create a detection - ODDetections *detections = new ODDetections; - - cv::Mat scaledwindow; - cv::resize(scene->getCVImage(), scaledwindow, hog_.winSize); - - std::vector foundLocations; - - hog_.detect(scene->getCVImage(), foundLocations, hitThreshold); - if (!foundLocations.empty()) - { - ODDetection2D *detection2D = new ODDetection2D; - detection2D->setId("PEOPLE"); - detection2D->setType(ODDetection::OD_DETECTION_CLASS); - detections->push_back(detection2D); - } - - return detections; - } - - void ODHOGDetector::setSVMFromFile(std::string fileName) - { - vector descriptor_vector; - printf("Reading descriptor vector from file '%s'\n", fileName.c_str()); - string separator = " "; // Use blank as default separator between single features - - ifstream File; - float percent; - File.open(fileName.c_str(), ios::in); - if (File.good() && File.is_open()) { - - double d; - while(File >> d) - { - //cout << d << " "; - descriptor_vector.push_back(d); - } - File.close(); - } - - hog_.setSVMDetector(descriptor_vector); - } - - void ODHOGDetector::printParameters() - { - cout << "winSize: " << winSize << endl; - cout << "blockSize: " << blockSize << endl; - cout << "blockStride: " << blockStride << endl; - cout << "cellSize: " << cellSize << endl; - cout << "hitThreshold: " << hitThreshold << endl; - } - } -} diff --git a/detectors/global2D/detection/ODHOGDetector.h b/detectors/global2D/detection/ODHOGDetector.h deleted file mode 100644 index b5781dcc..00000000 --- a/detectors/global2D/detection/ODHOGDetector.h +++ /dev/null @@ -1,192 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 15.07.15. -// - -#ifndef OPENDETECTION_ODHOGMULTISCALEDETECTOR_H -#define OPENDETECTION_ODHOGMULTISCALEDETECTOR_H - -#include "common/pipeline/ODDetector.h" -#include "common/pipeline/ODScene.h" -#include "common/utils/utils.h" -#include "common/utils/ODFeatureDetector2D.h" - -#include -#include - -namespace od -{ - - namespace g2d - { - /** \brief A linear classifier for HOG features. - * - * This class takes an image as an input, finds its HOG features using the parameters containing in the trained data, runs the linear classifier (present in the trained data) on the computed HOG features - * and finally produces the classification output. Covers both multiscale detection (detectOmni()) and detection on a fixed scene (detect() - the scene is resized to the HOG window size). - * - * Use ODHOGTrainer for the training of new objects. By default this class provides two people detector: OD_DEFAULT_PEOPLE, the people detector from OpenCV and OD_DAIMLER_PEOPLE, the second detector available from OpenCV. - * One can set any linear classifier, the linear weight vector through setSVMDetector() function but it is highly not recommended as the HOG parameters and the weight vector can be out of sync. - * One must set appropriate HOG parameters after using setSVMDetector() function with which the weight vector was trained. - * - * \author Kripasindhu Sarkar - * - */ - - - class ODHOGDetector : public ODDetector2D - { - public: - - OD_DEFINE_ENUM_WITH_STRING_CONVERSIONS(SVMType, (OD_CUSTOM)(OD_DEFAULT_PEOPLE)(OD_DAIMLER_PEOPLE)(OD_FILE)) - - - ODHOGDetector(std::string const &trained_data_location_ = "", cv::Size winsize = cv::Size(64,128), cv::Size blocksize = cv::Size(16,16), cv::Size blockstride = cv::Size(8,8), cv::Size cellsize = cv::Size(8,8), float hitshreshold = 0.0): - ODDetector2D(trained_data_location_), winSize(winsize), blockSize(blocksize), blockStride(blockstride), - cellSize(cellsize), hitThreshold(hitshreshold), hog_(winSize, blockSize, blockStride, cellSize, 9, 1, -1, - cv::HOGDescriptor::L2Hys, 0.2, false, cv::HOGDescriptor::DEFAULT_NLEVELS) - { - TRAINED_LOCATION_DENTIFIER_ = "HOG"; - TRAINED_DATA_ID_ = "hog.xml"; - metainfo_ = true; - svmtype_ = OD_DEFAULT_PEOPLE; - - if (trained_data_location_ != "") - svmtype_ = OD_FILE; - } - - - void init(); - void load(std::string filename); - - void setSVMFromFile(std::string fileName); - - void setSVMDetector(std::vector svmdetector) - { - hog_.setSVMDetector(svmdetector); - } - - ODDetections2D *detectOmni(ODSceneImage *scene); - ODDetections *detect(ODSceneImage *scene); - - int detect(ODScene *scene, std::vector &detections) - { } - - - void setTrainedDataLocation(std::string trained_data_location_) - { - this->trained_data_location_ = trained_data_location_; - this->svmtype_ = OD_FILE; - } - - SVMType const &getSvmtype() const - { - return svmtype_; - } - - void setSvmtype(SVMType const &svmtype_) - { - ODHOGDetector::svmtype_ = svmtype_; - } - - cv::Size const &getWinSize() const - { - return winSize; - } - - void setWinSize(cv::Size const &winSize) - { - ODHOGDetector::winSize = winSize; - } - - cv::Size const &getBlockSize() const - { - return blockSize; - } - - void setBlockSize(cv::Size const &blockSize) - { - ODHOGDetector::blockSize = blockSize; - } - - cv::Size const &getBlockStride() const - { - return blockStride; - } - - void setBlockStride(cv::Size const &blockStride) - { - ODHOGDetector::blockStride = blockStride; - } - - cv::Size const &getCellSize() const - { - return cellSize; - } - - void setCellSize(cv::Size const &cellSize) - { - ODHOGDetector::cellSize = cellSize; - } - - float getHitThreshold() const - { - return hitThreshold; - } - - void setHitThreshold(float hitThreshold) - { - ODHOGDetector::hitThreshold = hitThreshold; - } - - void printParameters(); - - protected: - //properteis - cv::Size winSize; - cv::Size blockSize; - cv::Size blockStride; - cv::Size cellSize; - - float hitThreshold; - - cv::HOGDescriptor hog_; - SVMType svmtype_; - - }; - - /** \example objectdetector/od_image_hog.cpp - * \example objectdetector/od_image_hog_files.cpp - * \example apps/global2D/od_multihog_app.cpp - * This is an example of how to use the ODHOGDetector class. - * - * More details about this example. - */ - } -} - - -#endif //OPENDETECTION_ODHOGMULTISCALEDETECTOR_H \ No newline at end of file diff --git a/detectors/global2D/training/ODHOGTrainer.cpp b/detectors/global2D/training/ODHOGTrainer.cpp deleted file mode 100644 index 38095050..00000000 --- a/detectors/global2D/training/ODHOGTrainer.cpp +++ /dev/null @@ -1,422 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 13.08.15. -// - - -#include "ODHOGTrainer.h" - - -#include -#include -#include - -#include -#include -#include - -//binding class for svmlight -#include "common/bindings/svmlight.h" - -#define TRAINHOG_SVM_TO_TRAIN SVMlight - -using namespace std; -using namespace cv; - -namespace od -{ - namespace g2d - { - - static void storeCursor(void) - { - printf("\033[s"); - } - - static void resetCursor(void) - { - printf("\033[u"); - } - - void ODHOGTrainer::saveDescriptorVectorToFile(vector &descriptorVector, vector &_vectorIndices, string fileName) - { - printf("Saving descriptor vector to file '%s'\n", fileName.c_str()); - string separator = " "; // Use blank as default separator between single features - fstream File; - float percent; - File.open(fileName.c_str(), ios::out); - if(File.good() && File.is_open()) - { - printf("Saving %lu descriptor vector features:\t", descriptorVector.size()); - storeCursor(); - for(int feature = 0; feature < descriptorVector.size(); ++feature) - { - if((feature % 10 == 0) || (feature == (descriptorVector.size() - 1))) - { - percent = ((1 + feature) * 100 / descriptorVector.size()); - printf("%4u (%3.0f%%)", feature, percent); - fflush(stdout); - resetCursor(); - } - File << descriptorVector.at(feature) << separator; - } - printf("\n"); - File << endl; - File.flush(); - File.close(); - } - } - - void ODHOGTrainer::calculateFeaturesFromInput(const string &imageFilename, vector &featureVector, HOGDescriptor &hog) - { - - Mat imageDataorig, imageData; - imageDataorig = imread(imageFilename, 0); - - - if(imageDataorig.empty()) - { - featureVector.clear(); - printf("Error: HOG image '%s' is empty, features calculation skipped!\n", imageFilename.c_str()); - return; - } - - vector locations; - locations.push_back(start_hog_pos); - hog.compute(imageDataorig, featureVector, winStride, trainingPadding, locations); - //cout << "Desc size :" << featureVector.size(); - //cout << ": Expected size :" << hog.getDescriptorSize() << endl; - imageDataorig.release(); // Release the image again after features are extracted - } - - void ODHOGTrainer::detectTrainingSetTest(const HOGDescriptor &hog, const double hitThreshold, const vector &posFileNames, const vector &negFileNames) - { - unsigned int truePositives = 0; - unsigned int trueNegatives = 0; - unsigned int falsePositives = 0; - unsigned int falseNegatives = 0; - vector foundDetection; - // Walk over positive training samples, generate images and detect - for(vector::const_iterator posTrainingIterator = posFileNames.begin(); - posTrainingIterator != posFileNames.end(); ++posTrainingIterator) - { - const Mat imageData = imread(*posTrainingIterator, 0); - hog.detect(imageData, foundDetection, hitThreshold, winStride, trainingPadding); - if(foundDetection.size() > 0) - { - ++truePositives; - falseNegatives += foundDetection.size() - 1; - } else - { - ++falseNegatives; - } - } - // Walk over negative training samples, generate images and detect - for(vector::const_iterator negTrainingIterator = negFileNames.begin(); - negTrainingIterator != negFileNames.end(); ++negTrainingIterator) - { - const Mat imageData = imread(*negTrainingIterator, 0); - hog.detect(imageData, foundDetection, hitThreshold, winStride, trainingPadding); - if(foundDetection.size() > 0) - { - falsePositives += foundDetection.size(); - } else - { - ++trueNegatives; - } - } - - printf("Results:\n\tTrue Positives: %u\n\tTrue Negatives: %u\n\tFalse Positives: %u\n\tFalse Negatives: %u\n", - truePositives, trueNegatives, falsePositives, falseNegatives); - } - - - void ODHOGTrainer::calculateFeaturesFromImageLoc(const Mat &imageData, vector &featureVector, const HOGDescriptor &hog, Point startpos) - { - - vector locations; - locations.push_back(startpos); - hog.compute(imageData, featureVector, winStride, trainingPadding, locations); - } - - void ODHOGTrainer::handleNegetivefile(string const imageFilename, HOGDescriptor &hog, fstream &file) - { - - Mat imageData; - imageData = imread(imageFilename, 0); - - //cout << "Image size : " << imageData.size() << "random points : " << endl; - //get hog at random 10 image location - for(int i = 0; i < nofeatures_neg; i++) - { - Point feat_loc(rand() % (imageData.cols - winSize.width), rand() % (imageData.rows - winSize.height)); - //cout << feat_loc << endl; - - //use this p for finding feature - vector featureVector; - calculateFeaturesFromImageLoc(imageData, featureVector, hog, feat_loc); - - if(!featureVector.empty()) - { - /* Put positive or negative sample class to file, - * true=positive, false=negative, - * and convert positive class to +1 and negative class to -1 for SVMlight - */ - file << "-1"; - // Save feature vector components - for(unsigned int feature = 0; feature < featureVector.size(); ++feature) - { - file << " " << (feature + 1) << ":" << featureVector.at(feature); - } - file << endl; - } - } - - } - - void ODHOGTrainer::createHardTrainingData(const HOGDescriptor &hog, const double hitThreshold, const vector &negFileNames) - { - fstream file; - file.open(featuresFile.c_str(), std::fstream::app); - if(!file.is_open()) - { - cout << "ERROR opening previous feature file! HARD training failed!" << endl; - } - cout << "Appending HARD negetive features to " + featuresFile << endl; - //cvNamedWindow("hardneg", WINDOW_AUTOSIZE); - - // Walk over negative training samples, generate images and detect - int counter = 0; - for(vector::const_iterator negTrainingIterator = negFileNames.begin(); - negTrainingIterator != negFileNames.end(); ++negTrainingIterator) - { - - const Mat imageData = imread(*negTrainingIterator, 0); - - - vector foundLocations; - hog.detectMultiScale(imageData, foundLocations, hitThreshold); - - - for(int i = 0; i < foundLocations.size(); i++) - { - counter++; - //cout << "## hard examples ## FALSE POS FOUND : including the descriptor in training set" << endl; - - Mat negimg(imageData(foundLocations[i])); - //imshow("hardneg", negimg); waitKey(2000); - - Mat resized_neg; - resize(negimg, resized_neg, winSize); - // imshow("hardneg", resized_neg); waitKey(4000); - - vector featureVector; - calculateFeaturesFromImageLoc(resized_neg, featureVector, hog, Point(0, 0)); - - if(!featureVector.empty()) - { - file << "-1"; - for(unsigned int feature = 0; feature < featureVector.size(); ++feature) - { - file << " " << (feature + 1) << ":" << featureVector.at(feature); - } - file << endl; - } - } - } - cout << "Wrote " << counter << " HARD negetive features" << endl; - - //CLOSE THE APPENDED DATA FILE - file.close(); - } - - double ODHOGTrainer::trainWithSVMLight(string svmModelFile, string svmDescriptorFile, vector &descriptorVector) - { - //training takes featurefile as input, produces hitthreshold and vector as output - printf("Calling %s\n", TRAINHOG_SVM_TO_TRAIN::getInstance()->getSVMName()); - TRAINHOG_SVM_TO_TRAIN::getInstance()->read_problem(const_cast (featuresFile.c_str())); - TRAINHOG_SVM_TO_TRAIN::getInstance()->train(); // Call the core libsvm training procedure - printf("Training done, saving model file!\n"); - TRAINHOG_SVM_TO_TRAIN::getInstance()->saveModelToFile(svmModelFile); - - printf("Generating representative single HOG feature vector using svmlight!\n"); - - descriptorVector.resize(0); - vector descriptorVectorIndices; - // Generate a single detecting feature vector (v1 | b) from the trained support vectors, for use e.g. with the HOG algorithm - TRAINHOG_SVM_TO_TRAIN::getInstance()->getSingleDetectingVector(descriptorVector, descriptorVectorIndices); - // And save the precious to file system - saveDescriptorVectorToFile(descriptorVector, descriptorVectorIndices, svmDescriptorFile); - // Detector detection tolerance threshold - return hitThreshold = TRAINHOG_SVM_TO_TRAIN::getInstance()->getThreshold(); - } - - int ODHOGTrainer::train() - { - - vector positiveTrainingImages; - vector negativeTrainingImages; - vector validExtensions; - validExtensions.push_back(".jpg"); - validExtensions.push_back(".png"); - validExtensions.push_back(".ppm"); - - FileUtils::getFilesInDirectoryRec(posSamplesDir, validExtensions, positiveTrainingImages); - FileUtils::getFilesInDirectoryRec(negSamplesDir, validExtensions, negativeTrainingImages); - cout << "No of positive Training Files: " << positiveTrainingImages.size() << endl; - cout << "No of neg Training Files: "<< negativeTrainingImages.size() << endl; - - - if( positiveTrainingImages.size() + negativeTrainingImages.size() == 0) - { - printf("No training sample files found, nothing to do!\n"); - return EXIT_SUCCESS; - } - - /// @WARNING: This is really important, some libraries (e.g. ROS) seems to set the system locale which takes decimal commata instead of points which causes the file input parsing to fail - setlocale(LC_ALL, "C"); // Do not use the system locale - setlocale(LC_NUMERIC, "C"); - setlocale(LC_ALL, "POSIX"); - - - printf("Reading files, generating HOG features and save them to file '%s':\n", featuresFile.c_str()); - float percent; - - - fstream File; - File.open(featuresFile.c_str(), std::fstream::out); - if(File.is_open()) - { - - // Iterate over POS IMAGES - for(unsigned long currentFile = 0; currentFile < positiveTrainingImages.size(); ++currentFile) - { - - vector featureVector; - const string currentImageFile = positiveTrainingImages.at(currentFile); - - - calculateFeaturesFromInput(currentImageFile, featureVector, hog_); - if(!featureVector.empty()) - { - /* Put positive or negative sample class to file, - * true=positive, false=negative, - * and convert positive class to +1 and negative class to -1 for SVMlight - */ - File << "+1"; - // Save feature vector components - for(unsigned int feature = 0; feature < featureVector.size(); ++feature) - { - File << " " << (feature + 1) << ":" << featureVector.at(feature); - } - File << endl; - } - } - - - // Iterate over NEG IMAGES - for(unsigned long currentFile = 0; currentFile < negativeTrainingImages.size(); ++currentFile) - { - const string currentImageFile = negativeTrainingImages.at(currentFile); - handleNegetivefile(currentImageFile, hog_, File); - } - - printf("\n"); - File.flush(); - File.close(); - - } else - { - printf("Error opening file '%s'!\n", featuresFile.c_str()); - return EXIT_FAILURE; - } - - - //train them with SVM - vector descriptorVector; - hitThreshold = trainWithSVMLight(svmModelFile, descriptorVectorFile, descriptorVector); - - // Pseudo test our custom detecting vector - hog_.setSVMDetector(descriptorVector); - printf( - "Testing training phase using training set as test set (just to check if training is ok - no detection quality conclusion with this!)\n"); - detectTrainingSetTest(hog_, hitThreshold, positiveTrainingImages, negativeTrainingImages); - - - - if(train_hard_negetive_) - { - cout << "Preparing for training HARD negetive windows" << endl; - //create hard training examples - createHardTrainingData(hog_, hitThreshold, negativeTrainingImages); - //train again - hitThreshold = trainWithSVMLight(svmModelHard, descriptorVectorHard, descriptorVector); - - // Pseudo test our custom detecting vector - hog_.setSVMDetector(descriptorVector); - printf( - "Testing training phase using training set as test set after HARD EXAMPLES (just to check if training is ok - no detection quality conclusion with this!)\n"); - detectTrainingSetTest(hog_, hitThreshold, positiveTrainingImages, negativeTrainingImages); - - } - - save(getSpecificTrainingDataLocation() + "/odtrained." + TRAINED_DATA_ID_); - - return EXIT_SUCCESS; - } - - - void ODHOGTrainer::readDescriptorsFromFile(string fileName, vector &descriptor_vector) - { - printf("Reading descriptor vector from file '%s'\n", fileName.c_str()); - string separator = " "; // Use blank as default separator between single features - - ifstream File; - float percent; - File.open(fileName.c_str(), ios::in); - if(File.good() && File.is_open()) - { - - double d; - while(File >> d) - { - //cout << d << " "; - descriptor_vector.push_back(d); - } - File.close(); - } - } - - void ODHOGTrainer::save(std::string filename) - { - FileStorage fs(filename, FileStorage::WRITE); - fs << "hitThreshold" << hitThreshold; - hog_.write(fs, FileStorage::getDefaultObjectName(filename)); - } - - } -} diff --git a/detectors/global2D/training/ODHOGTrainer.h b/detectors/global2D/training/ODHOGTrainer.h deleted file mode 100644 index 377d47e3..00000000 --- a/detectors/global2D/training/ODHOGTrainer.h +++ /dev/null @@ -1,267 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 13.08.15. -// - -#ifndef OPENDETECTION_ODHOGTRAINER_H -#define OPENDETECTION_ODHOGTRAINER_H - -#include -#include "common/pipeline/ODTrainer.h" -#include "common/utils/utils.h" - - - - -namespace od -{ - namespace g2d - { - /** \brief Class for training HOG based detector. - * - * Use ODHOGDetector after training with this class. This is the training class for training HOG based detector. SVMlight is used here to train linear SVM on the HOG features. It supports the usage of multiple random windows in negetive training images - * to increase the number of negetive features by the function 'setNOFeaturesNeg'. It also supports "Hard negetive" training which collects all the false positive - * windows after initial training to retrain and obtain a new feature vector. Use the function 'setTrainHardNegetive' to enable this feature. - * - * \author Kripasindhu Sarkar - */ - - class ODHOGTrainer : public ODTrainer - { - - public: - ODHOGTrainer(std::string const &training_input_location_ = "", std::string const &trained_data_location_ = "", cv::Size winsize = cv::Size(64,128), cv::Size blocksize = cv::Size(16,16), cv::Size blockstride = cv::Size(8,8), cv::Size cellsize = cv::Size(8,8), float hitshreshold = 0.0): - ODTrainer(training_input_location_, trained_data_location_), winSize(winsize), blockSize(blocksize), blockStride(blockstride), - cellSize(cellsize), hog_(winSize, blockSize, blockStride, cellSize, 9) - { - - TRAINED_LOCATION_DENTIFIER_ = "HOG"; - TRAINED_DATA_ID_ = "hog.xml"; - - //algo parameter init - trainingPadding = cv::Size(0, 0); - start_hog_pos = cv::Point(15, 15); - nofeatures_neg = 10; - winStride = cv::Size(); - train_hard_negetive_ = false; - - if(trained_data_location_ != "") - { - posSamplesDir = training_input_location_ + "/pos"; - negSamplesDir = training_input_location_ + "/neg"; - } - - - //internal data - FileUtils::createTrainingDir(getSpecificTrainingDataLocation()); - featuresFile = getSpecificTrainingDataLocation() + "/features.dat"; - svmModelFile = getSpecificTrainingDataLocation() + "/svmlightmodel.dat"; - svmModelHard = getSpecificTrainingDataLocation() + "/svmlightmodelhard.dat"; - descriptorVectorFile = getSpecificTrainingDataLocation() + "/descriptorvector.dat"; - descriptorVectorFile = getSpecificTrainingDataLocation() + "/descriptorvectorHard.dat"; - - - } - - int train(); - - void init() {} - - std::string const &getPosSamplesDir() const - { - return posSamplesDir; - } - - void setPosSamplesDir(std::string const &posSamplesDir) - { - ODHOGTrainer::posSamplesDir = posSamplesDir; - } - - std::string const &getNegSamplesDir() const - { - return negSamplesDir; - } - - void setNegSamplesDir(std::string const &negSamplesDir) - { - ODHOGTrainer::negSamplesDir = negSamplesDir; - } - - int getNOFeaturesNeg() const - { - return nofeatures_neg; - } - - void setNOFeaturesNeg(int featno) - { - ODHOGTrainer::nofeatures_neg = featno; - } - - cv::Point const &getStartHogPos() const - { - return start_hog_pos; - } - - void setStartHogPos(cv::Point const &start_hog_pos) - { - ODHOGTrainer::start_hog_pos = start_hog_pos; - } - - cv::Size const &getWinSize() const - { - return winSize; - } - - void setWinSize(cv::Size const &winSize) - { - ODHOGTrainer::winSize = winSize; - } - - cv::Size const &getBlockSize() const - { - return blockSize; - } - - void setBlockSize(cv::Size const &blockSize) - { - ODHOGTrainer::blockSize = blockSize; - } - - cv::Size const &getBlockStride() const - { - return blockStride; - } - - void setBlockStride(cv::Size const &blockStride) - { - ODHOGTrainer::blockStride = blockStride; - } - - cv::Size const &getCellSize() const - { - return cellSize; - } - - void setCellSize(cv::Size const &cellSize) - { - ODHOGTrainer::cellSize = cellSize; - } - - cv::Size const &getTrainingPadding() const - { - return trainingPadding; - } - - void setTrainingPadding(cv::Size const &trainingPadding) - { - ODHOGTrainer::trainingPadding = trainingPadding; - } - - bool isTrainHardNegetive() const - { - return train_hard_negetive_; - } - - void setTrainHardNegetive(bool train_hard_negetive) - { - ODHOGTrainer::train_hard_negetive_ = train_hard_negetive; - } - - double getHitThreshold() const - { - return hitThreshold; - } - - protected: - //hog specific - cv::Size winSize; - cv::Size blockSize; - cv::Size blockStride; - cv::Size cellSize; - - cv::HOGDescriptor hog_; - - //algo specific - cv::Size trainingPadding; - cv::Point start_hog_pos; - int nofeatures_neg; - cv::Size winStride; - bool train_hard_negetive_; - - //directories - std::string posSamplesDir; - std::string negSamplesDir; - - //properties retained - double hitThreshold; - - private: - //internal training data - std::string featuresFile; - std::string svmModelFile; - std::string svmModelHard; - std::string descriptorVectorFile; - std::string descriptorVectorHard; - - - void readDescriptorsFromFile(std::string fileName, std::vector &descriptor_vector); - - void save(std::string filename); - - void createHardTrainingData(cv::HOGDescriptor const &hog, double const hitThreshold, - std::vector const &negFileNames); - - void calculateFeaturesFromImageLoc(cv::Mat const &imageData, std::vector &featureVector, - cv::HOGDescriptor const &hog, cv::Point startpos); - - - - void detectTrainingSetTest(cv::HOGDescriptor const &hog, double const hitThreshold, - std::vector const &posFileNames, std::vector const &negFileNames); - - - void calculateFeaturesFromInput(std::string const &imageFilename, std::vector &featureVector, - cv::HOGDescriptor &hog); - - - - void saveDescriptorVectorToFile(std::vector &descriptorVector, std::vector &_vectorIndices, - std::string fileName); - - void handleNegetivefile(std::string const imageFilename, cv::HOGDescriptor &hog, std::fstream &file); - - double trainWithSVMLight(std::string svmModelFile, std::string svmDescriptorFile, std::vector &descriptorVector); - }; - /** \example objectdetector/od_hog_train.cpp - */ - - } -} - - - -#endif //OPENDETECTION_ODHOGTRAINER_H diff --git a/detectors/global3D/CMakeLists.txt b/detectors/global3D/CMakeLists.txt deleted file mode 100644 index 86ce4270..00000000 --- a/detectors/global3D/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -set(SUBSYS_NAME pointcloud_global_detector) -set(LIB_NAME od_${SUBSYS_NAME}) -set(SUBSYS_DESC "The global detector for point cloouds") -set(SUBSYS_DEPS od_common ${PCL_LIBRARIES} ${VTK_LIBRARIES} ${OpenCV_LIBS} pugixml siftgpu) - -set(build TRUE) -#PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -#PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS}) - - -if(build) - - #add_subdirectory(detection/simple_ransac_detection) - - set(incs - "ODPointCloudGlobalMatching.h" - - "detection/ODCADDetector3DGlobal.h" - "training/ODCADDetectTrainer3DGlobal.h" - ) - - set(impl_incs - "detection/ODCADDetector3DGlobal.hpp" - ) - - set(srcs - "ODPointCloudGlobalMatching.cpp" - - "detection/ODCADDetector3DGlobal.cpp" - "training/ODCADDetectTrainer3DGlobal.cpp" - - #${SUB_IMPL_SRCS} - ) - - #include all the individual implementation dirs - - - #set mandatory directories - include_directories("${OD_SOURCE_DIR}" ) - - OD_ADD_LIBRARY_ALL("${SUBSYS_NAME}" SRCS ${srcs} INCS ${incs} ${impl_incs}) - install(FILES ${incs} DESTINATION ${OD_INSTALL_INCLUDE_DIR}/${SUBSYS_NAME} COMPONENT ${LIB_NAME}) - - if(SUBSYS_DEPS) - target_link_libraries("${LIB_NAME}" ${SUBSYS_DEPS}) - endif(SUBSYS_DEPS) - - #PCL_MAKE_PKGCONFIG("${LIB_NAME}" "${SUBSYS_NAME}" "${SUBSYS_DESC}" "${SUBSYS_DEPS}" "" "" "" "") - - -endif(build) \ No newline at end of file diff --git a/detectors/global3D/detection/ODCADDetector3DGlobal.h b/detectors/global3D/detection/ODCADDetector3DGlobal.h deleted file mode 100644 index 92329e94..00000000 --- a/detectors/global3D/detection/ODCADDetector3DGlobal.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 16.06.15. -// - -#ifndef OPENDETECTION_ODPOINTCLOUDGLOBALMATCHINGDETECTOR_H -#define OPENDETECTION_ODPOINTCLOUDGLOBALMATCHINGDETECTOR_H - -#include - - - - -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include - -namespace od -{ - namespace g3d - { - /** \brief Detector based on 3D global features like VFH, ESF, CVFH etc. - * - * This class uses PCL 3d_recognition_framework in the background for the detection. First train your data using ODCADDetectTrainer3DGlobal and use this class for the detection. - * This detection will assume the presence of a plane (like a table top) in the pointcloud. It segments the point cloud assuming the presence of a plane and using a simple Euclidian segmentation. - * After that it finds the global features of each segmented scene match them with the trained data thereby performing a clssification. Read the documentation of ODCADDetectTrainer3DGlobal to know how - * the training data should be arranged and trained to get meaningful detection. - * - * This class provides a detection for each segmented scenes which matches them the best. So the number of positive detection is same as the number of possible segmented scene in the point cloud. - * - * \author Kripasindhu Sarkar - * - */ - template - class ODCADDetector3DGlobal : public ODDetector3D - { - - public: - ODCADDetector3DGlobal(std::string const &training_data_location = "", std::string const &training_input_location = "") : ODDetector3D(training_data_location), - NN(2), desc_name("esf") - { - this->TRAINED_LOCATION_DENTIFIER_ = "GLOBAL3DVFH"; - this->training_input_location_ = training_input_location; - } - - void init(); - - ODDetections *detect(ODScenePointCloud *scene); - - ODDetections3D *detectOmni(ODScenePointCloud *scene); - - int getNN() const - { - return NN; - } - - void setNN(int NN) - { - ODCADDetector3DGlobal::NN = NN; - } - - std::string const &getDescName() const - { - return desc_name; - } - - void setDescName(std::string const &desc_name) - { - ODCADDetector3DGlobal::desc_name = desc_name; - } - - protected: - int NN; - std::string desc_name; - boost::shared_ptr > global_; - - }; - /** \example objectdetector/od_pc_global_real_time.cpp - * \example objectdetector/od_pc_global_files.cpp - */ - } -} - -#include "ODCADDetector3DGlobal.hpp" -#endif //OPENDETECTION_ODPOINTCLOUDGLOBALMATCHINGDETECTOR_H diff --git a/detectors/global3D/detection/ODCADDetector3DGlobal.hpp b/detectors/global3D/detection/ODCADDetector3DGlobal.hpp deleted file mode 100644 index 1d5b3c64..00000000 --- a/detectors/global3D/detection/ODCADDetector3DGlobal.hpp +++ /dev/null @@ -1,200 +0,0 @@ -// -// Created by sarkar on 10.08.15. -// - -#ifndef OPENDETECTION_ODCADDETECTOR3DGLOBAL_HPP -#define OPENDETECTION_ODCADDETECTOR3DGLOBAL_HPP - - -namespace od -{ - namespace g3d - { - - template - void ODCADDetector3DGlobal::init() - { - - boost::shared_ptr > mesh_source(new pcl::rec_3d_framework::MeshSource); - mesh_source->setPath(this->training_input_location_); - std::string training_dir_specific = this->getSpecificTrainingDataLocation(); - mesh_source->setModelScale (1.f); - mesh_source->generate(training_dir_specific); - - boost::shared_ptr > cast_source; - cast_source = boost::static_pointer_cast >(mesh_source); - - boost::shared_ptr > normal_estimator; - normal_estimator.reset(new pcl::rec_3d_framework::PreProcessorAndNormalEstimator); - normal_estimator->setCMR(true); - normal_estimator->setDoVoxelGrid(true); - normal_estimator->setRemoveOutliers(true); - normal_estimator->setFactorsForCMR(3, 7); - - if(desc_name.compare("vfh") == 0) - { - boost::shared_ptr > vfh_estimator; - vfh_estimator.reset(new pcl::rec_3d_framework::VFHEstimation); - vfh_estimator->setNormalEstimator(normal_estimator); - - boost::shared_ptr > cast_estimator; - cast_estimator = boost::dynamic_pointer_cast >( - vfh_estimator); - - boost::shared_ptr > global( - new pcl::rec_3d_framework::GlobalNNPipeline()); - global->setDataSource(cast_source); - global->setTrainingDir(training_dir_specific); - global->setDescriptorName(desc_name); - global->setNN(NN); - global->setFeatureEstimator(cast_estimator); - global->initialize(false); - this->global_ = global; - - } else if(desc_name.compare("cvfh") == 0) - { - boost::shared_ptr > vfh_estimator; - vfh_estimator.reset(new pcl::rec_3d_framework::CVFHEstimation); - vfh_estimator->setNormalEstimator(normal_estimator); - - boost::shared_ptr > cast_estimator; - cast_estimator = boost::dynamic_pointer_cast >( - vfh_estimator); - - boost::shared_ptr > global( - new pcl::rec_3d_framework::GlobalNNPipeline()); - global->setDataSource(cast_source); - global->setTrainingDir(training_dir_specific); - global->setDescriptorName(desc_name); - global->setFeatureEstimator(cast_estimator); - global->setNN(NN); - global->initialize(false); - this->global_ = global; - } else if(desc_name.compare("esf") == 0) - { - boost::shared_ptr > estimator; - estimator.reset(new pcl::rec_3d_framework::ESFEstimation); - - boost::shared_ptr > cast_estimator; - cast_estimator = boost::dynamic_pointer_cast >( - estimator); - - boost::shared_ptr > global( - new pcl::rec_3d_framework::GlobalNNPipeline()); - global->setDataSource(cast_source); - global->setTrainingDir(training_dir_specific); - global->setDescriptorName(desc_name); - global->setFeatureEstimator(cast_estimator); - global->setNN(NN); - global->initialize(false); - this->global_ = global; - } else - { - std::cout << "FATAL: descriptor type not available."; - } - - } - - template - ODDetections3D* ODCADDetector3DGlobal::detectOmni(ODScenePointCloud *scene) - { - ODDetections3D *detections = new ODDetections3D; - - - typename pcl::PointCloud::Ptr frame; - float Z_DIST_ = 1.25f; - float text_scale = 0.015f; - - frame = scene->getPointCloud(); - pcl::PointCloud::Ptr xyz_points(new pcl::PointCloud); - pcl::copyPointCloud(*frame, *xyz_points); - - - //Step 1 -> Segment - pcl::apps::DominantPlaneSegmentation dps; - dps.setInputCloud(xyz_points); - dps.setMaxZBounds(Z_DIST_); - dps.setObjectMinHeight(0.005); - dps.setMinClusterSize(1000); - dps.setWSize(9); - dps.setDistanceBetweenClusters(0.1f); - - std::vector::Ptr> clusters; - std::vector indices; - dps.setDownsamplingSize(0.02f); - dps.compute_fast(clusters); - dps.getIndicesClusters(indices); - Eigen::Vector4f table_plane_; - Eigen::Vector3f normal_plane_ = Eigen::Vector3f(table_plane_[0], table_plane_[1], table_plane_[2]); - dps.getTableCoefficients(table_plane_); - - - float dist_ = 0.03f; - - for(size_t i = 0; i < clusters.size(); i++) - { - - global_->setInputCloud(xyz_points); - global_->setIndices(indices[i].indices); - global_->classify(); - - std::vector categories; - std::vector conf; - global_->getCategory(categories); - global_->getConfidence(conf); - //detection done! - - std::string category = categories[0]; - Eigen::Vector4d centroid; - pcl::compute3DCentroid(*xyz_points, indices[i].indices, centroid); - //position at 3D identified! - - //now fill up the detection: - ODDetection3D *detection = new ODDetection3D; - detection->setType(ODDetection::OD_DETECTION_CLASS); - detection->setId(categories[0]); - detection->setLocation(centroid); - detection->setMetainfoCluster(clusters[i]); - detections->push_back(detection); - } - - return detections; - } - - template - ODDetections* ODCADDetector3DGlobal::detect(ODScenePointCloud *scene) - { - ODDetections *detections = new ODDetections; - - - typename pcl::PointCloud::Ptr frame; - float Z_DIST_ = 1.25f; - float text_scale = 0.015f; - - frame = scene->getPointCloud(); - pcl::PointCloud::Ptr xyz_points(new pcl::PointCloud); - pcl::copyPointCloud(*frame, *xyz_points); - - global_->setInputCloud(xyz_points); - //no indices set, so it would try to classify the entire PC - global_->classify(); - - std::vector categories; - std::vector conf; - global_->getCategory(categories); - global_->getConfidence(conf); - //detection done! - - std::string category = categories[0]; - - //now fill up the detection: - ODDetection *detection = new ODDetection3D(ODDetection::OD_DETECTION_CLASS, categories[0], conf[0]); - detections->push_back(detection); - - return detections; - } - } -} - - -#endif //OPENDETECTION_ODCADDETECTOR3DGLOBAL_HPP diff --git a/detectors/global3D/training/ODCADDetectTrainer3DGlobal.cpp b/detectors/global3D/training/ODCADDetectTrainer3DGlobal.cpp deleted file mode 100644 index acbf755f..00000000 --- a/detectors/global3D/training/ODCADDetectTrainer3DGlobal.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 16.06.15. -// - -#include "ODCADDetectTrainer3DGlobal.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int od::g3d::ODCADDetectTrainer3DGlobal::train() -{ - boost::shared_ptr > mesh_source (new pcl::rec_3d_framework::MeshSource); - mesh_source->setPath (training_input_location_); - mesh_source->setResolution (150); - mesh_source->setTesselationLevel (1); - mesh_source->setViewAngle (57.f); - mesh_source->setRadiusSphere (1.5f); - mesh_source->setModelScale (1.f); - std::string training_dir = getSpecificTrainingDataLocation(); - mesh_source->generate (training_dir); - return 1; -} diff --git a/detectors/impl/od/detectors/global3D/detection/CADDetector3DGlobal.hpp b/detectors/impl/od/detectors/global3D/detection/CADDetector3DGlobal.hpp new file mode 100644 index 00000000..75000aa4 --- /dev/null +++ b/detectors/impl/od/detectors/global3D/detection/CADDetector3DGlobal.hpp @@ -0,0 +1,321 @@ +// +// Created by sarkar on 10.08.15. +// +#pragma once + +#include "od/common/pipeline/Detector.h" +#include +#include +#include +#include +#include +#include +#include + +namespace od +{ + namespace g3d + { + + template + class CADDetector3DGlobal : public Detector3D + { + + public: + CADDetector3DGlobal(const std::string & training_data_location = std::string(""), + const std::string & training_input_location = std::string("")) : + Detector3D(training_data_location), NN_(2), desc_name_("esf") + { + this->trained_location_identifier_ = std::string("GLOBAL3DVFH"); + this->training_input_location_ = training_input_location; + } + + void init(); + + int getNN() const + { + return NN_; + } + + void setNN(int NN) + { + NN_ = NN; + } + + const std::string & getDescName() const + { + return desc_name_; + } + + void setDescName(const std::string & desc_name) + { + desc_name_ = desc_name; + } + + shared_ptr detect(shared_ptr scene); + shared_ptr detectOmni(shared_ptr scene); + + shared_ptr detect(shared_ptr > scene); + shared_ptr detectOmni(shared_ptr > scene); + + protected: + + int NN_; + std::string desc_name_; + shared_ptr > global_; + + }; + + template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr>" << std::endl; + return nullptr; + }; + + template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr>" << std::endl; + return nullptr; + }; + + template + void CADDetector3DGlobal::init() + { + + shared_ptr > mesh_source(new pcl::rec_3d_framework::MeshSource); + mesh_source->setPath(this->training_input_location_); + std::string training_dir_specific = this->getSpecificTrainingDataLocation(); + mesh_source->setModelScale(1.f); + mesh_source->generate(training_dir_specific); + + shared_ptr > cast_source; + cast_source = dynamic_pointer_cast >(mesh_source); + + shared_ptr > normal_estimator; + normal_estimator.reset(new pcl::rec_3d_framework::PreProcessorAndNormalEstimator); + normal_estimator->setCMR(true); + normal_estimator->setDoVoxelGrid(true); + normal_estimator->setRemoveOutliers(true); + normal_estimator->setFactorsForCMR(3, 7); + + if(desc_name_.compare("vfh") == 0) + { + shared_ptr > vfh_estimator; + vfh_estimator.reset(new pcl::rec_3d_framework::VFHEstimation); + vfh_estimator->setNormalEstimator(normal_estimator); + + shared_ptr > cast_estimator; + cast_estimator = dynamic_pointer_cast >( + vfh_estimator); + + shared_ptr > global( + new pcl::rec_3d_framework::GlobalNNPipeline()); + global->setDataSource(cast_source); + global->setTrainingDir(training_dir_specific); + global->setDescriptorName(desc_name_); + global->setNN(NN_); + global->setFeatureEstimator(cast_estimator); + global->initialize(false); + global_ = global; + + } else if(desc_name_.compare("cvfh") == 0) + { + shared_ptr > vfh_estimator; + vfh_estimator.reset(new pcl::rec_3d_framework::CVFHEstimation); + vfh_estimator->setNormalEstimator(normal_estimator); + + shared_ptr > cast_estimator; + cast_estimator = dynamic_pointer_cast >( + vfh_estimator); + + shared_ptr > global( + new pcl::rec_3d_framework::GlobalNNPipeline()); + global->setDataSource(cast_source); + global->setTrainingDir(training_dir_specific); + global->setDescriptorName(desc_name_); + global->setFeatureEstimator(cast_estimator); + global->setNN(NN_); + global->initialize(false); + global_ = global; + } else if(desc_name_.compare("esf") == 0) + { + shared_ptr > estimator; + estimator = make_shared >(); + + shared_ptr > cast_estimator; + cast_estimator = dynamic_pointer_cast >( + estimator); + + shared_ptr > global( + new pcl::rec_3d_framework::GlobalNNPipeline()); + global->setDataSource(cast_source); + global->setTrainingDir(training_dir_specific); + global->setDescriptorName(desc_name_); + global->setFeatureEstimator(cast_estimator); + global->setNN(NN_); + global->initialize(false); + global_ = global; + } else + { + std::cout << "FATAL: descriptor type not available." << std::endl; + } + + } + + template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr > scene) + { + shared_ptr detections = make_shared(); + + typename pcl::PointCloud::Ptr frame = scene->getPointCloud(); + pcl::PointCloud::Ptr xyz_points(new pcl::PointCloud); + pcl::copyPointCloud(*frame, *xyz_points); + + //Step 1 -> Segment + pcl::apps::DominantPlaneSegmentation dps; + dps.setInputCloud(xyz_points); + dps.setMaxZBounds(1.25f); + dps.setObjectMinHeight(0.005); + dps.setMinClusterSize(1000); + dps.setWSize(9); + dps.setDistanceBetweenClusters(0.1f); + + std::vector::Ptr> clusters; + std::vector indices; + dps.setDownsamplingSize(0.02f); + dps.compute_fast(clusters); + dps.getIndicesClusters(indices); + Eigen::Vector4f table_plane_; + dps.getTableCoefficients(table_plane_); + + for(size_t i = 0; i < clusters.size(); ++i) + { + + global_->setInputCloud(xyz_points); + global_->setIndices(indices[i].indices); + global_->classify(); + + std::vector categories; + std::vector conf; + global_->getCategory(categories); + global_->getConfidence(conf); + //detection done! + + std::string category = categories[0]; + Eigen::Vector4d centroid; + pcl::compute3DCentroid(*xyz_points, indices[i].indices, centroid); + //position at 3D identified! + + //now fill up the detection: + shared_ptr detection = make_shared(); + detection->setType(detection::CLASSIFICATION); + detection->setId(categories[0]); + detection->setLocation(centroid); + detection->setMetainfoCluster(clusters[i]); + detections->push_back(detection); + } + + return detections; + } + + template + shared_ptr CADDetector3DGlobal::detect(shared_ptr > scene) + { + shared_ptr detections = make_shared(); + + typename pcl::PointCloud::Ptr frame = scene->getPointCloud(); + pcl::PointCloud::Ptr xyz_points(new pcl::PointCloud); + pcl::copyPointCloud(*frame, *xyz_points); + + global_->setInputCloud(xyz_points); + //no indices set, so it would try to classify the entire PC + global_->classify(); + + std::vector categories; + std::vector conf; + global_->getCategory(categories); + global_->getConfidence(conf); + //detection done! + + //now fill up the detection: + shared_ptr detection(new Detection(detection::CLASSIFICATION, categories[0], conf[0])); + + detections->push_back(detection); + + return detections; + } + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + extern template + void CADDetector3DGlobal::init(); + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr > scene); + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr > scene); + + + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + extern template + void CADDetector3DGlobal::init(); + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr > scene); + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr > scene); + + + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + extern template + void CADDetector3DGlobal::init(); + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + extern template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr > scene); + + extern template + shared_ptr CADDetector3DGlobal::detect(shared_ptr > scene); + +#endif + } +} diff --git a/detectors/impl/od/detectors/misc/detection/DetectorMultiAlgo.hpp b/detectors/impl/od/detectors/misc/detection/DetectorMultiAlgo.hpp new file mode 100644 index 00000000..45806813 --- /dev/null +++ b/detectors/impl/od/detectors/misc/detection/DetectorMultiAlgo.hpp @@ -0,0 +1,321 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 06.08.15. +// +#pragma once +#include "od/detectors/global2D/detection/CascadeDetector.h" +#include "od/detectors/global2D/detection/HOGDetector.h" +#include "od/detectors/global3D/detection/CADDetector3DGlobal.hpp" + +namespace od +{ + + template + class DetectorMultiAlgo2D : public Detector2D + { + public: + DetectorMultiAlgo2D(const std::string & training_data_location_) : Detector2D(training_data_location_){} + + shared_ptr detect(shared_ptr scene); + shared_ptr detectOmni(shared_ptr scene); + + shared_ptr detect(shared_ptr > scene); + shared_ptr detectOmni(shared_ptr > scene); + + shared_ptr detectOmni(shared_ptr scene); + shared_ptr detect(shared_ptr scene); + + void init(); + + private: + + std::vector > detectors_2d_; + std::vector > > detectors_3d_; + + }; + + template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr or shared_ptr>" << std::endl; + return nullptr; + } + + template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr or shared_ptr>" << std::endl; + return nullptr; + } + + //BASED ON 2D SCENE + template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene) + { + shared_ptr detections_all = make_shared(); + for(auto & d : detectors_2d_) + { + detections_all->append(d->detect(scene)); + } + + return detections_all; + } + + template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene) + { + shared_ptr detections_all = make_shared(); + for(auto & d : detectors_2d_) + { + detections_all->append(d->detectOmni(scene)); + } + + return detections_all; + } + + template + void DetectorMultiAlgo2D::init() + { + //make a list of different algorithms + //vector detectors = {new CascadeDetector(trained_data_location_), new HOGDetector(trained_data_location_), new CADRecognizer2DLocal(trained_data_location_)}; + +#ifndef WITH_BOOST_SHARED_PTR + #if WITH_GPU + detectors_2d_.push_back(shared_ptr(new g2d::CascadeDetector(true, trained_data_location_))); + #else + detectors_2d_.push_back(shared_ptr(new g2d::CascadeDetector(false, trained_data_location_))); + #endif + detectors_2d_.push_back(shared_ptr(new g2d::HOGDetector(trained_data_location_))); +#else + #if WITH_GPU + detectors_2d_.push_back(make_shared(true, trained_data_location_)); + #else + detectors_2d_.push_back(make_shared(false, trained_data_location_)); + #endif + detectors_2d_.push_back(make_shared(trained_data_location_)); +#endif + + // detectors.push_back(new CADRecognizer2DLocal(trained_data_location_)); + + for(auto & d : detectors_2d_) + { + d->init(); + } + } + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + extern template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + extern template + void DetectorMultiAlgo2D::init(); + + + + extern template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + extern template + void DetectorMultiAlgo2D::init(); + + + + + extern template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + extern template + void DetectorMultiAlgo2D::init(); + +#endif + + template + class DetectorMultiAlgo : public Detector + { + + public: + + DetectorMultiAlgo(const std::string & training_data_location_) : Detector(training_data_location_){} + + shared_ptr detect(shared_ptr scene); + shared_ptr detectOmni(shared_ptr scene); + + shared_ptr detect(shared_ptr > scene); + shared_ptr detectOmni(shared_ptr > scene); + + shared_ptr detectOmni(shared_ptr scene); + shared_ptr detect(shared_ptr scene); + + void init(); + + private: + + std::vector > detectors_2d_; + std::vector > > detectors_3d_; + + }; + + template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr or shared_ptr>" << std::endl; + return nullptr; + } + + template + shared_ptr DetectorMultiAlgo::detect(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr or shared_ptr>" << std::endl; + return nullptr; + } + + + /////############BASED ON 3D SCENE##################### + template + void DetectorMultiAlgo::init() + { + //3D +#ifndef WITH_BOOST_SHARED_PTR + detectors_3d_.push_back(shared_ptr >(new g3d::CADDetector3DGlobal(trained_data_location_, training_input_location_))); +#else + detectors_3d_.push_back(make_shared >(trained_data_location_, training_input_location_)); +#endif + for(auto & d : detectors_3d_) + { + d->init(); + } + } + + template + shared_ptr DetectorMultiAlgo::detect(shared_ptr > scene) + { + shared_ptr detections_all = make_shared(); + for(auto & d : detectors_3d_) + { + detections_all->append(d->detect(scene)); + } + + return detections_all; + } + + template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr > scene) + { + shared_ptr detections_all = make_shared(); + for(auto & d : detectors_3d_) + { + detections_all->append(d->detectOmni(scene)); + } + + return detections_all; + } + + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + + extern template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo::detect(shared_ptr scene); + + extern template + void DetectorMultiAlgo::init(); + + extern template + shared_ptr DetectorMultiAlgo::detect(shared_ptr > scene); + + extern template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr > scene); + + + + extern template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo::detect(shared_ptr scene); + + extern template + void DetectorMultiAlgo::init(); + + extern template + shared_ptr DetectorMultiAlgo::detect(shared_ptr > scene); + + extern template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr > scene); + + + + extern template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr scene); + + extern template + shared_ptr DetectorMultiAlgo::detect(shared_ptr scene); + + extern template + void DetectorMultiAlgo::init(); + + extern template + shared_ptr DetectorMultiAlgo::detect(shared_ptr > scene); + + extern template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr > scene); + + +#endif + +} \ No newline at end of file diff --git a/detectors/include/od/detectors/global2D/FaceRecognizer.h b/detectors/include/od/detectors/global2D/FaceRecognizer.h new file mode 100644 index 00000000..37998509 --- /dev/null +++ b/detectors/include/od/detectors/global2D/FaceRecognizer.h @@ -0,0 +1,101 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 16.06.15. +// +#pragma once +#include "od/common/pipeline/Detector.h" +#include + +namespace od +{ + namespace g2d + { + + + /** \brief A facerecognizer based on EigenFace and FischerFace algorithms. + * + * Currently it just supports detection on fixed scene (detect()) and does not support multiscale detection. This is due to the fact that class for cascade classifier - + * CascadeDetector supports multiscale detection and can be easily integrated with this recognizer - first by finding face using the Cascade and then applying this recognizer on that detected window. + * This is faster than trying to perform recognition on each multiscale window. + * + * \author Kripasindhu Sarkar + * + */ + + class FaceRecognizer : public ObjectDetector + { + public: + + _DEFINE_ENUM_WITH_STRING_CONVERSIONS(FaceRecogType, (_FACE_FISCHER)(_FACE_EIGEN)) + + FaceRecognizer(FaceRecogType recog_type = _FACE_EIGEN, int num_components = 0, double threshold = DBL_MAX); + + void init(); + + void initTrainer(); + + void initDetector(); + + int train(); + + shared_ptr detect(shared_ptr scene); + shared_ptr detectOmni(shared_ptr scene); + + virtual shared_ptr detect(shared_ptr scene); + virtual shared_ptr detectOmni(shared_ptr scene); + + virtual int detect(shared_ptr scene, const std::vector > & detections); + + const FaceRecogType & getRecogtype() const; + void setRecogtype(const FaceRecogType & recog_type); + + int getThreshold() const; + void setThreshold(int threshold); + + int getNumComponents() const; + void setNumComponents(int num_components); + + protected: + + cv::Ptr cv_recognizer_; + FaceRecogType recog_type_; + + int num_components_; + double threshold_; + unsigned int im_height_; + unsigned int im_width_; + + private: + + void read_csv(const std::string & file_name, std::vector & images, std::vector & labels, + const std::string & separator = std::string(";")); + + }; + + } + +} diff --git a/detectors/include/od/detectors/global2D/annotation/Annotation.h b/detectors/include/od/detectors/global2D/annotation/Annotation.h new file mode 100644 index 00000000..ed052af0 --- /dev/null +++ b/detectors/include/od/detectors/global2D/annotation/Annotation.h @@ -0,0 +1,119 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "opencv2/objdetect/objdetect.hpp" +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/core/core.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace od +{ + namespace g2d + { + + class Annotation : public Gtk::Window + { + public: + Annotation(); + virtual ~Annotation(); + + protected: + void on_button_clicked(Glib::ustring data); + void on_combo_changed(); + void on_cell_data_extra(const Gtk::TreeModel::const_iterator& iter); + void showWindow_main(); + void showWindow_imageLoad(Glib::ustring data); + bool on_button_press_event(GdkEventButton *event); + void createDot(int x, int y); + void loadOriginalImage(std::string data, bool st); + void createVisualROI(int xPressed, int yPressed, int xReleased, int yReleased); + void loadOriginalImageWithSavedMarkings(std::string filename, std::vector > & storageROILocationMultiple, bool st); + void loadResetedMarkings(std::string data, std::vector > & roi, bool st); + // Child widgets: + Gtk::Grid m_grid1, + m_grid_imageLoad; + + Gtk::ScrolledWindow m_sw1, + m_sw_imageLoad; + + Gtk::Button button_selectImageFileName, + button_loadImage, + button_loadAnotherImage, + button_resetMarkings, + button_loadMainWindow, + button_selectRoi, + button_saveMarked, + button_saveCropMarked, + button_resetMarkingsCurrent, + button_selectRoiCurrent, + button_saveMarkedMultiple, + button_selectDatasetFolder, + button_saveCropMarkedMultiple, + button_loadNextImage, + button_resetSegnetMaskCurrent, + button_selectSegnetMaskCurrent, + button_saveSegnetMask, + button_quit; + + Gtk::RadioButton rbutton_markBB, rbutton_cropBB, rbutton_markBBWithLabel, + rbutton_cropMultipleBB, rbutton_segnetMaskedBased; + + Gtk::Label label_annotationType, + label_outputFile, + label_annotationLabel; + + Gtk::Entry text_outputFile, + text_annotationLabel; + + private: + Glib::ustring imageFileLocation; + std::string filename, foldername, file_folder; + Gtk::Image image; + double imgFocusX,imgFocusY, scale; + int lastXMouse, lastYMouse, xPressed, yPressed, xReleased, yReleased, storage, imagesInFolder, storageID; + bool resetFlag, moveFlag, targetFlag, status; + + std::string currentWindow; + std::vector storageFileName, imageFileNames; + std::vector widthMultiplier, heightMultiplier; + std::vector > storageROILocationCurrent, roiPointsForMask, roiPointsForMaskPermanent, storageROILocation; + float w,h; + }; + + } +} \ No newline at end of file diff --git a/detectors/include/od/detectors/global2D/annotation/Annotator.h b/detectors/include/od/detectors/global2D/annotation/Annotator.h new file mode 100644 index 00000000..00533516 --- /dev/null +++ b/detectors/include/od/detectors/global2D/annotation/Annotator.h @@ -0,0 +1,27 @@ +#pragma once + +#include "od/common/pipeline/Trainer.h" +#include "od/common/utils/Utils.h" +#include + +#include "Annotation.h" + +namespace od +{ + namespace g2d + { + + class Annotator : public Trainer + { + public: + + Annotator(const std::string & training_input_location_ = std::string(""), const std::string & trained_data_location_ = std::string("")): + Trainer(training_input_location_, trained_data_location_){} + + int train(); + void init(){} + void startAnnotator(int argc, char *argv[]); + }; + } +} + diff --git a/detectors/global2D/detection/ODCascadeDetector.h b/detectors/include/od/detectors/global2D/detection/CascadeDetector.h similarity index 57% rename from detectors/global2D/detection/ODCascadeDetector.h rename to detectors/include/od/detectors/global2D/detection/CascadeDetector.h index 9d152d84..42a4516a 100644 --- a/detectors/global2D/detection/ODCascadeDetector.h +++ b/detectors/include/od/detectors/global2D/detection/CascadeDetector.h @@ -18,7 +18,7 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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 @@ -26,16 +26,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */// // Created by sarkar on 17.07.15. // +#pragma once +#include "od/common/pipeline/Detector.h" +#include "od/common/pipeline/Scene.h" +#include "od/common/utils/Utils.h" +#include "od/detectors/global2D/detection/CascadeDetectorInterface.h" +#include "od/detectors/global2D/detection/CascadeDetectorImpl.h" +#include "od/gpu/detectors/global2D/detection/CascadeDetectorImpl.h" -#ifndef OPENDETECTION_ODCASCADEDETECTOR_H -#define OPENDETECTION_ODCASCADEDETECTOR_H - -#include "common/pipeline/ODDetector.h" -#include "common/pipeline/ODScene.h" -#include "common/utils/utils.h" -#include "common/utils/ODFeatureDetector2D.h" - -#include #include namespace od @@ -43,7 +41,7 @@ namespace od namespace g2d { /** \brief A class for detection using Cascade classifiers. - * Given a scene and a cascade classifier, this class performs a classification and returns detections. The training is not supported in OD currently but is compatible to the cascade training of OpenCV. + * Given a scene and a cascade classifier, this class performs a classification and returns detections. The training is not supported in currently but is compatible to the cascade training of OpenCV. * Train your cascade classifiers using OpenCV's *opencv_traincascade* utility (http://docs.opencv.org/master/dc/d88/tutorial_traincascade.html#gsc.tab=0). It is a great tool for traning your cascade. * Paste the generated xml in trained_data_location_/TD_CASCADE/\*.cascade.xml to use your trained cascade. * @@ -51,41 +49,42 @@ namespace od * */ - class ODCascadeDetector : public ODDetector2D + class CascadeDetector : public Detector2D { + public: - ODCascadeDetector(std::string const &trained_data_location = "", double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0, cv::Size minSize = cv::Size(), cv::Size maxSize = cv::Size()) - : ODDetector2D(trained_data_location), scaleFactor_(scaleFactor), minNeighbors_(minNeighbors), minSize_(minSize), maxSize_(maxSize) - { - TRAINED_LOCATION_DENTIFIER_ = "CASCADE"; - TRAINED_DATA_ID_ = "cascade.xml"; - metainfo_ = true; - } + CascadeDetector(bool gpu = false, const std::string & trainer = std::string("cascade.xml"), const std::string & trained_data_location = std::string(""), double scale_factor = 1.1, int min_neighbors = 3, + int flags = 0, const cv::Size & min_size = cv::Size(), const cv::Size & max_size = cv::Size()); + + void init(); + + shared_ptr detectOmni(shared_ptr scene); + shared_ptr detect(shared_ptr scene); - void init() - { - haar_cascade_ = boost::make_shared(FileUtils::getFirstFile(getSpecificTrainingDataLocation(), - TRAINED_DATA_ID_)); - } + shared_ptr detectOmni(shared_ptr scene); - ODDetections2D *detectOmni(ODSceneImage *scene); - ODDetections* detect(ODSceneImage *scene); + void setScale(const float scale); + float getScale() const; + + void setMinNeighbors(const unsigned int min_neighbors); + unsigned int getMinNeighbors() const; + + void setMinSize(const cv::Size & size); + cv::Size getMinSize() const; + + void setMaxSize(const cv::Size & size); + cv::Size getMaxSize() const; private: - boost::shared_ptr haar_cascade_; - double scaleFactor_; - int minNeighbors_; - cv::Size minSize_; - cv::Size maxSize_; + shared_ptr cascade_detector_; }; - /** \example objectdetector/od_image_cascade.cpp - * \example objectdetector/od_image_cascade_files.cpp + + /** \examples objectdetector/od_image_cascade.cpp + * \examples objectdetector/od_image_cascade_files.cpp */ } -} - -#endif //OPENDETECTION_ODCASCADEDETECTOR_H +} \ No newline at end of file diff --git a/detectors/include/od/detectors/global2D/detection/CascadeDetectorImpl.h b/detectors/include/od/detectors/global2D/detection/CascadeDetectorImpl.h new file mode 100644 index 00000000..c57b887d --- /dev/null +++ b/detectors/include/od/detectors/global2D/detection/CascadeDetectorImpl.h @@ -0,0 +1,97 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 17.07.15. +// +#pragma once +#include "od/common/pipeline/Detector.h" +#include "od/common/pipeline/Scene.h" +#include "od/common/utils/Utils.h" +#include "od/detectors/global2D/detection/CascadeDetectorInterface.h" +#include + +namespace od +{ + namespace g2d + { + /** \brief A class for detection using Cascade classifiers. + * Given a scene and a cascade classifier, this class performs a classification and returns detections. The training is not supported in currently but is compatible to the cascade training of OpenCV. + * Train your cascade classifiers using OpenCV's *opencv_traincascade* utility (http://docs.opencv.org/master/dc/d88/tutorial_traincascade.html#gsc.tab=0). It is a great tool for traning your cascade. + * Paste the generated xml in trained_data_location_/TD_CASCADE/\*.cascade.xml to use your trained cascade. + * + * \author Kripasindhu Sarkar + * + */ + class CascadeDetectorImpl : public CascadeDetectorInterface + { + public: + + CascadeDetectorImpl(const std::string & trainer = std::string("cascade.xml"), const std::string & trained_data_location = std::string(""), double scale_factor = 1.1, int min_neighbors = 3, + int flags = 0, const cv::Size & min_size = cv::Size(), const cv::Size & max_size = cv::Size()); + + void init(); + + shared_ptr detectOmni(shared_ptr scene); + shared_ptr detect(shared_ptr scene); + + shared_ptr detectOmni(shared_ptr scene); + + void setScale(const float scale); + float getScale() const; + + void setMinNeighbors(const unsigned int min_neighbors); + unsigned int getMinNeighbors() const; + + void setMinSize(const cv::Size & size); + cv::Size getMinSize() const; + + void setMaxSize(const cv::Size & size); + cv::Size getMaxSize() const; + + private: + + shared_ptr haar_cascade_; + + bool meta_info_; + + std::string trained_data_location_, trained_data_id_, trained_location_identifier_; + double scale_factor_; + int min_neighbors_; + cv::Size min_size_; + cv::Size max_size_; + + + }; + /** \examples objectdetector/od_image_cascade.cpp + * \examples objectdetector/od_image_cascade_files.cpp + */ + } + +} + + + + diff --git a/detectors/global3D/detection/ODCADDetector3DGlobal.cpp b/detectors/include/od/detectors/global2D/detection/CascadeDetectorInterface.h similarity index 60% rename from detectors/global3D/detection/ODCADDetector3DGlobal.cpp rename to detectors/include/od/detectors/global2D/detection/CascadeDetectorInterface.h index f048ec70..b87bb04b 100644 --- a/detectors/global3D/detection/ODCADDetector3DGlobal.cpp +++ b/detectors/include/od/detectors/global2D/detection/CascadeDetectorInterface.h @@ -18,13 +18,42 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. */// -// Created by sarkar on 16.06.15. +// Created by Giacomo Dabisias on 21.07.16. // +#pragma once +#include +#include "od/common/utils/Shared_pointers.h" +namespace od +{ + class CascadeDetectorInterface + { + public: -#include "ODCADDetector3DGlobal.h" + virtual shared_ptr detectOmni(shared_ptr scene) = 0; + virtual shared_ptr detect(shared_ptr scene) = 0; + + virtual shared_ptr detectOmni(shared_ptr scene) = 0; + + virtual void init() = 0; + + virtual void setScale(const float scale) = 0; + virtual float getScale() const = 0; + + virtual void setMinNeighbors(const unsigned int min_neighbors) = 0; + virtual unsigned int getMinNeighbors() const = 0; + + virtual void setMinSize(const cv::Size & size) = 0; + virtual cv::Size getMinSize() const = 0; + + virtual void setMaxSize(const cv::Size & size) = 0; + virtual cv::Size getMaxSize() const = 0; + + }; + +} \ No newline at end of file diff --git a/detectors/include/od/detectors/global2D/detection/HOGDetector.h b/detectors/include/od/detectors/global2D/detection/HOGDetector.h new file mode 100644 index 00000000..1219cce0 --- /dev/null +++ b/detectors/include/od/detectors/global2D/detection/HOGDetector.h @@ -0,0 +1,127 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 15.07.15. +// +#pragma once +#include "od/common/pipeline/Detector.h" +#include "od/common/pipeline/Scene.h" +#include "od/common/utils/Utils.h" +#include "od/common/utils/FeatureDetector2D.h" +#include "od/common/utils/Shared_pointers.h" + +#include +#include + +namespace od +{ + + namespace g2d + { + /** \brief A linear classifier for HOG features. + * + * This class takes an image as an input, finds its HOG features using the parameters containing in the trained data, runs the linear classifier (present in the trained data) on the computed HOG features + * and finally produces the classification output. Covers both multiscale detection (detectOmni()) and detection on a fixed scene (detect() - the scene is resized to the HOG window size). + * + * Use HOGTrainer for the training of new objects. By default this class provides two people detector: _DEFAULT_PEOPLE, the people detector from OpenCV and _DAIMLER_PEOPLE, the second detector available from OpenCV. + * One can set any linear classifier, the linear weight vector through setSVMDetector() function but it is highly not recommended as the HOG parameters and the weight vector can be out of sync. + * One must set appropriate HOG parameters after using setSVMDetector() function with which the weight vector was trained. + * + * \author Kripasindhu Sarkar + * + */ + + + class HOGDetector : public Detector2D + { + public: + + HOGDetector(const std::string & trained_data_location_ = std::string(""), const cv::Size & win_size = cv::Size(64,128), + const cv::Size & block_size = cv::Size(16,16), const cv::Size & block_stride = cv::Size(8,8), + const cv::Size & cell_size = cv::Size(8,8), float hit_threshold = 0.0); + + _DEFINE_ENUM_WITH_STRING_CONVERSIONS(SVMType, (_DEFAULT_PEOPLE)(_DAIMLER_PEOPLE)(_FILE)) + + void init(); + void load(const std::string & file_name); + + void setSVMFromFile(const std::string & file_name); + + void setSVMDetector(std::vector svm_detector); + + shared_ptr detectOmni(shared_ptr scene); + shared_ptr detect(shared_ptr scene); + + int detect(shared_ptr scene, std::vector > & detections); + + void setTrainedDataLocation(const std::string & trained_data_location); + + const SVMType & getSvmtype() const; + void setSvmtype(const SVMType & svm_type); + + const cv::Size & getWinSize() const; + void setWinSize(const cv::Size & win_size); + + const cv::Size & getBlockSize() const; + void setBlockSize(const cv::Size & block_size); + + const cv::Size & getBlockStride() const; + void setBlockStride(const cv::Size & block_stride); + + const cv::Size & getCellSize() const; + void setCellSize(const cv::Size & cell_size); + + float getHitThreshold() const; + void setHitThreshold(float hit_threshold); + + void printParameters(); + + shared_ptr detectOmni(shared_ptr scene); + + protected: + //properties + cv::Size win_size_; + cv::Size block_size_; + cv::Size block_stride_; + cv::Size cell_size_; + + float hit_threshold_; + + cv::HOGDescriptor hog_; + SVMType svm_type_; + + }; + + /** \examples objectdetector/od_image_hog.cpp + * \examples objectdetector/od_image_hog_files.cpp + * \examples apps/global2D/od_multihog_app.cpp + * This is an example of how to use the HOGDetector class. + * + * More details about this example. + */ + } +} + diff --git a/detectors/include/od/detectors/global2D/training/HOGTrainer.h b/detectors/include/od/detectors/global2D/training/HOGTrainer.h new file mode 100644 index 00000000..3a00c973 --- /dev/null +++ b/detectors/include/od/detectors/global2D/training/HOGTrainer.h @@ -0,0 +1,155 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 13.08.15. +// +#pragma once +#include +#include +#include +#include "od/common/pipeline/Trainer.h" +#include "od/common/bindings/Svmlight.h" + +namespace od +{ + namespace g2d + { + /** \brief Class for training HOG based detector. + * + * Use HOGDetector after training with this class. This is the training class for training HOG based detector. SVMlight is used here to train linear SVM on the HOG features. It supports the usage of multiple random windows in negetive training images + * to increase the number of negetive features by the function 'setNOFeaturesNeg'. It also supports "Hard negetive" training which collects all the false positive + * windows after initial training to retrain and obtain a new feature vector. Use the function 'setTrainHardNegetive' to enable this feature. + * + * \author Kripasindhu Sarkar + */ + + class HOGTrainer : public Trainer + { + + public: + + HOGTrainer(const std::string & training_input_location_ = std::string(""), const std::string & trained_data_location_ = std::string(""), + const cv::Size & win_size = cv::Size(64,128), const cv::Size & block_size = cv::Size(16,16), + const cv::Size & block_stride = cv::Size(8,8), const cv::Size & cell_size = cv::Size(8,8), float hits_threshold = 0.0); + + int train(); + + void init(){} + + const std::string & getPosSamplesDir() const; + void setPosSamplesDir(const std::string & pos_samples_dir); + + const std::string & getNegSamplesDir() const; + void setNegSamplesDir(const std::string & neg_samples_dir); + + int getNOFeaturesNeg() const; + void setNOFeaturesNeg(int featno); + + const cv::Point & getStartHogPos() const; + void setStartHogPos(const cv::Point & start_hog_pos); + + const cv::Size & getWinSize() const; + void setWinSize(const cv::Size & win_size); + + const cv::Size & getBlockSize() const; + void setBlockSize(const cv::Size & block_size); + + const cv::Size & getBlockStride() const; + void setBlockStride(const cv::Size & block_stride); + + const cv::Size & getCellSize() const; + void setCellSize(const cv::Size & cell_size); + + const cv::Size & getTrainingPadding() const; + void setTrainingPadding(const cv::Size & training_padding); + + bool isTrainHardNegetive() const; + void setTrainHardNegetive(bool train_hard_negative); + + double getHitThreshold() const; + + protected: + //hog specific + cv::Size win_size_; + cv::Size block_size_; + cv::Size block_stride_; + cv::Size cell_size_; + cv::Size win_stride_; + cv::Size training_padding_; + + cv::HOGDescriptor hog_; + + //algo specific + cv::Point start_hog_pos_; + unsigned int no_features_neg_; + bool train_hard_negative_; + + //directories + std::string pos_samples_dir_, neg_samples_dir_; + + //properties retained + double hit_threshold_; + + private: + + void readDescriptorsFromFile(const std::string & file_name, std::vector & descriptor_vector); + + void save(const std::string & filename); + + void createHardTrainingData(const cv::HOGDescriptor & hog, double hit_threshold, + const std::vector & neg_file_names); + + void calculateFeaturesFromImageLoc(const cv::Mat & image_data, std::vector & feature_vector, + const cv::HOGDescriptor & hog, const cv::Point & start_pos); + + + + void detectTrainingSetTest(const cv::HOGDescriptor & hog, double hit_threshold, + const std::vector & pos_file_names, const std::vector & neg_file_names); + + + void calculateFeaturesFromInput(const std::string & image_filename, std::vector & featureVector, + cv::HOGDescriptor & hog); + + + + void saveDescriptorVectorToFile(const std::vector & descriptor_vector, const std::string & file_name); + + void handleNegetivefile(const std::string & image_filename, cv::HOGDescriptor & hog, std::fstream & file); + + double trainWithSVMLight(const std::string & svm_model_file, const std::string & svm_descriptor_file, std::vector & descriptor_vector); + + std::string features_file_; + std::string svm_model_file_; + std::string svm_model_hard_; + std::string descriptor_vector_file_; + std::string descriptor_vector_hard_; + + }; + + } + +} diff --git a/common/pipeline/ODAlgorithmBase.h b/detectors/include/od/detectors/global3D/PointCloudGlobalMatching.h similarity index 66% rename from common/pipeline/ODAlgorithmBase.h rename to detectors/include/od/detectors/global3D/PointCloudGlobalMatching.h index ba38a7cb..23891d84 100644 --- a/common/pipeline/ODAlgorithmBase.h +++ b/detectors/include/od/detectors/global3D/PointCloudGlobalMatching.h @@ -18,41 +18,44 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. -*/ +*/// +// Created by sarkar on 16.06.15. // -// Created by sarkar on 12.06.15. -// - -#ifndef OPENDETECTION_ODALGORITHMBASE_H -#define OPENDETECTION_ODALGORITHMBASE_H -#include -#include -#include - +#pragma once +#include "od/detectors/global3D/training/CADDetectTrainer3DGlobal.h" +#include "od/detectors/global3D/detection/CADDetector3DGlobal.hpp" namespace od { - /** \brief The base of all algorithm classes + namespace g3d + { + /** \brief PointCloudGlobalMatching: global feature based object detection in point cloud * * \author Kripasindhu Sarkar * */ - class ODAlgorithmBase - { - public: - virtual void parseParameterString(std::string parameter_string) - { } + class PointCloudGlobalMatching : ObjectDetector + { - virtual void init() - { } - }; -} + void init(){} + + int train(); -#endif //OPENDETECTION_ODALGORITHMBASE_H + int detect(shared_ptr scene, std::vector> & detections); + + protected: + + std::string desc_name_; + shared_ptr trainer_; + shared_ptr > detector_; + + }; + } +} diff --git a/detectors/global3D/training/ODCADDetectTrainer3DGlobal.h b/detectors/include/od/detectors/global3D/training/CADDetectTrainer3DGlobal.h similarity index 65% rename from detectors/global3D/training/ODCADDetectTrainer3DGlobal.h rename to detectors/include/od/detectors/global3D/training/CADDetectTrainer3DGlobal.h index 400de8a5..3c3668cc 100644 --- a/detectors/global3D/training/ODCADDetectTrainer3DGlobal.h +++ b/detectors/include/od/detectors/global3D/training/CADDetectTrainer3DGlobal.h @@ -18,7 +18,7 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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 @@ -26,20 +26,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */// // Created by sarkar on 16.06.15. // - -#ifndef OPENDETECTION_ODPOINTCLOUDGLOBALMATCHINGTRAINER_H -#define OPENDETECTION_ODPOINTCLOUDGLOBALMATCHINGTRAINER_H - -#include -#include +#pragma once +#include +#include "od/common/pipeline/Trainer.h" namespace od { namespace g3d { -/** \brief Training class for the detector ODCADDetector3DGlobal. +/** \brief Training class for the detector CADDetector3DGlobal. * - * This class uses PCL 3d_recognition_framework in the background for the training of 3D CAD models (in PLY format) and should be used with ODCADDetector3DGlobal for their detection in a pointcloud. + * This class uses PCL 3d_recognition_framework in the background for the training of 3D CAD models (in PLY format) and should be used with CADDetector3DGlobal for their detection in a pointcloud. * In the training_input_location_ the CAD models should be arranged in the following structure: * * - \ @@ -62,45 +59,31 @@ namespace od - /home/user/DB/fruit/banana.ply - After the training use the detector class ODCADDetector3DGlobal. + After the training use the detector class CADDetector3DGlobal. * * \author Kripasindhu Sarkar * */ - class ODCADDetectTrainer3DGlobal : public ODTrainer + class CADDetectTrainer3DGlobal : public Trainer { public: - ODCADDetectTrainer3DGlobal(std::string const &training_input_location_ = "", std::string const &training_data_location_ = "") : ODTrainer( - training_input_location_, training_data_location_) - { - desc_name = "esf"; - TRAINED_LOCATION_DENTIFIER_ = "GLOBAL3DVFH"; - } + + CADDetectTrainer3DGlobal(const std::string & training_input_location_ = std::string(""), + const std::string & training_data_location_ = std::string("")); int train(); void init() {}; - std::string const &getDescName() const - { - return desc_name; - } - - void setDescName(std::string const &desc_name) - { - ODCADDetectTrainer3DGlobal::desc_name = desc_name; - } + const std::string & getDescName() const; + void setDescName(const std::string & desc_name); protected: - std::string desc_name; - }; - - /** \example objectdetector/od_pc_global_real_time.cpp - * \example objectdetector/od_pc_global_files.cpp - */ + std::string desc_name_; + + }; } } -#endif //OPENDETECTION_ODPOINTCLOUDGLOBALMATCHINGTRAINER_H diff --git a/detectors/local2D/training/ODCADRecogTrainerSnapshotBased.h b/detectors/include/od/detectors/local2D/ImageLocalMatching.h similarity index 54% rename from detectors/local2D/training/ODCADRecogTrainerSnapshotBased.h rename to detectors/include/od/detectors/local2D/ImageLocalMatching.h index 42682489..a13d9d12 100644 --- a/detectors/local2D/training/ODCADRecogTrainerSnapshotBased.h +++ b/detectors/include/od/detectors/local2D/ImageLocalMatching.h @@ -18,71 +18,86 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. */ // -// Created by sarkar on 17.03.15. +// Created by sarkar on 05.06.15. // +#pragma once +#include "od/common/pipeline/Scene.h" +#include "od/common/pipeline/Trainer.h" +#include "od/common/pipeline/Detector.h" -#ifndef _SNAPSHOT_SNAP_VTK_H_ -#define _SNAPSHOT_SNAP_VTK_H_ - +namespace od +{ -#include "common/pipeline/ODTrainer.h" -#include "common/utils/utils.h" -#include "detectors/local2D/ODImageLocalMatching.h" + namespace l2d + { + /** \brief ImageLocalMatchingTrainer + * + * \author Kripasindhu Sarkar + * + */ + class ImageLocalMatchingTrainer : public Trainer + { + public: -#define VIEW_ANGLE 30 -#define NO_SNAPSHOTS 30 + ImageLocalMatchingTrainer(const std::string & training_input_location, const std::string & training_data_location); + }; + /** \brief ImageLocalMatchingDetector + * + * \author Kripasindhu Sarkar + * + */ + class ImageLocalMatchingDetector : public Detector2DComplete + { + public: + + ImageLocalMatchingDetector(const std::string & training_data_location); + }; -namespace od -{ - namespace l2d - { - /** \brief ODCADRecogTrainerSnapshotBased; One of the new algorithm; details will be explained later + /** \brief ImageLocalMatching * * \author Kripasindhu Sarkar * */ - - class ODCADRecogTrainerSnapshotBased : public ODImageLocalMatchingTrainer + class ImageLocalMatching : public ObjectDetector { public: - ODCADRecogTrainerSnapshotBased(std::string const &training_input_location_ = "", std::string const &training_data_location_ = "") : ODImageLocalMatchingTrainer( - training_input_location_, training_data_location_) - { } - int train(); + shared_ptr getTrainer() const; + + void setTrainer(shared_ptr trainer); + + shared_ptr getDetector() const; + + void setDetector(shared_ptr detector); + + ImageLocalMatching(); void init() {} - void trainSingleModel(std::string objname); + + int train(); + + int detect(shared_ptr scene, const std::vector > & detections); protected: - int no_ring_; - float view_angle_; - int no_snapshot_per_ring_; + shared_ptr trainer_; + shared_ptr detector_; }; - /** \example objectdetector/od_image_cadrecog_camera.cpp - * \example objectdetector/od_image_cadrecog_files.cpp - */ } } - - - -#endif //_SNAPSHOT_SNAP_VTK_H_ - diff --git a/detectors/include/od/detectors/local2D/detection/CADRecognizer2DLocal.h b/detectors/include/od/detectors/local2D/detection/CADRecognizer2DLocal.h new file mode 100644 index 00000000..e074438f --- /dev/null +++ b/detectors/include/od/detectors/local2D/detection/CADRecognizer2DLocal.h @@ -0,0 +1,148 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/ +// +// Created by sarkar on 08.06.15. +// +#pragma once +#include "od/detectors/local2D/ImageLocalMatching.h" +#include "od/common/pipeline/Scene.h" +#include "od/common/utils/FeatureDetector.h" +#include "od/detectors/local2D/simple_ransac_detection/Mesh.h" +#include "od/detectors/local2D/simple_ransac_detection/RobustMatcher.h" + +#include + +namespace od +{ + + namespace l2d + { + + /** \brief Simple RANSAC based 3D object recognizer. + * + * A recognizer which uses local features like SIFT/SURF to perform object recognition. + * Given a 'trained model' trained by CADRecogTrainerSnapshotBased or trained externally (manually augmenting features in 3D cad models), this class performs a complete detection + * in an image. It first extracts 2D features from the scene, matches them with all the feature augmented models (the trained data) and in the end solves PnP under RANSAC. + * + * \author Kripasindhu Sarkar + * + */ + class CADRecognizer2DLocal : public ImageLocalMatchingDetector + { + public: + + CADRecognizer2DLocal(const std::string & trained_data_location_ = std::string()); + + const std::string & getCameraIntrinsicFile() const; + + void setCameraIntrinsicFile(const std::string & camera_intrinsic_file); + + int getNumKeyPoints() const; + void setNumKeyPoints(int num_key_points); + + float getRatioTest() const; + void setRatioTest(float ratio_test); + + bool isFastMatch() const; + void setFastMatch(bool fast_match); + + bool isUseGpu() const; + void setUseGpu(bool use_gpu); + + bool isUseGpuMatch() const; + void setUseGpuMatch(bool use_gpu_match); + + bool isMetainfo() const; + void setMetainfo(bool meta_info); + + int getIterationsCount() const; + void setIterationsCount(int iterations_count); + + float getReprojectionError() const; + void setReprojectionError(float reprojection_error); + + double getConfidence() const; + void setConfidence(double confidence); + + int getMinInliers() const; + void setMinInliers(int min_inliers); + + int getPnpMethod() const; + void setPnpMethod(int pnp_method); + + void parseParameterString(const std::string & parameter_string); + + void init(); + + shared_ptr detect(shared_ptr scene); + shared_ptr detectOmni(shared_ptr scene); + + shared_ptr detect(shared_ptr scene); + shared_ptr detectOmni(shared_ptr scene); + + protected: + + bool detectSingleModel(shared_ptr scene, const Model & model, shared_ptr & detection3D, + const cv::Mat & frame_viz); + + std::string camera_intrinsic_file_; + + cv::Scalar red_; + cv::Scalar green_; + cv::Scalar blue_; + cv::Scalar yellow_; + +// Robust Matcher parameters + int num_key_points_; // number of detected keypoints + float ratio_test_; // ratio test + bool fast_match_; // fastRobustMatch() or robustMatch() + bool use_gpu_; + bool use_gpu_match_; + +// RANSAC parameters + int iterations_count_; // number of Ransac iterations. + float reprojection_error_; // maximum allowed distance to consider it an inlier. + double confidence_; // ransac successful confidence. + +// Kalman Filter parameters + int min_inliers_; // Kalman threshold updating + +// PnP parameters + int pnp_method_; + + //############NON-CONFIG PARAMETERS used for detection########### + std::vector model_names_; + std::vector models_; + PnPProblem pnp_detection_; + FeatureType f_type_default_; + shared_ptr feature_detector_; + + }; + + } +} + diff --git a/detectors/include/od/detectors/local2D/simple_ransac_detection/CsvReader.h b/detectors/include/od/detectors/local2D/simple_ransac_detection/CsvReader.h new file mode 100644 index 00000000..cf530ce9 --- /dev/null +++ b/detectors/include/od/detectors/local2D/simple_ransac_detection/CsvReader.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include +#include +#include +#include +#include "od/detectors/local2D/simple_ransac_detection/Utils.h" + + +namespace od { + + namespace l2d { + + class CsvReader { + public: + /** + * The default constructor of the CSV reader Class. + * The default separator is ' ' (empty space) + * + * @param path - The path of the file to read + * @param separator - The separator character between words per line + * @return + */ + CsvReader(const std::string & path, const std::string & separator = std::string(" ")); + + /** + * Read a plane text file with .ply format + * + * @param list_vertex - The container of the vertices list of the mesh + * @param list_triangles - The container of the triangles list of the mesh + * @return + */ + void readPLY(std::vector & list_vertex, std::vector > & list_triangles); + + private: + /** The current stream file for the reader */ + std::ifstream file_; + /** The separator character between words for each line */ + std::string separator_; + }; + + } + +} diff --git a/detectors/include/od/detectors/local2D/simple_ransac_detection/CsvWriter.h b/detectors/include/od/detectors/local2D/simple_ransac_detection/CsvWriter.h new file mode 100644 index 00000000..ad9ad194 --- /dev/null +++ b/detectors/include/od/detectors/local2D/simple_ransac_detection/CsvWriter.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include +#include "od/detectors/local2D/simple_ransac_detection/Utils.h" + + +namespace od { + + namespace l2d { + + class CsvWriter { + public: + CsvWriter(const std::string & path, const std::string & separator = std::string(" ")); + ~CsvWriter(); + void writeXYZ(const std::vector & list_points3d); + void writeUVXYZ(const std::vector & list_points3d, const std::vector & list_points2d, const cv::Mat & descriptors); + + private: + + std::ofstream file_; + std::string separator_; + bool is_first_term_; + + }; + + } + +} + diff --git a/detectors/include/od/detectors/local2D/simple_ransac_detection/Mesh.h b/detectors/include/od/detectors/local2D/simple_ransac_detection/Mesh.h new file mode 100644 index 00000000..7a850f09 --- /dev/null +++ b/detectors/include/od/detectors/local2D/simple_ransac_detection/Mesh.h @@ -0,0 +1,87 @@ +/* + * Mesh.h + * + * Created on: Apr 9, 2014 + * Author: edgar + */ + +#pragma once +#include +#include +#include "od/detectors/local2D/simple_ransac_detection/CsvReader.h" + +namespace od { + + namespace l2d { + // --------------------------------------------------- // + // TRIANGLE CLASS // + // --------------------------------------------------- // + + class Triangle { + public: + + explicit Triangle(int id, const cv::Point3f & V0, const cv::Point3f & V1, const cv::Point3f & V2); + + cv::Point3f getV0() const; + cv::Point3f getV1() const; + cv::Point3f getV2() const; + + private: + /** The identifier number of the triangle */ + int id_; + /** The three vertices that defines the triangle */ + cv::Point3f v0_, v1_, v2_; + }; + + + // --------------------------------------------------- // + // RAY CLASS // + // --------------------------------------------------- // + + class Ray { + public: + + explicit Ray(const cv::Point3f & P0, const cv::Point3f & P1); + + cv::Point3f getP0(); + cv::Point3f getP1(); + + private: + /** The two points that defines the ray */ + cv::Point3f p0_, p1_; + }; + + + // --------------------------------------------------- // + // OBJECT MESH CLASS // + // --------------------------------------------------- // + + class Mesh + { + public: + + Mesh(); + + std::vector > getTrianglesList() const; + std::vector getVertices(); + cv::Point3f getVertex(int pos) const; + int getNumVertices() const; + + void load(const std::string & path_file); + + private: + /** The identification number of the mesh */ + int id_; + /** The current number of vertices in the mesh */ + int num_vertexs_; + /** The current number of triangles in the mesh */ + int num_triangles_; + /* The list of triangles of the mesh */ + std::vector list_vertex_; + /* The list of triangles of the mesh */ + std::vector > list_triangles_; + }; + + } + +} diff --git a/detectors/include/od/detectors/local2D/simple_ransac_detection/Model.h b/detectors/include/od/detectors/local2D/simple_ransac_detection/Model.h new file mode 100644 index 00000000..6d2d5098 --- /dev/null +++ b/detectors/include/od/detectors/local2D/simple_ransac_detection/Model.h @@ -0,0 +1,68 @@ +/* + * Model.h + * + * Created on: Apr 9, 2014 + * Author: edgar + */ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include "od/detectors/local2D/simple_ransac_detection/CsvWriter.h" + + +namespace od { + + namespace l2d { + + class Model + { + public: + Model(); + virtual ~Model(); + + std::vector getPoints2dIn() const; + std::vector getPoints2dOut() const; + std::vector getPoints3d() const; + std::vector getKeypoints() const; + cv::Mat getDescriptors() const; + int getNumDescriptors() const; + + void addCorrespondence(const cv::Point2f &point2d, const cv::Point3f &point3d); + void addOutlier(const cv::Point2f &point2d); + void addDescriptor(const cv::Mat &descriptor); + void addKeypoint(const cv::KeyPoint &kp); + + void save(const std::string & path); + void load(const std::string & path); + void loadNewDesc(const std::string & path); + void loadNewXml(const std::string & path); + + std::string f_type_; + std::string id_; + + private: + + /** The current number of correspondecnes */ + int n_correspondences_; + /** The list of 2D points on the model surface */ + std::vector list_keypoints_; + /** The list of 2D points on the model surface */ + std::vector list_points2d_in_; + /** The list of 2D points outside the model surface */ + std::vector list_points2d_out_; + /** The list of 3D points on the model surface */ + std::vector list_points3d_in_; + /** The list of 2D points descriptors */ + cv::Mat descriptors_; + + unsigned int getDescriptorSize(); + }; + + } + +} diff --git a/detectors/include/od/detectors/local2D/simple_ransac_detection/ModelRegistration.h b/detectors/include/od/detectors/local2D/simple_ransac_detection/ModelRegistration.h new file mode 100644 index 00000000..5ae003e0 --- /dev/null +++ b/detectors/include/od/detectors/local2D/simple_ransac_detection/ModelRegistration.h @@ -0,0 +1,46 @@ +/* + * ModelRegistration.h + * + * Created on: Apr 18, 2014 + * Author: edgar + */ +#pragma once +#include +#include + +namespace od { + + namespace l2d { + + class ModelRegistration + { + public: + + ModelRegistration(); + virtual ~ModelRegistration(); + + void setNumMax(int n); + + std::vector getPoints2d() const; + std::vector getPoints3d() const; + int getNumMax() const; + int getNumRegist() const; + + bool isRegistrable() const; + void registerPoint(const cv::Point2f & point2d, const cv::Point3f & point3d); + void reset(); + + private: + /** The current number of registered points */ + int n_registrations_; + /** The total number of points to register */ + int max_registrations_; + /** The list of 2D points to register the model */ + std::vector list_points2d_; + /** The list of 3D points to register the model */ + std::vector list_points3d_; + }; + + } + +} \ No newline at end of file diff --git a/detectors/include/od/detectors/local2D/simple_ransac_detection/PnPProblem.h b/detectors/include/od/detectors/local2D/simple_ransac_detection/PnPProblem.h new file mode 100644 index 00000000..d4ed8596 --- /dev/null +++ b/detectors/include/od/detectors/local2D/simple_ransac_detection/PnPProblem.h @@ -0,0 +1,73 @@ +/* + * PnPProblem.h + * + * Created on: Mar 28, 2014 + * Author: Edgar Riba + */ +#pragma once +#include +#include +#include +#include +#include +#include "od/detectors/local2D/simple_ransac_detection/Mesh.h" +#include "od/detectors/local2D/simple_ransac_detection/ModelRegistration.h" +#include "od/common/utils/Shared_pointers.h" + +class Mesh; +class Ray; +class Triangle; + +namespace od { + + namespace l2d { + + class PnPProblem + { + + public: + explicit PnPProblem(double const param[], double const dists[]); // custom constructor + PnPProblem(const cv::Mat & intrin = cv::Mat::eye(3, 4, CV_64F), const cv::Mat & dist = cv::Mat::zeros(1, 5, CV_64F)); + virtual ~PnPProblem(); + + cv::Point3f CROSS(const cv::Point3f & v1, const cv::Point3f & v2); + double DOT(const cv::Point3f & v1, const cv::Point3f & v2); + cv::Point3f SUB(const cv::Point3f & v1, const cv::Point3f & v2); + cv::Point3f getNearest3DPoint(std::vector & points_list, const cv::Point3f & origin); + + bool backproject2DPoint(shared_ptr mesh, const cv::Point2f & point2d, cv::Point3f & point3d); + bool intersectMollerTrumbore(Ray & ray, Triangle & Triangle, double & out); + std::vector verifyPoints(shared_ptr mesh); + cv::Point2f backproject3DPoint(const cv::Point3f & point3d); + bool estimatePose(const std::vector & list_points3d, const std::vector & list_points2d, int flags); + void estimatePoseRANSAC(const std::vector & list_points3d, const std::vector & list_points2d, + int flags, const cv::Mat & inliers, int iterations_count, float reprojection_error, double confidence); + + cv::Mat getAMatrix() const; + cv::Mat getDistCoef() const; + cv::Mat getRMatrix() const; + cv::Mat getRVect() const; + cv::Mat getTMatrix() const; + cv::Mat getPMatrix() const; + + void setPMatrix(const cv::Mat & r_matrix, const cv::Mat & t_matrix); + void clearExtrinsics(); + + private: + + /** The calibration matrix */ + cv::Mat a_matrix_; + //dist mat + cv::Mat dist_; + /** The computed rotation matrix */ + cv::Mat r_matrix_; + cv::Mat r_vect_; + /** The computed translation matrix */ + cv::Mat t_matrix_; + /** The computed projection matrix */ + cv::Mat p_matrix_; + }; + + } + +} diff --git a/detectors/include/od/detectors/local2D/simple_ransac_detection/RobustMatcher.h b/detectors/include/od/detectors/local2D/simple_ransac_detection/RobustMatcher.h new file mode 100644 index 00000000..0b159cad --- /dev/null +++ b/detectors/include/od/detectors/local2D/simple_ransac_detection/RobustMatcher.h @@ -0,0 +1,107 @@ +/* + * RobustMatcher.h + * + * Created on: Jun 4, 2014 + * Author: eriba + */ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include "od/common/utils/FeatureDetector2D.h" +#include "od/common/utils/Utils.h" +#include "od/detectors/local2D/simple_ransac_detection/Model.h" +#include "od/detectors/local2D/simple_ransac_detection/Utils.h" + + +namespace od { + + namespace l2d { + + class + RobustMatcher { + + public: + RobustMatcher(Model const & model, bool use_gpu, bool b); + + virtual ~RobustMatcher(); + + // Set the feature detector + void setFeatureDetector(shared_ptr detect); + + // Set the descriptor extractor + void setDescriptorExtractor(shared_ptr desc); + + // Set the matcher + void setDescriptorMatcher(shared_ptr match); + + // Compute the keypoints of an image + void computeKeyPoints(const cv::Mat & image, std::vector & keypoints); + + // Compute the descriptors of an image given its keypoints + void computeDescriptors(const cv::Mat & image, std::vector & keypoints, cv::Mat & descriptors); + + // Set ratio parameter for the ratio test + void setRatio(float rat); + + // Clear matches for which NN ratio is > than threshold + // return the number of removed points + // (corresponding entries being cleared, + // i.e. size will be 0) + int ratioTest(std::vector > & matches); + + // Insert symmetrical matches in symMatches vector + void symmetryTest(const std::vector > & matches1, + const std::vector > & matches2, + std::vector & symMatches ); + + // Match feature points using ratio and symmetry test + void robustMatch(const cv::Mat & frame, std::vector & good_matches, + std::vector & keypoints_frame, + const cv::Mat & descriptors_model ); + + // Match feature points using ratio test + void fastRobustMatch(const cv::Mat & frame, std::vector & good_matches, + std::vector & keypoints_frame, + const cv::Mat & descriptors_model ); + + void findFeatureAndMatch(const cv::Mat & frame, std::vector & good_matches, std::vector & keypoints_frame, + const cv::Mat & descriptors_model); + + void match(const cv::Mat & descriptors_frame, const cv::Mat & descriptors_model, std::vector & good_matches); + + void matchNormalized(cv::Mat & descriptors_frame, cv::Mat & descriptors_model, std::vector & good_matches); + + int mode_; + bool use_gpu_; + + private: + + void instantiateMatcher(const Model & feature_type, bool use_gpu); + void instantiateMatcher1(const Model & model, bool use_gpu); + + // pointer to the feature point detector object + shared_ptr featureDetector_; + + shared_ptr detector_; + // pointer to the feature descriptor extractor object + shared_ptr extractor_; + // pointer to the matcher object + + //The important feature of this class starts here + //DIFFERENT TYPES OF MATCHERS, add here in this list (based on the construction + shared_ptr matcher_; + cv::Ptr matcher_gpu_; + // max ratio between 1st and 2nd NN + float ratio_; + }; + + } + +} + diff --git a/detectors/include/od/detectors/local2D/simple_ransac_detection/Utils.h b/detectors/include/od/detectors/local2D/simple_ransac_detection/Utils.h new file mode 100644 index 00000000..d573dc5c --- /dev/null +++ b/detectors/include/od/detectors/local2D/simple_ransac_detection/Utils.h @@ -0,0 +1,79 @@ +/* + * Utils.h + * + * Created on: Mar 28, 2014 + * Author: Edgar Riba + */ +#pragma once +#include +#include "od/detectors/local2D/simple_ransac_detection/PnPProblem.h" +#include "od/detectors/local2D/simple_ransac_detection/ModelRegistration.h" +#include "od/detectors/local2D/simple_ransac_detection/Model.h" +#include "od/detectors/local2D/simple_ransac_detection/Mesh.h" +#include +#include + +class Mesh; +class PnPProblem; +class Model; + +namespace od { + + namespace l2d { + + void viewImage(const cv::Mat & image, const std::vector & keypoints = std::vector(0)); + + // Draw a text with the question point + void drawQuestion(cv::Mat & image, const cv::Point3f & point, const cv::Scalar & color); + + // Draw a text with the number of entered points + void drawText(cv::Mat & image, const std::string & text, const cv::Scalar & color); + + // Draw a text with the number of entered points + void drawText2(cv::Mat & image, const std::string & text, const cv::Scalar & color); + + // Draw a text with the frame ratio + void drawFPS(cv::Mat & image, double fps, const cv::Scalar & color); + + // Draw a text with the frame ratio + void drawConfidence(cv::Mat & image, double confidence, const cv::Scalar & color); + + // Draw a text with the number of entered points + void drawCounter(cv::Mat & image, int n, int n_max, const cv::Scalar & color); + + // Draw the points and the coordinates + void drawPoints(cv::Mat & image, const std::vector & list_points_2d, const std::vector & list_points_3d, + const cv::Scalar & color); + + // Draw only the 2D points + void draw2DPoints(cv::Mat & image, const std::vector & list_points, const cv::Scalar & color); + + // Draw an arrow into the image + void drawArrow(cv::Mat & image, cv::Point2i & p, const cv::Point2i & q, const cv::Scalar & color, int arrowMagnitude = 9, + int thickness = 1, int line_type = 8, int shift = 0); + + // Draw the 3D coordinate axes + void draw3DCoordinateAxes(cv::Mat & image, const std::vector & list_points2d); + + // Draw the object mesh + void drawObjectMesh(cv::Mat & image, const Mesh & mesh, PnPProblem & pnpProblem, const cv::Scalar & color); + void drawModel(cv::Mat & image, const Model & model, PnPProblem & pnpProblem, const cv::Scalar color); + void drawModel(cv::Mat & image, const Model & model, cv::Mat r_vect, cv::Mat t_mat, cv::Mat a_mat, + cv::Mat dist, const cv::Scalar & color); + + // Computes the norm of the translation error + double getTranslationError(const cv::Mat & t_true, const cv::Mat & t); + + // Computes the norm of the rotation error + double getRotationError(const cv::Mat & r_true, const cv::Mat & r); + + // Converts a given Rotation Matrix to Euler angles + cv::Mat rot2euler(const cv::Mat & rotationMatrix); + + // Converts a given Euler angles to Rotation Matrix + cv::Mat euler2rot(const cv::Mat & euler); + + } + +} + diff --git a/detectors/include/od/detectors/local2D/training/CADRecogTrainerSnapshotBased.h b/detectors/include/od/detectors/local2D/training/CADRecogTrainerSnapshotBased.h new file mode 100644 index 00000000..ef39cbd6 --- /dev/null +++ b/detectors/include/od/detectors/local2D/training/CADRecogTrainerSnapshotBased.h @@ -0,0 +1,144 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/ +// +// Created by sarkar on 17.03.15. +// +#pragma once +#include "od/detectors/local2D/ImageLocalMatching.h" +#include "pugixml.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define VIEW_ANGLE 30 +#define NO_SNAPSHOTS 30 + +namespace od +{ + namespace l2d + { + /** \brief CADRecogTrainerSnapshotBased; One of the new algorithm; details will be explained later + * + * \author Kripasindhu Sarkar + * + */ + + class CADRecogTrainerSnapshotBased : public ImageLocalMatchingTrainer + { + + public: + + CADRecogTrainerSnapshotBased(const std::string & training_input_location = std::string(""), + const std::string & training_data_location = std::string("")) : + ImageLocalMatchingTrainer(training_input_location, training_data_location){} + + int train(); + void init() {} + void trainSingleModel(const std::string & objname); + + protected: + + int no_ring_; + float view_angle_; + int no_snapshot_per_ring_; + + }; + + struct fcomp3d_euclidian + { + bool operator()(const cv::Point3f & lhs, const cv::Point3f & rhs) const + { + return lhs.x < rhs.x; + } + }; + + class vtkTimerCallbackSnapshot : public vtkCommand + { + public: + + static vtkTimerCallbackSnapshot * New() + { + vtkTimerCallbackSnapshot * cb = new vtkTimerCallbackSnapshot; + cb->snap_count_ = 0; + cb->snap_mode = true; + cb->feature_type = std::string("SIFT"); + return cb; + } + + virtual void Execute(vtkObject * caller, unsigned long eventId, void * vtkNotUsed(callData)); + + private: + + int snap_count_; + + public: + + std::string takeSnapshot(vtkRenderWindow * render_window, int snap_no); + + void write_pairs(const std::vector > & pairs, const cv::Mat & descriptors, const std::string & file_name); + + void write_pairs_xml(const std::vector > & pairs, const cv::Mat & descriptors, const std::string & file_name); + + void process_image(const std::string & img_name, vtkRenderer * ren, vtkActor * actor, int ino); + + void process(vtkRenderWindowInteractor * iren, vtkActor * actor, vtkRenderer * renderer, int ino); + + //some local variables used + + std::vector > pairs_3d_2d; + cv::Mat common_descriptors; + std::map map_3d_2d; + std::string feature_type; + std::string input_file, input_dir, output_dir, output_extension; + + vtkActor * actor; + vtkRenderer * renderer; + bool snap_mode; + + }; + + + } +} + diff --git a/detectors/local2D/CMakeLists.txt b/detectors/local2D/CMakeLists.txt deleted file mode 100644 index cbce88eb..00000000 --- a/detectors/local2D/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -set(SUBSYS_NAME local_image_detector) -set(LIB_NAME od_${SUBSYS_NAME}) -set(SUBSYS_DESC "The local feature matching based detector") - -set(SUBSYS_DEPS od_common ${PCL_LIBRARIES} ${VTK_LIBRARIES} ${OpenCV_LIBS} pugixml) - - -set(build TRUE) -#PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -#PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS}) - - -if(build) - - #include all the individual implementation dirs - add_subdirectory(detection/simple_ransac_detection) - - set(incs - "ODImageLocalMatching.h" - - "training/ODCADRecogTrainerSnapshotBased.h" - "detection/ODCADRecognizer2DLocal.h" - - ) - - set(impl_incs - ) - - set(srcs - "ODImageLocalMatching.cpp" - "training/ODCADRecogTrainerSnapshotBased.cpp" - "detection/ODCADRecognizer2DLocal.cpp" - - ${SUB_IMPL_SRCS} - ) - - - OD_ADD_LIBRARY_ALL("${SUBSYS_NAME}" SRCS ${srcs} INCS ${incs} ${impl_incs}) - install(FILES ${incs} DESTINATION ${OD_INSTALL_INCLUDE_DIR}/${SUBSYS_NAME} COMPONENT ${LIB_NAME}) - - if(SUBSYS_DEPS) - target_link_libraries("${LIB_NAME}" ${SUBSYS_DEPS}) - endif(SUBSYS_DEPS) - - #PCL_MAKE_PKGCONFIG("${LIB_NAME}" "${SUBSYS_NAME}" "${SUBSYS_DESC}" "${SUBSYS_DEPS}" "" "" "" "") - - -endif(build) \ No newline at end of file diff --git a/detectors/local2D/ODImageLocalMatching.cpp b/detectors/local2D/ODImageLocalMatching.cpp deleted file mode 100644 index 4d68fd7c..00000000 --- a/detectors/local2D/ODImageLocalMatching.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 05.06.15. -// - -#include "ODImageLocalMatching.h" diff --git a/detectors/local2D/ODImageLocalMatching.h b/detectors/local2D/ODImageLocalMatching.h deleted file mode 100644 index bfef0c49..00000000 --- a/detectors/local2D/ODImageLocalMatching.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 05.06.15. -// - -#ifndef OPENDETECTION_ODIMAGELOCALMATCHINGSIMPLE_H -#define OPENDETECTION_ODIMAGELOCALMATCHINGSIMPLE_H - -#include "common/pipeline/ODScene.h" -#include "common/pipeline/ODTrainer.h" -#include "common/pipeline/ODDetector.h" -#include "common/pipeline/ObjectDetector.h" - - -namespace od -{ - - namespace l2d - { - /** \brief ODImageLocalMatchingTrainer - * - * \author Kripasindhu Sarkar - * - */ - class ODImageLocalMatchingTrainer : public ODTrainer - { - - public: - ODImageLocalMatchingTrainer(std::string const &training_input_location_, std::string const &training_data_location_) : ODTrainer(training_input_location_, training_data_location_) - { - TRAINED_LOCATION_DENTIFIER_ = "FEATCORR"; - TRAINED_DATA_ID_ = "corr.xml"; - } - }; - - /** \brief ODImageLocalMatchingDetector - * - * \author Kripasindhu Sarkar - * - */ - class ODImageLocalMatchingDetector : public ODDetector2DComplete - { - - public: - ODImageLocalMatchingDetector(std::string const &training_data_location_) : ODDetector2DComplete(training_data_location_) - { - TRAINED_LOCATION_DENTIFIER_ = "FEATCORR"; - TRAINED_DATA_ID_ = ".xml"; - } - }; - - /** \brief ODImageLocalMatching - * - * \author Kripasindhu Sarkar - * - */ - class ODImageLocalMatching : public ObjectDetector - { - - public: - - ODImageLocalMatchingTrainer *getTrainer() const - { - return trainer_; - } - - void setTrainer(ODImageLocalMatchingTrainer *trainer_) - { - ODImageLocalMatching::trainer_ = trainer_; - } - - ODImageLocalMatchingDetector *getDetector() const - { - return detector_; - } - - void setDetector(ODImageLocalMatchingDetector *detector_) - { - ODImageLocalMatching::detector_ = detector_; - } - - - ODImageLocalMatching() - { - TRAINED_DATA_EXT_ = "corr.xml"; - } - - void init() - { } - - - int train() - { - return trainer_->train(); - } - - int detect(ODScene *scene, std::vector detections) - { - //detector_->detect(scene, detections); - return 1; - } - - - protected: - - ODImageLocalMatchingTrainer *trainer_; - ODImageLocalMatchingDetector *detector_; - - }; - - } -} -#endif //OPENDETECTION_ODIMAGELOCALMATCHINGSIMPLE_H diff --git a/detectors/local2D/detection/ODCADRecognizer2DLocal.cpp b/detectors/local2D/detection/ODCADRecognizer2DLocal.cpp deleted file mode 100644 index 078f82a2..00000000 --- a/detectors/local2D/detection/ODCADRecognizer2DLocal.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 08.06.15. -// - -#include "ODCADRecognizer2DLocal.h" - - -#include -#include -#include -#include -#include -#include -#include -#include - -// PnP Tutorial -#include "simple_ransac_detection/Mesh.h" -#include "simple_ransac_detection/Model.h" -#include "simple_ransac_detection/PnPProblem.h" -#include "simple_ransac_detection/RobustMatcher.h" -#include "simple_ransac_detection/ModelRegistration.h" -#include "simple_ransac_detection/Utils.h" - - -using namespace cv; -using namespace std; -using namespace cv::xfeatures2d; - -namespace od -{ - namespace l2d - { - - void ODCADRecognizer2DLocal::parseParameterString(string parameter_string) - { - const String keys = "{help h | | print this message }" - "{video v | | path to recorded video }" - "{test_images img | | image for detection }" - "{cam_id | | pass true if you want the input from the camera }" - "{camera_intrinsic_file | | yml file containing camera parameters }" - "{use_gpu | | use gpu or cpu }" - "{use_gpu_match | | use gpu or cpu for matching }" - "{keypoints k |2000 | number of keypoints to detect }" - "{ratio r |0.7 | threshold for ratio test }" - "{iterations it |500 | RANSAC maximum iterations count }" - "{error e |2.0 | RANSAC reprojection errror }" - "{confidence c |0.95 | RANSAC confidence }" - "{inliers in |30 | minimum inliers for Kalman update }" - "{method pnp |0 | PnP method: (0) ITERATIVE - (1) EPNP - (2) P3P - (3) DLS}" - "{fast f |false | use of robust fast match }" - "{metainfo meta | | provide meta information in Detection }"; - - char **argv; - int argc; - FileUtils::getArgvArgc(parameter_string, &argv, argc); - - CommandLineParser parser(argc, argv, keys); - if(parser.has("help")) - { - parser.printMessage(); - - } else - { - camera_intrinsic_file = - parser.get("camera_intrinsic_file").size() > 0 ? parser.get("camera_intrinsic_file") : camera_intrinsic_file; - - use_gpu = parser.has("use_gpu"); - use_gpu_match = parser.has("use_gpu_match"); - - numKeyPoints = !parser.has("keypoints") ? parser.get("keypoints") : numKeyPoints; - ratioTest = !parser.has("ratio") ? parser.get("ratio") : ratioTest; - fast_match = !parser.has("fast") ? parser.get("fast") : fast_match; - iterationsCount = !parser.has("iterations") ? parser.get("iterations") : iterationsCount; - reprojectionError = !parser.has("error") ? parser.get("error") : reprojectionError; - confidence = !parser.has("confidence") ? parser.get("confidence") : confidence; - minInliers = !parser.has("inliers") ? parser.get("inliers") : minInliers; - pnpMethod = !parser.has("method") ? parser.get("method") : pnpMethod; - metainfo_ = parser.has("metainfo"); - } - - } - - void ODCADRecognizer2DLocal::init() - { - FileStorage fs(camera_intrinsic_file, FileStorage::READ); - Mat cam_man, dist_coeff; - fs["Camera_Matrix"] >> cam_man; - fs["Distortion_Coefficients"] >> dist_coeff; - pnp_detection = PnPProblem(cam_man, dist_coeff); - - // get all trained models - FileUtils::getFilesInDirectoryRec(getSpecificTrainingDataLocation(), TRAINED_DATA_ID_, model_names); - - for(int i = 0; i < model_names.size(); i++) - { - Model model; - model.load_new_xml(model_names[i]); - models.push_back(model); - } - if(models.size() > 0) - f_type_default = models[0].f_type; - - featureDetector = boost::make_shared(f_type_default, use_gpu); - - } - - - - ODDetections* ODCADRecognizer2DLocal::detect(ODSceneImage *scene) - { - ODDetections3D *detections = detectOmni(scene); - return detections; - } - - - ODDetections3D* ODCADRecognizer2DLocal::detectOmni(ODSceneImage *scene) - { - - vector keypoints_scene; - Mat descriptor_scene; - featureDetector->computeKeypointsAndDescriptors(scene->getCVImage(), descriptor_scene, keypoints_scene); - scene->setDescriptors(descriptor_scene); - scene->setKeypoints(keypoints_scene); - - ODDetections3D *detections = new ODDetections3D; - cv::Mat viz = scene->getCVImage().clone(); - - for(int i = 0; i < models.size(); i++) - { - - ODDetection3D *detection; - if(detectSingleModel(scene, models[i], detection, viz)) - { - detections->push_back(detection); - - if(metainfo_) - drawModel(viz, &models[i], pnp_detection.get_R_vect(), pnp_detection.get_t_matrix(), pnp_detection.get_A_matrix(), pnp_detection.get_dist_coef(), yellow); - } - } - detections->setMetainfoImage(viz); - return detections; - } - - bool ODCADRecognizer2DLocal::detectSingleModel(ODSceneImage *scene, Model const &model, ODDetection3D *&detection3D, Mat & frame_vis) - { - - //reset - pnp_detection.clearExtrinsics(); - - vector list_points3d_model = model.get_points3d(); // list with model 3D coordinates - vector list_keypoints_model = model.get_keypoints(); // list with model 3D coordinates - Mat descriptors_model = model.get_descriptors(); // list with descriptors of each 3D coordinate - - RobustMatcher rmatcher(model, use_gpu, use_gpu_match); // instantiate RobustMatcher - - - // -- Step 1: Robust matching between model descriptors and scene descriptors - vector good_matches; // to obtain the 3D points of the model - vector keypoints_scene = scene->getKeypoints(); // to obtain the 2D points of the scene - - Mat frame = scene->getCVImage(); - - //normalize - Mat scenedes = scene->getDescriptors(); - rmatcher.matchNormalized(scenedes, descriptors_model, good_matches); - //rmatcher.match(scenedes, descriptors_model, good_matches); - - if(good_matches.size() <= 0) return false; - - vector list_points3d_model_match; // container for the model 3D coordinates found in the scene - vector list_keypoints_model_match; // container for the model 2D coordinates in the textured image of the corresponding 3D coordinates - vector list_points2d_scene_match; // container for the model 2D coordinates found in the scene - - for(unsigned int match_index = 0; match_index < good_matches.size(); ++match_index) - { - Point3f point3d_model = list_points3d_model[good_matches[match_index].trainIdx]; // 3D point from model - KeyPoint kp_model = list_keypoints_model[good_matches[match_index].trainIdx]; // 2D point from model - Point2f point2d_scene = keypoints_scene[good_matches[match_index].queryIdx].pt; // 2D point from the scene - - list_points3d_model_match.push_back(point3d_model); // add 3D point - list_keypoints_model_match.push_back(kp_model); - list_points2d_scene_match.push_back(point2d_scene); // add 2D point - } - - - Mat inliers_idx; - vector list_points2d_inliers; - - - // -- Step 3: Estimate the pose using RANSAC approach - pnp_detection.estimatePoseRANSAC(list_points3d_model_match, list_points2d_scene_match, pnpMethod, inliers_idx, - iterationsCount, reprojectionError, confidence); - - if(inliers_idx.rows < minInliers) return false; - - cout << "RECOGNIZED: " << model.id << endl; - //else everything is fine; report the detection - detection3D = new ODDetection3D(); - detection3D->setLocation(pnp_detection.get_t_matrix()); - detection3D->setPose(pnp_detection.get_R_matrix()); - detection3D->setType(ODDetection::OD_DETECTION_RECOG); - detection3D->setId(model.id); - - - - return true; - } - - } -} \ No newline at end of file diff --git a/detectors/local2D/detection/ODCADRecognizer2DLocal.h b/detectors/local2D/detection/ODCADRecognizer2DLocal.h deleted file mode 100644 index 2b3313d2..00000000 --- a/detectors/local2D/detection/ODCADRecognizer2DLocal.h +++ /dev/null @@ -1,274 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/ -// -// Created by sarkar on 08.06.15. -// - -#ifndef OPENDETECTION_SIMPLERANSACDETECTOR_H -#define OPENDETECTION_SIMPLERANSACDETECTOR_H - -#include - -#include "common/pipeline/ODDetector.h" -#include "common/pipeline/ODScene.h" -#include "common/utils/utils.h" -#include "common/utils/ODFeatureDetector2D.h" - -#include -#include -// OpenCV -#include -#include -#include - - - -#include "simple_ransac_detection/Utils.h" - - -class Model; -class PnpProblem; - -namespace od -{ - - namespace l2d - { - - /** \brief Simple RANSAC based 3D object recognizer. - * - * A recognizer which uses local features like SIFT/SURF to perform object recognition. - * Given a 'trained model' trained by ODCADRecogTrainerSnapshotBased or trained externally (manually augmenting features in 3D cad models), this class performs a complete detection - * in an image. It first extracts 2D features from the scene, matches them with all the feature augmented models (the trained data) and in the end solves PnP under RANSAC. - * - * \author Kripasindhu Sarkar - * - */ - class ODCADRecognizer2DLocal : public ODImageLocalMatchingDetector - { - public: - string const &getCameraIntrinsicFile() const - { - return camera_intrinsic_file; - } - - void setCameraIntrinsicFile(string const &camera_intrinsic_file) - { - ODCADRecognizer2DLocal::camera_intrinsic_file = camera_intrinsic_file; - } - - int getNumKeyPoints() const - { - return numKeyPoints; - } - - void setNumKeyPoints(int numKeyPoints) - { - ODCADRecognizer2DLocal::numKeyPoints = numKeyPoints; - } - - float getRatioTest() const - { - return ratioTest; - } - - void setRatioTest(float ratioTest) - { - ODCADRecognizer2DLocal::ratioTest = ratioTest; - } - - bool isFast_match() const - { - return fast_match; - } - - void setFast_match(bool fast_match) - { - ODCADRecognizer2DLocal::fast_match = fast_match; - } - - bool isUse_gpu() const - { - return use_gpu; - } - - void setUse_gpu(bool use_gpu) - { - ODCADRecognizer2DLocal::use_gpu = use_gpu; - } - - bool isUse_gpu_match() const - { - return use_gpu_match; - } - - void setUse_gpu_match(bool use_gpu_match) - { - ODCADRecognizer2DLocal::use_gpu_match = use_gpu_match; - } - - bool isMetainfo() const - { - return metainfo_; - } - - void setMetainfo(bool metainfo) - { - ODCADRecognizer2DLocal::metainfo_ = metainfo; - } - - int getIterationsCount() const - { - return iterationsCount; - } - - void setIterationsCount(int iterationsCount) - { - ODCADRecognizer2DLocal::iterationsCount = iterationsCount; - } - - float getReprojectionError() const - { - return reprojectionError; - } - - void setReprojectionError(float reprojectionError) - { - ODCADRecognizer2DLocal::reprojectionError = reprojectionError; - } - - double getConfidence() const - { - return confidence; - } - - void setConfidence(double confidence) - { - ODCADRecognizer2DLocal::confidence = confidence; - } - - int getMinInliers() const - { - return minInliers; - } - - void setMinInliers(int minInliers) - { - ODCADRecognizer2DLocal::minInliers = minInliers; - } - - int getPnpMethod() const - { - return pnpMethod; - } - - void setPnpMethod(int pnpMethod) - { - ODCADRecognizer2DLocal::pnpMethod = pnpMethod; - } - - ODCADRecognizer2DLocal(string const &trained_data_location_ = 0) : ODImageLocalMatchingDetector( - trained_data_location_) - { - metainfo_ = true; - - camera_intrinsic_file = "Data/out_camera_data_lion_old.yml"; // mesh - - red = cv::Scalar(0, 0, 255); - green = cv::Scalar(0, 255, 0); - blue = cv::Scalar(255, 0, 0); - yellow = cv::Scalar(0, 255, 255); - - - numKeyPoints = 2000; // number of detected keypoints - ratioTest = 0.70f; // ratio test - fast_match = true; // fastRobustMatch() or robustMatch() - use_gpu = false; - use_gpu_match = false; - - iterationsCount = 500; // number of Ransac iterations. - reprojectionError = 2.0; // maximum allowed distance to consider it an inlier. - confidence = 0.95; // ransac successful confidence. - - minInliers = 30; // Kalman threshold updating - - pnpMethod = cv::SOLVEPNP_EPNP; - f_type_default = "SIFT"; - featureDetector = boost::make_shared(f_type_default, use_gpu); - } - - void parseParameterString(string parameter_string); - - void init(); - - ODDetections* detect(ODSceneImage *scene); - - ODDetections3D* detectOmni(ODSceneImage *scene); - - protected: - - string camera_intrinsic_file; // mesh - - cv::Scalar red; - cv::Scalar green; - cv::Scalar blue; - cv::Scalar yellow; - -// Robust Matcher parameters - int numKeyPoints; // number of detected keypoints - float ratioTest; // ratio test - bool fast_match; // fastRobustMatch() or robustMatch() - bool use_gpu; - bool use_gpu_match; - -// RANSAC parameters - int iterationsCount; // number of Ransac iterations. - float reprojectionError; // maximum allowed distance to consider it an inlier. - double confidence; // ransac successful confidence. - -// Kalman Filter parameters - int minInliers; // Kalman threshold updating - -// PnP parameters - int pnpMethod; - - //############NON-CONFIG PARAMETERS used for detection########### - vector model_names; - vector models; - PnPProblem pnp_detection; - std::string f_type_default; - boost::shared_ptr featureDetector; - - bool detectSingleModel(ODSceneImage *scene, Model const &model, ODDetection3D *&pD, cv::Mat &frame_viz); - }; - /** \example objectdetector/od_image_cadrecog_camera.cpp - * \example objectdetector/od_image_cadrecog_files.cpp - */ - } -} - -#endif //OPENDETECTION_SIMPLERANSACDETECTOR_H diff --git a/detectors/local2D/detection/simple_ransac_detection/CMakeLists.txt b/detectors/local2D/detection/simple_ransac_detection/CMakeLists.txt deleted file mode 100644 index beb84896..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(simple_ransac_src_dir ${CMAKE_CURRENT_SOURCE_DIR}) - -set(SUB_IMPL_SRCS - ${simple_ransac_src_dir}/CsvReader.cpp - ${simple_ransac_src_dir}/CsvWriter.cpp - ${simple_ransac_src_dir}/ModelRegistration.cpp - ${simple_ransac_src_dir}/Mesh.cpp - ${simple_ransac_src_dir}/Model.cpp - ${simple_ransac_src_dir}/PnPProblem.cpp - ${simple_ransac_src_dir}/Utils.cpp - ${simple_ransac_src_dir}/RobustMatcher.cpp -PARENT_SCOPE) \ No newline at end of file diff --git a/detectors/local2D/detection/simple_ransac_detection/CsvReader.cpp b/detectors/local2D/detection/simple_ransac_detection/CsvReader.cpp deleted file mode 100644 index 4da06dd4..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/CsvReader.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "CsvReader.h" -#include - -/** The default constructor of the CSV reader Class */ -CsvReader::CsvReader(const string &path, const char &separator){ - _file.open(path.c_str(), ifstream::in); - _separator = separator; -} - -/* Read a plane text file with .ply format */ -void CsvReader::readPLY(vector &list_vertex, vector > &list_triangles) -{ - std::string line, tmp_str, n; - int num_vertex = 0, num_triangles = 0; - int count = 0; - bool end_header = false; - bool end_vertex = false; - - // Read the whole *.ply file - while (getline(_file, line)) { - stringstream liness(line); - - // read header - if(!end_header) - { - getline(liness, tmp_str, _separator); - if( tmp_str == "element" ) - { - getline(liness, tmp_str, _separator); - getline(liness, n); - if(tmp_str == "vertex") num_vertex = StringToInt(n); - if(tmp_str == "face") num_triangles = StringToInt(n); - } - if(tmp_str == "end_header") end_header = true; - } - - // read file content - else if(end_header) - { - // read vertex and add into 'list_vertex' - if(!end_vertex && count < num_vertex) - { - string x, y, z; - getline(liness, x, _separator); - getline(liness, y, _separator); - getline(liness, z); - - cv::Point3f tmp_p; - tmp_p.x = atof(x.c_str()); - tmp_p.y = atof(y.c_str()); - tmp_p.z = atof(z.c_str()); - list_vertex.push_back(tmp_p); - - count++; - if(count == num_vertex) - { - count = 0; - end_vertex = !end_vertex; - } - } - // read faces and add into 'list_triangles' - else if(end_vertex && count < num_triangles) - { - string num_pts_per_face, id0, id1, id2; - getline(liness, num_pts_per_face, _separator); - getline(liness, id0, _separator); - getline(liness, id1, _separator); - getline(liness, id2); - - std::vector tmp_triangle(3); - tmp_triangle[0] = StringToInt(id0); - tmp_triangle[1] = StringToInt(id1); - tmp_triangle[2] = StringToInt(id2); - list_triangles.push_back(tmp_triangle); - - count++; - } - } - } -} diff --git a/detectors/local2D/detection/simple_ransac_detection/CsvReader.h b/detectors/local2D/detection/simple_ransac_detection/CsvReader.h deleted file mode 100644 index 3e8c4989..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/CsvReader.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef CSVREADER_H -#define CSVREADER_H - -#include -#include -#include -#include "Utils.h" - -using namespace std; -using namespace cv; - -class CsvReader { -public: - /** - * The default constructor of the CSV reader Class. - * The default separator is ' ' (empty space) - * - * @param path - The path of the file to read - * @param separator - The separator character between words per line - * @return - */ - CsvReader(const string &path, const char &separator = ' '); - - /** - * Read a plane text file with .ply format - * - * @param list_vertex - The container of the vertices list of the mesh - * @param list_triangle - The container of the triangles list of the mesh - * @return - */ - void readPLY(vector &list_vertex, vector > &list_triangles); - -private: - /** The current stream file for the reader */ - ifstream _file; - /** The separator character between words for each line */ - char _separator; -}; - -#endif diff --git a/detectors/local2D/detection/simple_ransac_detection/CsvWriter.cpp b/detectors/local2D/detection/simple_ransac_detection/CsvWriter.cpp deleted file mode 100644 index a64fb691..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/CsvWriter.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "CsvWriter.h" - -CsvWriter::CsvWriter(const string &path, const string &separator){ - _file.open(path.c_str(), ofstream::out); - _isFirstTerm = true; - _separator = separator; -} - -CsvWriter::~CsvWriter() { - _file.flush(); - _file.close(); -} - -void CsvWriter::writeXYZ(const vector &list_points3d) -{ - string x, y, z; - for(unsigned int i = 0; i < list_points3d.size(); ++i) - { - x = FloatToString(list_points3d[i].x); - y = FloatToString(list_points3d[i].y); - z = FloatToString(list_points3d[i].z); - - _file << x << _separator << y << _separator << z << std::endl; - } - -} - -void CsvWriter::writeUVXYZ(const vector &list_points3d, const vector &list_points2d, const Mat &descriptors) -{ - string u, v, x, y, z, descriptor_str; - for(unsigned int i = 0; i < list_points3d.size(); ++i) - { - u = FloatToString(list_points2d[i].x); - v = FloatToString(list_points2d[i].y); - x = FloatToString(list_points3d[i].x); - y = FloatToString(list_points3d[i].y); - z = FloatToString(list_points3d[i].z); - - _file << u << _separator << v << _separator << x << _separator << y << _separator << z; - - for(int j = 0; j < 32; ++j) - { - descriptor_str = FloatToString(descriptors.at(i,j)); - _file << _separator << descriptor_str; - } - _file << std::endl; - } -} diff --git a/detectors/local2D/detection/simple_ransac_detection/CsvWriter.h b/detectors/local2D/detection/simple_ransac_detection/CsvWriter.h deleted file mode 100644 index d8132f5b..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/CsvWriter.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef CSVWRITER_H -#define CSVWRITER_H - -#include -#include -#include -#include "Utils.h" - -using namespace std; -using namespace cv; - -class CsvWriter { -public: - CsvWriter(const string &path, const string &separator = " "); - ~CsvWriter(); - void writeXYZ(const vector &list_points3d); - void writeUVXYZ(const vector &list_points3d, const vector &list_points2d, const Mat &descriptors); - -private: - ofstream _file; - string _separator; - bool _isFirstTerm; -}; - -#endif diff --git a/detectors/local2D/detection/simple_ransac_detection/Mesh.cpp b/detectors/local2D/detection/simple_ransac_detection/Mesh.cpp deleted file mode 100644 index e6c84c47..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/Mesh.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Mesh.cpp - * - * Created on: Apr 9, 2014 - * Author: edgar - */ - -#include "Mesh.h" -#include "CsvReader.h" - - -// --------------------------------------------------- // -// TRIANGLE CLASS // -// --------------------------------------------------- // - -/** The custom constructor of the Triangle Class */ -Triangle::Triangle(int id, cv::Point3f V0, cv::Point3f V1, cv::Point3f V2) -{ - id_ = id; v0_ = V0; v1_ = V1; v2_ = V2; -} - -/** The default destructor of the Class */ -Triangle::~Triangle() -{ - // TODO Auto-generated destructor stub -} - - -// --------------------------------------------------- // -// RAY CLASS // -// --------------------------------------------------- // - -/** The custom constructor of the Ray Class */ -Ray::Ray(cv::Point3f P0, cv::Point3f P1) { - p0_ = P0; p1_ = P1; -} - -/** The default destructor of the Class */ -Ray::~Ray() -{ - // TODO Auto-generated destructor stub -} - - -// --------------------------------------------------- // -// OBJECT MESH CLASS // -// --------------------------------------------------- // - -/** The default constructor of the ObjectMesh Class */ -Mesh::Mesh() : list_vertex_(0) , list_triangles_(0) -{ - id_ = 0; - num_vertexs_ = 0; - num_triangles_ = 0; -} - -/** The default destructor of the ObjectMesh Class */ -Mesh::~Mesh() -{ - // TODO Auto-generated destructor stub -} - - -/** Load a CSV with *.ply format **/ -void Mesh::load(const std::string path) -{ - - // Create the reader - CsvReader csvReader(path); - - // Clear previous data - list_vertex_.clear(); - list_triangles_.clear(); - - // Read from .ply file - csvReader.readPLY(list_vertex_, list_triangles_); - - // Update mesh attributes - num_vertexs_ = (int)list_vertex_.size(); - num_triangles_ = (int)list_triangles_.size(); - -} diff --git a/detectors/local2D/detection/simple_ransac_detection/Mesh.h b/detectors/local2D/detection/simple_ransac_detection/Mesh.h deleted file mode 100644 index d82c8d48..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/Mesh.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Mesh.h - * - * Created on: Apr 9, 2014 - * Author: edgar - */ - -#ifndef MESH_H_ -#define MESH_H_ - -#include -#include - - -// --------------------------------------------------- // -// TRIANGLE CLASS // -// --------------------------------------------------- // - -class Triangle { -public: - - explicit Triangle(int id, cv::Point3f V0, cv::Point3f V1, cv::Point3f V2); - virtual ~Triangle(); - - cv::Point3f getV0() const { return v0_; } - cv::Point3f getV1() const { return v1_; } - cv::Point3f getV2() const { return v2_; } - -private: - /** The identifier number of the triangle */ - int id_; - /** The three vertices that defines the triangle */ - cv::Point3f v0_, v1_, v2_; -}; - - -// --------------------------------------------------- // -// RAY CLASS // -// --------------------------------------------------- // - -class Ray { -public: - - explicit Ray(cv::Point3f P0, cv::Point3f P1); - virtual ~Ray(); - - cv::Point3f getP0() { return p0_; } - cv::Point3f getP1() { return p1_; } - -private: - /** The two points that defines the ray */ - cv::Point3f p0_, p1_; -}; - - -// --------------------------------------------------- // -// OBJECT MESH CLASS // -// --------------------------------------------------- // - -class Mesh -{ -public: - - Mesh(); - virtual ~Mesh(); - - std::vector > getTrianglesList() const { return list_triangles_; } - std::vector getVertices() const { return list_vertex_; } - cv::Point3f getVertex(int pos) const { return list_vertex_[pos]; } - int getNumVertices() const { return num_vertexs_; } - - void load(const std::string path_file); - -private: - /** The identification number of the mesh */ - int id_; - /** The current number of vertices in the mesh */ - int num_vertexs_; - /** The current number of triangles in the mesh */ - int num_triangles_; - /* The list of triangles of the mesh */ - std::vector list_vertex_; - /* The list of triangles of the mesh */ - std::vector > list_triangles_; -}; - -#endif /* OBJECTMESH_H_ */ diff --git a/detectors/local2D/detection/simple_ransac_detection/Model.cpp b/detectors/local2D/detection/simple_ransac_detection/Model.cpp deleted file mode 100644 index 660199f2..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/Model.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Model.cpp - * - * Created on: Apr 9, 2014 - * Author: edgar - */ - -#include -#include -#include -#include "Model.h" -#include "CsvWriter.h" -#include -#include -#include - -Model::Model() : list_points2d_in_(0), list_points2d_out_(0), list_points3d_in_(0) -{ - n_correspondences_ = 0; -} - -Model::~Model() -{ - // TODO Auto-generated destructor stub -} - -void Model::add_correspondence(const cv::Point2f &point2d, const cv::Point3f &point3d) -{ - list_points2d_in_.push_back(point2d); - list_points3d_in_.push_back(point3d); - n_correspondences_++; -} - -void Model::add_outlier(const cv::Point2f &point2d) -{ - list_points2d_out_.push_back(point2d); -} - -void Model::add_descriptor(const cv::Mat &descriptor) -{ - descriptors_.push_back(descriptor); -} - -void Model::add_keypoint(const cv::KeyPoint &kp) -{ - list_keypoints_.push_back(kp); -} - - -/** Save a CSV file and fill the object mesh */ -void Model::save(const std::string path) -{ - cv::Mat points3dmatrix = cv::Mat(list_points3d_in_); - cv::Mat points2dmatrix = cv::Mat(list_points2d_in_); - //cv::Mat keyPointmatrix = cv::Mat(list_keypoints_); - - cv::FileStorage storage(path, cv::FileStorage::WRITE); - storage << "points_3d" << points3dmatrix; - storage << "points_2d" << points2dmatrix; - storage << "keypoints" << list_keypoints_; - storage << "descriptors" << descriptors_; - - storage.release(); -} - -/** Load a YAML file using OpenCv functions **/ -void Model::load(const std::string path) -{ - cv::Mat points3d_mat; - - cv::FileStorage storage(path, cv::FileStorage::READ); - storage["points_3d"] >> points3d_mat; - storage["descriptors"] >> descriptors_; - - points3d_mat.copyTo(list_points3d_in_); - - std::cout << list_points3d_in_.size() << endl; - std::cout << descriptors_; - storage.release(); - id = path; -} - -void Model::load_new_desc(const std::string path) -{ - f_type = "SIFT"; - - std::fstream infile(path.c_str()); - if (!infile.is_open()) - { - std::cout << "ERRROR opening model file!!"; - return ; - - } - int nop, desc_size, point_size; - infile >> nop; - infile >> point_size >> desc_size; - - descriptors_ = Mat(nop, desc_size, CV_32FC1); - - - for (int i = 0; i < nop; i++) - { - - float x, y, z; - infile >> x >> y >> z; - cv::Point3f p3d(x, y, z); - list_points3d_in_.push_back(p3d); - - cv::KeyPoint kp; - infile >> kp.pt.x >> kp.pt.y >> kp.octave >> kp.angle >> kp.response >> kp.size; - list_keypoints_.push_back(kp); - - for (int j = 0; j < desc_size; j++) - { - infile >> descriptors_.at(i, j); - } - } - id = path; -} - -template -string ps ( T thing ) -{ - cout << thing; - ostringstream ss; - ss << thing; - return ss.str(); -} - -void Model::load_new_xml(const std::string path) -{ - - pugi::xml_document doc; - pugi::xml_parse_result result = doc.load_file(path.c_str()); - - if (!result) - { - std::cout << "ERRROR opening model file!!"; - return ; - - } - pugi::xml_node pts_node = doc.child("Model").child("Points"); - - if (pts_node.first_child()) - f_type = pts_node.first_child().attribute("desc_type").as_string(); - else return; - - - for (pugi::xml_node pt_node = pts_node.first_child(); pt_node; pt_node = pt_node.next_sibling()) - { - Mat single_desc = Mat::zeros(1, get_descriptor_size(), CV_32FC1); - stringstream ss; - ss.str(pt_node.attribute("p3d").as_string()); - float x, y, z; - ss >> x >> y >> z; ss.clear(); - cv::Point3f p3d(x, y, z); - list_points3d_in_.push_back(p3d); - - ss.str(pt_node.attribute("p2d_prop").as_string()); - cv::KeyPoint kp; - ss >> kp.pt.x >> kp.pt.y >> kp.octave >> kp.angle >> kp.response >> kp.size; ss.clear(); - list_keypoints_.push_back(kp); - - ss.str(pt_node.attribute("desc").as_string()); - float d; - for(int it = 0; it < get_descriptor_size(); it ++) - { - ss >> d; - //cout < (0, it) = d; - } - ss.clear(); - - descriptors_.push_back(single_desc); - } - - id = path; - //std::cout << list_points3d_in_.size() << endl; - //std::cout << descriptors_; -} - diff --git a/detectors/local2D/detection/simple_ransac_detection/Model.h b/detectors/local2D/detection/simple_ransac_detection/Model.h deleted file mode 100644 index ef029cd4..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/Model.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Model.h - * - * Created on: Apr 9, 2014 - * Author: edgar - */ - -#ifndef MODEL_H_ -#define MODEL_H_ - -#include -#include -#include -#include - -class Model -{ -public: - Model(); - virtual ~Model(); - - std::vector get_points2d_in() const { return list_points2d_in_; } - std::vector get_points2d_out() const { return list_points2d_out_; } - std::vector get_points3d() const { return list_points3d_in_; } - std::vector get_keypoints() const { return list_keypoints_; } - cv::Mat get_descriptors() const { return descriptors_; } - int get_numDescriptors() const { return descriptors_.rows; } - - - void add_correspondence(const cv::Point2f &point2d, const cv::Point3f &point3d); - void add_outlier(const cv::Point2f &point2d); - void add_descriptor(const cv::Mat &descriptor); - void add_keypoint(const cv::KeyPoint &kp); - - - void save(const std::string path); - void load(const std::string path); - void load_new_desc(const std::string path); - void load_new_xml(const std::string path); - - - std::string f_type; - std::string id; - -private: - - /** The current number of correspondecnes */ - int n_correspondences_; - /** The list of 2D points on the model surface */ - std::vector list_keypoints_; - /** The list of 2D points on the model surface */ - std::vector list_points2d_in_; - /** The list of 2D points outside the model surface */ - std::vector list_points2d_out_; - /** The list of 3D points on the model surface */ - std::vector list_points3d_in_; - /** The list of 2D points descriptors */ - cv::Mat descriptors_; - - int get_descriptor_size() - { - if (f_type == "SIFT") return 128; - return 128; - } -}; - -#endif /* OBJECTMODEL_H_ */ diff --git a/detectors/local2D/detection/simple_ransac_detection/ModelRegistration.cpp b/detectors/local2D/detection/simple_ransac_detection/ModelRegistration.cpp deleted file mode 100644 index e8da8856..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/ModelRegistration.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * ModelRegistration.cpp - * - * Created on: Apr 18, 2014 - * Author: edgar - */ - -#include "ModelRegistration.h" - -ModelRegistration::ModelRegistration() -{ - n_registrations_ = 0; - max_registrations_ = 0; -} - -ModelRegistration::~ModelRegistration() -{ - // TODO Auto-generated destructor stub -} - -void ModelRegistration::registerPoint(const cv::Point2f &point2d, const cv::Point3f &point3d) - { - // add correspondence at the end of the vector - list_points2d_.push_back(point2d); - list_points3d_.push_back(point3d); - n_registrations_++; - } - -void ModelRegistration::reset() -{ - n_registrations_ = 0; - max_registrations_ = 0; - list_points2d_.clear(); - list_points3d_.clear(); -} diff --git a/detectors/local2D/detection/simple_ransac_detection/ModelRegistration.h b/detectors/local2D/detection/simple_ransac_detection/ModelRegistration.h deleted file mode 100644 index f1e7aca4..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/ModelRegistration.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * ModelRegistration.h - * - * Created on: Apr 18, 2014 - * Author: edgar - */ - -#ifndef MODELREGISTRATION_H_ -#define MODELREGISTRATION_H_ - -#include -#include - -class ModelRegistration -{ -public: - - ModelRegistration(); - virtual ~ModelRegistration(); - - void setNumMax(int n) { max_registrations_ = n; } - - std::vector get_points2d() const { return list_points2d_; } - std::vector get_points3d() const { return list_points3d_; } - int getNumMax() const { return max_registrations_; } - int getNumRegist() const { return n_registrations_; } - - bool is_registrable() const { return (n_registrations_ < max_registrations_); } - void registerPoint(const cv::Point2f &point2d, const cv::Point3f &point3d); - void reset(); - -private: -/** The current number of registered points */ -int n_registrations_; -/** The total number of points to register */ -int max_registrations_; -/** The list of 2D points to register the model */ -std::vector list_points2d_; -/** The list of 3D points to register the model */ -std::vector list_points3d_; -}; - -#endif /* MODELREGISTRATION_H_ */ diff --git a/detectors/local2D/detection/simple_ransac_detection/PnPProblem.cpp b/detectors/local2D/detection/simple_ransac_detection/PnPProblem.cpp deleted file mode 100644 index 3b361fc7..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/PnPProblem.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* - * PnPProblem.cpp - * - * Created on: Mar 28, 2014 - * Author: Edgar Riba - */ - -#include -#include - -#include "PnPProblem.h" -#include "Mesh.h" - -#include - -/* Functions headers */ -cv::Point3f CROSS(cv::Point3f v1, cv::Point3f v2); -double DOT(cv::Point3f v1, cv::Point3f v2); -cv::Point3f SUB(cv::Point3f v1, cv::Point3f v2); -cv::Point3f get_nearest_3D_point(std::vector &points_list, cv::Point3f origin); - - -/* Functions for Möller–Trumbore intersection algorithm */ - -cv::Point3f CROSS(cv::Point3f v1, cv::Point3f v2) -{ - cv::Point3f tmp_p; - tmp_p.x = v1.y*v2.z - v1.z*v2.y; - tmp_p.y = v1.z*v2.x - v1.x*v2.z; - tmp_p.z = v1.x*v2.y - v1.y*v2.x; - return tmp_p; -} - -double DOT(cv::Point3f v1, cv::Point3f v2) -{ - return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; -} - -cv::Point3f SUB(cv::Point3f v1, cv::Point3f v2) -{ - cv::Point3f tmp_p; - tmp_p.x = v1.x - v2.x; - tmp_p.y = v1.y - v2.y; - tmp_p.z = v1.z - v2.z; - return tmp_p; -} - -/* End functions for Möller–Trumbore intersection algorithm - * */ - -// Function to get the nearest 3D point to the Ray origin -cv::Point3f get_nearest_3D_point(std::vector &points_list, cv::Point3f origin) -{ - cv::Point3f p1 = points_list[0]; - cv::Point3f p2 = points_list[1]; - - double d1 = std::sqrt( std::pow(p1.x-origin.x, 2) + std::pow(p1.y-origin.y, 2) + std::pow(p1.z-origin.z, 2) ); - double d2 = std::sqrt( std::pow(p2.x-origin.x, 2) + std::pow(p2.y-origin.y, 2) + std::pow(p2.z-origin.z, 2) ); - - if(d1 < d2) - { - return p1; - } - else - { - return p2; - } -} - -// Custom constructor given the intrinsic camera parameters - -PnPProblem::PnPProblem(double const params[], double const dists[]) -{ - _A_matrix = cv::Mat::zeros(3, 3, CV_64FC1); // intrinsic camera parameters - _A_matrix.at(0, 0) = params[0]; // [ fx 0 cx ] - _A_matrix.at(1, 1) = params[1]; // [ 0 fy cy ] - _A_matrix.at(0, 2) = params[2]; // [ 0 0 1 ] - _A_matrix.at(1, 2) = params[3]; - _A_matrix.at(2, 2) = 1; - _dist = cv::Mat::zeros(4, 1, CV_64FC1); - _dist.at(0,0) = dists[0]; _dist.at(1,0) = dists[1]; _dist.at(2,0) = dists[2]; _dist.at(3,0) = dists[3]; - - _R_matrix = cv::Mat::zeros(3, 3, CV_64FC1); // rotation matrix - _t_matrix = cv::Mat::zeros(3, 1, CV_64FC1); // translation matrix - _P_matrix = cv::Mat::zeros(3, 4, CV_64FC1); // rotation-translation matrix - -} - -PnPProblem::PnPProblem(cv::Mat intrin, cv::Mat dist) { - intrin.copyTo(_A_matrix); - dist.copyTo(_dist); - - _R_matrix = cv::Mat::zeros(3, 3, CV_64FC1); // rotation matrix - _t_matrix = cv::Mat::zeros(3, 1, CV_64FC1); // translation matrix - _P_matrix = cv::Mat::zeros(3, 4, CV_64FC1); // rotation-translation matrix -} - - -PnPProblem::~PnPProblem() -{ - // TODO Auto-generated destructor stub -} - -void PnPProblem::set_P_matrix( const cv::Mat &R_matrix, const cv::Mat &t_matrix) -{ - // Rotation-Translation Matrix Definition - _P_matrix.at(0,0) = R_matrix.at(0,0); - _P_matrix.at(0,1) = R_matrix.at(0,1); - _P_matrix.at(0,2) = R_matrix.at(0,2); - _P_matrix.at(1,0) = R_matrix.at(1,0); - _P_matrix.at(1,1) = R_matrix.at(1,1); - _P_matrix.at(1,2) = R_matrix.at(1,2); - _P_matrix.at(2,0) = R_matrix.at(2,0); - _P_matrix.at(2,1) = R_matrix.at(2,1); - _P_matrix.at(2,2) = R_matrix.at(2,2); - - _P_matrix.at(0,3) = t_matrix.at(0); - _P_matrix.at(1,3) = t_matrix.at(1); - _P_matrix.at(2,3) = t_matrix.at(2); - -} - - -// Estimate the pose given a list of 2D/3D correspondences and the method to use -bool PnPProblem::estimatePose( const std::vector &list_points3d, - const std::vector &list_points2d, - int flags) -{ - //cv::Mat distCoeffs = cv::Mat::zeros(4, 1, CV_64FC1); - cv::Mat rvec = cv::Mat::zeros(3, 1, CV_64FC1); - cv::Mat tvec = cv::Mat::zeros(3, 1, CV_64FC1); - - bool useExtrinsicGuess = false; - - // Pose estimation - bool correspondence = cv::solvePnP( list_points3d, list_points2d, _A_matrix, _dist, rvec, tvec, - useExtrinsicGuess, flags); - - // Transforms Rotation Vector to Matrix - Rodrigues(rvec,_R_matrix); - _t_matrix = tvec; - - // Set projection matrix - this->set_P_matrix(_R_matrix, _t_matrix); - - return correspondence; -} - -// Estimate the pose given a list of 2D/3D correspondences with RANSAC and the method to use - -void PnPProblem::estimatePoseRANSAC( const std::vector &list_points3d, // list with model 3D coordinates - const std::vector &list_points2d, // list with scene 2D coordinates - int flags, cv::Mat &inliers, int iterationsCount, // PnP method; inliers container - float reprojectionError, double confidence ) // Ransac parameters -{ - //cv::Mat distCoeffs = cv::Mat::zeros(4, 1, CV_64FC1); // vector of distortion coefficients - cv::Mat rvec = cv::Mat::zeros(3, 1, CV_64FC1); // output rotation vector - cv::Mat tvec = cv::Mat::zeros(3, 1, CV_64FC1); // output translation vector - - bool useExtrinsicGuess = false; // if true the function uses the provided rvec and tvec values as - // initial approximations of the rotation and translation vectors - - cv::solvePnPRansac( list_points3d, list_points2d, _A_matrix, _dist, rvec, tvec, - useExtrinsicGuess, iterationsCount, reprojectionError, confidence, - inliers, flags ); - - rvec.copyTo(_R_vect); - Rodrigues(rvec,_R_matrix); // converts Rotation Vector to Matrix - _t_matrix = tvec; // set translation matrix - - this->set_P_matrix(_R_matrix, _t_matrix); // set rotation-translation matrix - -} - -// Given the mesh, backproject the 3D points to 2D to verify the pose estimation -std::vector PnPProblem::verify_points(Mesh *mesh) -{ - std::vector verified_points_2d; - for( int i = 0; i < mesh->getNumVertices(); i++) - { - cv::Point3f point3d = mesh->getVertex(i); - cv::Point2f point2d = this->backproject3DPoint(point3d); - verified_points_2d.push_back(point2d); - } - - return verified_points_2d; -} - - -// Backproject a 3D point to 2D using the estimated pose parameters - -cv::Point2f PnPProblem::backproject3DPoint(const cv::Point3f &point3d) -{ - // 3D point vector [x y z 1]' - cv::Mat point3d_vec = cv::Mat(4, 1, CV_64FC1); - point3d_vec.at(0) = point3d.x; - point3d_vec.at(1) = point3d.y; - point3d_vec.at(2) = point3d.z; - point3d_vec.at(3) = 1; - - // 2D point vector [u v 1]' - cv::Mat point2d_vec = cv::Mat(4, 1, CV_64FC1); - point2d_vec = _A_matrix * _P_matrix * point3d_vec; - - // Normalization of [u v]' - cv::Point2f point2d; - point2d.x = (float)(point2d_vec.at(0) / point2d_vec.at(2)); - point2d.y = (float)(point2d_vec.at(1) / point2d_vec.at(2)); - - - return point2d; -} - -// Back project a 2D point to 3D and returns if it's on the object surface -bool PnPProblem::backproject2DPoint(const Mesh *mesh, const cv::Point2f &point2d, cv::Point3f &point3d) -{ - // Triangles list of the object mesh - std::vector > triangles_list = mesh->getTrianglesList(); - - double lambda = 8; - double u = point2d.x; - double v = point2d.y; - - // Point in vector form - cv::Mat point2d_vec = cv::Mat::ones(3, 1, CV_64F); // 3x1 - point2d_vec.at(0) = u * lambda; - point2d_vec.at(1) = v * lambda; - point2d_vec.at(2) = lambda; - - // Point in camera coordinates - cv::Mat X_c = _A_matrix.inv() * point2d_vec ; // 3x1 - - // Point in world coordinates - cv::Mat X_w = _R_matrix.inv() * ( X_c - _t_matrix ); // 3x1 - - // Center of projection - cv::Mat C_op = cv::Mat(_R_matrix.inv()).mul(-1) * _t_matrix; // 3x1 - - // Ray direction vector - cv::Mat ray = X_w - C_op; // 3x1 - ray = ray / cv::norm(ray); // 3x1 - - // Set up Ray - Ray R((cv::Point3f)C_op, (cv::Point3f)ray); - - // A vector to store the intersections found - std::vector intersections_list; - - // Loop for all the triangles and check the intersection - for (unsigned int i = 0; i < triangles_list.size(); i++) - { - cv::Point3f V0 = mesh->getVertex(triangles_list[i][0]); - cv::Point3f V1 = mesh->getVertex(triangles_list[i][1]); - cv::Point3f V2 = mesh->getVertex(triangles_list[i][2]); - - Triangle T(i, V0, V1, V2); - - double out; - if(this->intersect_MollerTrumbore(R, T, &out)) - { - cv::Point3f tmp_pt = R.getP0() + out*R.getP1(); // P = O + t*D - intersections_list.push_back(tmp_pt); - } - } - - // If there are intersection, find the nearest one - if (!intersections_list.empty()) - { - point3d = get_nearest_3D_point(intersections_list, R.getP0()); - return true; - } - else - { - return false; - } -} - -// Möller–Trumbore intersection algorithm -bool PnPProblem::intersect_MollerTrumbore(Ray &Ray, Triangle &Triangle, double *out) -{ - const double EPSILON = 0.000001; - - cv::Point3f e1, e2; - cv::Point3f P, Q, T; - double det, inv_det, u, v; - double t; - - cv::Point3f V1 = Triangle.getV0(); // Triangle vertices - cv::Point3f V2 = Triangle.getV1(); - cv::Point3f V3 = Triangle.getV2(); - - cv::Point3f O = Ray.getP0(); // Ray origin - cv::Point3f D = Ray.getP1(); // Ray direction - - //Find vectors for two edges sharing V1 - e1 = SUB(V2, V1); - e2 = SUB(V3, V1); - - // Begin calculation determinant - also used to calculate U parameter - P = CROSS(D, e2); - - // If determinant is near zero, ray lie in plane of triangle - det = DOT(e1, P); - - //NOT CULLING - if(det > -EPSILON && det < EPSILON) return false; - inv_det = 1.f / det; - - //calculate distance from V1 to ray origin - T = SUB(O, V1); - - //Calculate u parameter and test bound - u = DOT(T, P) * inv_det; - - //The intersection lies outside of the triangle - if(u < 0.f || u > 1.f) return false; - - //Prepare to test v parameter - Q = CROSS(T, e1); - - //Calculate V parameter and test bound - v = DOT(D, Q) * inv_det; - - //The intersection lies outside of the triangle - if(v < 0.f || u + v > 1.f) return false; - - t = DOT(e2, Q) * inv_det; - - if(t > EPSILON) { //ray intersection - *out = t; - return true; - } - - // No hit, no win - return false; -} diff --git a/detectors/local2D/detection/simple_ransac_detection/PnPProblem.h b/detectors/local2D/detection/simple_ransac_detection/PnPProblem.h deleted file mode 100644 index d8de5413..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/PnPProblem.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * PnPProblem.h - * - * Created on: Mar 28, 2014 - * Author: Edgar Riba - */ - -#ifndef PNPPROBLEM_H_ -#define PNPPROBLEM_H_ - -#include - -#include -#include - -#include "Mesh.h" -#include "ModelRegistration.h" - -class PnPProblem -{ - -public: - explicit PnPProblem(double const param[], double const dists[]); // custom constructor - PnPProblem(cv::Mat intrin = cv::Mat::eye(3, 4, CV_64F), cv::Mat dist = cv::Mat::zeros(1, 5, CV_64F)); - virtual ~PnPProblem(); - - bool backproject2DPoint(const Mesh *mesh, const cv::Point2f &point2d, cv::Point3f &point3d); - bool intersect_MollerTrumbore(Ray &R, Triangle &T, double *out); - std::vector verify_points(Mesh *mesh); - cv::Point2f backproject3DPoint(const cv::Point3f &point3d); - bool estimatePose(const std::vector &list_points3d, const std::vector &list_points2d, int flags); - void estimatePoseRANSAC( const std::vector &list_points3d, const std::vector &list_points2d, - int flags, cv::Mat &inliers, - int iterationsCount, float reprojectionError, double confidence ); - - cv::Mat get_A_matrix() const { return _A_matrix; } - cv::Mat get_dist_coef() const { return _dist; } - cv::Mat get_R_matrix() const { return _R_matrix; } - cv::Mat get_R_vect() const { return _R_vect; } - cv::Mat get_t_matrix() const { return _t_matrix; } - cv::Mat get_P_matrix() const { return _P_matrix; } - - void set_P_matrix( const cv::Mat &R_matrix, const cv::Mat &t_matrix); - - void clearExtrinsics() - { - _R_matrix = cv::Mat::zeros(3, 3, CV_64FC1); // rotation matrix - _t_matrix = cv::Mat::zeros(3, 1, CV_64FC1); // translation matrix - _P_matrix = cv::Mat::zeros(3, 4, CV_64FC1); - } - -private: - /** The calibration matrix */ - cv::Mat _A_matrix; - //dist mat - cv::Mat _dist; - /** The computed rotation matrix */ - cv::Mat _R_matrix; - cv::Mat _R_vect; - /** The computed translation matrix */ - cv::Mat _t_matrix; - /** The computed projection matrix */ - cv::Mat _P_matrix; -}; - -// Functions for Möller–Trumbore intersection algorithm -cv::Point3f CROSS(cv::Point3f v1, cv::Point3f v2); -double DOT(cv::Point3f v1, cv::Point3f v2); -cv::Point3f SUB(cv::Point3f v1, cv::Point3f v2); - -#endif /* PNPPROBLEM_H_ */ diff --git a/detectors/local2D/detection/simple_ransac_detection/RobustMatcher.cpp b/detectors/local2D/detection/simple_ransac_detection/RobustMatcher.cpp deleted file mode 100644 index cd5fffd2..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/RobustMatcher.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - * RobustMatcher.cpp - * - * Created on: Jun 4, 2014 - * Author: eriba - */ - -#include "RobustMatcher.h" -#include "Utils.h" -#include "Model.h" -#include - -#include -#include -#include -#include -#include - - -void convertToUnsignedSiftGPU(cv::Mat const &cv_des, vector &siftgpu_des) -{ - int totdes = cv_des.rows * 128; - siftgpu_des.resize(cv_des.rows * 128); - - int desi = 0; - - for (int i = 0; i < cv_des.rows; i++){ - for (int j = 0; j < 128; j++, desi++) - siftgpu_des[desi] = (unsigned char)cv_des.at(i,j); - } -} - -void convertToDmatch(int siftgpu_matches[][2], int num_match, vector &cv_matches) -{ - cv_matches.resize(num_match); - for(int i = 0; i < num_match; ++i) - { - //How to get the feature matches: - //SiftGPU::SiftKeypoint & key1 = keys1[match_buf[i][0]]; - //SiftGPU::SiftKeypoint & key2 = keys2[match_buf[i][1]]; - //key1 in the first image matches with key2 in the second image - cv_matches[i].trainIdx = siftgpu_matches[i][0]; //Assigned first at init - cv_matches[i].queryIdx = siftgpu_matches[i][1]; - } -} - - -void RobustMatcher::instantiateMatcher(Model const &model, bool use_gpu) -{ - - if (use_gpu_ == true) { - - //####GPU - - //1. for SIFT - matcher_gpu_ = cv::cuda::DescriptorMatcher::createBFMatcher(cv::NORM_L2); - cv::cuda::GpuMat train_descriptors(model.get_descriptors()); - matcher_gpu_->add(std::vector(1, train_descriptors)); - cout << "GPU matcher instantiated ..." << endl; - - } - else - { - matcher_ = cv::makePtr(); - } -} - -RobustMatcher::RobustMatcher(Model const &model, bool use_gpu, bool use_gpu_match) -{ - - use_gpu_ = use_gpu_match; - - - - // ORB is the default feature - ratio_ =0.8f; - detector_ = cv::ORB::create(); - extractor_ = cv::ORB::create(); - - - - instantiateMatcher(model, use_gpu_match); - -// // BruteFroce matcher with Norm Hamming is the default matcher -// //matcher_ = cv::makePtr((int)cv::NORM_HAMMING, false); -// //matcher_ = cv::makePtr((int)cv::NORM_L2, false); -// -// -// //####################TEMPORARY CODE BELOW!!!!!!!!!!!!!!!!!!!!!!!! -// -// cv::Ptr indexParams = cv::makePtr(6, 12, 1); // instantiate LSH index parameters -// cv::Ptr searchParams = cv::makePtr(50); // instantiate flann search parameters -// // instantiate FlannBased matcher -// //Ptr matcher = makePtr(indexParams, searchParams); -// //matcher_ = cv::makePtr(indexParams, searchParams); -// matcher_ = cv::makePtr(); - -} - -RobustMatcher::~RobustMatcher() -{ - // TODO Auto-generated destructor stub -} - -void RobustMatcher::computeKeyPoints( const cv::Mat& image, std::vector& keypoints) -{ - detector_->detect(image, keypoints); -} - -void RobustMatcher::computeDescriptors( const cv::Mat& image, std::vector& keypoints, cv::Mat& descriptors) -{ - extractor_->compute(image, keypoints, descriptors); -} - -int RobustMatcher::ratioTest(std::vector > &matches) -{ - int removed = 0; - // for all matches - for ( std::vector >::iterator - matchIterator= matches.begin(); matchIterator!= matches.end(); ++matchIterator) - { - // if 2 NN has been identified - if (matchIterator->size() > 1) - { - // check distance ratio - if ((*matchIterator)[0].distance / (*matchIterator)[1].distance > ratio_) - { - matchIterator->clear(); // remove match - removed++; - } - } - else - { // does not have 2 neighbours - matchIterator->clear(); // remove match - removed++; - } - } - return removed; -} - -void get_good_matches(const std::vector >& matches, std::vector& goodMatches) -{ - for (std::vector >::const_iterator - matchIterator1 = matches.begin(); matchIterator1 != matches.end(); ++matchIterator1) - { - // ignore deleted matches - if (matchIterator1->empty() || matchIterator1->size() < 2) - continue; - if ((*matchIterator1)[0].distance < (*matchIterator1)[1].distance) - goodMatches.push_back((*matchIterator1)[0]); - } - -} - -void RobustMatcher::symmetryTest( const std::vector >& matches1, - const std::vector >& matches2, - std::vector& symMatches ) -{ - - // for all matches image 1 -> image 2 - for (std::vector >::const_iterator - matchIterator1 = matches1.begin(); matchIterator1 != matches1.end(); ++matchIterator1) - { - - // ignore deleted matches - if (matchIterator1->empty() || matchIterator1->size() < 2) - continue; - - // for all matches image 2 -> image 1 - for (std::vector >::const_iterator - matchIterator2 = matches2.begin(); matchIterator2 != matches2.end(); ++matchIterator2) - { - // ignore deleted matches - if (matchIterator2->empty() || matchIterator2->size() < 2) - continue; - - // Match symmetry test - if ((*matchIterator1)[0].queryIdx == - (*matchIterator2)[0].trainIdx && - (*matchIterator2)[0].queryIdx == - (*matchIterator1)[0].trainIdx) - { - // add symmetrical match - symMatches.push_back( - cv::DMatch((*matchIterator1)[0].queryIdx, - (*matchIterator1)[0].trainIdx, - (*matchIterator1)[0].distance)); - break; // next match in image 1 -> image 2 - } - } - } - -} - -void RobustMatcher::match(const cv::Mat & descriptors_frame, const cv::Mat &descriptors_model, std::vector& good_matches) -{ - std::vector > matches; - - if (use_gpu_) - { - matcher_gpu_->knnMatch(cv::cuda::GpuMat(descriptors_frame), matches, 2); // return 2 nearest neighbours - ratioTest(matches); - for ( std::vector >::iterator - matchIterator= matches.begin(); matchIterator!= matches.end(); ++matchIterator) - { - if (!matchIterator->empty()) good_matches.push_back((*matchIterator)[0]); - } - } - else - { - matcher_->knnMatch(descriptors_frame, descriptors_model, matches, 2); // return 2 nearest neighbours - ratioTest(matches); - // 4. Fill good matches container - for ( std::vector >::iterator - matchIterator= matches.begin(); matchIterator!= matches.end(); ++matchIterator) - { - if (!matchIterator->empty()) good_matches.push_back((*matchIterator)[0]); - } - - } -} - -void RobustMatcher::matchNormalized(cv::Mat & descriptors_frame, cv::Mat &descriptors_model, std::vector& good_matches) -{ - od::normL2(descriptors_frame); od::normL2(descriptors_model); - match(descriptors_frame, descriptors_model, good_matches); -} - -void RobustMatcher::robustMatch( const cv::Mat& frame, std::vector& good_matches, - std::vector& keypoints_frame, const cv::Mat& descriptors_model ) -{ - // 1a. Detection of the ORB features - //this->computeKeyPoints(frame, keypoints_frame); - - // 1b. Extraction of the ORB descriptors - cv::Mat descriptors_frame; - //this->computeDescriptors(frame, keypoints_frame, descriptors_frame); - - featureDetector_->computeKeypointsAndDescriptors(frame, descriptors_frame, keypoints_frame); - //cout << "After Restacking: \n" << descriptors_frame << endl; - // 2. Match the two image descriptors - std::vector > matches12, matches21; - - // 2a. From image 1 to image 2 - matcher_->knnMatch(descriptors_frame, descriptors_model, matches12, 2); // return 2 nearest neighbours - - // 2b. From image 2 to image 1 - matcher_->knnMatch(descriptors_model, descriptors_frame, matches21, 2); // return 2 nearest neighbours - - - // 3. Remove matches for which NN ratio is > than threshold - // clean image 1 -> image 2 matches - ratioTest(matches12); - // clean image 2 -> image 1 matches - ratioTest(matches21); - - //get_good_matches(matches12, good_matches); - - // 4. Remove non-symmetrical matches - symmetryTest(matches12, matches21, good_matches); - - -} - -void RobustMatcher::findFeatureAndMatch( const cv::Mat& frame, std::vector& good_matches, - std::vector& keypoints_frame, - const cv::Mat& descriptors_model ) -{ - good_matches.clear(); - - // 1b. Extraction of the ORB descriptors - cv::Mat descriptors_frame; - featureDetector_->computeKeypointsAndDescriptors(frame, descriptors_frame, keypoints_frame); - - cout << "df " << descriptors_model.rows << endl; - cout << "kf" << descriptors_frame.rows << endl; - - match(descriptors_frame, descriptors_model, good_matches); - -} - - -void RobustMatcher::fastRobustMatch( const cv::Mat& frame, std::vector& good_matches, - std::vector& keypoints_frame, - const cv::Mat& descriptors_model ) -{ - good_matches.clear(); - - cv::Mat d_f, d_m; - // 1a. Detection of the ORB features - //this->computeKeyPoints(frame, keypoints_frame); - - // 1b. Extraction of the ORB descriptors - cv::Mat descriptors_frame; - //this->computeDescriptors(frame, keypoints_frame, descriptors_frame); - - featureDetector_->computeKeypointsAndDescriptors(frame, descriptors_frame, keypoints_frame); - - if (descriptors_frame.type() != CV_32F) { - descriptors_frame.convertTo(d_f, CV_32F); - } - else { - d_f = descriptors_frame; - } - if (descriptors_model.type() != CV_32F) { - descriptors_model.convertTo(d_f, CV_32F); - } - else - { - d_m = descriptors_model; - } - - // 2. Match the two image descriptors - std::vector > matches; - matcher_->knnMatch(d_f, d_m, matches, 2); - - // 3. Remove matches for which NN ratio is > than threshold - ratioTest(matches); - - // 4. Fill good matches container - for ( std::vector >::iterator - matchIterator= matches.begin(); matchIterator!= matches.end(); ++matchIterator) - { - if (!matchIterator->empty()) good_matches.push_back((*matchIterator)[0]); - } - -} - - diff --git a/detectors/local2D/detection/simple_ransac_detection/RobustMatcher.h b/detectors/local2D/detection/simple_ransac_detection/RobustMatcher.h deleted file mode 100644 index 4674b33c..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/RobustMatcher.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * RobustMatcher.h - * - * Created on: Jun 4, 2014 - * Author: eriba - */ - -#ifndef ROBUSTMATCHER_H_ -#define ROBUSTMATCHER_H_ - -#include - -#include -#include -#include -#include "common/utils/ODFeatureDetector2D.h" -#include "Model.h" - -using namespace std; - -class -RobustMatcher { -public: - RobustMatcher(Model const &model, bool use_gpu, bool b); - - - int mode_; - bool use_gpu_; - - virtual ~RobustMatcher(); - - // Set the feature detector - void setFeatureDetector(const cv::Ptr& detect) { detector_ = detect; } - - // Set the descriptor extractor - void setDescriptorExtractor(const cv::Ptr& desc) { extractor_ = desc; } - - // Set the matcher - void setDescriptorMatcher(const cv::Ptr& match) { matcher_ = match; } - - // Compute the keypoints of an image - void computeKeyPoints( const cv::Mat& image, std::vector& keypoints); - - // Compute the descriptors of an image given its keypoints - void computeDescriptors( const cv::Mat& image, std::vector& keypoints, cv::Mat& descriptors); - - // Set ratio parameter for the ratio test - void setRatio( float rat) { ratio_ = rat; } - - // Clear matches for which NN ratio is > than threshold - // return the number of removed points - // (corresponding entries being cleared, - // i.e. size will be 0) - int ratioTest(std::vector > &matches); - - // Insert symmetrical matches in symMatches vector - void symmetryTest( const std::vector >& matches1, - const std::vector >& matches2, - std::vector& symMatches ); - - // Match feature points using ratio and symmetry test - void robustMatch( const cv::Mat& frame, std::vector& good_matches, - std::vector& keypoints_frame, - const cv::Mat& descriptors_model ); - - // Match feature points using ratio test - void fastRobustMatch( const cv::Mat& frame, std::vector& good_matches, - std::vector& keypoints_frame, - const cv::Mat& descriptors_model ); - - void findFeatureAndMatch(cv::Mat const &frame, vector &good_matches, vector &keypoints_frame, - cv::Mat const &descriptors_model); - - void match(const cv::Mat & descriptors_frame, const cv::Mat &descriptors_model, std::vector& good_matches); - - void matchNormalized(cv::Mat &descriptors_frame, cv::Mat &descriptors_model, vector &good_matches); - -private: - // pointer to the feature point detector object - cv::Ptr featureDetector_; - - cv::Ptr detector_; - // pointer to the feature descriptor extractor object - cv::Ptr extractor_; - // pointer to the matcher object - - //The important feature of this class starts here - //DIFFERENT TYPES OF MATCHERS, add here in this list (based on the construction - cv::Ptr matcher_; - cv::Ptr matcher_gpu_; - // max ratio between 1st and 2nd NN - float ratio_; - - void instantiateMatcher(Model const &feature_type, bool use_gpu); - - - - - void instantiateMatcher1(Model const &model, bool use_gpu); - -}; - -#endif /* ROBUSTMATCHER_H_ */ diff --git a/detectors/local2D/detection/simple_ransac_detection/Utils.cpp b/detectors/local2D/detection/simple_ransac_detection/Utils.cpp deleted file mode 100644 index 3501eac1..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/Utils.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Utils.cpp - * - * Created on: Mar 28, 2014 - * Author: Edgar Riba - */ - -#include - - - -#include "PnPProblem.h" -#include "ModelRegistration.h" -#include "Utils.h" -#include "Model.h" - -#include -#include - -// For text -int fontFace = cv::FONT_ITALIC; -double fontScale = 0.75; -int thickness_font = 2; - -// For circles -int lineType = 16; -int radius = 1; -double thickness_circ = -1; - - -using namespace std; - - - -void viewImage(cv::Mat image, vector keypoints) -{ - cv::Mat outimage = image; - cv::drawKeypoints(image, keypoints, outimage, cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); - - cv::namedWindow( "Keypoints", cv::WINDOW_NORMAL ); // Create a window for display. - cv::resizeWindow("Keypoints", 800, 600); - - cv::imshow("Keypoints", outimage); - cv::waitKey(0); -} - -// Draw a text with the question point -void drawQuestion(cv::Mat image, cv::Point3f point, cv::Scalar color) -{ - std::string x = IntToString((int)point.x); - std::string y = IntToString((int)point.y); - std::string z = IntToString((int)point.z); - - std::string text = " Where is point (" + x + "," + y + "," + z + ") ?"; - cv::putText(image, text, cv::Point(25,50), fontFace, fontScale, color, thickness_font, 8); -} - -// Draw a text with the number of entered points -void drawText(cv::Mat image, std::string text, cv::Scalar color) -{ - cv::putText(image, text, cv::Point(25,50), fontFace, fontScale, color, thickness_font, 8); -} - -// Draw a text with the number of entered points -void drawText2(cv::Mat image, std::string text, cv::Scalar color) -{ - cv::putText(image, text, cv::Point(25,75), fontFace, fontScale, color, thickness_font, 8); -} - -// Draw a text with the frame ratio -void drawFPS(cv::Mat image, double fps, cv::Scalar color) -{ - std::string fps_str = IntToString((int)fps); - std::string text = fps_str + " FPS"; - cv::putText(image, text, cv::Point(500,50), fontFace, fontScale, color, thickness_font, 8); -} - -// Draw a text with the frame ratio -void drawConfidence(cv::Mat image, double confidence, cv::Scalar color) -{ - std::string conf_str = IntToString((int)confidence); - std::string text = conf_str + " %"; - cv::putText(image, text, cv::Point(500,75), fontFace, fontScale, color, thickness_font, 8); -} - -// Draw a text with the number of entered points -void drawCounter(cv::Mat image, int n, int n_max, cv::Scalar color) -{ - std::string n_str = IntToString(n); - std::string n_max_str = IntToString(n_max); - std::string text = n_str + " of " + n_max_str + " points"; - cv::putText(image, text, cv::Point(500,50), fontFace, fontScale, color, thickness_font, 8); -} - -// Draw the points and the coordinates -void drawPoints(cv::Mat image, std::vector &list_points_2d, std::vector &list_points_3d, cv::Scalar color) -{ - for (unsigned int i = 0; i < list_points_2d.size(); ++i) - { - cv::Point2f point_2d = list_points_2d[i]; - cv::Point3f point_3d = list_points_3d[i]; - - // Draw Selected points - cv::circle(image, point_2d, radius, color, -1, lineType ); - - std::string idx = IntToString(i+1); - std::string x = IntToString((int)point_3d.x); - std::string y = IntToString((int)point_3d.y); - std::string z = IntToString((int)point_3d.z); - std::string text = "P" + idx + " (" + x + "," + y + "," + z +")"; - - point_2d.x = point_2d.x + 10; - point_2d.y = point_2d.y - 10; - cv::putText(image, text, point_2d, fontFace, fontScale*0.5, color, thickness_font, 8); - } -} - -// Draw only the 2D points -void draw2DPoints(cv::Mat image, std::vector &list_points, cv::Scalar color) -{ - for( size_t i = 0; i < list_points.size(); i++) - { - cv::Point2f point_2d = list_points[i]; - - // Draw Selected points - cv::circle(image, point_2d, radius, color, -1, lineType ); - } -} - -// Draw an arrow into the image -void drawArrow(cv::Mat image, cv::Point2i p, cv::Point2i q, cv::Scalar color, int arrowMagnitude, int thickness, int line_type, int shift) -{ - //Draw the principle line - cv::line(image, p, q, color, thickness, line_type, shift); - const double PI = CV_PI; - //compute the angle alpha - double angle = atan2((double)p.y-q.y, (double)p.x-q.x); - //compute the coordinates of the first segment - p.x = (int) ( q.x + arrowMagnitude * cos(angle + PI/4)); - p.y = (int) ( q.y + arrowMagnitude * sin(angle + PI/4)); - //Draw the first segment - cv::line(image, p, q, color, thickness, line_type, shift); - //compute the coordinates of the second segment - p.x = (int) ( q.x + arrowMagnitude * cos(angle - PI/4)); - p.y = (int) ( q.y + arrowMagnitude * sin(angle - PI/4)); - //Draw the second segment - cv::line(image, p, q, color, thickness, line_type, shift); -} - -// Draw the 3D coordinate axes -void draw3DCoordinateAxes(cv::Mat image, const std::vector &list_points2d) -{ - cv::Scalar red(0, 0, 255); - cv::Scalar green(0,255,0); - cv::Scalar blue(255,0,0); - cv::Scalar black(0,0,0); - - cv::Point2i origin = list_points2d[0]; - cv::Point2i pointX = list_points2d[1]; - cv::Point2i pointY = list_points2d[2]; - cv::Point2i pointZ = list_points2d[3]; - - drawArrow(image, origin, pointX, red, 9, 2); - drawArrow(image, origin, pointY, blue, 9, 2); - drawArrow(image, origin, pointZ, green, 9, 2); - cv::circle(image, origin, radius/2, black, -1, lineType ); - -} - -// Draw the object mesh -void drawObjectMesh(cv::Mat image, const Mesh *mesh, PnPProblem *pnpProblem, cv::Scalar color) -{ - std::vector > list_triangles = mesh->getTrianglesList(); - int skip = 1; -// if (pnpProblem->get_A_matrix().at(0,2) < 300 && list_triangles.size() > 1000) -// skip = 10; - - for( size_t i = 0; i < list_triangles.size(); i+= skip) - { - std::vector tmp_triangle = list_triangles.at(i); - - cv::Point3f point_3d_0 = mesh->getVertex(tmp_triangle[0]); - cv::Point3f point_3d_1 = mesh->getVertex(tmp_triangle[1]); - cv::Point3f point_3d_2 = mesh->getVertex(tmp_triangle[2]); - - //std::cout << point_3d_0 << std::endl << point_3d_1 << std::endl << point_3d_2 << std::endl << std::endl; - - cv::Point2f point_2d_0 = pnpProblem->backproject3DPoint(point_3d_0); - cv::Point2f point_2d_1 = pnpProblem->backproject3DPoint(point_3d_1); - cv::Point2f point_2d_2 = pnpProblem->backproject3DPoint(point_3d_2); - - cv::line(image, point_2d_0, point_2d_1, color, 1); - cv::line(image, point_2d_1, point_2d_2, color, 1); - cv::line(image, point_2d_2, point_2d_0, color, 1); - } -} - -void drawObjectMesh1(cv::Mat image, const Mesh *mesh, const Model *model, PnPProblem *pnpProblem, cv::Scalar color) -{ - std::vector imgpoints; - cv::projectPoints(model->get_points3d(), pnpProblem->get_R_vect(), pnpProblem->get_t_matrix(), pnpProblem->get_A_matrix(), pnpProblem->get_dist_coef(), imgpoints); - draw2DPoints(image, imgpoints, color); - -} - -void drawModel(cv::Mat image, const Model *model, PnPProblem *pnpProblem, cv::Scalar color) -{ - std::vector imgpoints; - cv::projectPoints(model->get_points3d(), pnpProblem->get_R_vect(), pnpProblem->get_t_matrix(), pnpProblem->get_A_matrix(), pnpProblem->get_dist_coef(), imgpoints); - draw2DPoints(image, imgpoints, color); - -} - -void drawModel(cv::Mat image, const Model *model, cv::Mat R_vect, cv::Mat t_mat, cv::Mat A_mat, cv::Mat dist, cv::Scalar color) -{ - std::vector imgpoints; - cv::projectPoints(model->get_points3d(), R_vect, t_mat, A_mat, dist, imgpoints); - draw2DPoints(image, imgpoints, color); - -} - - -// Computes the norm of the translation error -double get_translation_error(const cv::Mat &t_true, const cv::Mat &t) -{ - return cv::norm( t_true - t ); -} - -// Computes the norm of the rotation error -double get_rotation_error(const cv::Mat &R_true, const cv::Mat &R) -{ - cv::Mat error_vec, error_mat; - error_mat = R_true * cv::Mat(R.inv()).mul(-1); - cv::Rodrigues(error_mat, error_vec); - - return cv::norm(error_vec); -} - -// Converts a given Rotation Matrix to Euler angles -cv::Mat rot2euler(const cv::Mat & rotationMatrix) -{ - cv::Mat euler(3,1,CV_64F); - - double m00 = rotationMatrix.at(0,0); - double m02 = rotationMatrix.at(0,2); - double m10 = rotationMatrix.at(1,0); - double m11 = rotationMatrix.at(1,1); - double m12 = rotationMatrix.at(1,2); - double m20 = rotationMatrix.at(2,0); - double m22 = rotationMatrix.at(2,2); - - double x, y, z; - - // Assuming the angles are in radians. - if (m10 > 0.998) { // singularity at north pole - x = 0; - y = CV_PI/2; - z = atan2(m02,m22); - } - else if (m10 < -0.998) { // singularity at south pole - x = 0; - y = -CV_PI/2; - z = atan2(m02,m22); - } - else - { - x = atan2(-m12,m11); - y = asin(m10); - z = atan2(-m20,m00); - } - - euler.at(0) = x; - euler.at(1) = y; - euler.at(2) = z; - - return euler; -} - -// Converts a given Euler angles to Rotation Matrix -cv::Mat euler2rot(const cv::Mat & euler) -{ - cv::Mat rotationMatrix(3,3,CV_64F); - - double x = euler.at(0); - double y = euler.at(1); - double z = euler.at(2); - - // Assuming the angles are in radians. - double ch = cos(z); - double sh = sin(z); - double ca = cos(y); - double sa = sin(y); - double cb = cos(x); - double sb = sin(x); - - double m00, m01, m02, m10, m11, m12, m20, m21, m22; - - m00 = ch * ca; - m01 = sh*sb - ch*sa*cb; - m02 = ch*sa*sb + sh*cb; - m10 = sa; - m11 = ca*cb; - m12 = -ca*sb; - m20 = -sh*ca; - m21 = sh*sa*cb + ch*sb; - m22 = -sh*sa*sb + ch*cb; - - rotationMatrix.at(0,0) = m00; - rotationMatrix.at(0,1) = m01; - rotationMatrix.at(0,2) = m02; - rotationMatrix.at(1,0) = m10; - rotationMatrix.at(1,1) = m11; - rotationMatrix.at(1,2) = m12; - rotationMatrix.at(2,0) = m20; - rotationMatrix.at(2,1) = m21; - rotationMatrix.at(2,2) = m22; - - return rotationMatrix; -} - -// Converts a given string to an integer -int StringToInt ( const std::string &Text ) -{ - std::istringstream ss(Text); - int result; - return ss >> result ? result : 0; -} - -// Converts a given float to a string -std::string FloatToString ( float Number ) -{ - std::ostringstream ss; - ss << Number; - return ss.str(); -} - -// Converts a given integer to a string -std::string IntToString ( int Number ) -{ - std::ostringstream ss; - ss << Number; - return ss.str(); -} diff --git a/detectors/local2D/detection/simple_ransac_detection/Utils.h b/detectors/local2D/detection/simple_ransac_detection/Utils.h deleted file mode 100644 index 29ff27af..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/Utils.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Utils.h - * - * Created on: Mar 28, 2014 - * Author: Edgar Riba - */ - -#ifndef UTILS_H_ -#define UTILS_H_ - -#include -#include - -#include "PnPProblem.h" -#include "Model.h" - -using namespace std; - -void viewImage(cv::Mat image, vector keypoints = vector(0)); - -// Draw a text with the question point -void drawQuestion(cv::Mat image, cv::Point3f point, cv::Scalar color); - -// Draw a text with the number of entered points -void drawText(cv::Mat image, std::string text, cv::Scalar color); - -// Draw a text with the number of entered points -void drawText2(cv::Mat image, std::string text, cv::Scalar color); - -// Draw a text with the frame ratio -void drawFPS(cv::Mat image, double fps, cv::Scalar color); - -// Draw a text with the frame ratio -void drawConfidence(cv::Mat image, double confidence, cv::Scalar color); - -// Draw a text with the number of entered points -void drawCounter(cv::Mat image, int n, int n_max, cv::Scalar color); - -// Draw the points and the coordinates -void drawPoints(cv::Mat image, std::vector &list_points_2d, std::vector &list_points_3d, cv::Scalar color); - -// Draw only the 2D points -void draw2DPoints(cv::Mat image, std::vector &list_points, cv::Scalar color); - -// Draw an arrow into the image -void drawArrow(cv::Mat image, cv::Point2i p, cv::Point2i q, cv::Scalar color, int arrowMagnitude = 9, int thickness=1, int line_type=8, int shift=0); - -// Draw the 3D coordinate axes -void draw3DCoordinateAxes(cv::Mat image, const std::vector &list_points2d); - -// Draw the object mesh -void drawObjectMesh(cv::Mat image, const Mesh *mesh, PnPProblem *pnpProblem, cv::Scalar color); -void drawObjectMesh1(cv::Mat image, const Mesh *mesh, const Model *model, PnPProblem *pnpProblem, cv::Scalar color); -void drawModel(cv::Mat image, const Model *model, PnPProblem *pnpProblem, cv::Scalar color); -void drawModel(cv::Mat image, const Model *model, cv::Mat R_vect, cv::Mat t_mat, cv::Mat A_mat, cv::Mat dist, cv::Scalar color); - -// Computes the norm of the translation error -double get_translation_error(const cv::Mat &t_true, const cv::Mat &t); - -// Computes the norm of the rotation error -double get_rotation_error(const cv::Mat &R_true, const cv::Mat &R); - -// Converts a given Rotation Matrix to Euler angles -cv::Mat rot2euler(const cv::Mat & rotationMatrix); - -// Converts a given Euler angles to Rotation Matrix -cv::Mat euler2rot(const cv::Mat & euler); - -// Converts a given string to an integer -int StringToInt ( const std::string &Text ); - -// Converts a given float to a string -std::string FloatToString ( float Number ); - -// Converts a given integer to a string -std::string IntToString ( int Number ); - - - -#endif /* UTILS_H_ */ diff --git a/detectors/local2D/detection/simple_ransac_detection/main_detection_image_wo_k.cpp b/detectors/local2D/detection/simple_ransac_detection/main_detection_image_wo_k.cpp deleted file mode 100644 index c8e0f96a..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/main_detection_image_wo_k.cpp +++ /dev/null @@ -1,578 +0,0 @@ -//--model=Data/Chicken/Mesh.xml --mesh=Data/Chicken/Mesh.ply -// --use_gpu --fast --method=1 --error=2 --confidence=0.9 --iterations=500 --inliers=30 --model=Data/Chicken/Mesh.xml --mesh=Data/Chicken/Mesh.ply --test_images=./Data/Chicken/Chicken/*.JPG --camera_intrinsic_file=Data/out_camera_dataset_101.yml -// --use_gpu --fast --method=1 --error=2 --confidence=0.9 --iterations=500 --inliers=30 --test_images=./Data/Lion/test_images/IMG_*.JPG --camera_intrinsic_file=Data/out_camera_data_lion_old.yml -// --fast --method=1 --error=2 --confidence=0.9 --iterations=500 --inliers=30 --test_images=./Data/Lion/Lion2/IMG_*.JPG --camera_intrinsic_file=Data/out_camera_dataset_101.yml -//--fast --method=1 --error=2 --confidence=0.9 --iterations=500 --inliers=10 --model=Data/Totem/Param.SIFT.xml --mesh=Data/Totem/Param.ply --test_images=./Data/Totem/Totem/IMG_0251.JPG --camera_intrinsic_file=Data/out_camera_dataset_101.yml - -// C++ -#include -#include -// OpenCV -#include -#include -#include -#include -#include -#include -#include -#include - - -#include - -// PnP Tutorial -#include "Mesh.h" -#include "Model.h" -#include "PnPProblem.h" -#include "RobustMatcher.h" -#include "ModelRegistration.h" -#include "Utils.h" - -/** GLOBAL VARIABLES **/ - -using namespace cv; -using namespace std; -using namespace cv::xfeatures2d; - - -string tutorial_path = ""; // path to tutorial - - - -//string yml_read_path = tutorial_path + "Data/cookies_ORB.yml"; // 3dpts + descriptors -//string ply_read_path = tutorial_path + "Data/box.ply"; // mesh - -//string video_read_path = tutorial_path + "Data/box.mp4"; // recorded video -string yml_read_path = tutorial_path + "Data/Lion/Final.SIFT.xml"; // 3dpts + descriptors -string ply_read_path = tutorial_path + "Data/Lion/Final.ply"; // mesh -string ply_tex_path = tutorial_path + "Data/Totem/Texture.png"; // mesh - - -string camera_intrinsic_file = tutorial_path + "Data/out_camera_data_lion_old.yml"; // mesh - -// -//string yml_read_path = tutorial_path + "Data/Lion/low_res_texture/Final.pairs"; // 3dpts + descriptors -//string ply_read_path = tutorial_path + "Data/Lion/low_res_texture/Final.ply"; // mesh -//string ply_tex_path = tutorial_path + "Data/Lion/low_res_texture/Texture_1024.png"; // mesh - - -//// Intrinsic camera parameters: UVC WEBCAM -//double fx = 3.51567979e+03; // focal length in mm -//double fy = 3.52343259e+03; -//double sx = 1, sy = 1; // sensor size -//double cx = 2.11793527e+03, cy = 1.49318756e+03; // image size - -// Intrinsic camera parameters: UVC WEBCAM -double fx = 3.51567979e+03; // focal length in mm -double fy = 3.52343259e+03; -double sx = 1, sy = 1; // sensor size -double cx = 2.11793527e+03, cy = 1.49318756e+03; // image size - -double params_WEBCAM[] = { fx, // fx - fy, // fy - cx, // cx - cy}; // cy -//double param_dist[] = {-0.18835486, 0.09173112, 0.00188108, 0.00033594, 0.16224491}; -double param_dist[] = {1.4481173997393210e-01, -3.5247562241022906e-01, 0, 0, 1.4483165395214911e-01}; - -// Some basic colors -Scalar red(0, 0, 255); -Scalar green(0,255,0); -Scalar blue(255,0,0); -Scalar yellow(0,255,255); - - -// Robust Matcher parameters -int numKeyPoints = 2000; // number of detected keypoints -float ratioTest = 0.70f; // ratio test -bool fast_match = true; // fastRobustMatch() or robustMatch() -bool use_gpu = false; -bool use_gpu_match = false; - -// RANSAC parameters -int iterationsCount = 500; // number of Ransac iterations. -float reprojectionError = 2.0; // maximum allowed distance to consider it an inlier. -double confidence = 0.95; // ransac successful confidence. - -// Kalman Filter parameters -int minInliersKalman = 30; // Kalman threshold updating - -// PnP parameters -int pnpMethod = SOLVEPNP_EPNP; - - -/** Functions headers **/ -void help(); -void initKalmanFilter( KalmanFilter &KF, int nStates, int nMeasurements, int nInputs, double dt); -void updateKalmanFilter( KalmanFilter &KF, Mat &measurements, - Mat &translation_estimated, Mat &rotation_estimated ); -void fillMeasurements( Mat &measurements, - const Mat &translation_measured, const Mat &rotation_measured); - - -class FrameGenerator -{ -public: - FrameGenerator(CommandLineParser parser) - { - //some hardcoded default values (TEST ONE IMAGES), the program will run even without any arguments - cameraID = 0; - curr_image = -1; - string test_images = tutorial_path + "Data/Lion/test_images/IMG_20150226_102852.jpg"; - image_list = myglob(test_images); - - inputType = IMAGE_LIST; - - exhausted = false; - cout << "yo " << parser.get("cam_id") << endl; - - //parsing input from the arguments now - if (parser.get("test_images").size() > 0) - { - test_images = parser.get("test_images"); - inputType = IMAGE_LIST; - image_list = myglob(test_images); - } - if (parser.get("video").size() > 0) { - video_read_path = parser.get("video"); - inputType = VIDEO_FILE; - inputCapture.open(video_read_path); - if (!inputCapture.isOpened()) { cout << "FATAL: Cannot open video capture!"; exhausted = true;} - } - if(parser.has("cam_id")) //MAX PREFERENCE - { - cameraID = !parser.get("cam_id") ? parser.get("cam_id") : cameraID; - inputType = CAMERA; - inputCapture.open(cameraID); - if (!inputCapture.isOpened()) { cout << "FATAL: Cannot open video capture!"; exhausted = true;} - } - - - } - - Mat getNextFrame() - { - Mat result; - if (inputType == IMAGE_LIST) - { - curr_image ++ ; - - //sleep(3); //wait for 3 seconds - - if (curr_image == image_list.size() - 1) - exhausted = true; - cout << "Frame: " << image_list[curr_image] << endl; - - -// KFeatureDetector fd("SIFT", true); -// cv::Mat descriptors; vector kps; - //fd.findSiftGPUDescriptors(image_list[curr_image].c_str(), descriptors, kps); - - result = imread(image_list[curr_image], IMREAD_COLOR); -// Mat result1 = imread(image_list[curr_image], IMREAD_GRAYSCALE); -// Mat temp; -// cv::cvtColor(result, temp, cv::COLOR_BGR2GRAY); - - //2 -// fd.findSiftGPUDescriptors(result1, descriptors, kps ); -// fd.findSiftGPUDescriptors(temp, descriptors, kps ); -// fd.findSiftGPUDescriptors(result, descriptors, kps ); - - } - else - { - if( inputCapture.isOpened() ) { - //as real time as possible - inputCapture.read(result); - } - else exhausted = false; - } - - return result; - } - -public: - enum InputType { INVALID, CAMERA, VIDEO_FILE, IMAGE_LIST }; - - string input; - - int cameraID; - vector image_list; - string video_read_path; - int curr_image; - VideoCapture inputCapture; - - InputType inputType; - bool exhausted; - - -private: - string patternToUse; - - -}; - -Mat drawMatchesAfterRansac(Mat frame_vis, vector l_pt_scene, vector l_kp_model, Mat inliner_idx) { - - Mat img_object = imread(ply_tex_path, IMREAD_GRAYSCALE ); - - vector l_kp_scene; - - for (int i =0; i < l_pt_scene.size(); i++) - { - KeyPoint kp(l_pt_scene[i].x, l_pt_scene[i].y, 1); l_kp_scene.push_back(kp); - } - - //make matches - vector match; - for (int i =0; i < inliner_idx.rows; i++) - { - int good_index = inliner_idx.at(i); // i-inlier - DMatch m(good_index, good_index, 1); match.push_back(m); - } - - Mat img_matches; - drawMatches(frame_vis, l_kp_scene, - img_object, l_kp_model, - match, img_matches, Scalar::all(-1), Scalar::all(-1), - vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); - - return img_matches; -} - -viz::Mesh getMesh() -{ - Mat lena = imread("Data/simplecube/flower.jpeg"); - - std::vector points; - std::vector tcoords; - std::vector polygons; - for(size_t i = 0; i < 64; ++i) - { - double angle = CV_PI/2 * i/64.0; - points.push_back(Vec3d(0.00, cos(angle), sin(angle))*0.75); - points.push_back(Vec3d(1.57, cos(angle), sin(angle))*0.75); - tcoords.push_back(Vec2d(0.0, i/64.0)); - tcoords.push_back(Vec2d(1.0, i/64.0)); - } - - 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])); - } - - cv::viz::Mesh mesh; - mesh.cloud = Mat(points, true).reshape(3, 1); - mesh.tcoords = Mat(tcoords, true).reshape(2, 1); - mesh.polygons = Mat(polygons, true).reshape(1, 1); - mesh.texture = lena; - return mesh; -} - -void viz_exp() -{ - viz::Mesh mesh = getMesh(); - - double w = 1024, h = 800; - viz::Camera camera(606, 606, w/2, h/2, Size(w, h)); - - viz::Viz3d viz("show_textured_mesh"); - viz.setCamera(camera); - - - viz.setBackgroundMeshLab(); - - viz.showWidget("mesh", viz::WMesh(mesh)); - viz.setRenderingProperty("mesh", viz::SHADING, viz::SHADING_PHONG); - viz.showWidget("text2d", viz::WText("Textured mesh", Point(20, 20), 20, viz::Color::green())); - viz.spin(); -} - -/** Main program **/ -int main(int argc, char *argv[]) -{ - - //viz_exp(); - - - help(); - - const String keys = - "{help h | | print this message }" - "{video v | | path to recorded video }" - "{test_images img | | image for detection }" - "{cam_id | | pass true if you want the input from the camera }" - "{camera_intrinsic_file | | yml file containing camera parameters }" - "{model | | path to yml model }" - "{mesh | | path to ply mesh }" - "{use_gpu | | use gpu or cpu }" - "{use_gpu_match | | use gpu or cpu for matching }" - "{keypoints k |2000 | number of keypoints to detect }" - "{ratio r |0.7 | threshold for ratio test }" - "{iterations it |500 | RANSAC maximum iterations count }" - "{error e |2.0 | RANSAC reprojection errror }" - "{confidence c |0.95 | RANSAC confidence }" - "{inliers in |30 | minimum inliers for Kalman update }" - "{method pnp |0 | PnP method: (0) ITERATIVE - (1) EPNP - (2) P3P - (3) DLS}" - "{fast f |false | use of robust fast match }" - ; - CommandLineParser parser(argc, argv, keys); - if (parser.has("help")) - { - parser.printMessage(); - return 0; - } - else - { - camera_intrinsic_file = parser.get("camera_intrinsic_file").size() > 0 ? parser.get("camera_intrinsic_file") : camera_intrinsic_file; - yml_read_path = parser.get("model").size() > 0 ? parser.get("model") : yml_read_path; - ply_read_path = parser.get("mesh").size() > 0 ? parser.get("mesh") : ply_read_path; - - use_gpu = parser.has("use_gpu"); - use_gpu_match = parser.has("use_gpu_match"); - - numKeyPoints = !parser.has("keypoints") ? parser.get("keypoints") : numKeyPoints; - ratioTest = !parser.has("ratio") ? parser.get("ratio") : ratioTest; - fast_match = !parser.has("fast") ? parser.get("fast") : fast_match; - iterationsCount = !parser.has("iterations") ? parser.get("iterations") : iterationsCount; - reprojectionError = !parser.has("error") ? parser.get("error") : reprojectionError; - confidence = !parser.has("confidence") ? parser.get("confidence") : confidence; - minInliersKalman = !parser.has("inliers") ? parser.get("inliers") : minInliersKalman; - pnpMethod = !parser.has("method") ? parser.get("method") : pnpMethod; - } - - - FileStorage fs(camera_intrinsic_file, FileStorage::READ); - Mat cam_man, dist_coeff; - fs["Camera_Matrix"] >> cam_man; - fs["Distortion_Coefficients"] >> dist_coeff; - PnPProblem pnp_detection(cam_man, dist_coeff); - PnPProblem pnp_detection_est(cam_man, dist_coeff); - - - - KalmanFilter KF; // instantiate Kalman Filter - int nStates = 18; // the number of states - int nMeasurements = 6; // the number of measured states - int nInputs = 0; // the number of control actions - double dt = 0.125; // time between measurements (1/FPS) - - Mat measurements(nMeasurements, 1, CV_64F); measurements.setTo(Scalar(0)); - bool good_measurement = false; - - - - // 3D model and its correspondenses - Model model; // instantiate Model object - model.load_new_xml(yml_read_path); // load a 3D textured object model - Mesh mesh; // instantiate Mesh object - mesh.load(ply_read_path); // load an object mesh - - vector list_points3d_model = model.get_points3d(); // list with model 3D coordinates - vector list_keypoints_model = model.get_keypoints(); // list with model 3D coordinates - Mat descriptors_model = model.get_descriptors(); // list with descriptors of each 3D coordinate - - - - RobustMatcher rmatcher(model, use_gpu, use_gpu_match); // instantiate RobustMatcher - - - //Timers! - timeval start, end, end_detect; - Timer timer_algo = Timer(); - Timer timer_display = Timer(); - Timer timer_fps = Timer(); - timer_fps.start(); - - - double fps, sec; - // frame counter - int counter = 0; - - - //Frames! - FrameGenerator frameGenerator(parser); - Mat frame_vis; - Mat img_all_matches; - Mat img_selective_matches; - Mat frame; - namedWindow("Overlay", WINDOW_NORMAL); - - - - //namedWindow("Before", WINDOW_NORMAL); namedWindow("After", WINDOW_NORMAL); - - while(!frameGenerator.exhausted && waitKey(30) != 27) // while valid frame - { - //read the frame - cout << "Processing next frame ...." << endl; - frame = frameGenerator.getNextFrame(); - frame_vis = frame.clone(); // refresh visualisation frame - - - // start the clock - timer_algo.start(); timer_display.start(); - - - // -- Step 1: Robust matching between model descriptors and scene descriptors - vector good_matches; // to obtain the 3D points of the model - vector keypoints_scene; // to obtain the 2D points of the scene - - - if (fast_match) { - rmatcher.findFeatureAndMatch(frame, good_matches, keypoints_scene, descriptors_model); - } - else { - rmatcher.robustMatch(frame, good_matches, keypoints_scene, descriptors_model); - } - - - Mat img_object = imread(ply_tex_path, IMREAD_GRAYSCALE); - drawMatches(frame, keypoints_scene, - img_object, model.get_keypoints(), - good_matches, img_all_matches, Scalar::all(-1), Scalar::all(-1), - vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); - //imshow("Before", img_all_matches); - - // -- Step 2: Find out the 2D/3D correspondences - - vector list_points3d_model_match; // container for the model 3D coordinates found in the scene - vector list_keypoints_model_match; // container for the model 2D coordinates in the textured image of the corresponding 3D coordinates - vector list_points2d_scene_match; // container for the model 2D coordinates found in the scene - - for (unsigned int match_index = 0; match_index < good_matches.size(); ++match_index) { - Point3f point3d_model = list_points3d_model[good_matches[match_index].trainIdx]; // 3D point from model - KeyPoint kp_model = list_keypoints_model[good_matches[match_index].trainIdx]; // 2D point from model - Point2f point2d_scene = keypoints_scene[good_matches[match_index].queryIdx].pt; // 2D point from the scene - - list_points3d_model_match.push_back(point3d_model); // add 3D point - list_keypoints_model_match.push_back(kp_model); - list_points2d_scene_match.push_back(point2d_scene); // add 2D point - } - - // Draw outliers - draw2DPoints(frame_vis, list_points2d_scene_match, red); - - - Mat inliers_idx; - vector list_points2d_inliers; - - if (good_matches.size() > 0) // None matches, then RANSAC crashes - { - - // -- Step 3: Estimate the pose using RANSAC approach - pnp_detection.estimatePoseRANSAC(list_points3d_model_match, list_points2d_scene_match, - pnpMethod, inliers_idx, - iterationsCount, reprojectionError, confidence); - - // -- Step 4: Catch the inliers keypoints to draw - for (int inliers_index = 0; inliers_index < inliers_idx.rows; ++inliers_index) { - int n = inliers_idx.at(inliers_index); // i-inlier - Point2f point2d = list_points2d_scene_match[n]; // i-inlier point 2D - list_points2d_inliers.push_back(point2d); // add i-inlier to list - - } - - /*std::cout << pnp_detection.get_R_matrix() << std::endl; - std::cout << pnp_detection.get_t_matrix() << std::endl; - std::cout << pnp_detection.get_P_matrix() << std::endl; - std::cout << pnp_detection.get_A_matrix() << std::endl << std::endl;*/ - // Draw inliers points 2D - draw2DPoints(frame_vis, list_points2d_inliers, blue); - - - //##########DEBUG DRAWING########### - img_selective_matches = drawMatchesAfterRansac(frame_vis, list_points2d_scene_match, list_keypoints_model_match, inliers_idx); - //imshow("After", img_selective_matches); - - - if (inliers_idx.rows >= minInliersKalman) good_measurement = true; - else good_measurement = false; - - } - - // -- Step X: Draw pose - timer_algo.stop(); - cout << "Time taken algo: " << timer_algo.getDuration() << endl; - - if (good_measurement) { - //drawObjectMesh1(frame_vis, &mesh, &model, &pnp_detection, green); // draw current pose - pnp_detection_est.set_P_matrix(pnp_detection.get_R_matrix(), pnp_detection.get_t_matrix()); - drawObjectMesh(frame_vis, &mesh, &pnp_detection_est, yellow); // draw estimated pose - cout << "Object detected!!!" << endl; - if(frameGenerator.inputType == FrameGenerator::IMAGE_LIST) - imwrite(frameGenerator.image_list[frameGenerator.curr_image] + ".detected.jpg", frame_vis); - } - else { - //drawObjectMesh1(frame_vis, &mesh, &model, &pnp_detection_est, yellow); // draw estimated pose - //drawObjectMesh(frame_vis, &mesh, &pnp_detection_est, yellow); // draw estimated pose - - } - - - // FRAME RATE - - // see how much time has elapsed - timer_display.stop(); - timer_fps.stop(); - - // calculate current FPS - ++counter; - sec = timer_fps.getDuration(); - cout << "Time taken frame: " << timer_display.getDuration() << endl; - fps = counter / sec; - - drawFPS(frame_vis, fps, yellow); // frame ratio - double detection_ratio = ((double) inliers_idx.rows / (double) good_matches.size()) * 100; - drawConfidence(frame_vis, detection_ratio, yellow); - - - // -- Step X: Draw some debugging text - - // Draw some debug text - int inliers_int = inliers_idx.rows; - int outliers_int = (int) good_matches.size() - inliers_int; - string inliers_str = IntToString(inliers_int); - string outliers_str = IntToString(outliers_int); - string n = IntToString((int) good_matches.size()); - string text = "Found " + inliers_str + " of " + n + " matches"; - string text2 = "Inliers: " + inliers_str + " - Outliers: " + outliers_str; - - drawText(frame_vis, text, green); - drawText2(frame_vis, text2, red); - - imshow("Overlay", frame_vis); - - if (good_measurement) { - if(frameGenerator.inputType == FrameGenerator::IMAGE_LIST) - imwrite(frameGenerator.image_list[frameGenerator.curr_image] + ".detected.jpg", frame_vis); - } - - } - - - waitKey(0); - - - - - cout << "GOODBYE ..." << endl; - -} - -/**********************************************************************************************************/ -void help() -{ -cout -<< "--------------------------------------------------------------------------" << endl -<< "This program shows how to detect an object given its 3D textured model. You can choose to " -<< "use a recorded video or the webcam." << endl -<< "Usage:" << endl -<< "./cpp-tutorial-pnp_detection -help" << endl -<< "Keys:" << endl -<< "'esc' - to quit." << endl -<< "--------------------------------------------------------------------------" << endl -<< endl; -} - diff --git a/detectors/local2D/detection/simple_ransac_detection/main_detection_video.cpp b/detectors/local2D/detection/simple_ransac_detection/main_detection_video.cpp deleted file mode 100644 index ebabfff7..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/main_detection_video.cpp +++ /dev/null @@ -1,562 +0,0 @@ -// C++ -#include -#include -// OpenCV -#include -#include -#include -#include -#include -#include -#include - -// PnP Tutorial -#include "Mesh.h" -#include "Model.h" -#include "PnPProblem.h" -#include "RobustMatcher.h" -#include "ModelRegistration.h" -#include "Utils.h" - -/** GLOBAL VARIABLES **/ - -using namespace cv; -using namespace std; -using namespace cv::xfeatures2d; - - -string tutorial_path = "../"; // path to tutorial - -//string video_read_path = tutorial_path + "Data/box.mp4"; // recorded video -//string yml_read_path = tutorial_path + "Data/cookies_ORB.yml"; // 3dpts + descriptors -//string ply_read_path = tutorial_path + "Data/box.ply"; // mesh - -string video_read_path = tutorial_path + "Data/box.mp4"; // recorded video -string yml_read_path = tutorial_path + "Data/Lion/low_res_texture/Final.pairs"; // 3dpts + descriptors -string ply_read_path = tutorial_path + "Data/Lion/low_res_texture/Final.ply"; // mesh -string ply_tex_path = tutorial_path + "Data/Lion/low_res_texture/Texture_1024.png"; // mesh - -string test_image = tutorial_path + "Data/Lion/test_images/IMG_20150226_102852.jpg"; - -// Intrinsic camera parameters: UVC WEBCAM -//double fx = 3.51567979e+03; // focal length in mm -//double fy = 3.52343259e+03; -//double sx = 1, sy = 1; // sensor size -//double cx = 2.11793527e+03, cy = 1.49318756e+03; // image size - -// Intrinsic camera parameters: UVC WEBCAM -double fx = 5.3349052641864398e+02; // focal length in mm -double fy = 5.3349052641864398e+02; -double sx = 1, sy = 1; // sensor size -double cx = 3.1950000000000000e+02, cy = 2.3950000000000000e+02; // image size - -double params_WEBCAM[] = { fx, // fx - fy, // fy - cx, // cx - cy}; // cy -//double param_dist[] = {-0.18835486, 0.09173112, 0.00188108, 0.00033594, 0.16224491}; -double param_dist[] = {1.4481173997393210e-01, -3.5247562241022906e-01, 0, 0, 1.4483165395214911e-01}; - -// Some basic colors -Scalar red(0, 0, 255); -Scalar green(0,255,0); -Scalar blue(255,0,0); -Scalar yellow(0,255,255); - - -// Robust Matcher parameters -int numKeyPoints = 2000; // number of detected keypoints -float ratioTest = 0.70f; // ratio test -bool fast_match = true; // fastRobustMatch() or robustMatch() - -// RANSAC parameters -int iterationsCount = 500; // number of Ransac iterations. -float reprojectionError = 2.0; // maximum allowed distance to consider it an inlier. -double confidence = 0.95; // ransac successful confidence. - -// Kalman Filter parameters -int minInliersKalman = 30; // Kalman threshold updating - -// PnP parameters -int pnpMethod = SOLVEPNP_EPNP; - - -/** Functions headers **/ -void help(); -void initKalmanFilter( KalmanFilter &KF, int nStates, int nMeasurements, int nInputs, double dt); -void updateKalmanFilter( KalmanFilter &KF, Mat &measurements, - Mat &translation_estimated, Mat &rotation_estimated ); -void fillMeasurements( Mat &measurements, - const Mat &translation_measured, const Mat &rotation_measured); - - -Mat drawMatchesAfterRansac(Mat frame_vis, vector l_pt_scene, vector l_kp_model, Mat inliner_idx) { - - Mat img_object = imread(ply_tex_path, IMREAD_GRAYSCALE ); - - vector l_kp_scene; - - for (int i =0; i < l_pt_scene.size(); i++) - { - KeyPoint kp(l_pt_scene[i].x, l_pt_scene[i].y, 1); l_kp_scene.push_back(kp); - } - - //make matches - vector match; - for (int i =0; i < inliner_idx.rows; i++) - { - int good_index = inliner_idx.at(i); // i-inlier - DMatch m(good_index, good_index, 1); match.push_back(m); - } - - Mat img_matches; - drawMatches(frame_vis, l_kp_scene, - img_object, l_kp_model, - match, img_matches, Scalar::all(-1), Scalar::all(-1), - vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); - - return img_matches; -} - -/** Main program **/ -int main(int argc, char *argv[]) -{ - - help(); - - const String keys = - "{help h | | print this message }" - "{video v | | path to recorded video }" - "{test_image img | | image for detection }" - "{model | | path to yml model }" - "{mesh | | path to ply mesh }" - "{keypoints k |2000 | number of keypoints to detect }" - "{ratio r |0.7 | threshold for ratio test }" - "{iterations it |500 | RANSAC maximum iterations count }" - "{error e |2.0 | RANSAC reprojection errror }" - "{confidence c |0.95 | RANSAC confidence }" - "{inliers in |30 | minimum inliers for Kalman update }" - "{method pnp |0 | PnP method: (0) ITERATIVE - (1) EPNP - (2) P3P - (3) DLS}" - "{fast f |false | use of robust fast match }" - ; - CommandLineParser parser(argc, argv, keys); - - if (parser.has("help")) - { - parser.printMessage(); - return 0; - } - else - { - video_read_path = parser.get("video").size() > 0 ? parser.get("video") : video_read_path; - test_image = parser.get("test_image").size() > 0 ? parser.get("test_image") : test_image; - yml_read_path = parser.get("model").size() > 0 ? parser.get("model") : yml_read_path; - ply_read_path = parser.get("mesh").size() > 0 ? parser.get("mesh") : ply_read_path; - numKeyPoints = !parser.has("keypoints") ? parser.get("keypoints") : numKeyPoints; - ratioTest = !parser.has("ratio") ? parser.get("ratio") : ratioTest; - fast_match = !parser.has("fast") ? parser.get("fast") : fast_match; - iterationsCount = !parser.has("iterations") ? parser.get("iterations") : iterationsCount; - reprojectionError = !parser.has("error") ? parser.get("error") : reprojectionError; - confidence = !parser.has("confidence") ? parser.get("confidence") : confidence; - minInliersKalman = !parser.has("inliers") ? parser.get("inliers") : minInliersKalman; - pnpMethod = !parser.has("method") ? parser.get("method") : pnpMethod; - } - - PnPProblem pnp_detection(params_WEBCAM, param_dist); - PnPProblem pnp_detection_est(params_WEBCAM, param_dist); - - Model model; // instantiate Model object - model.load_new_desc(yml_read_path); // load a 3D textured object model - - Mesh mesh; // instantiate Mesh object - mesh.load(ply_read_path); // load an object mesh - - RobustMatcher rmatcher; // instantiate RobustMatcher - - //Ptr orb = ORB::create(); - Ptr fdetector = SIFT::create(); - - rmatcher.setFeatureDetector(fdetector); // set feature detector - rmatcher.setDescriptorExtractor(fdetector); // set descriptor extractor - - Ptr indexParams = makePtr(6, 12, 1); // instantiate LSH index parameters - Ptr searchParams = makePtr(50); // instantiate flann search parameters - - // instantiate FlannBased matcher - Ptr matcher = makePtr(indexParams, searchParams); - //rmatcher.setDescriptorMatcher(matcher); // set matcher - //rmatcher.setRatio(ratioTest); // set ratio test parameter - - KalmanFilter KF; // instantiate Kalman Filter - int nStates = 18; // the number of states - int nMeasurements = 6; // the number of measured states - int nInputs = 0; // the number of control actions - double dt = 0.125; // time between measurements (1/FPS) - - initKalmanFilter(KF, nStates, nMeasurements, nInputs, dt); // init function - Mat measurements(nMeasurements, 1, CV_64F); measurements.setTo(Scalar(0)); - bool good_measurement = false; - - - // Get the MODEL INFO - vector list_points3d_model = model.get_points3d(); // list with model 3D coordinates - vector list_keypoints_model = model.get_keypoints(); // list with model 3D coordinates - Mat descriptors_model = model.get_descriptors(); // list with descriptors of each 3D coordinate - - // Create & Open Window - namedWindow("REAL TIME DEMO", WINDOW_NORMAL); - - - VideoCapture cap; // instantiate VideoCapture - cap.open(0); // open a recorded video - - if(!cap.isOpened()) // check if we succeeded - { - cout << "Could not open the camera device" << endl; - return -1; - } - - // start and end times - time_t start, end; - - // fps calculated using number of frames / seconds - // floating point seconds elapsed since start - double fps, sec; - - // frame counter - int counter = 0; - - // start the clock - time(&start); - - Mat frame_vis; - Mat img_all_matches; - Mat img_selective_matches; - Mat frame; - - //Mat frame = imread(test_image, IMREAD_COLOR); - - while(cap.read(frame) && waitKey(30) != 27) // capture frame until ESC is pressed - { - frame_vis = frame.clone(); // refresh visualisation frame - - - // -- Step 1: Robust matching between model descriptors and scene descriptors - - vector good_matches; // to obtain the 3D points of the model - vector keypoints_scene; // to obtain the 2D points of the scene - - - if (fast_match) { - rmatcher.fastRobustMatch(frame, good_matches, keypoints_scene, descriptors_model); - } - else { - rmatcher.robustMatch(frame, good_matches, keypoints_scene, descriptors_model); - } - - - Mat img_object = imread(ply_tex_path, IMREAD_GRAYSCALE); - drawMatches(frame, keypoints_scene, - img_object, model.get_keypoints(), - good_matches, img_all_matches, Scalar::all(-1), Scalar::all(-1), - vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); - - - // -- Step 2: Find out the 2D/3D correspondences - - vector list_points3d_model_match; // container for the model 3D coordinates found in the scene - vector list_keypoints_model_match; // container for the model 2D coordinates in the textured image of the corresponding 3D coordinates - vector list_points2d_scene_match; // container for the model 2D coordinates found in the scene - - for (unsigned int match_index = 0; match_index < good_matches.size(); ++match_index) { - Point3f point3d_model = list_points3d_model[good_matches[match_index].trainIdx]; // 3D point from model - KeyPoint kp_model = list_keypoints_model[good_matches[match_index].trainIdx]; // 2D point from model - Point2f point2d_scene = keypoints_scene[good_matches[match_index].queryIdx].pt; // 2D point from the scene - - list_points3d_model_match.push_back(point3d_model); // add 3D point - list_keypoints_model_match.push_back(kp_model); - list_points2d_scene_match.push_back(point2d_scene); // add 2D point - } - - // Draw outliers - draw2DPoints(frame_vis, list_points2d_scene_match, red); - - - Mat inliers_idx; - vector list_points2d_inliers; - - if (good_matches.size() > 0) // None matches, then RANSAC crashes - { - - // -- Step 3: Estimate the pose using RANSAC approach - pnp_detection.estimatePoseRANSAC(list_points3d_model_match, list_points2d_scene_match, - pnpMethod, inliers_idx, - iterationsCount, reprojectionError, confidence); - - // -- Step 4: Catch the inliers keypoints to draw - for (int inliers_index = 0; inliers_index < inliers_idx.rows; ++inliers_index) { - int n = inliers_idx.at(inliers_index); // i-inlier - Point2f point2d = list_points2d_scene_match[n]; // i-inlier point 2D - list_points2d_inliers.push_back(point2d); // add i-inlier to list - - } - - std::cout << pnp_detection.get_R_matrix() << std::endl; - std::cout << pnp_detection.get_t_matrix() << std::endl; - std::cout << pnp_detection.get_P_matrix() << std::endl; - std::cout << pnp_detection.get_A_matrix() << std::endl << std::endl; - // Draw inliers points 2D - draw2DPoints(frame_vis, list_points2d_inliers, blue); - - img_selective_matches = drawMatchesAfterRansac(frame_vis, list_points2d_scene_match, - list_keypoints_model_match, inliers_idx); - - - - - - // -- Step 5: Kalman Filter - - good_measurement = false; - - // GOOD MEASUREMENT - if (inliers_idx.rows >= minInliersKalman) { - - // Get the measured translation - Mat translation_measured(3, 1, CV_64F); - translation_measured = pnp_detection.get_t_matrix(); - - // Get the measured rotation - Mat rotation_measured(3, 3, CV_64F); - rotation_measured = pnp_detection.get_R_matrix(); - - // fill the measurements vector - fillMeasurements(measurements, translation_measured, rotation_measured); - - good_measurement = true; - - } - - // Instantiate estimated translation and rotation - Mat translation_estimated(3, 1, CV_64F); - Mat rotation_estimated(3, 3, CV_64F); - - // update the Kalman filter with good measurements - updateKalmanFilter(KF, measurements, - translation_estimated, rotation_estimated); - - - // -- Step 6: Set estimated projection matrix - pnp_detection_est.set_P_matrix(rotation_estimated, translation_estimated); - - - std::cout << pnp_detection.get_R_matrix() << std::endl; - std::cout << pnp_detection.get_t_matrix() << std::endl; - std::cout << pnp_detection.get_P_matrix() << std::endl; - std::cout << pnp_detection.get_A_matrix() << std::endl << std::endl; - } - - // -- Step X: Draw pose - - if (good_measurement) { - //drawObjectMesh1(frame_vis, &mesh, &model, &pnp_detection, green); // draw current pose - drawObjectMesh(frame_vis, &mesh, &pnp_detection_est, yellow); // draw estimated pose - } - else { - //drawObjectMesh1(frame_vis, &mesh, &model, &pnp_detection_est, yellow); // draw estimated pose - //drawObjectMesh(frame_vis, &mesh, &pnp_detection_est, yellow); // draw estimated pose - - } - - float l = 5; - vector pose_points2d; - pose_points2d.push_back(pnp_detection_est.backproject3DPoint(Point3f(0, 0, 0))); // axis center - pose_points2d.push_back(pnp_detection_est.backproject3DPoint(Point3f(l, 0, 0))); // axis x - pose_points2d.push_back(pnp_detection_est.backproject3DPoint(Point3f(0, l, 0))); // axis y - pose_points2d.push_back(pnp_detection_est.backproject3DPoint(Point3f(0, 0, l))); // axis z - draw3DCoordinateAxes(frame_vis, pose_points2d); // draw axes - - // FRAME RATE - - // see how much time has elapsed - time(&end); - - // calculate current FPS - ++counter; - sec = difftime(end, start); - - fps = counter / sec; - - drawFPS(frame_vis, fps, yellow); // frame ratio - double detection_ratio = ((double) inliers_idx.rows / (double) good_matches.size()) * 100; - drawConfidence(frame_vis, detection_ratio, yellow); - - - // -- Step X: Draw some debugging text - - // Draw some debug text - int inliers_int = inliers_idx.rows; - int outliers_int = (int) good_matches.size() - inliers_int; - string inliers_str = IntToString(inliers_int); - string outliers_str = IntToString(outliers_int); - string n = IntToString((int) good_matches.size()); - string text = "Found " + inliers_str + " of " + n + " matches"; - string text2 = "Inliers: " + inliers_str + " - Outliers: " + outliers_str; - - drawText(frame_vis, text, green); - drawText2(frame_vis, text2, red); - - imshow("REAL TIME DEMO", frame_vis); - - } - - namedWindow("Matches before PNP", WINDOW_NORMAL); - namedWindow("Matches after PNP", WINDOW_NORMAL); - namedWindow("Overlay", WINDOW_NORMAL); - - imshow( "Matches before PNP", img_all_matches ); - imshow( "Matches after PNP", img_selective_matches ); - imshow( "Overlay", frame_vis); - - while(1) { - - char key = waitKey(0); - if (key == 'Q' || key == 'q') break; - } - - - cout << "GOODBYE ..." << endl; - -} - -/**********************************************************************************************************/ -void help() -{ -cout -<< "--------------------------------------------------------------------------" << endl -<< "This program shows how to detect an object given its 3D textured model. You can choose to " -<< "use a recorded video or the webcam." << endl -<< "Usage:" << endl -<< "./cpp-tutorial-pnp_detection -help" << endl -<< "Keys:" << endl -<< "'esc' - to quit." << endl -<< "--------------------------------------------------------------------------" << endl -<< endl; -} - -/**********************************************************************************************************/ -void initKalmanFilter(KalmanFilter &KF, int nStates, int nMeasurements, int nInputs, double dt) -{ - - KF.init(nStates, nMeasurements, nInputs, CV_64F); // init Kalman Filter - - setIdentity(KF.processNoiseCov, Scalar::all(1e-5)); // set process noise - setIdentity(KF.measurementNoiseCov, Scalar::all(1e-2)); // set measurement noise - setIdentity(KF.errorCovPost, Scalar::all(1)); // error covariance - - - /** DYNAMIC MODEL **/ - - // [1 0 0 dt 0 0 dt2 0 0 0 0 0 0 0 0 0 0 0] - // [0 1 0 0 dt 0 0 dt2 0 0 0 0 0 0 0 0 0 0] - // [0 0 1 0 0 dt 0 0 dt2 0 0 0 0 0 0 0 0 0] - // [0 0 0 1 0 0 dt 0 0 0 0 0 0 0 0 0 0 0] - // [0 0 0 0 1 0 0 dt 0 0 0 0 0 0 0 0 0 0] - // [0 0 0 0 0 1 0 0 dt 0 0 0 0 0 0 0 0 0] - // [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] - // [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0] - // [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0] - // [0 0 0 0 0 0 0 0 0 1 0 0 dt 0 0 dt2 0 0] - // [0 0 0 0 0 0 0 0 0 0 1 0 0 dt 0 0 dt2 0] - // [0 0 0 0 0 0 0 0 0 0 0 1 0 0 dt 0 0 dt2] - // [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 dt 0 0] - // [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 dt 0] - // [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 dt] - // [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0] - // [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0] - // [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] - - // position - KF.transitionMatrix.at(0,3) = dt; - KF.transitionMatrix.at(1,4) = dt; - KF.transitionMatrix.at(2,5) = dt; - KF.transitionMatrix.at(3,6) = dt; - KF.transitionMatrix.at(4,7) = dt; - KF.transitionMatrix.at(5,8) = dt; - KF.transitionMatrix.at(0,6) = 0.5*pow(dt,2); - KF.transitionMatrix.at(1,7) = 0.5*pow(dt,2); - KF.transitionMatrix.at(2,8) = 0.5*pow(dt,2); - - // orientation - KF.transitionMatrix.at(9,12) = dt; - KF.transitionMatrix.at(10,13) = dt; - KF.transitionMatrix.at(11,14) = dt; - KF.transitionMatrix.at(12,15) = dt; - KF.transitionMatrix.at(13,16) = dt; - KF.transitionMatrix.at(14,17) = dt; - KF.transitionMatrix.at(9,15) = 0.5*pow(dt,2); - KF.transitionMatrix.at(10,16) = 0.5*pow(dt,2); - KF.transitionMatrix.at(11,17) = 0.5*pow(dt,2); - - - /** MEASUREMENT MODEL **/ - - // [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] - // [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] - // [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] - // [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0] - // [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0] - // [0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] - - KF.measurementMatrix.at(0,0) = 1; // x - KF.measurementMatrix.at(1,1) = 1; // y - KF.measurementMatrix.at(2,2) = 1; // z - KF.measurementMatrix.at(3,9) = 1; // roll - KF.measurementMatrix.at(4,10) = 1; // pitch - KF.measurementMatrix.at(5,11) = 1; // yaw - -} - -/**********************************************************************************************************/ -void updateKalmanFilter( KalmanFilter &KF, Mat &measurement, - Mat &translation_estimated, Mat &rotation_estimated ) -{ - - // First predict, to update the internal statePre variable - Mat prediction = KF.predict(); - - // The "correct" phase that is going to use the predicted value and our measurement - Mat estimated = KF.correct(measurement); - - // Estimated translation - translation_estimated.at(0) = estimated.at(0); - translation_estimated.at(1) = estimated.at(1); - translation_estimated.at(2) = estimated.at(2); - - // Estimated euler angles - Mat eulers_estimated(3, 1, CV_64F); - eulers_estimated.at(0) = estimated.at(9); - eulers_estimated.at(1) = estimated.at(10); - eulers_estimated.at(2) = estimated.at(11); - - // Convert estimated quaternion to rotation matrix - rotation_estimated = euler2rot(eulers_estimated); - -} - -/**********************************************************************************************************/ -void fillMeasurements( Mat &measurements, - const Mat &translation_measured, const Mat &rotation_measured) -{ - // Convert rotation matrix to euler angles - Mat measured_eulers(3, 1, CV_64F); - measured_eulers = rot2euler(rotation_measured); - - // Set measurement to predict - measurements.at(0) = translation_measured.at(0); // x - measurements.at(1) = translation_measured.at(1); // y - measurements.at(2) = translation_measured.at(2); // z - measurements.at(3) = measured_eulers.at(0); // roll - measurements.at(4) = measured_eulers.at(1); // pitch - measurements.at(5) = measured_eulers.at(2); // yaw -} diff --git a/detectors/local2D/detection/simple_ransac_detection/main_registration.cpp b/detectors/local2D/detection/simple_ransac_detection/main_registration.cpp deleted file mode 100644 index da775a06..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/main_registration.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// C++ -#include -// OpenCV -#include -#include -#include -#include -// PnP Tutorial -#include "Mesh.h" -#include "Model.h" -#include "PnPProblem.h" -#include "RobustMatcher.h" -#include "ModelRegistration.h" -#include "Utils.h" - -using namespace cv; -using namespace std; - -/** GLOBAL VARIABLES **/ - -string tutorial_path = "../../samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/"; // path to tutorial - -string img_path = tutorial_path + "Data/resized_IMG_3875.JPG"; // image to register -string ply_read_path = tutorial_path + "Data/box.ply"; // object mesh -string write_path = tutorial_path + "Data/cookies_ORB.yml"; // output file - -// Boolean the know if the registration it's done -bool end_registration = false; - -// Intrinsic camera parameters: UVC WEBCAM -double f = 45; // focal length in mm -double sx = 22.3, sy = 14.9; -double width = 2592, height = 1944; -double params_CANON[] = { width*f/sx, // fx - height*f/sy, // fy - width/2, // cx - height/2}; // cy - -// Setup the points to register in the image -// In the order of the *.ply file and starting at 1 -int n = 8; -int pts[] = {1, 2, 3, 4, 5, 6, 7, 8}; // 3 -> 4 - -// Some basic colors -Scalar red(0, 0, 255); -Scalar green(0,255,0); -Scalar blue(255,0,0); -Scalar yellow(0,255,255); - -/* - * CREATE MODEL REGISTRATION OBJECT - * CREATE OBJECT MESH - * CREATE OBJECT MODEL - * CREATE PNP OBJECT - */ -ModelRegistration registration; -Model model; -Mesh mesh; -PnPProblem pnp_registration(params_CANON); - -/** Functions headers **/ -void help(); - -// Mouse events for model registration -static void onMouseModelRegistration( int event, int x, int y, int, void* ) -{ - if ( event == EVENT_LBUTTONUP ) - { - int n_regist = registration.getNumRegist(); - int n_vertex = pts[n_regist]; - - Point2f point_2d = Point2f((float)x,(float)y); - Point3f point_3d = mesh.getVertex(n_vertex-1); - - bool is_registrable = registration.is_registrable(); - if (is_registrable) - { - registration.registerPoint(point_2d, point_3d); - if( registration.getNumRegist() == registration.getNumMax() ) end_registration = true; - } - } -} - -/** Main program **/ -int main() -{ - - help(); - - // load a mesh given the *.ply file path - mesh.load(ply_read_path); - - // set parameters - int numKeyPoints = 10000; - - //Instantiate robust matcher: detector, extractor, matcher - RobustMatcher rmatcher; - Ptr detector = ORB::create(numKeyPoints); - rmatcher.setFeatureDetector(detector); - - /** GROUND TRUTH OF THE FIRST IMAGE **/ - - // Create & Open Window - namedWindow("MODEL REGISTRATION", WINDOW_KEEPRATIO); - - // Set up the mouse events - setMouseCallback("MODEL REGISTRATION", onMouseModelRegistration, 0 ); - - // Open the image to register - Mat img_in = imread(img_path, IMREAD_COLOR); - Mat img_vis = img_in.clone(); - - if (!img_in.data) { - cout << "Could not open or find the image" << endl; - return -1; - } - - // Set the number of points to register - int num_registrations = n; - registration.setNumMax(num_registrations); - - cout << "Click the box corners ..." << endl; - cout << "Waiting ..." << endl; - - // Loop until all the points are registered - while ( waitKey(30) < 0 ) - { - // Refresh debug image - img_vis = img_in.clone(); - - // Current registered points - vector list_points2d = registration.get_points2d(); - vector list_points3d = registration.get_points3d(); - - // Draw current registered points - drawPoints(img_vis, list_points2d, list_points3d, red); - - // If the registration is not finished, draw which 3D point we have to register. - // If the registration is finished, breaks the loop. - if (!end_registration) - { - // Draw debug text - int n_regist = registration.getNumRegist(); - int n_vertex = pts[n_regist]; - Point3f current_poin3d = mesh.getVertex(n_vertex-1); - - drawQuestion(img_vis, current_poin3d, green); - drawCounter(img_vis, registration.getNumRegist(), registration.getNumMax(), red); - } - else - { - // Draw debug text - drawText(img_vis, "END REGISTRATION", green); - drawCounter(img_vis, registration.getNumRegist(), registration.getNumMax(), green); - break; - } - - // Show the image - imshow("MODEL REGISTRATION", img_vis); - } - - /** COMPUTE CAMERA POSE **/ - - cout << "COMPUTING POSE ..." << endl; - - // The list of registered points - vector list_points2d = registration.get_points2d(); - vector list_points3d = registration.get_points3d(); - - // Estimate pose given the registered points - bool is_correspondence = pnp_registration.estimatePose(list_points3d, list_points2d, SOLVEPNP_ITERATIVE); - if ( is_correspondence ) - { - cout << "Correspondence found" << endl; - - // Compute all the 2D points of the mesh to verify the algorithm and draw it - vector list_points2d_mesh = pnp_registration.verify_points(&mesh); - draw2DPoints(img_vis, list_points2d_mesh, green); - - } else { - cout << "Correspondence not found" << endl << endl; - } - - // Show the image - imshow("MODEL REGISTRATION", img_vis); - - // Show image until ESC pressed - waitKey(0); - - - /** COMPUTE 3D of the image Keypoints **/ - - // Containers for keypoints and descriptors of the model - vector keypoints_model; - Mat descriptors; - - // Compute keypoints and descriptors - rmatcher.computeKeyPoints(img_in, keypoints_model); - rmatcher.computeDescriptors(img_in, keypoints_model, descriptors); - - // Check if keypoints are on the surface of the registration image and add to the model - for (unsigned int i = 0; i < keypoints_model.size(); ++i) { - Point2f point2d(keypoints_model[i].pt); - Point3f point3d; - bool on_surface = pnp_registration.backproject2DPoint(&mesh, point2d, point3d); - if (on_surface) - { - model.add_correspondence(point2d, point3d); - model.add_descriptor(descriptors.row(i)); - model.add_keypoint(keypoints_model[i]); - } - else - { - model.add_outlier(point2d); - } - } - - // save the model into a *.yaml file - model.save(write_path); - - // Out image - img_vis = img_in.clone(); - - // The list of the points2d of the model - vector list_points_in = model.get_points2d_in(); - vector list_points_out = model.get_points2d_out(); - - // Draw some debug text - string num = IntToString((int)list_points_in.size()); - string text = "There are " + num + " inliers"; - drawText(img_vis, text, green); - - // Draw some debug text - num = IntToString((int)list_points_out.size()); - text = "There are " + num + " outliers"; - drawText2(img_vis, text, red); - - // Draw the object mesh - drawObjectMesh(img_vis, &mesh, &pnp_registration, blue); - - // Draw found keypoints depending on if are or not on the surface - draw2DPoints(img_vis, list_points_in, green); - draw2DPoints(img_vis, list_points_out, red); - - // Show the image - imshow("MODEL REGISTRATION", img_vis); - - // Wait until ESC pressed - waitKey(0); - - // Close and Destroy Window - destroyWindow("MODEL REGISTRATION"); - - cout << "GOODBYE" << endl; - -} - -/**********************************************************************************************************/ -void help() -{ - cout - << "--------------------------------------------------------------------------" << endl - << "This program shows how to create your 3D textured model. " << endl - << "Usage:" << endl - << "./cpp-tutorial-pnp_registration" << endl - << "--------------------------------------------------------------------------" << endl - << endl; -} diff --git a/detectors/local2D/detection/simple_ransac_detection/scale_intrinsic.cpp b/detectors/local2D/detection/simple_ransac_detection/scale_intrinsic.cpp deleted file mode 100644 index 6a1e15f4..00000000 --- a/detectors/local2D/detection/simple_ransac_detection/scale_intrinsic.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// -// Created by sarkar on 04.05.15. -// - - -// C++ -#include -#include -// OpenCV -#include -#include - - -using namespace std; -using namespace cv; - -int main(int argc, char *argv[]) -{ - if( argc != 4 ) - { cout << "Not sufficient arguments!!"; return -1; } - - string matname = argv[1]; - string matnamescaled = argv[2]; - float scale = atof(argv[3]); - - FileStorage fr(matname, FileStorage::READ); - FileStorage fw(matnamescaled, FileStorage::WRITE); - - Mat K, d; - fr["Camera_Matrix"] >> K; - fr["Distortion_Coefficients"] >> d; - - - K = scale * K; - K.at(2, 2) = 1; - - fw << "Camera_Matrix" << K; - fw << "Distortion_Coefficients" << d; - - return 1; -} \ No newline at end of file diff --git a/detectors/misc/CMakeLists.txt b/detectors/misc/CMakeLists.txt deleted file mode 100644 index 65c8a4d0..00000000 --- a/detectors/misc/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -set(SUBSYS_NAME miscellaneous_detector) -set(LIB_NAME od_${SUBSYS_NAME}) -set(SUBSYS_DESC "global feature based detection in 2D images") - -set(SUBSYS_DEPS od_common od_global_image_detector od_local_image_detector ${OpenCV_LIBS}) - - -set(build TRUE) -#PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON) -#PCL_SUBSYS_DEPEND(build "${SUBSYS_NAME}" DEPS ${SUBSYS_DEPS}) - - -if(build) - - set(incs - "detection/ODDetectorMultiAlgo.h" - ) - - set(impl_incs - ) - - set(srcs - "detection/ODDetectorMultiAlgo.cpp" - ) - - - OD_ADD_LIBRARY_ALL("${SUBSYS_NAME}" SRCS ${srcs} INCS ${incs} ${impl_incs}) - - - if(SUBSYS_DEPS) - target_link_libraries("${LIB_NAME}" ${SUBSYS_DEPS}) - endif(SUBSYS_DEPS) - - #PCL_MAKE_PKGCONFIG("${LIB_NAME}" "${SUBSYS_NAME}" "${SUBSYS_DESC}" "${SUBSYS_DEPS}" "" "" "" "") - - -endif(build) \ No newline at end of file diff --git a/detectors/misc/detection/ODDetectorMultiAlgo.cpp b/detectors/misc/detection/ODDetectorMultiAlgo.cpp deleted file mode 100644 index d5223cf0..00000000 --- a/detectors/misc/detection/ODDetectorMultiAlgo.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 06.08.15. -// - -#include "ODDetectorMultiAlgo.h" -#include "detectors/global2D/detection/ODCascadeDetector.h" -#include "detectors/global2D/detection/ODHOGDetector.h" -#include "detectors/global2D/ODFaceRecognizer.h" - -#include "detectors/local2D/detection/ODCADRecognizer2DLocal.h" - - -//3D detectors -#include "detectors/global3D/detection/ODCADDetector3DGlobal.h" - - -using namespace std; -using namespace od::g2d; -using namespace od::g3d; -using namespace od::l2d; - -namespace od -{ - - //BASED ON 2D SCENE - ODDetections *ODDetectorMultiAlgo2D::detect(ODSceneImage *scene) - { - ODDetections * detections_all = new ODDetections; - for (int i = 0; i < detectors_2d_.size(); i++) - { - ODDetections * detections_individual = detectors_2d_[i]->detect(scene); - detections_all->append(detections_individual); - } - - return detections_all; - } - - ODDetections2D *ODDetectorMultiAlgo2D::detectOmni(ODSceneImage *scene) - { - ODDetections2D * detections_all = new ODDetections2D; - for (int i = 0; i < detectors_2d_.size(); i++) - { - ODDetections2D * detections_individual = detectors_2d_[i]->detectOmni(scene); - detections_all->append(detections_individual); - } - - return detections_all; - } - - - - - - - void ODDetectorMultiAlgo2D::init() - { - //make a list of different algorithms - //vector detectors = {new ODCascadeDetector(trained_data_location_), new ODHOGDetector(trained_data_location_), new ODCADRecognizer2DLocal(trained_data_location_)}; - detectors_2d_.push_back(new ODCascadeDetector(trained_data_location_)); - detectors_2d_.push_back(new ODHOGDetector(trained_data_location_)); - // detectors.push_back(new ODCADRecognizer2DLocal(trained_data_location_)); - - for (int i = 0; i < detectors_2d_.size(); i++) - { - detectors_2d_[i]->init(); - } - } - - - - - /////############BASED ON 3D SCENE##################### - - void ODDetectorMultiAlgo::init() - { - //3D - detectors_3d_.push_back(new ODCADDetector3DGlobal(trained_data_location_, training_input_location_)); - - for (int i = 0; i < detectors_3d_.size(); i++) - { - detectors_3d_[i]->init(); - } - } - - - ODDetections* ODDetectorMultiAlgo::detect(ODScenePointCloud *scene) - { - ODDetections * detections_all = new ODDetections; - for (int i = 0; i < detectors_3d_.size(); i++) - { - ODDetections * detections_individual = detectors_3d_[i]->detect(scene); - detections_all->append(detections_individual); - } - - return detections_all; - } - - ODDetections3D* ODDetectorMultiAlgo::detectOmni(ODScenePointCloud *scene) - { - ODDetections3D * detections_all = new ODDetections3D; - for (int i = 0; i < detectors_3d_.size(); i++) - { - ODDetections3D * detections_individual = detectors_3d_[i]->detectOmni(scene); - detections_all->append(detections_individual); - } - - return detections_all; - } -} \ No newline at end of file diff --git a/detectors/misc/detection/ODDetectorMultiAlgo.h b/detectors/misc/detection/ODDetectorMultiAlgo.h deleted file mode 100644 index 29da28d0..00000000 --- a/detectors/misc/detection/ODDetectorMultiAlgo.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright (c) 2015, Kripasindhu Sarkar -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions 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. - * Neither the name of the copyright holder(s) nor the - names of its contributors may 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 COPYRIGHT HOLDER 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. -*/// -// Created by sarkar on 06.08.15. -// - -#ifndef OPENDETECTION_ODDETECTORMULTIALGO_H -#define OPENDETECTION_ODDETECTORMULTIALGO_H - -#include -#include - -namespace od -{ - - /** \brief Class for running multiple Detection algorithms (with default parameters) on the same scene. - * - * Using this class one can do object detection/recognition using multiple algorithms and provide outcome of detections (eg. people detected by HOG, face detected by Cascade, bottle detected PnPRansac in the same image). - * - * \author Kripasindhu Sarkar - * - */ - class ODDetectorMultiAlgo2D : public ODDetector2D - { - public: - ODDetectorMultiAlgo2D(std::string const &training_data_location_) : ODDetector2D(training_data_location_) - { } - - - typedef pcl::PointXYZRGBA PointT; - - - - ODDetections *detect(ODSceneImage *scene) ; - ODDetections2D *detectOmni(ODSceneImage *scene); - - ODDetections* detect(ODScenePointCloud *scene); - ODDetections3D* detectOmni(ODScenePointCloud *scene); - - - void init(); - - private: - std::vector detectors_2d_; - std::vector *> detectors_3d_; - }; - - class ODDetectorMultiAlgo : public ODDetector - { - public: - ODDetectorMultiAlgo(std::string const &training_data_location_) : ODDetector(training_data_location_) - { } - - - typedef pcl::PointXYZRGBA PointT; - - - - ODDetections *detect(ODSceneImage *scene) ; - ODDetections2D *detectOmni(ODSceneImage *scene); - - ODDetections* detect(ODScenePointCloud *scene); - ODDetections3D* detectOmni(ODScenePointCloud *scene); - - - void init(); - - private: - std::vector detectors_2d_; - std::vector *> detectors_3d_; - }; - - /** \example objectdetector/od_multialgo_files.cpp - * \example objectdetector/od_multialgo_pc.cpp - */ - -} -#endif //OPENDETECTION_ODDETECTORMULTIALGO_H diff --git a/detectors/src/global2D/CMakeLists.txt b/detectors/src/global2D/CMakeLists.txt new file mode 100644 index 00000000..cd020622 --- /dev/null +++ b/detectors/src/global2D/CMakeLists.txt @@ -0,0 +1,65 @@ +set(SUBSYS_NAME global_image_detector) +set(LIB_NAME od_${SUBSYS_NAME}) +set(SUBSYS_DESC "global feature based detection in 2D images") + +set(SUBSYS_DEPS od_common) + +if(BUILD_GLOBAL_2D_DETECTION) + + if(WITH_GPU) + set(SUBSYS_DEPS ${SUBSYS_DEPS} od_gpu_global_image_detector) + endif() + + set(SOURCES + "FaceRecognizer.cpp" + "detection/CascadeDetector.cpp" + "detection/CascadeDetectorImpl.cpp" + ) + +if(0) + if(WITH_CAFFE AND Caffe_FOUND) + set(SOURCES ${SOURCES} + "detection/ConvClassification.cpp" + "localization/SelectiveSearchBase.cpp" + "localization/SelectiveSearchModel.cpp" + "training/HOGTrainer.cpp" + ) + set(SUBSYS_DEPS ${SUBSYS_DEPS} ${Caffe_LIBRARIES}) + include_directories(${CAFFE_INCLUDE_DIR}) + if(WITH_GPU) + include_directories(${CUDA_INCLUDE_DIRS}) + endif() + + if(WITH_GTKMM AND GTKMM_FOUND) + set(SOURCES ${SOURCES} "training/Solver.cpp" + "training/ConvTrainer.cpp" + "training/Network.cpp" + ) + include_directories(${GTKMM_INCLUDE_DIRS}) + link_directories(${GTKMM_LIBRARY_DIRS}) + set(SUBSYS_DEPS ${SUBSYS_DEPS} ${GTKMM_LIBRARIES}) + endif() + + endif() +endif(0) + + if(WITH_GTKMM AND GTKMM_FOUND) + set(SOURCES ${SOURCES} "annotation/Annotation.cpp" + "annotation/Annotator.cpp") + endif() + + if(WITH_SVMLIGHT) + set(SOURCES ${SOURCES} "training/HOGTrainer.cpp" "detection/HOGDetector.cpp") + include_directories(${CMAKE_3RDPARTY_DIR}/svmlight/) + set(SUBSYS_DEPS ${SUBSYS_DEPS} svmlight) + endif() + + include_directories(${OpenCV_INCLUDE_DIRS}) + include_directories(${DETECTORS_INCLUDE_DIR}) + include_directories(${COMMON_INCLUDE_DIR}) + include_directories(${COMMON_IMPL_DIR}) + include_directories(${PCL_INCLUDE_DIRS}) + + OD_ADD_LIBRARY("${SUBSYS_NAME}" SRCS ${SOURCES} LINK_WITH ${SUBSYS_DEPS}) + +endif(BUILD_GLOBAL_2D_DETECTION) \ No newline at end of file diff --git a/detectors/src/global2D/FaceRecognizer.cpp b/detectors/src/global2D/FaceRecognizer.cpp new file mode 100644 index 00000000..7d9fcbc4 --- /dev/null +++ b/detectors/src/global2D/FaceRecognizer.cpp @@ -0,0 +1,213 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 16.07.15. +// + +#include "od/detectors/global2D/FaceRecognizer.h" + +namespace od +{ + namespace g2d + { + + FaceRecognizer::FaceRecognizer(FaceRecogType recog_type, int num_components, double threshold): + recog_type_(recog_type), num_components_(num_components), threshold_(threshold), + im_height_(0), im_width_(0) + { + trained_data_identifier_ = std::string("FACERECOG"); + trained_data_ext_ = std::string("facerec.xml"); + } + + void FaceRecognizer::init() + { + switch(recog_type_) + { + case _FACE_FISCHER: + cv_recognizer_ = cv::face::createFisherFaceRecognizer(num_components_, threshold_); + break; + case _FACE_EIGEN: + cv_recognizer_ = cv::face::createEigenFaceRecognizer(num_components_, threshold_); + break; + default: + std::cout << "FATAL: FACETYPE NOT FOUND!"; + } + } + + void FaceRecognizer::initTrainer() + { + init(); + } + + void FaceRecognizer::initDetector() + { + if(!trained_) + { + init(); + + //get models in the directory + std::vector files; + fileutils::getFilesInDirectoryRec(getSpecificTrainingDataLocation(), trained_data_ext_, files); + + if(files.size() == 0) + { + std::cout << "FATAL: Trained data not found" << std::endl; + exit(1); + } + + //choose the first + cv_recognizer_->load(files[0]); + } + } + + int FaceRecognizer::train() + { + std::vector images; + std::vector labels; + try + { + read_csv(training_input_location_, images, labels); + } catch(cv::Exception & e) + { + std::cerr << "Error opening file \"" << training_input_location_ << "\". Reason: " << e.msg << std::endl; + return -1; + } + cv_recognizer_->train(images, labels); + fileutils::createTrainingDir(getSpecificTrainingDataLocation()); + + cv_recognizer_->save(getSpecificTrainingDataLocation() + "/trained." + trained_data_ext_); + trained_ = true; + + //the training set has atleast one image + im_width_ = images[0].cols; + im_height_ = images[0].rows; + + return 0; + } + + shared_ptr FaceRecognizer::detect(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr" < FaceRecognizer::detectOmni(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr" < scene, const std::vector > & detections) + { + std::cout << "not implemented, use with shared_ptr" < FaceRecognizer::detectOmni(shared_ptr scene) + { + std::cout << "not implemented, use detect()" < FaceRecognizer::detect(shared_ptr scene) + { + cv::Mat face_edited; + cv::cvtColor(scene->getCVImage(), face_edited, CV_BGR2GRAY); + + if(trained_) + { + cv::resize(face_edited.clone(), face_edited, cv::Size(im_width_, im_height_), 1.0, 1.0, cv::INTER_CUBIC); + } + + int label = 100; + double confidence; + cv_recognizer_->predict(face_edited, label, confidence); + + //fill in the detection + shared_ptr detection(new Detection2D(detection::CLASSIFICATION, std::to_string(label), confidence)); + shared_ptr detections = make_shared(); + detections->push_back(detection); + + return detections; + } + + + void FaceRecognizer::read_csv(const std::string & filename, std::vector & images, std::vector & labels, + const std::string & separator) + { + std::ifstream file(filename.c_str(), std::ifstream::in); + if(!file) + { + std::string error_message("No valid input file was given, please check the given filename."); + CV_Error(CV_StsBadArg, error_message); + } + std::string line, path, classlabel; + while(getline(file, line)) + { + std::stringstream liness(line); + getline(liness, path, *separator.c_str()); + getline(liness, classlabel); + if(!path.empty() && !classlabel.empty()) + { + images.push_back(cv::imread(path, 0)); + labels.push_back(atoi(classlabel.c_str())); + } + } + } + + const FaceRecognizer::FaceRecogType & FaceRecognizer::getRecogtype() const + { + return recog_type_; + } + + void FaceRecognizer::setRecogtype(const FaceRecognizer::FaceRecogType & recog_type) + { + recog_type_ = recog_type; + } + + int FaceRecognizer::getThreshold() const + { + return threshold_; + } + + void FaceRecognizer::setThreshold(int threshold) + { + threshold_ = threshold; + } + + int FaceRecognizer::getNumComponents() const + { + return num_components_; + } + + void FaceRecognizer::setNumComponents(int num_components) + { + num_components_ = num_components; + } + + } +} \ No newline at end of file diff --git a/detectors/src/global2D/annotation/Annotation.cpp b/detectors/src/global2D/annotation/Annotation.cpp new file mode 100644 index 00000000..37a6f903 --- /dev/null +++ b/detectors/src/global2D/annotation/Annotation.cpp @@ -0,0 +1,1465 @@ +#include "od/detectors/global2D/annotation/Annotation.h" + +namespace od +{ + namespace g2d + { + + void Annotation::showWindow_main() + { + storage = 0; + storageROILocation.clear(); + storageROILocationCurrent.clear(); + storageFileName.clear(); + imageFileNames.clear(); + widthMultiplier.clear(); + heightMultiplier.clear(); + currentWindow = "mainWindow"; + remove(); + set_title("Network Creator"); + set_border_width(10); + add(m_sw1); + m_grid1.set_column_spacing (10); + m_grid1.set_row_spacing (50); + // m_sw1.add(m_grid1); + m_sw1.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + // m_grid1.show(); + show_all_children(); + m_sw1.show(); + } + + void Annotation::showWindow_imageLoad(Glib::ustring data) + { + cv::Mat img = cv::imread(filename, 1); + cv::imwrite("../examples/objectdetector/Annotation/temp.png", img); + currentWindow = "imageLoadWindow"; + remove(); + set_title("Image Window"); + set_border_width(10); + add(m_sw_imageLoad); + m_grid_imageLoad.set_column_spacing (10); + m_grid_imageLoad.set_row_spacing (10); + + if(rbutton_markBB.get_active() == 1) + { + label_annotationType.set_text("Annotion Type: Selecting Single Bounding Box"); + } + else if(rbutton_cropBB.get_active() == 1) + { + label_annotationType.set_text("Annotion Type: Cropping Single Bounding Box"); + } + else if(rbutton_markBBWithLabel.get_active() == 1) + { + label_annotationType.set_text("Annotion Type: Selecting Multiple Bounding Boxes and labelling them"); + } + + label_annotationType.set_line_wrap(); + label_annotationType.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_annotationType,0,0,2,1); + label_annotationType.show(); + + + if(rbutton_markBB.get_active() == 1 && file_folder == "file") + { + + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + + loadOriginalImage(data, 0); + button_resetMarkings.show(); + button_selectRoi.show(); + button_loadAnotherImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveMarked.show(); + + } + else if(rbutton_cropBB.get_active() == 1 && file_folder == "file") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + + + loadOriginalImage(data, 0); + button_resetMarkings.show(); + button_selectRoi.show(); + button_loadAnotherImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveCropMarked.show(); + } + else if(rbutton_markBBWithLabel.get_active() == 1 && file_folder == "file") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + + loadOriginalImage(data, 0); + button_resetMarkingsCurrent.show(); + + label_annotationLabel.set_text("Give a label to ROI: "); + label_annotationLabel.set_line_wrap(); + label_annotationLabel.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_annotationLabel,0,4,2,1); + label_annotationLabel.show(); + + + text_annotationLabel.set_max_length(100); + text_annotationLabel.set_text(""); + text_annotationLabel.select_region(0, text_annotationLabel.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,4,1,1); + text_annotationLabel.show(); + + button_selectRoiCurrent.show(); + button_loadAnotherImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveMarkedMultiple.show(); + + + } + else if(rbutton_cropMultipleBB.get_active() == 1 && file_folder == "file") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + + loadOriginalImage(data, 0); + button_resetMarkingsCurrent.show(); + + label_annotationLabel.set_text("Give a label to ROI: "); + label_annotationLabel.set_line_wrap(); + label_annotationLabel.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_annotationLabel,0,4,2,1); + label_annotationLabel.show(); + + + text_annotationLabel.set_max_length(100); + text_annotationLabel.set_text(""); + text_annotationLabel.select_region(0, text_annotationLabel.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,4,1,1); + text_annotationLabel.show(); + + button_selectRoiCurrent.show(); + button_loadAnotherImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveCropMarkedMultiple.show(); + + + } + else if(rbutton_segnetMaskedBased.get_active() == 1 && file_folder == "file") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_saveCropMarked.hide(); + button_loadAnotherImage.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + button_resetSegnetMaskCurrent.hide(); + button_selectSegnetMaskCurrent.hide(); + button_saveSegnetMask.hide(); + + loadOriginalImage(data, 0); + button_resetSegnetMaskCurrent.show(); + button_selectSegnetMaskCurrent.show(); + + label_annotationLabel.set_text("Give a label to ROI: "); + label_annotationLabel.set_line_wrap(); + label_annotationLabel.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_annotationLabel,0,4,2,1); + label_annotationLabel.show(); + + + text_annotationLabel.set_max_length(100); + text_annotationLabel.set_text(""); + text_annotationLabel.select_region(0, text_annotationLabel.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,4,1,1); + text_annotationLabel.show(); + + button_loadAnotherImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveSegnetMask.show(); + } + else if(rbutton_markBB.get_active() == 1 && file_folder == "folder") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + + + DIR *dpdf; + struct dirent *epdf; + + dpdf = opendir(foldername.c_str()); + if (dpdf != NULL) + { + while (epdf = readdir(dpdf)) + { + std::string val = epdf->d_name; + if(val.length() > 3) + { + std::string fName = foldername + "/" + epdf->d_name; + std::cout << fName << std::endl; + imageFileNames.push_back(fName); + imagesInFolder++; + } + } + } + filename = imageFileNames[--imagesInFolder]; + loadOriginalImage(filename, 0); + + button_resetMarkings.show(); + button_selectRoi.show(); + button_loadNextImage.show(); + + button_loadAnotherImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveMarked.show(); + } + else if(rbutton_cropBB.get_active() == 1 && file_folder == "folder") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + + + DIR *dpdf; + struct dirent *epdf; + + dpdf = opendir(foldername.c_str()); + if (dpdf != NULL) + { + while (epdf = readdir(dpdf)) + { + std::string val = epdf->d_name; + if(val.length() > 3) + { + std::string fName = foldername + "/" + epdf->d_name; + std::cout << fName << std::endl; + imageFileNames.push_back(fName); + imagesInFolder++; + } + } + } + filename = imageFileNames[--imagesInFolder]; + loadOriginalImage(filename, 0); + + button_resetMarkings.show(); + button_selectRoi.show(); + button_loadNextImage.show(); + + button_loadAnotherImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveCropMarked.show(); + + } + else if(rbutton_markBBWithLabel.get_active() == 1 && file_folder == "folder") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + + + DIR *dpdf; + struct dirent *epdf; + + dpdf = opendir(foldername.c_str()); + if (dpdf != NULL) + { + while (epdf = readdir(dpdf)) + { + std::string val = epdf->d_name; + if(val.length() > 3) + { + std::string fName = foldername + "/" + epdf->d_name; + std::cout << fName << std::endl; + imageFileNames.push_back(fName); + imagesInFolder++; + } + } + } + filename = imageFileNames[--imagesInFolder]; + loadOriginalImage(filename, 0); + + button_resetMarkingsCurrent.show(); + + label_annotationLabel.set_text("Give a label to ROI: "); + label_annotationLabel.set_line_wrap(); + label_annotationLabel.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_annotationLabel,0,4,2,1); + label_annotationLabel.show(); + + + text_annotationLabel.set_max_length(100); + text_annotationLabel.set_text(""); + text_annotationLabel.select_region(0, text_annotationLabel.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,4,1,1); + text_annotationLabel.show(); + + button_selectRoiCurrent.show(); + button_loadAnotherImage.show(); + button_loadNextImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveMarkedMultiple.show(); + } + else if(rbutton_cropMultipleBB.get_active() == 1 && file_folder == "folder") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + + + DIR *dpdf; + struct dirent *epdf; + + dpdf = opendir(foldername.c_str()); + if (dpdf != NULL) + { + while (epdf = readdir(dpdf)) + { + std::string val = epdf->d_name; + if(val.length() > 3) + { + std::string fName = foldername + "/" + epdf->d_name; + std::cout << fName << std::endl; + imageFileNames.push_back(fName); + imagesInFolder++; + } + } + } + filename = imageFileNames[--imagesInFolder]; + loadOriginalImage(filename, 0); + + button_resetMarkingsCurrent.show(); + + label_annotationLabel.set_text("Give a label to ROI: "); + label_annotationLabel.set_line_wrap(); + label_annotationLabel.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_annotationLabel,0,4,2,1); + label_annotationLabel.show(); + + + text_annotationLabel.set_max_length(100); + text_annotationLabel.set_text(""); + text_annotationLabel.select_region(0, text_annotationLabel.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,4,1,1); + text_annotationLabel.show(); + + button_selectRoiCurrent.show(); + button_loadAnotherImage.show(); + button_loadNextImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveCropMarkedMultiple.show(); + } + else if(rbutton_segnetMaskedBased.get_active() == 1 && file_folder == "folder") + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + button_resetSegnetMaskCurrent.hide(); + button_selectSegnetMaskCurrent.hide(); + button_saveSegnetMask.hide(); + + + DIR *dpdf; + struct dirent *epdf; + + dpdf = opendir(foldername.c_str()); + if (dpdf != NULL) + { + while (epdf = readdir(dpdf)) + { + std::string val = epdf->d_name; + if(val.length() > 3) + { + std::string fName = foldername + "/" + epdf->d_name; + std::cout << fName << std::endl; + imageFileNames.push_back(fName); + imagesInFolder++; + } + } + } + filename = imageFileNames[--imagesInFolder]; + loadOriginalImage(filename, 0); + button_resetSegnetMaskCurrent.show(); + button_selectSegnetMaskCurrent.show(); + + label_annotationLabel.set_text("Give a label to ROI: "); + label_annotationLabel.set_line_wrap(); + label_annotationLabel.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_annotationLabel,0,4,2,1); + label_annotationLabel.show(); + + + text_annotationLabel.set_max_length(100); + text_annotationLabel.set_text(""); + text_annotationLabel.select_region(0, text_annotationLabel.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,4,1,1); + text_annotationLabel.show(); + + button_loadAnotherImage.show(); + button_loadNextImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + // m_grid_imageLoad.attach(label_outputFile,0,2,2,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + // m_grid_imageLoad.attach(text_outputFile,2,2,1,1); + text_outputFile.show(); + + button_saveSegnetMask.show(); + } + else + { + label_outputFile.hide(); + text_outputFile.hide(); + button_resetMarkings.hide(); + button_selectRoi.hide(); + button_saveMarked.hide(); + button_loadAnotherImage.hide(); + button_saveCropMarked.hide(); + button_resetMarkingsCurrent.hide(); + button_selectRoiCurrent.hide(); + label_annotationLabel.hide(); + text_annotationLabel.hide(); + button_saveMarkedMultiple.hide(); + button_loadNextImage.hide(); + button_saveCropMarkedMultiple.hide(); + } + + + + button_loadMainWindow.show(); + + + m_sw_imageLoad.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + m_grid_imageLoad.show(); + // show_all_children(); + m_sw_imageLoad.show(); + } + + + bool Annotation::on_button_press_event(GdkEventButton *event) + { + // Check if the event is a left button click. + if (event->button == 1) + { + // Memorize pointer position + lastXMouse=event->x; + lastYMouse=event->y; + xPressed=event->x; + yPressed=event->y; + // Start moving the view + moveFlag=true; + // Event has been handled + // cout << lastXMouse << " " << lastYMouse << endl; + if(currentWindow == "imageLoadWindow") + { + // std::cout << lastXMouse - 10 << " " << lastYMouse - 10 << std::endl; + createDot(lastXMouse-10, lastYMouse-35); + } + if(rbutton_segnetMaskedBased.get_active() == 1) + { + std::vector temp; + std::string label = text_annotationLabel.get_text(); + int Result; + std::stringstream convert(label); + if ( !(convert >> Result) ) + Result = 0; + temp.push_back(Result); + temp.push_back(lastXMouse-10); + temp.push_back(lastYMouse-35); + roiPointsForMask.push_back(temp); + } + return true; + } + + // Check if the event is a right button click. + if(event->button == 4) + { + // Memorize mouse coordinates + lastXMouse=event->x; + lastYMouse=event->y; + xReleased=event->x; + yReleased=event->y; + if(currentWindow == "imageLoadWindow") + { + createVisualROI(xPressed-10, yPressed-35, xReleased-10, yReleased-35); + } + // Display the popup menu + // m_Menu_Popup.popup(event->button, event->time); + // The event has been handled. + return true; + } + + // Check if the event is a right button click. + if(event->button == 3) + { + // Memorize mouse coordinates + lastXMouse=event->x; + lastYMouse=event->y; + xReleased=event->x; + yReleased=event->y; + createVisualROI(xPressed-10, yPressed-35, xReleased-10, yReleased-35); + // Display the popup menu + // m_Menu_Popup.popup(event->button, event->time); + // The event has been handled. + return true; + } + return false; + } + + + void Annotation::createDot(int x, int y) + { + cv::Mat img = cv::imread("../examples/objectdetector/Annotation/temp_resized_dotted.png", 1); + cv::circle(img, cv::Point(x,y), 3, cv::Scalar(255,0,0), 3, 8, 0 ); + cv::imwrite("../examples/objectdetector/Annotation/temp_resized_dotted.png", img); + image.set("../examples/objectdetector/Annotation/temp_resized_dotted.png"); + image.show(); + } + + void Annotation::createVisualROI(int x1, int y1, int x2, int y2) + { + std::string text = text_annotationLabel.get_text(); + int fontFace = cv::FONT_HERSHEY_SCRIPT_SIMPLEX; + double fontScale = 1; + int thickness = 2; + cv::Point textOrg(x1, y1); + cv::Mat img = cv::imread("../examples/objectdetector/Annotation/temp_resized_dotted.png", 1); + cv::rectangle(img, cv::Point(x1,y1), cv::Point(x2,y2), cv::Scalar(0,255,0), 3, 8, 0 ); + cv::putText(img, text, textOrg, fontFace, fontScale, cv::Scalar(0,0,255), thickness,8); + cv::imwrite("../examples/objectdetector/Annotation/temp_resized_dotted.png", img); + image.set("../examples/objectdetector/Annotation/temp_resized_dotted.png"); + image.show(); + } + + void Annotation::loadOriginalImage(std::string data, bool st) + { + cv::Mat img = cv::imread(data, 1); + int c = img.cols; + int r = img.rows; + float wTemp = 1; + float hTemp = 1; + // if(img.rows > 480 or img.cols > 640) + // { + cv::resize(img, img, cv::Size(640,480)); + wTemp = (float)c/640.0; + hTemp = (float)r/480.0; + // } + if(st) + { + widthMultiplier.push_back(wTemp); + heightMultiplier.push_back(hTemp); + } + cv::imwrite("../examples/objectdetector/Annotation/temp_resized.png", img); + cv::imwrite("../examples/objectdetector/Annotation/temp_resized_dotted.png", img); + image.set("../examples/objectdetector/Annotation/temp_resized.png"); + image.show(); + } + + void Annotation::loadOriginalImageWithSavedMarkings(std::string data, std::vector > & roi, bool st) + { + cv::Mat img = cv::imread(data, 1); + int c = img.cols; + int r = img.rows; + float wTemp = 1; + float hTemp = 1; + // if(img.rows > 480 or img.cols > 640) + // { + cv::resize(img, img, cv::Size(640,480)); + wTemp = (float)c/640.0; + hTemp = (float)r/480.0; + // } + if(st) + { + widthMultiplier.push_back(wTemp); + heightMultiplier.push_back(hTemp); + } + cv::imwrite("../examples/objectdetector/Annotation/temp_resized.png", img); + for(int i = 0; i < roi.size(); i++) + { + if(storageFileName[i] == data) + cv::rectangle(img, cv::Point(roi[i][1],roi[i][2]), cv::Point(roi[i][3],roi[i][4]), cv::Scalar(0,255,0), 3, 8, 0 ); + } + cv::imwrite("../examples/objectdetector/Annotation/temp_resized_dotted.png", img); + image.set("../examples/objectdetector/Annotation/temp_resized_dotted.png"); + image.show(); + } + + void Annotation::loadResetedMarkings(std::string data, std::vector > & roi, bool st) + { + + + cv::Mat img1 = cv::imread(data, 1); + int c = img1.cols; + int r = img1.rows; + float wTemp = 1.0; + float hTemp = 1.0; + // if(img1.rows > 480 or img1.cols > 640) + // { + cv::resize(img1, img1, cv::Size(640,480)); + wTemp = (float)c/640.0; + hTemp = (float)r/480.0; + // } + // if(st) + // { + // widthMultiplier.push_back(wTemp); + // heightMultiplier.push_back(hTemp); + // } + cv::imwrite("../examples/objectdetector/Annotation/temp_resized.png", img1); + if(roi.size() > 0) + { + for(int i = 0; i < roi.size()-1; i++) + { + // cout << roi.size() << " " << roi[i+1][3] << " " << roi[i][3] << endl; + if((roi[i+1][0] == roi[i][0]) && (roi[i+1][3] == roi[i][3])) + { + if(storageFileName[i] == filename) + cv::line(img1, cv::Point(roi[i][1],roi[i][2]), cv::Point(roi[i+1][1],roi[i+1][2]), cv::Scalar(0,255,0), 3, 8, 0 ); + } + } + } + cv::imwrite("../examples/objectdetector/Annotation/temp_resized_dotted.png", img1); + image.set("../examples/objectdetector/Annotation/temp_resized_dotted.png"); + image.show(); + } + + + + + Annotation::Annotation(): + button_selectImageFileName("Select The Image Location"), + button_loadImage("Load the image"), + button_loadAnotherImage("Load Next Image from a different location"), + rbutton_markBB("Save points for a single Bounding Box per Image"), + rbutton_cropBB("Save points and crop single Bounding Box per image"), + rbutton_markBBWithLabel("Save Multiple Bounding Boxes' Points with attached class labels"), + rbutton_cropMultipleBB("Save points and crop multiple Bounding Boxes per image with attached class labels"), + rbutton_segnetMaskedBased("Create masks based on labels, as required by segnet"), + label_annotationType(""), + text_outputFile(), + label_outputFile(""), + button_resetMarkings("Reset Markings"), + button_loadMainWindow("Load Main Window"), + button_selectRoi("Select the ROI"), + button_saveMarked("Save the ROI details of all images into the stated file"), + button_saveCropMarked("Save the ROI details with of all images into the stated file and crop the ROI and save"), + button_resetMarkingsCurrent("Reset the current Marking"), + button_selectRoiCurrent("Select the roi with mentioned label"), + button_saveMarkedMultiple("Save the ROI details with labels of all images into the stated file"), + button_saveCropMarkedMultiple("Save and crop the ROIs with labels of all images into the stated file"), + text_annotationLabel(), + label_annotationLabel(""), + button_selectDatasetFolder("Select the Dataset Folder"), + button_loadNextImage("Load Next Image from same folder"), + button_resetSegnetMaskCurrent("Reset Current Markings"), + button_selectSegnetMaskCurrent("Save the region's points with stated label"), + button_saveSegnetMask("Save all Masks"), + + button_quit("Quit") + { + storage = 0; + storageID=0; + imagesInFolder = 0; + currentWindow = "mainWindow"; + set_title("Annotator"); + set_border_width(10); + add(m_sw1); + m_grid1.set_column_spacing (10); + m_grid1.set_row_spacing (50); + + + button_selectImageFileName.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "selectImageFileName")); + m_grid1.attach(button_selectImageFileName,0,1,1,1); + button_selectImageFileName.show(); + + button_selectDatasetFolder.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "selectDatasetFolder")); + m_grid1.attach(button_selectDatasetFolder,1,1,1,1); + button_selectDatasetFolder.show(); + + Gtk::RadioButton::Group group1 = rbutton_markBB.get_group(); + rbutton_cropBB.set_group(group1); + rbutton_markBBWithLabel.set_group(group1); + rbutton_cropMultipleBB.set_group(group1); + rbutton_segnetMaskedBased.set_group(group1); + rbutton_markBB.set_active(); + m_grid1.attach(rbutton_markBB,0,2,1,1); + rbutton_markBB.show(); + m_grid1.attach(rbutton_cropBB,1,2,1,1); + rbutton_cropBB.show(); + m_grid1.attach(rbutton_markBBWithLabel,2,2,1,1); + rbutton_markBBWithLabel.show(); + m_grid1.attach(rbutton_cropMultipleBB,0,3,2,1); + rbutton_cropMultipleBB.show(); + m_grid1.attach(rbutton_segnetMaskedBased,2,3,2,1); + rbutton_segnetMaskedBased.show(); + + button_loadImage.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "loadImage")); + m_grid1.attach(button_loadImage,0,4,1,1); + button_loadImage.show(); + + /* + Gtk::RadioButton::Group group1 = rbutton_extraLayerLMDB.get_group(); + rbutton_extraLayerLEVELDB.set_group(group15); + rbutton_extraLayerLMDB.set_active(); + m_grid_extraLayerType.attach(rbutton_extraLayerLMDB,2,16,1,1); + rbutton_extraLayerLMDB.show(); + m_grid_extraLayerType.attach(rbutton_extraLayerLEVELDB,3,16,1,1); + rbutton_extraLayerLEVELDB.show(); + */ + button_quit.signal_pressed().connect(sigc::mem_fun(*this,&Annotation::close)); + m_grid1.attach(button_quit,0,10,1,1); + + + + //imageLoadWindow + + button_loadMainWindow.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "loadMainWindow")); + m_grid_imageLoad.attach(button_loadMainWindow,0,10,1,1); + button_resetMarkings.show(); + + m_grid_imageLoad.attach(image,0,1,2,1); + + + + label_annotationType.set_text("Annotion Type: Selecting Single Bounding Box"); + label_annotationType.set_line_wrap(); + label_annotationType.set_justify(Gtk::JUSTIFY_FILL); + m_grid_imageLoad.attach(label_annotationType,0,0,2,1); + label_annotationType.show(); + + button_resetMarkings.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "resetMarkings")); + m_grid_imageLoad.attach(button_resetMarkings,0,3,1,1); + button_resetMarkings.show(); + + button_resetMarkingsCurrent.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "resetMarkingsCurrent")); + m_grid_imageLoad.attach(button_resetMarkingsCurrent,0,3,1,1); + button_resetMarkingsCurrent.show(); + + button_resetSegnetMaskCurrent.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "resetSegnetMaskCurrent")); + m_grid_imageLoad.attach(button_resetSegnetMaskCurrent,0,3,1,1); + button_resetSegnetMaskCurrent.show(); + + button_selectRoi.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "selectRoi")); + m_grid_imageLoad.attach(button_selectRoi,0,4,1,1); + button_selectRoi.show(); + + label_annotationLabel.set_text("Give a label to ROI: "); + label_annotationLabel.set_line_wrap(); + label_annotationLabel.set_justify(Gtk::JUSTIFY_FILL); + m_grid_imageLoad.attach(label_annotationLabel,0,4,1,1); + label_annotationLabel.show(); + + + text_annotationLabel.set_max_length(100); + text_annotationLabel.set_text(""); + text_annotationLabel.select_region(0, text_annotationLabel.get_text_length()); + m_grid_imageLoad.attach(text_annotationLabel,1,4,1,1); + text_annotationLabel.show(); + + button_selectRoiCurrent.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "selectRoiCurrent")); + m_grid_imageLoad.attach(button_selectRoiCurrent,2,4,1,1); + button_selectRoiCurrent.show(); + + button_selectSegnetMaskCurrent.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "selectSegnetMaskCurrent")); + m_grid_imageLoad.attach(button_selectSegnetMaskCurrent,2,4,1,1); + button_selectSegnetMaskCurrent.show(); + + button_loadAnotherImage.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "loadAnotherImage")); + m_grid_imageLoad.attach(button_loadAnotherImage,0,5,2,1); + button_loadMainWindow.show(); + + button_loadNextImage.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "loadNextImage")); + m_grid_imageLoad.attach(button_loadNextImage,2,5,1,1); + button_loadNextImage.show(); + + label_outputFile.set_text("OutPut Text File Name: "); + label_outputFile.set_line_wrap(); + label_outputFile.set_justify(Gtk::JUSTIFY_FILL); + m_grid_imageLoad.attach(label_outputFile,0,6,1,1); + label_outputFile.show(); + + + text_outputFile.set_max_length(100); + text_outputFile.set_text("../examples/objectdetector/Annotation/output.txt"); + text_outputFile.select_region(0, text_outputFile.get_text_length()); + m_grid_imageLoad.attach(text_outputFile,1,6,1,1); + text_outputFile.show(); + + button_saveMarked.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "saveMarked")); + m_grid_imageLoad.attach(button_saveMarked,2,6,1,1); + button_saveMarked.show(); + + button_saveCropMarked.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "saveCropMarked")); + m_grid_imageLoad.attach(button_saveCropMarked,2,6,2,1); + button_saveCropMarked.show(); + + button_saveMarkedMultiple.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "saveMarkedMultiple")); + m_grid_imageLoad.attach(button_saveMarkedMultiple,2,6,1,1); + button_saveMarkedMultiple.show(); + + button_saveCropMarkedMultiple.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "saveCropMarkedMultiple")); + m_grid_imageLoad.attach(button_saveCropMarkedMultiple,2,6,1,1); + button_saveCropMarkedMultiple.show(); + + button_saveSegnetMask.signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &Annotation::on_button_clicked), "saveSegnetMask")); + m_grid_imageLoad.attach(button_saveSegnetMask,2,6,1,1); + button_saveSegnetMask.show(); + + m_sw_imageLoad.add(m_grid_imageLoad); + + m_sw1.add(m_grid1); + m_sw1.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + // m_grid1.show(); + show_all_children(); + m_sw1.show(); + + } + + Annotation::~Annotation() + {} + + void Annotation::on_button_clicked(Glib::ustring data) + { + if(data == "selectImageFileName" || data == "loadAnotherImage") + { + if(data == "selectImageFileName") + file_folder = "file"; + // Create the dialog box FileChooser + Gtk::FileChooserDialog dialog("Please choose a file",Gtk::FILE_CHOOSER_ACTION_OPEN); + dialog.set_transient_for(*this); + + //Add response buttons the the dialog: + dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL); + dialog.add_button("_Open", Gtk::RESPONSE_OK); + + //Add filters, so that only certain file types can be selected: + Glib::RefPtr filter_any = Gtk::FileFilter::create(); + filter_any->set_name("Any files"); + filter_any->add_pattern("*"); + dialog.add_filter(filter_any); + + Glib::RefPtr filter_text = Gtk::FileFilter::create(); + filter_text->set_name("Text files"); + filter_text->add_mime_type("text/plain"); + dialog.add_filter(filter_text); + + Glib::RefPtr filter_cpp = Gtk::FileFilter::create(); + filter_cpp->set_name("C/C++ files"); + filter_cpp->add_mime_type("text/x-c"); + filter_cpp->add_mime_type("text/x-c++"); + filter_cpp->add_mime_type("text/x-c-header"); + dialog.add_filter(filter_cpp); + + + + //Show the dialog and wait for a user response: + int result = dialog.run(); + + //Handle the response: + switch(result) + { + case(Gtk::RESPONSE_OK): + { + // The user selected a file + std::cout << "Open clicked." << std::endl; + filename = dialog.get_filename(); + std::cout << "File selected: " << filename << std::endl; + break; + } + case(Gtk::RESPONSE_CANCEL): + { + // The user clicked cancel + std::cout << "Cancel clicked." << std::endl; + break; + } + default: + { + // The user closed the dialog box + std::cout << "Unexpected button clicked." << std::endl; + break; + } + } + if(data == "loadAnotherImage") + loadOriginalImage(filename, 1); + } + else if(data == "selectDatasetFolder") + { + file_folder = "folder"; + // Create the dialog box FileChooser + Gtk::FileChooserDialog dialog("Please choose a file",Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + dialog.set_transient_for(*this); + + //Add response buttons the the dialog: + dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL); + dialog.add_button("_Open", Gtk::RESPONSE_OK); + + //Add filters, so that only certain file types can be selected: + Glib::RefPtr filter_any = Gtk::FileFilter::create(); + filter_any->set_name("Any files"); + filter_any->add_pattern("*"); + dialog.add_filter(filter_any); + + Glib::RefPtr filter_text = Gtk::FileFilter::create(); + filter_text->set_name("Text files"); + filter_text->add_mime_type("text/plain"); + dialog.add_filter(filter_text); + + Glib::RefPtr filter_cpp = Gtk::FileFilter::create(); + filter_cpp->set_name("C/C++ files"); + filter_cpp->add_mime_type("text/x-c"); + filter_cpp->add_mime_type("text/x-c++"); + filter_cpp->add_mime_type("text/x-c-header"); + dialog.add_filter(filter_cpp); + + + + //Show the dialog and wait for a user response: + int result = dialog.run(); + + //Handle the response: + switch(result) + { + case(Gtk::RESPONSE_OK): + { + // The user selected a file + std::cout << "Open clicked." << std::endl; + foldername = dialog.get_filename(); + std::cout << "File selected: " << filename << std::endl; + break; + } + case(Gtk::RESPONSE_CANCEL): + { + // The user clicked cancel + std::cout << "Cancel clicked." << std::endl; + break; + } + default: + { + // The user closed the dialog box + std::cout << "Unexpected button clicked." << std::endl; + break; + } + } + if(data == "loadAnotherImage") + loadOriginalImage(filename, 1); + } + else if(data == "loadNextImage") + { + if(imagesInFolder > 0) + { + filename = imageFileNames[--imagesInFolder]; + loadOriginalImage(filename, 1); + } + } + else if(data == "loadImage") + { + showWindow_imageLoad(filename); + } + else if(data == "loadMainWindow") + { + showWindow_main(); + } + else if(data == "resetMarkings") + { + loadOriginalImage(filename, 0); + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("Recently marked Points have been discarded"); + dialog.run(); + } + else if(data == "resetMarkingsCurrent") + { + loadOriginalImageWithSavedMarkings(filename, storageROILocationCurrent, 0); + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("Recently marked Points have been discarded"); + dialog.run(); + } + else if(data == "resetSegnetMaskCurrent") + { + /* int length = roiPointsForMask.size(); + std::string label = text_annotationLabel.get_text(); + int Result; + istringstream convert(label); + if ( !(convert >> Result) ) + Result = 0; + for( int i = length-1; i > -1; i--) + { + if(roiPointsForMask[roiPointsForMask.size()-1][0] == Result) + roiPointsForMask.pop_back(); + else + break; + } + */ + roiPointsForMask.clear(); + loadResetedMarkings(filename, roiPointsForMaskPermanent, 0); + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("Recently marked Points have been discarded"); + dialog.run(); + } + else if(data == "selectRoi") + { + std::vector temp; + temp.push_back(xPressed-10); + temp.push_back(yPressed-35); + temp.push_back(xReleased-10); + temp.push_back(yReleased-35); + + storageROILocation.push_back(temp); + storageFileName.push_back(filename); + storage++; + loadOriginalImage(filename, 1); + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("ROI has been added to the list"); + dialog.run(); + } + else if(data == "selectRoiCurrent") + { + std::vector temp; + std::string label = text_annotationLabel.get_text(); + int Result; + std::stringstream convert(label); + if(!(convert >> Result)) + Result = 0; + temp.push_back(Result); + temp.push_back(xPressed-10); + temp.push_back(yPressed-35); + temp.push_back(xReleased-10); + temp.push_back(yReleased-35); + storageROILocationCurrent.push_back(temp); + storageFileName.push_back(filename); + storage++; + std::cout << "filename = " << filename << std::endl; + loadOriginalImageWithSavedMarkings(filename, storageROILocationCurrent, 1); + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("ROI has been added to the list"); + dialog.run(); + + } + else if(data == "selectSegnetMaskCurrent") + { + storageID++; + cv::Mat img1 = cv::imread(filename, 1); + int c = img1.cols; + int r = img1.rows; + cv::resize(img1, img1, cv::Size(640,480)); + float wTemp = (float)c/640.0; + float hTemp = (float)r/480.0; + + for(unsigned int i = 0; i < roiPointsForMask.size(); ++i) + { + std::vector temp; + temp.push_back(roiPointsForMask[i][0]); + temp.push_back(roiPointsForMask[i][1]); + temp.push_back(roiPointsForMask[i][2]); + temp.push_back(storageID); + roiPointsForMaskPermanent.push_back(temp); + storageFileName.push_back(filename); + widthMultiplier.push_back(wTemp); + heightMultiplier.push_back(hTemp); + storage++; + } + roiPointsForMask.clear(); + + loadResetedMarkings(filename, roiPointsForMaskPermanent, 1); + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("ROI has been added to the list"); + dialog.run(); + // roiPointsForMaskPermanent + } + else if(data == "saveMarked") + { + std::ofstream myfile; + myfile.open(text_outputFile.get_text()); + for(unsigned int i = 0; i < storage; ++i) + { + myfile << storageFileName[i] << " " << int(storageROILocation[i][0]*widthMultiplier[i]) << " " << int(storageROILocation[i][1]*heightMultiplier[i]) << " " << int(storageROILocation[i][2]*widthMultiplier[i]) << " " << int(storageROILocation[i][3]*heightMultiplier[i]) << std::endl; + } + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("The details have been saved into the file " + text_outputFile.get_text()); + + dialog.run(); + } + else if(data == "saveMarkedMultiple") + { + std::ofstream myfile; + myfile.open(text_outputFile.get_text()); + std::string tempFileName(storageFileName[0]); + + for(unsigned int i = 0; i < storage; i++) + { + if(i == 0) + { + myfile << storageFileName[i] << " " << storageROILocationCurrent[i][0] << " " << int(storageROILocationCurrent[i][1]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][2]*heightMultiplier[i]) << " " << int(storageROILocationCurrent[i][3]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][4]*heightMultiplier[i]) << " "; + } + else + { + if(tempFileName == storageFileName[i]) + { + myfile << storageROILocationCurrent[i][0] << " " << int(storageROILocationCurrent[i][1]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][2]*heightMultiplier[i]) << " " << int(storageROILocationCurrent[i][3]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][4]*heightMultiplier[i]) << " "; + } + else + { + myfile << std::endl; + myfile << storageFileName[i] << " " << storageROILocationCurrent[i][0] << " " << int(storageROILocationCurrent[i][1]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][2]*heightMultiplier[i]) << " " << int(storageROILocationCurrent[i][3]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][4]*heightMultiplier[i]) << " "; + tempFileName = storageFileName[i]; + } + } + } + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("The details have been saved into the file " + text_outputFile.get_text()); + + dialog.run(); + } + else if(data == "saveCropMarked") + { + std::ofstream myfile; + myfile.open(text_outputFile.get_text()); + for(int i = 0; i < storage; i++) + { + myfile << storageFileName[i] << " " << int(storageROILocation[i][0]*widthMultiplier[i]) << " " << int(storageROILocation[i][1]*heightMultiplier[i]) << " " << int(storageROILocation[i][2]*widthMultiplier[i]) << " " << int(storageROILocation[i][3]*heightMultiplier[i]) << std::endl; + std::string str2 = storageFileName[i].substr (0,storageFileName[i].length()-4); + str2 += "_cropped.png"; + cv::Rect roi(int(storageROILocation[i][0]*widthMultiplier[i]), int(storageROILocation[i][1]*heightMultiplier[i]), int(storageROILocation[i][2]*widthMultiplier[i]) - int(storageROILocation[i][0]*widthMultiplier[i]), int(storageROILocation[i][3]*heightMultiplier[i]) - int(storageROILocation[i][1]*heightMultiplier[i])); + cv::Mat img = cv::imread(storageFileName[i],1); + cv::Mat image_roi = img(roi); + imwrite(str2, image_roi); + } + + //Create the cv::Mat with the ROI you need, where "image" is the cv::Mat you want to extract the ROI from + + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("The details have been saved into the file " + text_outputFile.get_text() + " and the cropped images have been saved"); + + // dialog.run(); + } + else if(data == "saveSegnetMask") + { + std::ofstream myfile; + myfile.open(text_outputFile.get_text()); + std::string tempFileName = storageFileName[0]; + + for(unsigned int i = 0; i < storage; i++) + { + if(i == 0) + { + myfile << storageFileName[i] << " ID" << roiPointsForMaskPermanent[i][3] << " " << roiPointsForMaskPermanent[i][0] << " " << int(roiPointsForMaskPermanent[i][1]*widthMultiplier[i]) << " " << int(roiPointsForMaskPermanent[i][2]*heightMultiplier[i]) << " "; + } + else + { + if(tempFileName == storageFileName[i]) + { + if(roiPointsForMaskPermanent[i][3] == roiPointsForMaskPermanent[i-1][3]) + myfile << int(roiPointsForMaskPermanent[i][1]*widthMultiplier[i]) << " " << int(roiPointsForMaskPermanent[i][2]*heightMultiplier[i]) << " "; + else + myfile << " ID" << roiPointsForMaskPermanent[i][3] << " " << roiPointsForMaskPermanent[i][0] << " " << int(roiPointsForMaskPermanent[i][1]*widthMultiplier[i]) << " " << int(roiPointsForMaskPermanent[i][2]*heightMultiplier[i]) << " "; + } + else + { + myfile << std::endl; + myfile << storageFileName[i] << " ID" << roiPointsForMaskPermanent[i][3] << " " << roiPointsForMaskPermanent[i][0] << " " << int(roiPointsForMaskPermanent[i][1]*widthMultiplier[i]) << " " << int(roiPointsForMaskPermanent[i][2]*heightMultiplier[i]) << " "; + tempFileName = storageFileName[i]; + } + } + } + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("The details have been saved into the file " + text_outputFile.get_text()); + dialog.run(); + + } + else if(data == "saveCropMarkedMultiple") + { + std::ofstream myfile; + myfile.open(text_outputFile.get_text()); + std::string tempFileName = storageFileName[0]; + + for(unsigned int i = 0; i < storage; i++) + { + // cout << storageFileName[i] << " " << storageROILocationCurrent[i][0] << " " << widthMultiplier[i] << " " << heightMultiplier[i] << endl; + if(i == 0) + { + myfile << storageFileName[i] << " " << storageROILocationCurrent[i][0] << " " << int(storageROILocationCurrent[i][1]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][2]*heightMultiplier[i]) << " " << int(storageROILocationCurrent[i][3]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][4]*heightMultiplier[i]) << " "; + } + else + { + if(tempFileName == storageFileName[i]) + { + myfile << storageROILocationCurrent[i][0] << " " << int(storageROILocationCurrent[i][1]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][2]*heightMultiplier[i]) << " " << int(storageROILocationCurrent[i][3]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][4]*heightMultiplier[i]) << " "; + } + else + { + myfile << std::endl; + myfile << storageFileName[i] << " " << storageROILocationCurrent[i][0] << " " << int(storageROILocationCurrent[i][1]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][2]*heightMultiplier[i]) << " " << int(storageROILocationCurrent[i][3]*widthMultiplier[i]) << " " << int(storageROILocationCurrent[i][4]*heightMultiplier[i]) << " "; + tempFileName = storageFileName[i]; + } + } + std::string str2 = storageFileName[i].substr (0,storageFileName[i].length()-4); + std::string result; + std::ostringstream convert; + convert << i; + result = convert.str(); + str2 = str2 + "_cropped_"; + std::string label; + std::ostringstream convert1; + convert1 << storageROILocationCurrent[i][0]; + label = convert.str(); + str2 = str2 + label + "_" + result + ".png"; + cv::Rect roi(int(storageROILocationCurrent[i][1]*widthMultiplier[i]), int(storageROILocationCurrent[i][2]*heightMultiplier[i]), int(storageROILocationCurrent[i][3]*widthMultiplier[i]) - int(storageROILocationCurrent[i][1]*widthMultiplier[i]), int(storageROILocationCurrent[i][4]*heightMultiplier[i]) - int(storageROILocationCurrent[i][2]*heightMultiplier[i])); + cv::Mat img = cv::imread(storageFileName[i],1); + cv::Mat image_roi = img(roi); + imwrite(str2, image_roi); + } + Gtk::MessageDialog dialog(*this, "Message"); + dialog.set_secondary_text("The details have been saved into the file " + text_outputFile.get_text()); + dialog.run(); + } + } + + } +} \ No newline at end of file diff --git a/detectors/src/global2D/annotation/Annotator.cpp b/detectors/src/global2D/annotation/Annotator.cpp new file mode 100644 index 00000000..b46efe5c --- /dev/null +++ b/detectors/src/global2D/annotation/Annotator.cpp @@ -0,0 +1,20 @@ +#include "od/detectors/global2D/annotation/Annotator.h" + +namespace od +{ + namespace g2d + { + int Annotator::train() + { + return 1; + } + + void Annotator::startAnnotator(int argc, char *argv[]) + { + auto app = Gtk::Application::create(argc, argv, std::string("org.gtkmm.example")); + Annotation annotation; + annotation.set_default_geometry(10000, 10000); + app->run(annotation); + } + } +} diff --git a/detectors/src/global2D/detection/CascadeDetector.cpp b/detectors/src/global2D/detection/CascadeDetector.cpp new file mode 100644 index 00000000..602d16b3 --- /dev/null +++ b/detectors/src/global2D/detection/CascadeDetector.cpp @@ -0,0 +1,125 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 17.07.15. +// + +#include "od/detectors/global2D/detection/CascadeDetector.h" + +namespace od +{ + + namespace g2d + { + + CascadeDetector::CascadeDetector(bool gpu, const std::string & trainer, const std::string & trained_data_location, double scale_factor, int min_neighbors, int flags, + const cv::Size & min_size, const cv::Size & max_size) + { + if(gpu){ + std::cout << "creating gpu cascade detector" << std::endl; +#if WITH_GPU + #ifndef WITH_BOOST_SHARED_PTR + cascade_detector_ = shared_ptr(new od::gpu::g2d::CascadeDetectorImpl(trainer, trained_data_location, scale_factor, min_neighbors, flags, min_size, max_size)); + #else + cascade_detector_ = make_shared(trainer, trained_data_location, scale_factor, min_neighbors, flags, min_size, max_size); + #endif +#else + std::cout << "Error !! GPU CascadeDetector has not been compiled. Recompile with WITH_GPU." << std::endl; + exit(-1); +#endif + } + else { + std::cout << "creating cpu cascade detector" << std::endl; +#ifndef WITH_BOOST_SHARED_PTR + cascade_detector_ = shared_ptr(new CascadeDetectorImpl(trainer, trained_data_location, scale_factor, min_neighbors, flags, min_size, max_size)); +#else + cascade_detector_ = make_shared(trainer, trained_data_location, scale_factor, min_neighbors, flags, min_size, max_size); +#endif + } + } + + shared_ptr CascadeDetector::detectOmni(shared_ptr scene) + { + return cascade_detector_->detectOmni(scene); + }; + + void CascadeDetector::init() + { + cascade_detector_->init(); + } + + shared_ptr CascadeDetector::detectOmni(shared_ptr scene) + { + return cascade_detector_->detectOmni(scene); + } + + shared_ptr CascadeDetector::detect(shared_ptr scene) + { + return cascade_detector_->detect(scene); + } + + void CascadeDetector::setScale(const float scale) + { + cascade_detector_->setScale(scale); + } + + float CascadeDetector::getScale() const + { + return cascade_detector_->getScale(); + } + + void CascadeDetector::setMinNeighbors(const unsigned int min_neighbors) + { + cascade_detector_->setMinNeighbors(min_neighbors); + } + + unsigned int CascadeDetector::getMinNeighbors() const + { + return cascade_detector_->getMinNeighbors(); + } + + void CascadeDetector::setMinSize(const cv::Size & size) + { + cascade_detector_->setMinSize(size); + } + + cv::Size CascadeDetector::getMinSize() const + { + return cascade_detector_->getMinSize(); + } + + void CascadeDetector::setMaxSize(const cv::Size & size) + { + cascade_detector_->setMaxSize(size); + } + + cv::Size CascadeDetector::getMaxSize() const + { + return cascade_detector_->getMaxSize(); + } + + } +} \ No newline at end of file diff --git a/detectors/src/global2D/detection/CascadeDetectorImpl.cpp b/detectors/src/global2D/detection/CascadeDetectorImpl.cpp new file mode 100644 index 00000000..3bff63f2 --- /dev/null +++ b/detectors/src/global2D/detection/CascadeDetectorImpl.cpp @@ -0,0 +1,165 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 17.07.15. +// + +#include "od/detectors/global2D/detection/CascadeDetectorImpl.h" + +namespace od +{ + + namespace g2d + { + + CascadeDetectorImpl::CascadeDetectorImpl(const std::string & trainer, const std::string & trained_data_location, double scale_factor, int min_neighbors, int flags, + const cv::Size & min_size, const cv::Size & max_size): + trained_data_location_(trained_data_location), scale_factor_(scale_factor), min_neighbors_(min_neighbors), + min_size_(min_size), max_size_(max_size) + { + trained_location_identifier_ = std::string("CASCADE"); + trained_data_id_ = trainer; + meta_info_ = true; + } + + shared_ptr CascadeDetectorImpl::detectOmni(shared_ptr scene) + { + std::cout << "not implemented, use detect()" <(new cv::CascadeClassifier(trained_data_id_)); +#else + haar_cascade_ = make_shared(trained_data_id_); +#endif + } + + shared_ptr CascadeDetectorImpl::detectOmni(shared_ptr scene) + { + + if(!haar_cascade_){ + std::cout << "Call init() first!" << std::endl; + return nullptr; + } + + cv::Mat gray; + cv::cvtColor(scene->getCVImage(), gray, CV_BGR2GRAY); + + std::vector > objects; + haar_cascade_->detectMultiScale(gray, objects, scale_factor_, min_neighbors_, 0, min_size_, max_size_); + + //always create detections + shared_ptr detections = make_shared(); + cv::Mat viz = scene->getCVImage(); + for(auto & o : objects) + { + // Process object by object: + shared_ptr detection2D = make_shared(detection::CLASSIFICATION, "OBJ", 1); + detection2D->setBoundingBox(o); + detections->push_back(detection2D); + + if(meta_info_) + { + cv::rectangle(viz, o, CV_RGB(0, 255, 0), 1); + } + } + detections->setMetainfoImage(viz); + + return detections; + } + + shared_ptr CascadeDetectorImpl::detect(shared_ptr scene) + { + + if(!haar_cascade_){ + std::cout << "Call init() first!" << std::endl; + return nullptr; + } + + //always create detections + shared_ptr detections = make_shared(); + + cv::Mat gray; + cv::cvtColor(scene->getCVImage(), gray, CV_BGR2GRAY); + // Find the objects in the frame: + std::vector > objects; + + //hack for single detection, + //note: maxsize = minsize = size of input image for single window detection + //todo: implement in some other way of fast single detection; currently this will work, but maynot be fast + haar_cascade_->detectMultiScale(gray, objects, 5, min_neighbors_, 0, gray.size(), gray.size()); + if(objects.size() > 0) + { + detections->push_back(make_shared(detection::CLASSIFICATION, "OBJ", 1)); + } + return detections; + } + + void CascadeDetectorImpl::setScale(const float scale) + { + scale_factor_ = scale; + } + + float CascadeDetectorImpl::getScale() const + { + return scale_factor_; + } + + void CascadeDetectorImpl::setMinNeighbors(const unsigned int min_neighbors) + { + min_neighbors_ = min_neighbors; + } + + unsigned int CascadeDetectorImpl::getMinNeighbors() const + { + return min_neighbors_; + } + + void CascadeDetectorImpl::setMinSize(const cv::Size & size) + { + min_size_ = size; + } + + cv::Size CascadeDetectorImpl::getMinSize() const + { + return min_size_; + } + + void CascadeDetectorImpl::setMaxSize(const cv::Size & size) + { + max_size_ = size; + } + + cv::Size CascadeDetectorImpl::getMaxSize() const + { + return max_size_; + } + + } +} \ No newline at end of file diff --git a/detectors/src/global2D/detection/HOGDetector.cpp b/detectors/src/global2D/detection/HOGDetector.cpp new file mode 100644 index 00000000..488fffe5 --- /dev/null +++ b/detectors/src/global2D/detection/HOGDetector.cpp @@ -0,0 +1,248 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 15.07.15. +// + +#include "od/detectors/global2D/detection/HOGDetector.h" + +namespace od +{ + namespace g2d + { + + HOGDetector::HOGDetector(const std::string & trained_data_location_, const cv::Size & win_size, const cv::Size & block_size, + const cv::Size & block_stride, const cv::Size & cell_size, float hit_threshold): + Detector2D(trained_data_location_), win_size_(win_size), block_size_(block_size), block_stride_(block_stride), + cell_size_(cell_size), hit_threshold_(hit_threshold), hog_(win_size, block_size, block_stride, cell_size, 9, 1, -1, + cv::HOGDescriptor::L2Hys, 0.2, false, cv::HOGDescriptor::DEFAULT_NLEVELS) + { + trained_location_identifier_ = std::string("HOG"); + trained_data_id_ = std::string("hog.xml"); + meta_info_ = true; + svm_type_ = _DEFAULT_PEOPLE; + + if(trained_data_location_ != std::string("")) + svm_type_ = _FILE; + } + + void HOGDetector::init() + { + + switch(svm_type_) + { + case _DEFAULT_PEOPLE: + hog_.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector()); + std::cout << "HOG TYPE: OpenCV Default People" << std::endl; + //hog_.save(getSpecificTrainingDataLocation() + "/defaultpeople." + TRAINED_DATA_EXT_); + break; + case _DAIMLER_PEOPLE: + hog_.winSize = cv::Size(48, 96); + hit_threshold_ = 1.2; + hog_.setSVMDetector(cv::HOGDescriptor::getDaimlerPeopleDetector()); + std::cout << "HOG TYPE: OpenCV Daimler People" << std::endl; + //hog_.save(getSpecificTrainingDataLocation() + "/daimlerpeople." + TRAINED_DATA_EXT_); + break; + case _FILE: + std::string hogfile = fileutils::getFirstFile(getSpecificTrainingDataLocation(), trained_data_id_); + load(hogfile); + std::cout << "HOG TYPE: Custom HOG features loaded from: " << hogfile << std::endl; + break; + //dont set anything for custom, it is to be set by the user by setSVMDetector + } + + printParameters(); + } + + void HOGDetector::load(const std::string & file_name) + { + cv::FileStorage fs(file_name, cv::FileStorage::READ); + fs["hitThreshold"] >> hit_threshold_; + cv::FileNode fn = fs[cv::FileStorage::getDefaultObjectName(file_name)]; + hog_.read(fn); + } + + void HOGDetector::setSVMDetector(std::vector svm_detector) + { + hog_.setSVMDetector(svm_detector); + } + + shared_ptr HOGDetector::detectOmni(shared_ptr scene) + { + //always create a detection + shared_ptr detections = make_shared(); + + std::vector found; + hog_.detectMultiScale(scene->getCVImage(), found, hit_threshold_, cv::Size(8, 8), cv::Size(32, 32), 1.05, 2); + + cv::Mat viz = scene->getCVImage().clone(); + for(size_t i = 0; i < found.size(); ++i) + { + shared_ptr detection2D = make_shared(); + detection2D->setBoundingBox(found[i]); + detection2D->setId("PEOPLE"); + detection2D->setType(od::detection::CLASSIFICATION); + detections->push_back(detection2D); + + if(meta_info_) + { + cv::Rect r = found[i]; + r.x += cvRound(r.width * 0.1); + r.width = cvRound(r.width * 0.8); + r.y += cvRound(r.height * 0.06); + r.height = cvRound(r.height * 0.9); + rectangle(viz, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2); + } + } + detections->setMetainfoImage(viz); + + return detections; + } + + shared_ptr HOGDetector::detect(shared_ptr scene) + { + //always create a detection + shared_ptr detections = make_shared(); + + cv::Mat scaled_window; + cv::resize(scene->getCVImage(), scaled_window, hog_.winSize); + + std::vector found_locations; + + hog_.detect(scene->getCVImage(), found_locations, hit_threshold_); + if(!found_locations.empty()) + { + shared_ptr detection2D = make_shared(); + detection2D->setId("PEOPLE"); + detection2D->setType(od::detection::CLASSIFICATION); + detections->push_back(detection2D); + } + + return detections; + } + + void HOGDetector::setTrainedDataLocation(const std::string & trained_data_location) + { + trained_data_location_ = trained_data_location; + svm_type_ = _FILE; + } + + const HOGDetector::SVMType & HOGDetector::getSvmtype() const + { + return svm_type_; + } + + void HOGDetector::setSvmtype(const HOGDetector::SVMType & svm_type) + { + svm_type_ = svm_type; + } + + const cv::Size & HOGDetector::getWinSize() const + { + return win_size_; + } + + void HOGDetector::setWinSize(const cv::Size & win_size) + { + win_size_ = win_size; + } + + const cv::Size & HOGDetector::getBlockSize() const + { + return block_size_; + } + + void HOGDetector::setBlockSize(const cv::Size & block_size) + { + block_size_ = block_size; + } + + const cv::Size & HOGDetector::getBlockStride() const + { + return block_stride_; + } + + void HOGDetector::setBlockStride(const cv::Size & block_stride) + { + block_stride_ = block_stride; + } + + const cv::Size & HOGDetector::getCellSize() const + { + return cell_size_; + } + + void HOGDetector::setCellSize(const cv::Size & cell_size) + { + cell_size_ = cell_size; + } + + float HOGDetector::getHitThreshold() const + { + return hit_threshold_; + } + + void HOGDetector::setHitThreshold(float hit_threshold) + { + hit_threshold_ = hit_threshold; + } + + void HOGDetector::setSVMFromFile(const std::string & file_name) + { + std::vector descriptor_vector; + std::cout << "Reading descriptor vector from file " << file_name << std::endl;; + + std::ifstream file; + file.open(file_name.c_str(), std::ios::in); + if(file.good() && file.is_open()) { + + double d; + while(file >> d) + { + //cout << d << " "; + descriptor_vector.push_back(d); + } + file.close(); + } + + hog_.setSVMDetector(descriptor_vector); + } + + void HOGDetector::printParameters() + { + std::cout << "winSize: " << win_size_ << std::endl; + std::cout << "blockSize: " << block_size_ << std::endl; + std::cout << "blockStride: " << block_stride_ << std::endl; + std::cout << "cellSize: " << cell_size_ << std::endl; + std::cout << "hitThreshold: " << hit_threshold_ << std::endl; + } + + shared_ptr HOGDetector::detectOmni(shared_ptr scene) + { + return nullptr; + } + } +} diff --git a/detectors/src/global2D/training/HOGTrainer.cpp b/detectors/src/global2D/training/HOGTrainer.cpp new file mode 100644 index 00000000..65294c6a --- /dev/null +++ b/detectors/src/global2D/training/HOGTrainer.cpp @@ -0,0 +1,515 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/// +// Created by sarkar on 13.08.15. +// + + +#include "od/detectors/global2D/training/HOGTrainer.h" + +namespace od +{ + namespace g2d + { + + HOGTrainer::HOGTrainer(const std::string & training_input_location_, const std::string & trained_data_location_, const cv::Size & win_size, + const cv::Size & block_size, const cv::Size & block_stride, const cv::Size & cell_size, float hit_threshold): + Trainer(training_input_location_, trained_data_location_), win_size_(win_size), block_size_(block_size), + block_stride_(block_stride), cell_size_(cell_size), hog_(win_size, block_size, block_stride, cell_size, 9) + { + + trained_location_identifier_ = std::string("HOG"); + trained_data_id_ = std::string("hog.xml"); + + //algo parameter init + training_padding_ = cv::Size(0, 0); + start_hog_pos_ = cv::Point(15, 15); + no_features_neg_ = 10; + win_stride_ = cv::Size(); + train_hard_negative_ = false; + + if(trained_data_location_ != std::string("")) + { + pos_samples_dir_ = training_input_location_ + std::string("/pos"); + neg_samples_dir_ = training_input_location_ + std::string("/neg"); + } + + + //internal data + fileutils::createTrainingDir(getSpecificTrainingDataLocation()); + features_file_ = getSpecificTrainingDataLocation() + std::string("/features.dat"); + svm_model_file_ = getSpecificTrainingDataLocation() + std::string("/svmlightmodel.dat"); + svm_model_hard_ = getSpecificTrainingDataLocation() + std::string("/svmlightmodelhard.dat"); + descriptor_vector_file_ = getSpecificTrainingDataLocation() + std::string("/descriptorvector.dat"); + descriptor_vector_file_ = getSpecificTrainingDataLocation() + std::string("/descriptorvectorHard.dat"); + + } + + void HOGTrainer::saveDescriptorVectorToFile(const std::vector & descriptor_vector, const std::string & file_name) + { + std::cout << "Saving descriptor vector to file " << file_name << std::endl; + std::fstream file; + float percent; + file.open(file_name.c_str(), std::ios::out); + const unsigned int descriptors_num = descriptor_vector.size(); + + if(file.good() && file.is_open()) + { + std::cout << "Saving " << descriptors_num << " descriptor vector features:\t" << std::endl; + for(size_t feature = 0; feature < descriptors_num; ++feature) + { + if((feature % 10 == 0) || (feature == (descriptors_num - 1))) + { + percent = ((1 + feature) * 100 / descriptors_num); + std::cout << feature << "(" < & feature_vector, cv::HOGDescriptor & hog) + { + + cv::Mat image_data_orig = cv::imread(image_file_name, 0); + + if(image_data_orig.empty()) + { + feature_vector.clear(); + std::cout << "Error: HOG image " << image_file_name << " is empty, features calculation skipped!" << std::endl; + return; + } + + std::vector locations; + locations.push_back(start_hog_pos_); + hog.compute(image_data_orig, feature_vector, win_stride_, training_padding_, locations); + //cout << "Desc size :" << featureVector.size(); + //cout << ": Expected size :" << hog.getDescriptorSize() << endl; + } + + void HOGTrainer::detectTrainingSetTest(const cv::HOGDescriptor & hog, double hit_threshold, const std::vector & pos_file_names, + const std::vector & neg_file_names) + { + unsigned int true_positives = 0; + unsigned int true_negatives = 0; + unsigned int false_positives = 0; + unsigned int false_negatives = 0; + + std::vector found_detection; + cv::Mat image_data; + // Walk over positive training samples, generate images and detect + for(auto & pf : pos_file_names) + { + image_data = cv::imread(pf, 0); + hog.detect(image_data, found_detection, hit_threshold, win_stride_, training_padding_); + if(found_detection.size() > 0) + { + ++true_positives; + false_negatives += found_detection.size() - 1; + } else + { + ++false_negatives; + } + } + // Walk over negative training samples, generate images and detect + for(auto & nf : neg_file_names) + { + image_data = cv::imread(nf, 0); + hog.detect(image_data, found_detection, hit_threshold, win_stride_, training_padding_); + if(found_detection.size() > 0) + { + false_positives += found_detection.size(); + } else + { + ++true_negatives; + } + } + + std::cout << "Results: " << std::endl << "\tTrue Positives: " << true_positives << std::endl << "\tTrue Negatives: " + << true_negatives << "\tFalse Positives: " << false_positives << std::endl << " \tFalse Negatives:" << false_negatives << std::endl; + } + + + void HOGTrainer::calculateFeaturesFromImageLoc(const cv::Mat & image_data, std::vector & feature_vector, const cv::HOGDescriptor & hog, + const cv::Point & start_pos) + { + + std::vector locations; + locations.push_back(start_pos); + hog.compute(image_data, feature_vector, win_stride_, training_padding_, locations); + } + + void HOGTrainer::handleNegetivefile(const std::string & image_file_name, cv::HOGDescriptor & hog, std::fstream & file) + { + + cv::Mat image_data = cv::imread(image_file_name, 0); + + //cout << "Image size : " << imageData.size() << "random points : " << endl; + //get hog at random 10 image location + for(size_t i = 0; i < no_features_neg_; ++i) + { + cv::Point feat_loc(rand() % (image_data.cols - win_size_.width), rand() % (image_data.rows - win_size_.height)); + //cout << feat_loc << endl; + + //use this p for finding feature + std::vector feature_vector; + calculateFeaturesFromImageLoc(image_data, feature_vector, hog, feat_loc); + + if(!feature_vector.empty()) + { + /* Put positive or negative sample class to file, + * true=positive, false=negative, + * and convert positive class to +1 and negative class to -1 for SVMlight + */ + file << "-1"; + // Save feature vector components + for(size_t feature = 0; feature < feature_vector.size(); ++feature) + { + file << " " << (feature + 1) << ":" << feature_vector[feature]; + } + file << std::endl; + } + } + + } + + void HOGTrainer::createHardTrainingData(const cv::HOGDescriptor & hog, double hit_threshold, const std::vector & neg_file_names) + { + std::fstream file; + file.open(features_file_.c_str(), std::fstream::app); + if(!file.is_open()) + { + std::cout << "ERROR opening previous feature file! HARD training failed!" << std::endl; + } + std::cout << "Appending HARD negetive features to " + features_file_ << std::endl; + //cvNamedWindow("hardneg", WINDOW_AUTOSIZE); + + // Walk over negative training samples, generate images and detect + int counter = 0; + for(auto & nf : neg_file_names) + { + const cv::Mat image_data = cv::imread(nf, 0); + + std::vector found_locations; + hog.detectMultiScale(image_data, found_locations, hit_threshold); + + for(size_t i = 0; i < found_locations.size(); ++i) + { + counter++; + //cout << "## hard examples ## FALSE POS FOUND : including the descriptor in training set" << endl; + + cv::Mat neg_img(image_data(found_locations[i])); + //imshow("hardneg", negimg); waitKey(2000); + + cv::Mat resized_neg; + resize(neg_img, resized_neg, win_size_); + // imshow("hardneg", resized_neg); waitKey(4000); + + std::vector feature_vector; + calculateFeaturesFromImageLoc(resized_neg, feature_vector, hog, cv::Point(0, 0)); + + if(!feature_vector.empty()) + { + file << "-1"; + for(size_t feature = 0; feature < feature_vector.size(); ++feature) + { + file << " " << (feature + 1) << ":" << feature_vector.at(feature); + } + file << std::endl; + } + } + } + std::cout << "Wrote " << counter << " HARD negetive features" << std::endl; + + //CLOSE THE APPENDED DATA FILE + file.close(); + } + + double HOGTrainer::trainWithSVMLight(const std::string & svm_model_file, const std::string & svm_descriptor_file, + std::vector & descriptor_vector) + { + SVMlight * svmlight= SVMlight::getInstance(); + //training takes featurefile as input, produces hitthreshold and vector as output + std::cout << "Calling " << svmlight->getSVMName() << std::endl; + svmlight->read_problem(const_cast (features_file_.c_str())); + svmlight->train(); // Call the core libsvm training procedure + + std::cout << "Training done, saving model file!"<< std::endl; + svmlight->saveModelToFile(svm_model_file); + + std::cout << "Generating representative single HOG feature vector using svmlight!" << std::endl; + descriptor_vector.resize(0); + // Generate a single detecting feature vector (v1 | b) from the trained support vectors, for use e.g. with the HOG algorithm + svmlight->getSingleDetectingVector(descriptor_vector); + // And save the precious to file system + saveDescriptorVectorToFile(descriptor_vector, svm_descriptor_file); + // Detector detection tolerance threshold + hit_threshold_ = svmlight->getThreshold(); + return hit_threshold_; + } + + int HOGTrainer::train() + { + + std::vector positive_training_images; + std::vector negative_training_images; + std::vector valid_extensions; + + valid_extensions.push_back(".jpg"); + valid_extensions.push_back(".png"); + valid_extensions.push_back(".ppm"); + + fileutils::getFilesInDirectoryRec(pos_samples_dir_, valid_extensions, positive_training_images); + fileutils::getFilesInDirectoryRec(neg_samples_dir_, valid_extensions, negative_training_images); + + unsigned int pos_size = positive_training_images.size(); + unsigned int neg_size = negative_training_images.size(); + std::cout << "No of positive Training Files: " << pos_size << std::endl; + std::cout << "No of neg Training Files: "<< neg_size << std::endl; + + if(pos_size + neg_size == 0) + { + std::cout << "No training sample files found, nothing to do!" << std::endl; + return 0; + } + + /// @WARNING: This is really important, some libraries (e.g. ROS) seems to set the system locale + // which takes decimal commata instead of points which causes the file input parsing to fail + setlocale(LC_ALL, "C"); // Do not use the system locale + setlocale(LC_NUMERIC, "C"); + setlocale(LC_ALL, "POSIX"); + + std::cout << "Reading files, generating HOG features and save them to file: " << features_file_ << std::endl; + + std::fstream file; + file.open(features_file_.c_str(), std::fstream::out); + if(file.is_open()) + { + + // Iterate over POS IMAGES + for(auto & pt : positive_training_images) + { + + std::vector feature_vector; + calculateFeaturesFromInput(pt, feature_vector, hog_); + if(!feature_vector.empty()) + { + /* Put positive or negative sample class to file, + * true=positive, false=negative, + * and convert positive class to +1 and negative class to -1 for SVMlight + */ + file << "+1"; + // Save feature vector components + for(unsigned int feature = 0; feature < feature_vector.size(); ++feature) + { + file << " " << (feature + 1) << ":" << feature_vector[feature]; + } + file << std::endl; + } + } + + + // Iterate over NEG IMAGES + for(auto & ni : negative_training_images) + { + handleNegetivefile(ni, hog_, file); + } + + std::cout << std::endl; + file.flush(); + file.close(); + + } else + { + std::cout << "Error opening file " << features_file_; + return -1; + } + + + //train them with SVM + std::vector descriptor_vector; + hit_threshold_ = trainWithSVMLight(svm_model_file_, descriptor_vector_file_, descriptor_vector); + + // Pseudo test our custom detecting vector + hog_.setSVMDetector(descriptor_vector); + std::cout << "Testing training phase using training set as test set (just to check if training is ok - no detection quality conclusion with this!)" << std::endl; + detectTrainingSetTest(hog_, hit_threshold_, positive_training_images, negative_training_images); + + if(train_hard_negative_) + { + std::cout << "Preparing for training HARD negetive windows" << std::endl; + //create hard training examples + createHardTrainingData(hog_, hit_threshold_, negative_training_images); + //train again + hit_threshold_ = trainWithSVMLight(svm_model_hard_, descriptor_vector_hard_, descriptor_vector); + + // Pseudo test our custom detecting vector + hog_.setSVMDetector(descriptor_vector); + std::cout << "Testing training phase using training set as test set after HARD EXAMPLES (just to check if training is ok - no detection quality conclusion with this!)" << std::endl; + detectTrainingSetTest(hog_, hit_threshold_, positive_training_images, negative_training_images); + } + + save(getSpecificTrainingDataLocation() + "/odtrained." + trained_data_id_); + + return 0; + } + + + void HOGTrainer::readDescriptorsFromFile(const std::string & file_name, std::vector & descriptor_vector) + { + std::cout << "Reading descriptor vector from file " << file_name << std::endl; + + std::ifstream file; + file.open(file_name.c_str(), std::ios::in); + if(file.good() && file.is_open()) + { + double d; + while(file >> d) + { + descriptor_vector.push_back(d); + } + file.close(); + } + } + + void HOGTrainer::save(const std::string & file_name) + { + cv::FileStorage fs(file_name, cv::FileStorage::WRITE); + fs << "hitThreshold" << hit_threshold_; + hog_.write(fs, cv::FileStorage::getDefaultObjectName(file_name)); + } + + const std::string & HOGTrainer::getPosSamplesDir() const + { + return pos_samples_dir_; + } + + void HOGTrainer::setPosSamplesDir(const std::string & pos_samples_dir) + { + pos_samples_dir_ = pos_samples_dir; + } + + const std::string & HOGTrainer::getNegSamplesDir() const + { + return neg_samples_dir_; + } + + void HOGTrainer::setNegSamplesDir(const std::string & neg_samples_dir) + { + neg_samples_dir_ = neg_samples_dir; + } + + int HOGTrainer::getNOFeaturesNeg() const + { + return no_features_neg_; + } + + void HOGTrainer::setNOFeaturesNeg(int featno) + { + no_features_neg_ = featno; + } + + const cv::Point & HOGTrainer::getStartHogPos() const + { + return start_hog_pos_; + } + + void HOGTrainer::setStartHogPos(const cv::Point & start_hog_pos) + { + start_hog_pos_ = start_hog_pos; + } + + const cv::Size & HOGTrainer::getWinSize() const + { + return win_size_; + } + + void HOGTrainer::setWinSize(const cv::Size & win_size) + { + win_size_ = win_size; + } + + const cv::Size & HOGTrainer::getBlockSize() const + { + return block_size_; + } + + void HOGTrainer::setBlockSize(const cv::Size & block_size) + { + block_size_ = block_size; + } + + const cv::Size & HOGTrainer::getBlockStride() const + { + return block_stride_; + } + + void HOGTrainer::setBlockStride(const cv::Size & block_stride) + { + block_stride_ = block_stride; + } + + const cv::Size & HOGTrainer::getCellSize() const + { + return cell_size_; + } + + void HOGTrainer::setCellSize(const cv::Size & cell_size) + { + cell_size_ = cell_size; + } + + const cv::Size & HOGTrainer::getTrainingPadding() const + { + return training_padding_; + } + + void HOGTrainer::setTrainingPadding(const cv::Size & training_padding) + { + training_padding_ = training_padding; + } + + bool HOGTrainer::isTrainHardNegetive() const + { + return train_hard_negative_; + } + + void HOGTrainer::setTrainHardNegetive(bool train_hard_negative) + { + train_hard_negative_ = train_hard_negative; + } + + double HOGTrainer::getHitThreshold() const + { + return hit_threshold_; + } + + } +} diff --git a/detectors/src/global3D/CMakeLists.txt b/detectors/src/global3D/CMakeLists.txt new file mode 100644 index 00000000..7f7bc98a --- /dev/null +++ b/detectors/src/global3D/CMakeLists.txt @@ -0,0 +1,27 @@ +set(SUBSYS_NAME pointcloud_global_detector) +set(LIB_NAME od_${SUBSYS_NAME}) +set(SUBSYS_DESC "The global detector for point clouds") +set(SUBSYS_DEPS od_common) + +if(BUILD_GLOBAL_3D_DETECTION) + + if(WITH_GPU) + set(SUBSYS_DEPS ${SUBSYS_DEPS} siftgpu) + endif() + + set(SOURCES + "PointCloudGlobalMatching.cpp" + "training/CADDetectTrainer3DGlobal.cpp" + "detection/CADDetector3DGlobal.cpp" + ) + + include_directories(${OpenCV_INCLUDE_DIRS}) + include_directories(${DETECTORS_INCLUDE_DIR}) + include_directories(${DETECTORS_IMPL_DIR}) + include_directories(${COMMON_INCLUDE_DIR}) + include_directories(${COMMON_IMPL_DIR}) + include_directories(${PCL_INCLUDE_DIRS}) + + OD_ADD_LIBRARY("${SUBSYS_NAME}" SRCS ${SOURCES} LINK_WITH ${SUBSYS_DEPS}) + +endif(BUILD_GLOBAL_3D_DETECTION) \ No newline at end of file diff --git a/detectors/global3D/ODPointCloudGlobalMatching.cpp b/detectors/src/global3D/PointCloudGlobalMatching.cpp similarity index 77% rename from detectors/global3D/ODPointCloudGlobalMatching.cpp rename to detectors/src/global3D/PointCloudGlobalMatching.cpp index 91b9454b..e53ff289 100644 --- a/detectors/global3D/ODPointCloudGlobalMatching.cpp +++ b/detectors/src/global3D/PointCloudGlobalMatching.cpp @@ -18,7 +18,7 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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 @@ -27,4 +27,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Created by sarkar on 16.06.15. // -#include "ODPointCloudGlobalMatching.h" +#include "od/detectors/global3D/PointCloudGlobalMatching.h" + +namespace od { + + namespace g3d { + + int PointCloudGlobalMatching::train() + { + return trainer_->train(); + } + + int PointCloudGlobalMatching::detect(shared_ptr scene, std::vector> & detections) + { + //detector_->detect(scene, detections); + return 0; + } + + } + +} \ No newline at end of file diff --git a/detectors/src/global3D/detection/CADDetector3DGlobal.cpp b/detectors/src/global3D/detection/CADDetector3DGlobal.cpp new file mode 100644 index 00000000..525240d1 --- /dev/null +++ b/detectors/src/global3D/detection/CADDetector3DGlobal.cpp @@ -0,0 +1,59 @@ +#include "od/detectors/global3D/detection/CADDetector3DGlobal.hpp" +#include "od/common/pipeline/Detection.h" + +namespace od { + + namespace g3d { + + template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + template + void CADDetector3DGlobal::init(); + + template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr > scene); + + template + shared_ptr CADDetector3DGlobal::detect(shared_ptr > scene); + + + + template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + template + void CADDetector3DGlobal::init(); + + template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr > scene); + + template + shared_ptr CADDetector3DGlobal::detect(shared_ptr > scene); + + + + template + shared_ptr CADDetector3DGlobal::detect(shared_ptr scene); + + template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr scene); + + template + void CADDetector3DGlobal::init(); + + template + shared_ptr CADDetector3DGlobal::detectOmni(shared_ptr > scene); + + template + shared_ptr CADDetector3DGlobal::detect(shared_ptr > scene); + + } + +} \ No newline at end of file diff --git a/detectors/global3D/ODPointCloudGlobalMatching.h b/detectors/src/global3D/training/CADDetectTrainer3DGlobal.cpp similarity index 52% rename from detectors/global3D/ODPointCloudGlobalMatching.h rename to detectors/src/global3D/training/CADDetectTrainer3DGlobal.cpp index a0ec5f46..d03634b8 100644 --- a/detectors/global3D/ODPointCloudGlobalMatching.h +++ b/detectors/src/global3D/training/CADDetectTrainer3DGlobal.cpp @@ -18,7 +18,7 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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 @@ -27,52 +27,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Created by sarkar on 16.06.15. // -#ifndef OPENDETECTION_ODPOINTCLOUDGLOBALMATCHING_H -#define OPENDETECTION_ODPOINTCLOUDGLOBALMATCHING_H +#include "od/detectors/global3D/training/CADDetectTrainer3DGlobal.h" -#include -#include -#include "detectors/global3D/training/ODCADDetectTrainer3DGlobal.h" -#include "detectors/global3D/detection/ODCADDetector3DGlobal.h" +namespace od { -namespace od -{ + namespace g3d { - namespace g3d - { - /** \brief ODPointCloudGlobalMatching: global feature based object detection in point cloud - * - * \author Kripasindhu Sarkar - * - */ - - class ODPointCloudGlobalMatching : ObjectDetector + CADDetectTrainer3DGlobal::CADDetectTrainer3DGlobal(const std::string & training_input_location_, const std::string & training_data_location_): + Trainer(training_input_location_, training_data_location_) { + desc_name_ = std::string("esf"); + trained_location_identifier_ = std::string("GLOBAL3DVFH"); + } - ODPointCloudGlobalMatching() - { - } - void init() - { } + int CADDetectTrainer3DGlobal::train() + { + shared_ptr > mesh_source(new pcl::rec_3d_framework::MeshSource()); + mesh_source->setPath(training_input_location_); + mesh_source->setResolution(150); + mesh_source->setTesselationLevel(1); + mesh_source->setViewAngle(57.f); + mesh_source->setRadiusSphere(1.5f); + mesh_source->setModelScale(1.f); + std::string location = getSpecificTrainingDataLocation(); + mesh_source->generate(location); + + return 1; + } - int train() - { - return trainer_->train(); - } + const std::string & CADDetectTrainer3DGlobal::getDescName() const + { + return desc_name_; + } - int detect(ODScene *scene, std::vector detections) - { - //detector_->detect(scene, detections); - return 0; - } + void CADDetectTrainer3DGlobal::setDescName(const std::string & desc_name) + { + desc_name_ = desc_name; + } - protected: - std::string desc_name; - ODCADDetectTrainer3DGlobal *trainer_; - ODCADDetector3DGlobal *detector_; - }; } } -#endif //OPENDETECTION_ODPOINTCLOUDGLOBALMATCHING_H + + diff --git a/detectors/src/local2D/CMakeLists.txt b/detectors/src/local2D/CMakeLists.txt new file mode 100644 index 00000000..fe1d30e0 --- /dev/null +++ b/detectors/src/local2D/CMakeLists.txt @@ -0,0 +1,31 @@ +set(SUBSYS_NAME local_image_detector) +set(LIB_NAME od_${SUBSYS_NAME}) +set(SUBSYS_DESC "The local feature matching based detector") +set(SUBSYS_DEPS od_common pugixml) + +if(BUILD_LOCAL_2D_DETECTION) + + set(SOURCES + "ImageLocalMatching.cpp" + "training/CADRecogTrainerSnapshotBased.cpp" + "detection/CADRecognizer2DLocal.cpp" + "simple_ransac_detection/CsvReader.cpp" + "simple_ransac_detection/CsvWriter.cpp" + "simple_ransac_detection/ModelRegistration.cpp" + "simple_ransac_detection/Mesh.cpp" + "simple_ransac_detection/Model.cpp" + "simple_ransac_detection/PnPProblem.cpp" + "simple_ransac_detection/Utils.cpp" + "simple_ransac_detection/RobustMatcher.cpp" + ) + + include_directories(${DETECTORS_INCLUDE_DIR}) + include_directories(${CMAKE_3RDPARTY_DIR}/pugixml/src/) + include_directories(${OpenCV_INCLUDE_DIRS}) + include_directories(${COMMON_INCLUDE_DIR}) + include_directories(${COMMON_IMPL_DIR}) + include_directories(${PCL_INCLUDE_DIRS}) + + OD_ADD_LIBRARY("${SUBSYS_NAME}" SRCS ${SOURCES} LINK_WITH ${SUBSYS_DEPS}) + +endif(BUILD_LOCAL_2D_DETECTION) \ No newline at end of file diff --git a/detectors/src/local2D/ImageLocalMatching.cpp b/detectors/src/local2D/ImageLocalMatching.cpp new file mode 100644 index 00000000..545f81f3 --- /dev/null +++ b/detectors/src/local2D/ImageLocalMatching.cpp @@ -0,0 +1,90 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/ +// +// Created by sarkar on 05.06.15. +// + +#include "od/detectors/local2D/ImageLocalMatching.h" + +namespace od +{ + + namespace l2d + { + + ImageLocalMatchingTrainer::ImageLocalMatchingTrainer(const std::string & training_input_location, + const std::string & training_data_location) : + Trainer(training_input_location, training_data_location) + { + trained_location_identifier_ = std::string("FEATCORR"); + trained_data_id_ = std::string("corr.xml"); + } + + ImageLocalMatchingDetector::ImageLocalMatchingDetector(const std::string & training_data_location) : + Detector2DComplete(training_data_location) + { + trained_location_identifier_ = std::string("FEATCORR"); + trained_data_id_ = std::string(".xml"); + } + + shared_ptr ImageLocalMatching::getTrainer() const + { + return trainer_; + } + + void ImageLocalMatching::setTrainer(shared_ptr trainer) + { + trainer_ = trainer; + } + + shared_ptr ImageLocalMatching::getDetector() const + { + return detector_; + } + + void ImageLocalMatching:: setDetector(shared_ptr detector) + { + detector_ = detector; + } + + ImageLocalMatching::ImageLocalMatching() + { + trained_data_ext_ = std::string("corr.xml"); + } + + int ImageLocalMatching::train() + { + return trainer_->train(); + } + + int ImageLocalMatching::detect(shared_ptr scene, const std::vector > & detections) + { + //detector_->detect(scene, detections); + return 1; + } + } +} \ No newline at end of file diff --git a/detectors/src/local2D/detection/CADRecognizer2DLocal.cpp b/detectors/src/local2D/detection/CADRecognizer2DLocal.cpp new file mode 100644 index 00000000..523ea159 --- /dev/null +++ b/detectors/src/local2D/detection/CADRecognizer2DLocal.cpp @@ -0,0 +1,379 @@ +/* +Copyright (c) 2015, Kripasindhu Sarkar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions 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. + * Neither the name of the copyright holder(s) nor the + names of its contributors may 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 COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. +*/ +// +// Created by sarkar on 08.06.15. +// + +#include "od/detectors/local2D/detection/CADRecognizer2DLocal.h" + +namespace od +{ + namespace l2d + { + + CADRecognizer2DLocal::CADRecognizer2DLocal(const std::string & trained_data_location): + ImageLocalMatchingDetector(trained_data_location) + { + meta_info_ = true; + + camera_intrinsic_file_ = std::string("Data/out_camera_data_lion_old.yml"); // mesh + + red_ = cv::Scalar(0, 0, 255); + green_ = cv::Scalar(0, 255, 0); + blue_ = cv::Scalar(255, 0, 0); + yellow_ = cv::Scalar(0, 255, 255); + + num_key_points_ = 2000; // number of detected keypoints + ratio_test_ = 0.70f; // ratio test + fast_match_ = true; // fastRobustMatch() or robustMatch() + use_gpu_ = false; + use_gpu_match_ = false; + + iterations_count_ = 500; // number of Ransac iterations. + reprojection_error_ = 2.0; // maximum allowed distance to consider it an inlier. + confidence_ = 0.95; // ransac successful confidence. + + min_inliers_ = 30; // Kalman threshold updating + + pnp_method_ = cv::SOLVEPNP_EPNP; + f_type_default_ = SIFT; + +#ifndef WITH_BOOST_SHARED_PTR + feature_detector_ = shared_ptr(new FeatureDetector(f_type_default_)); +#else + feature_detector_ = make_shared(f_type_default_); +#endif + + } + + const std::string & CADRecognizer2DLocal::getCameraIntrinsicFile() const + { + return camera_intrinsic_file_; + } + + void CADRecognizer2DLocal::setCameraIntrinsicFile(const std::string & camera_intrinsic_file) + { + camera_intrinsic_file_ = camera_intrinsic_file; + } + + int CADRecognizer2DLocal::getNumKeyPoints() const + { + return num_key_points_; + } + + void CADRecognizer2DLocal::setNumKeyPoints(int num_key_points) + { + num_key_points_ = num_key_points; + } + + float CADRecognizer2DLocal::getRatioTest() const + { + return ratio_test_; + } + + void CADRecognizer2DLocal::setRatioTest(float ratio_test) + { + ratio_test_ = ratio_test; + } + + bool CADRecognizer2DLocal::isFastMatch() const + { + return fast_match_; + } + + void CADRecognizer2DLocal::setFastMatch(bool fast_match) + { + fast_match_ = fast_match; + } + + bool CADRecognizer2DLocal::isUseGpu() const + { + return use_gpu_; + } + + void CADRecognizer2DLocal::setUseGpu(bool use_gpu) + { + use_gpu_ = use_gpu; + } + + bool CADRecognizer2DLocal::isUseGpuMatch() const + { + return use_gpu_match_; + } + + void CADRecognizer2DLocal::setUseGpuMatch(bool use_gpu_match) + { + use_gpu_match_ = use_gpu_match; + } + + bool CADRecognizer2DLocal::isMetainfo() const + { + return meta_info_; + } + + void CADRecognizer2DLocal::setMetainfo(bool meta_info) + { + meta_info_ = meta_info; + } + + int CADRecognizer2DLocal::getIterationsCount() const + { + return iterations_count_; + } + + void CADRecognizer2DLocal::setIterationsCount(int iterations_count) + { + iterations_count_ = iterations_count; + } + + float CADRecognizer2DLocal::getReprojectionError() const + { + return reprojection_error_; + } + + void CADRecognizer2DLocal::setReprojectionError(float reprojection_error) + { + reprojection_error_ = reprojection_error; + } + + double CADRecognizer2DLocal::getConfidence() const + { + return confidence_; + } + + void CADRecognizer2DLocal::setConfidence(double confidence) + { + confidence_ = confidence; + } + + int CADRecognizer2DLocal::getMinInliers() const + { + return min_inliers_; + } + + void CADRecognizer2DLocal::setMinInliers(int min_inliers) + { + min_inliers_ = min_inliers; + } + + int CADRecognizer2DLocal::getPnpMethod() const + { + return pnp_method_; + } + + void CADRecognizer2DLocal::setPnpMethod(int pnp_method) + { + pnp_method_ = pnp_method; + } + + void CADRecognizer2DLocal::parseParameterString(const std::string & parameter_string) + { + const std::string keys = "{help h | | print this message }" + "{video v | | path to recorded video }" + "{test_images img | | image for detection }" + "{cam_id | | pass true if you want the input from the camera }" + "{camera_intrinsic_file | | yml file containing camera parameters }" + "{use_gpu | | use gpu or cpu }" + "{use_gpu_match | | use gpu or cpu for matching }" + "{keypoints k |2000 | number of keypoints to detect }" + "{ratio r |0.7 | threshold for ratio test }" + "{iterations it |500 | RANSAC maximum iterations count }" + "{error e |2.0 | RANSAC reprojection errror }" + "{confidence c |0.95 | RANSAC confidence }" + "{inliers in |30 | minimum inliers for Kalman update }" + "{method pnp |0 | PnP method: (0) ITERATIVE - (1) EPNP - (2) P3P - (3) DLS}" + "{fast f |false | use of robust fast match }" + "{metainfo meta | | provide meta information in Detection }"; + + char **argv; + int argc; + fileutils::getArgvArgc(parameter_string, &argv, argc); + + cv::CommandLineParser parser(argc, argv, keys); + if(parser.has("help")) + { + parser.printMessage(); + + } else + { + camera_intrinsic_file_ = + parser.get("camera_intrinsic_file").size() > 0 ? parser.get("camera_intrinsic_file") : camera_intrinsic_file_; + + use_gpu_ = parser.has("use_gpu"); + use_gpu_match_ = parser.has("use_gpu_match"); + num_key_points_ = !parser.has("keypoints") ? parser.get("keypoints") : num_key_points_; + ratio_test_ = !parser.has("ratio") ? parser.get("ratio") : ratio_test_; + fast_match_ = !parser.has("fast") ? parser.get("fast") : fast_match_; + iterations_count_ = !parser.has("iterations") ? parser.get("iterations") : iterations_count_; + reprojection_error_ = !parser.has("error") ? parser.get("error") : reprojection_error_; + confidence_ = !parser.has("confidence") ? parser.get("confidence") : confidence_; + min_inliers_ = !parser.has("inliers") ? parser.get("inliers") : min_inliers_; + pnp_method_ = !parser.has("method") ? parser.get("method") : pnp_method_; + meta_info_ = parser.has("metainfo"); + } + + } + + void CADRecognizer2DLocal::init() + { + cv::FileStorage fs(camera_intrinsic_file_, cv::FileStorage::READ); + cv::Mat cam_man, dist_coeff; + fs["Camera_Matrix"] >> cam_man; + fs["Distortion_Coefficients"] >> dist_coeff; + pnp_detection_ = PnPProblem(cam_man, dist_coeff); + + // get all trained models + fileutils::getFilesInDirectoryRec(getSpecificTrainingDataLocation(), trained_data_id_, model_names_); + + for(size_t i = 0; i < model_names_.size(); ++i) + { + Model model; + model.loadNewXml(model_names_[i]); + models_.push_back(model); + } + if(models_.size() > 0) + f_type_default_ = string2FeatureType(models_[0].f_type_); + +#ifndef WITH_BOOST_SHARED_PTR + feature_detector_ = shared_ptr(new FeatureDetector(f_type_default_)); +#else + feature_detector_ = make_shared(f_type_default_); +#endif + + } + + shared_ptr CADRecognizer2DLocal::detect(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr" < CADRecognizer2DLocal::detectOmni(shared_ptr scene) + { + std::cout << "not implemented, use with shared_ptr" < CADRecognizer2DLocal::detect(shared_ptr scene) + { + shared_ptr detections = detectOmni(scene); + return dynamic_pointer_cast(detections); + } + + bool CADRecognizer2DLocal::detectSingleModel(shared_ptr scene, const Model & model, shared_ptr & detection3D, + const cv::Mat & frame_vis) + { + + //reset + pnp_detection_.clearExtrinsics(); + + std::vector list_points3d_model = model.getPoints3d(); // list with model 3D coordinates + std::vector list_keypoints_model = model.getKeypoints(); // list with model 3D coordinates + cv::Mat descriptors_model = model.getDescriptors(); // list with descriptors of each 3D coordinate + + RobustMatcher rmatcher(model, use_gpu_, use_gpu_match_); // instantiate RobustMatcher + + + // -- Step 1: Robust matching between model descriptors and scene descriptors + std::vector good_matches; // to obtain the 3D points of the model + std::vector keypoints_scene = scene->getKeypoints(); // to obtain the 2D points of the scene + + cv::Mat frame = scene->getCVImage(); + + //normalize + cv::Mat scenedes = scene->getDescriptors(); + rmatcher.matchNormalized(scenedes, descriptors_model, good_matches); + //rmatcher.match(scenedes, descriptors_model, good_matches); + + if(good_matches.size() <= 0) + return false; + + std::vector list_points3d_model_match; // container for the model 3D coordinates found in the scene + std::vector list_points2d_scene_match; // container for the model 2D coordinates found in the scene + + for(size_t match_index = 0; match_index < good_matches.size(); ++match_index) + { + cv::Point3f point3d_model = list_points3d_model[good_matches[match_index].trainIdx]; // 3D point from model + cv::Point2f point2d_scene = keypoints_scene[good_matches[match_index].queryIdx].pt; // 2D point from the scene + + list_points3d_model_match.push_back(point3d_model); // add 3D point + list_points2d_scene_match.push_back(point2d_scene); // add 2D point + } + + + cv::Mat inliers_idx; + + // -- Step 3: Estimate the pose using RANSAC approach + pnp_detection_.estimatePoseRANSAC(list_points3d_model_match, list_points2d_scene_match, pnp_method_, inliers_idx, + iterations_count_, reprojection_error_, confidence_); + + if(inliers_idx.rows < min_inliers_) + return false; + + std::cout << "Recognized: " << model.id_ << std::endl; + //else everything is fine; report the detection + if(!detection3D) + detection3D = make_shared(); + detection3D->setLocation(pnp_detection_.getTMatrix()); + detection3D->setPose(pnp_detection_.getRMatrix()); + detection3D->setType(detection::RECOGNITION); + detection3D->setId(model.id_); + + return true; + } + + shared_ptr CADRecognizer2DLocal::detectOmni(shared_ptr scene) + { + + std::vector keypoints_scene; + cv::Mat descriptor_scene; + feature_detector_->computeKeypointsAndDescriptors(scene->getCVImage(), descriptor_scene, keypoints_scene); + scene->setDescriptors(descriptor_scene); + scene->setKeypoints(keypoints_scene); + + shared_ptr detections = make_shared(); + cv::Mat viz = scene->getCVImage().clone(); + + for(size_t i = 0; i < models_.size(); ++i) + { + + shared_ptr detection = make_shared(); + if(detectSingleModel(scene, models_[i], detection, viz)) + { + detections->push_back(detection); + + if(meta_info_) + drawModel(viz, models_[i], pnp_detection_.getRVect(), pnp_detection_.getTMatrix(), pnp_detection_.getAMatrix(), + pnp_detection_.getDistCoef(), yellow_); + } + } + detections->setMetainfoImage(viz); + return detections; + } + + } +} \ No newline at end of file diff --git a/detectors/src/local2D/simple_ransac_detection/CsvReader.cpp b/detectors/src/local2D/simple_ransac_detection/CsvReader.cpp new file mode 100644 index 00000000..887a5b52 --- /dev/null +++ b/detectors/src/local2D/simple_ransac_detection/CsvReader.cpp @@ -0,0 +1,88 @@ +#include "od/detectors/local2D/simple_ransac_detection/CsvReader.h" + +namespace od { + + namespace l2d { + + /** The default constructor of the CSV reader Class */ + CsvReader::CsvReader(const std::string & path, const std::string & separator){ + file_.open(path.c_str(), std::ifstream::in); + separator_ = separator; + } + + /* Read a plane text file with .ply format */ + void CsvReader::readPLY(std::vector & list_vertex, std::vector > & list_triangles) + { + std::string line, tmp_str, n; + int num_vertex = 0, num_triangles = 0; + int count = 0; + bool end_header = false; + bool end_vertex = false; + + // Read the whole *.ply file + while(getline(file_, line)) { + std::stringstream liness(line); + + // read header + if(!end_header) + { + getline(liness, tmp_str, *separator_.c_str()); + if(tmp_str == "element") + { + getline(liness, tmp_str, *separator_.c_str()); + getline(liness, n); + if(tmp_str == "vertex") + num_vertex = std::stoi(n); + if(tmp_str == "face") + num_triangles = std::stoi(n); + } + if(tmp_str == "end_header") + end_header = true; + } + + // read file content + else if(end_header) + { + // read vertex and add into 'list_vertex' + if(!end_vertex && count < num_vertex) + { + std::string x, y, z; + getline(liness, x, *separator_.c_str()); + getline(liness, y, *separator_.c_str()); + getline(liness, z); + + cv::Point3f tmp_p; + tmp_p.x = atof(x.c_str()); + tmp_p.y = atof(y.c_str()); + tmp_p.z = atof(z.c_str()); + list_vertex.push_back(tmp_p); + + count++; + if(count == num_vertex) + { + count = 0; + end_vertex = !end_vertex; + } + } + // read faces and add into 'list_triangles' + else if(end_vertex && count < num_triangles) + { + std::string num_pts_per_face, id0, id1, id2; + getline(liness, num_pts_per_face, *separator_.c_str()); + getline(liness, id0, *separator_.c_str()); + getline(liness, id1, *separator_.c_str()); + getline(liness, id2); + + std::vector tmp_triangle(3); + tmp_triangle[0] = std::stoi(id0); + tmp_triangle[1] = std::stoi(id1); + tmp_triangle[2] = std::stoi(id2); + list_triangles.push_back(tmp_triangle); + + count++; + } + } + } + } + } +} \ No newline at end of file diff --git a/detectors/src/local2D/simple_ransac_detection/CsvWriter.cpp b/detectors/src/local2D/simple_ransac_detection/CsvWriter.cpp new file mode 100644 index 00000000..6737bd7d --- /dev/null +++ b/detectors/src/local2D/simple_ransac_detection/CsvWriter.cpp @@ -0,0 +1,56 @@ +#include "od/detectors/local2D/simple_ransac_detection/CsvWriter.h" + +namespace od { + + namespace l2d { + + CsvWriter::CsvWriter(const std::string & path, const std::string & separator){ + file_.open(path.c_str(), std::ofstream::out); + is_first_term_ = true; + separator_ = separator; + } + + CsvWriter::~CsvWriter() { + file_.flush(); + file_.close(); + } + + void CsvWriter::writeXYZ(const std::vector & list_points3d) + { + std::string x, y, z; + for(size_t i = 0; i < list_points3d.size(); ++i) + { + x = std::to_string(list_points3d[i].x); + y = std::to_string(list_points3d[i].y); + z = std::to_string(list_points3d[i].z); + + file_ << x << separator_ << y << separator_ << z << std::endl; + } + + } + + void CsvWriter::writeUVXYZ(const std::vector & list_points3d, const std::vector & list_points2d, const cv::Mat & descriptors) + { + std::string u, v, x, y, z, descriptor_str; + for(size_t i = 0; i < list_points3d.size(); ++i) + { + u = std::to_string(list_points2d[i].x); + v = std::to_string(list_points2d[i].y); + x = std::to_string(list_points3d[i].x); + y = std::to_string(list_points3d[i].y); + z = std::to_string(list_points3d[i].z); + + file_ << u << separator_ << v << separator_ << x << separator_ << y << separator_ << z; + + for(size_t j = 0; j < 32; ++j) + { + descriptor_str = std::to_string(descriptors.at(i,j)); + file_ << separator_ << descriptor_str; + } + file_ << std::endl; + } + } + + } + +} \ No newline at end of file diff --git a/detectors/src/local2D/simple_ransac_detection/Mesh.cpp b/detectors/src/local2D/simple_ransac_detection/Mesh.cpp new file mode 100644 index 00000000..77efba26 --- /dev/null +++ b/detectors/src/local2D/simple_ransac_detection/Mesh.cpp @@ -0,0 +1,112 @@ +/* + * Mesh.cpp + * + * Created on: Apr 9, 2014 + * Author: edgar + */ + +#include "od/detectors/local2D/simple_ransac_detection/Mesh.h" + +namespace od { + + namespace l2d { + + // --------------------------------------------------- // + // TRIANGLE CLASS // + // --------------------------------------------------- // + + /** The custom constructor of the Triangle Class */ + Triangle::Triangle(int id, const cv::Point3f & V0, const cv::Point3f & V1, const cv::Point3f & V2) + { + id_ = id; v0_ = V0; v1_ = V1; v2_ = V2; + } + + cv::Point3f Triangle::getV0() const { + return v0_; + } + cv::Point3f Triangle::getV1() const { + return v1_; + } + cv::Point3f Triangle::getV2() const { + return v2_; + } + + + + // --------------------------------------------------- // + // RAY CLASS // + // --------------------------------------------------- // + + /** The custom constructor of the Ray Class */ + Ray::Ray(const cv::Point3f & P0, const cv::Point3f & P1) { + p0_ = P0; p1_ = P1; + } + + cv::Point3f Ray::getP0() + { + return p0_; + } + cv::Point3f Ray::getP1() + { + return p1_; + } + + + + // --------------------------------------------------- // + // OBJECT MESH CLASS // + // --------------------------------------------------- // + + /** The default constructor of the ObjectMesh Class */ + Mesh::Mesh() : list_vertex_(0) , list_triangles_(0) + { + id_ = 0; + num_vertexs_ = 0; + num_triangles_ = 0; + } + + + + std::vector > Mesh::getTrianglesList() const + { + return list_triangles_; + } + + std::vector Mesh::getVertices() + { + return list_vertex_; + } + + cv::Point3f Mesh::getVertex(int pos) const + { + return list_vertex_[pos]; + } + + int Mesh::getNumVertices() const + { + return num_vertexs_; + } + + /** Load a CSV with *.ply format **/ + void Mesh::load(const std::string & path) + { + + // Create the reader + CsvReader csvReader(path); + + // Clear previous data + list_vertex_.clear(); + list_triangles_.clear(); + + // Read from .ply file + csvReader.readPLY(list_vertex_, list_triangles_); + + // Update mesh attributes + num_vertexs_ = (int)list_vertex_.size(); + num_triangles_ = (int)list_triangles_.size(); + + } + + } + +} \ No newline at end of file diff --git a/detectors/src/local2D/simple_ransac_detection/Model.cpp b/detectors/src/local2D/simple_ransac_detection/Model.cpp new file mode 100644 index 00000000..1b14adc7 --- /dev/null +++ b/detectors/src/local2D/simple_ransac_detection/Model.cpp @@ -0,0 +1,209 @@ +/* + * Model.cpp + * + * Created on: Apr 9, 2014 + * Author: edgar + */ + + +#include "od/detectors/local2D/simple_ransac_detection/Model.h" + +namespace od { + + namespace l2d { + + std::vector Model::getPoints2dIn() const + { + return list_points2d_in_; + } + + std::vector Model::getPoints2dOut() const + { + return list_points2d_out_; + } + + std::vector Model::getPoints3d() const + { + return list_points3d_in_; + } + + std::vector Model::getKeypoints() const + { + return list_keypoints_; + } + + cv::Mat Model::getDescriptors() const + { + return descriptors_; + } + + int Model::getNumDescriptors() const + { + return descriptors_.rows; + } + + Model::Model() : list_points2d_in_(0), list_points2d_out_(0), list_points3d_in_(0) + { + n_correspondences_ = 0; + } + + Model::~Model() + { + // TO Auto-generated destructor stub + } + + void Model::addCorrespondence(const cv::Point2f & point2d, const cv::Point3f & point3d) + { + list_points2d_in_.push_back(point2d); + list_points3d_in_.push_back(point3d); + n_correspondences_++; + } + + void Model::addOutlier(const cv::Point2f & point2d) + { + list_points2d_out_.push_back(point2d); + } + + void Model::addDescriptor(const cv::Mat & descriptor) + { + descriptors_.push_back(descriptor); + } + + void Model::addKeypoint(const cv::KeyPoint & kp) + { + list_keypoints_.push_back(kp); + } + + + /** Save a CSV file and fill the object mesh */ + void Model::save(const std::string & path) + { + cv::Mat points3dmatrix = cv::Mat(list_points3d_in_); + cv::Mat points2dmatrix = cv::Mat(list_points2d_in_); + //cv::Mat keyPointmatrix = cv::Mat(list_keypoints_); + + cv::FileStorage storage(path, cv::FileStorage::WRITE); + storage << "points_3d" << points3dmatrix; + storage << "points_2d" << points2dmatrix; + storage << "keypoints" << list_keypoints_; + storage << "descriptors" << descriptors_; + + storage.release(); + } + + /** Load a YAML file using OpenCv functions **/ + void Model::load(const std::string & path) + { + cv::Mat points3d_mat; + + cv::FileStorage storage(path, cv::FileStorage::READ); + storage["points_3d"] >> points3d_mat; + storage["descriptors"] >> descriptors_; + + points3d_mat.copyTo(list_points3d_in_); + + std::cout << list_points3d_in_.size() << std::endl; + std::cout << descriptors_; + storage.release(); + id_ = path; + } + + void Model::loadNewDesc(const std::string & path) + { + f_type_ = "SIFT"; + + std::fstream infile(path.c_str()); + if(!infile.is_open()) + { + std::cout << "ERRROR opening model file!!"; + return ; + + } + unsigned int nop, desc_size, point_size; + infile >> nop; + infile >> point_size >> desc_size; + + descriptors_ = cv::Mat(nop, desc_size, CV_32FC1); + + for(size_t i = 0; i < nop; ++i) + { + + float x, y, z; + infile >> x >> y >> z; + cv::Point3f p3d(x, y, z); + list_points3d_in_.push_back(p3d); + + cv::KeyPoint kp; + infile >> kp.pt.x >> kp.pt.y >> kp.octave >> kp.angle >> kp.response >> kp.size; + list_keypoints_.push_back(kp); + + for(size_t j = 0; j < desc_size; ++j) + { + infile >> descriptors_.at(i, j); + } + } + id_ = path; + } + + unsigned int Model::getDescriptorSize() + { + //if (f_type == "SIFT") + //return 128; + return 128; + } + + void Model::loadNewXml(const std::string & path) + { + + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(path.c_str()); + + if (!result) + { + std::cout << "ERRROR opening model file!!"; + return ; + + } + pugi::xml_node pts_node = doc.child("Model").child("Points"); + + if (pts_node.first_child()) + f_type_ = pts_node.first_child().attribute("desc_type").as_string(); + else return; + + + for(pugi::xml_node pt_node = pts_node.first_child(); pt_node; pt_node = pt_node.next_sibling()) + { + cv::Mat single_desc = cv::Mat::zeros(1, getDescriptorSize(), CV_32FC1); + std::stringstream ss; + ss.str(pt_node.attribute("p3d").as_string()); + float x, y, z; + ss >> x >> y >> z; ss.clear(); + cv::Point3f p3d(x, y, z); + list_points3d_in_.push_back(p3d); + + ss.str(pt_node.attribute("p2d_prop").as_string()); + cv::KeyPoint kp; + ss >> kp.pt.x >> kp.pt.y >> kp.octave >> kp.angle >> kp.response >> kp.size; ss.clear(); + list_keypoints_.push_back(kp); + + ss.str(pt_node.attribute("desc").as_string()); + float d; + for(size_t it = 0; it < getDescriptorSize(); it ++) + { + ss >> d; + //cout < (0, it) = d; + } + ss.clear(); + + descriptors_.push_back(single_desc); + } + + id_ = path; + //std::cout << list_points3d_in_.size() << endl; + //std::cout << descriptors_; + } + + } + +} \ No newline at end of file diff --git a/detectors/src/local2D/simple_ransac_detection/ModelRegistration.cpp b/detectors/src/local2D/simple_ransac_detection/ModelRegistration.cpp new file mode 100644 index 00000000..bf6905d2 --- /dev/null +++ b/detectors/src/local2D/simple_ransac_detection/ModelRegistration.cpp @@ -0,0 +1,73 @@ +/* + * ModelRegistration.cpp + * + * Created on: Apr 18, 2014 + * Author: edgar + */ + +#include "od/detectors/local2D/simple_ransac_detection/ModelRegistration.h" + +namespace od { + + namespace l2d { + + void ModelRegistration::setNumMax(int n) + { + max_registrations_ = n; + } + + std::vector ModelRegistration::getPoints2d() const + { + return list_points2d_; + } + + std::vector ModelRegistration::getPoints3d() const + { + return list_points3d_; + } + + int ModelRegistration::getNumMax() const + { + return max_registrations_; + } + + int ModelRegistration::getNumRegist() const + { + return n_registrations_; + } + + bool ModelRegistration::isRegistrable() const + { + return n_registrations_ < max_registrations_; + } + + ModelRegistration::ModelRegistration() + { + n_registrations_ = 0; + max_registrations_ = 0; + } + + ModelRegistration::~ModelRegistration() + { + // TO Auto-generated destructor stub + } + + void ModelRegistration::registerPoint(const cv::Point2f & point2d, const cv::Point3f & point3d) + { + // add correspondence at the end of the vector + list_points2d_.push_back(point2d); + list_points3d_.push_back(point3d); + n_registrations_++; + } + + void ModelRegistration::reset() + { + n_registrations_ = 0; + max_registrations_ = 0; + list_points2d_.clear(); + list_points3d_.clear(); + } + + } + +} diff --git a/detectors/src/local2D/simple_ransac_detection/PnPProblem.cpp b/detectors/src/local2D/simple_ransac_detection/PnPProblem.cpp new file mode 100644 index 00000000..532a2b91 --- /dev/null +++ b/detectors/src/local2D/simple_ransac_detection/PnPProblem.cpp @@ -0,0 +1,373 @@ +/* + * PnPProblem.cpp + * + * Created on: Mar 28, 2014 + * Author: Edgar Riba + */ + +#include "od/detectors/local2D/simple_ransac_detection/PnPProblem.h" + +namespace od { + + namespace l2d { + + /* Functions headers */ + + /* Functions for Möller–Trumbore intersection algorithm */ + + cv::Point3f PnPProblem::CROSS(const cv::Point3f & v1, const cv::Point3f & v2) + { + cv::Point3f tmp_p; + tmp_p.x = v1.y*v2.z - v1.z*v2.y; + tmp_p.y = v1.z*v2.x - v1.x*v2.z; + tmp_p.z = v1.x*v2.y - v1.y*v2.x; + return tmp_p; + } + + double PnPProblem::DOT(const cv::Point3f & v1, const cv::Point3f & v2) + { + return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; + } + + cv::Point3f PnPProblem::SUB(const cv::Point3f & v1, const cv::Point3f & v2) + { + cv::Point3f tmp_p; + tmp_p.x = v1.x - v2.x; + tmp_p.y = v1.y - v2.y; + tmp_p.z = v1.z - v2.z; + return tmp_p; + } + + cv::Mat PnPProblem::getAMatrix() const + { + return a_matrix_; + } + + cv::Mat PnPProblem::getDistCoef() const + { + return dist_; + } + + cv::Mat PnPProblem::getRMatrix() const + { + return r_matrix_; + } + + cv::Mat PnPProblem::getRVect() const + { + return r_vect_; + } + + cv::Mat PnPProblem::getTMatrix() const + { + return t_matrix_; + } + + cv::Mat PnPProblem::getPMatrix() const + { + return p_matrix_; + } + + void PnPProblem::clearExtrinsics() + { + r_matrix_ = cv::Mat::zeros(3, 3, CV_64FC1); // rotation matrix + t_matrix_ = cv::Mat::zeros(3, 1, CV_64FC1); // translation matrix + p_matrix_ = cv::Mat::zeros(3, 4, CV_64FC1); + } + + /* End functions for Möller–Trumbore intersection algorithm + * */ + + // Function to get the nearest 3D point to the Ray origin + cv::Point3f PnPProblem::getNearest3DPoint(std::vector & points_list, const cv::Point3f & origin) + { + cv::Point3f p1 = points_list[0]; + cv::Point3f p2 = points_list[1]; + + double d1 = std::sqrt( std::pow(p1.x-origin.x, 2) + std::pow(p1.y-origin.y, 2) + std::pow(p1.z-origin.z, 2) ); + double d2 = std::sqrt( std::pow(p2.x-origin.x, 2) + std::pow(p2.y-origin.y, 2) + std::pow(p2.z-origin.z, 2) ); + + if(d1 < d2) + { + return p1; + } + else + { + return p2; + } + } + + // Custom constructor given the intrinsic camera parameters + + PnPProblem::PnPProblem(double const params[], double const dists[]) + { + a_matrix_ = cv::Mat::zeros(3, 3, CV_64FC1); // intrinsic camera parameters + a_matrix_.at(0, 0) = params[0]; // [ fx 0 cx ] + a_matrix_.at(1, 1) = params[1]; // [ 0 fy cy ] + a_matrix_.at(0, 2) = params[2]; // [ 0 0 1 ] + a_matrix_.at(1, 2) = params[3]; + a_matrix_.at(2, 2) = 1; + dist_ = cv::Mat::zeros(4, 1, CV_64FC1); + dist_.at(0,0) = dists[0]; dist_.at(1,0) = dists[1]; dist_.at(2,0) = dists[2]; dist_.at(3,0) = dists[3]; + + r_matrix_ = cv::Mat::zeros(3, 3, CV_64FC1); // rotation matrix + t_matrix_ = cv::Mat::zeros(3, 1, CV_64FC1); // translation matrix + p_matrix_ = cv::Mat::zeros(3, 4, CV_64FC1); // rotation-translation matrix + + } + + PnPProblem::PnPProblem(const cv::Mat & intrin, const cv::Mat & dist) { + intrin.copyTo(a_matrix_); + dist.copyTo(dist_); + + r_matrix_ = cv::Mat::zeros(3, 3, CV_64FC1); // rotation matrix + t_matrix_ = cv::Mat::zeros(3, 1, CV_64FC1); // translation matrix + p_matrix_ = cv::Mat::zeros(3, 4, CV_64FC1); // rotation-translation matrix + } + + + PnPProblem::~PnPProblem() + { + // TO Auto-generated destructor stub + } + + void PnPProblem::setPMatrix(const cv::Mat & r_matrix, const cv::Mat & t_matrix) + { + // Rotation-Translation Matrix Definition + p_matrix_.at(0,0) = r_matrix.at(0,0); + p_matrix_.at(0,1) = r_matrix.at(0,1); + p_matrix_.at(0,2) = r_matrix.at(0,2); + p_matrix_.at(1,0) = r_matrix.at(1,0); + p_matrix_.at(1,1) = r_matrix.at(1,1); + p_matrix_.at(1,2) = r_matrix.at(1,2); + p_matrix_.at(2,0) = r_matrix.at(2,0); + p_matrix_.at(2,1) = r_matrix.at(2,1); + p_matrix_.at(2,2) = r_matrix.at(2,2); + + p_matrix_.at(0,3) = t_matrix.at(0); + p_matrix_.at(1,3) = t_matrix.at(1); + p_matrix_.at(2,3) = t_matrix.at(2); + + } + + + // Estimate the pose given a list of 2D/3D correspondences and the method to use + bool PnPProblem::estimatePose(const std::vector & list_points3d, + const std::vector & list_points2d, + int flags) + { + //cv::Mat distCoeffs = cv::Mat::zeros(4, 1, CV_64FC1); + cv::Mat rvec = cv::Mat::zeros(3, 1, CV_64FC1); + cv::Mat tvec = cv::Mat::zeros(3, 1, CV_64FC1); + + bool use_extrinsic_guess = false; + + // Pose estimation + bool correspondence = cv::solvePnP(list_points3d, list_points2d, a_matrix_, dist_, rvec, tvec, + use_extrinsic_guess, flags); + + // Transforms Rotation Vector to Matrix + cv::Rodrigues(rvec, r_matrix_); + t_matrix_ = tvec; + + // Set projection matrix + setPMatrix(r_matrix_, t_matrix_); + + return correspondence; + } + + // Estimate the pose given a list of 2D/3D correspondences with RANSAC and the method to use + + void PnPProblem::estimatePoseRANSAC( const std::vector & list_points3d, // list with model 3D coordinates + const std::vector & list_points2d, // list with scene 2D coordinates + int flags, const cv::Mat & inliers, int iterations_count, // PnP method; inliers container + float reprojection_error, double confidence) // Ransac parameters + { + //cv::Mat distCoeffs = cv::Mat::zeros(4, 1, CV_64FC1); // vector of distortion coefficients + cv::Mat rvec = cv::Mat::zeros(3, 1, CV_64FC1); // output rotation vector + cv::Mat tvec = cv::Mat::zeros(3, 1, CV_64FC1); // output translation vector + + bool use_extrinsic_guess = false; // if true the function uses the provided rvec and tvec values as + // initial approximations of the rotation and translation vectors + + cv::solvePnPRansac(list_points3d, list_points2d, a_matrix_, dist_, rvec, tvec, + use_extrinsic_guess, iterations_count, reprojection_error, confidence, + inliers, flags ); + + rvec.copyTo(r_vect_); + Rodrigues(rvec, r_matrix_); // converts Rotation Vector to Matrix + t_matrix_ = tvec; // set translation matrix + + setPMatrix(r_matrix_, t_matrix_); // set rotation-translation matrix + + } + + // Given the mesh, backproject the 3D points to 2D to verify the pose estimation + std::vector PnPProblem::verifyPoints(shared_ptr mesh) + { + std::vector verified_points_2d; + for(int i = 0; i < mesh->getNumVertices(); ++i) + { + cv::Point3f point3d = mesh->getVertex(i); + cv::Point2f point2d = backproject3DPoint(point3d); + verified_points_2d.push_back(point2d); + } + + return verified_points_2d; + } + + + // Backproject a 3D point to 2D using the estimated pose parameters + + cv::Point2f PnPProblem::backproject3DPoint(const cv::Point3f & point3d) + { + // 3D point vector [x y z 1]' + cv::Mat point3d_vec = cv::Mat(4, 1, CV_64FC1); + point3d_vec.at(0) = point3d.x; + point3d_vec.at(1) = point3d.y; + point3d_vec.at(2) = point3d.z; + point3d_vec.at(3) = 1; + + // 2D point vector [u v 1]' + cv::Mat point2d_vec = cv::Mat(4, 1, CV_64FC1); + point2d_vec = a_matrix_ * p_matrix_ * point3d_vec; + + // Normalization of [u v]' + cv::Point2f point2d; + point2d.x = static_cast(point2d_vec.at(0) / point2d_vec.at(2)); + point2d.y = static_cast(point2d_vec.at(1) / point2d_vec.at(2)); + + return point2d; + } + + // Back project a 2D point to 3D and returns if it's on the object surface + bool PnPProblem::backproject2DPoint(shared_ptr mesh, const cv::Point2f & point2d, cv::Point3f & point3d) + { + // Triangles list of the object mesh + std::vector > triangles_list = mesh->getTrianglesList(); + + double lambda = 8; + double u = point2d.x; + double v = point2d.y; + + // Point in vector form + cv::Mat point2d_vec = cv::Mat::ones(3, 1, CV_64F); // 3x1 + point2d_vec.at(0) = u * lambda; + point2d_vec.at(1) = v * lambda; + point2d_vec.at(2) = lambda; + + // Point in camera coordinates + cv::Mat x_c = a_matrix_.inv() * point2d_vec ; // 3x1 + + // Point in world coordinates + cv::Mat x_w = r_matrix_.inv() * ( x_c - t_matrix_); // 3x1 + + // Center of projection + cv::Mat c_op = cv::Mat(r_matrix_.inv()).mul(-1) * t_matrix_; // 3x1 + + // Ray direction vector + cv::Mat ray = x_w - c_op; // 3x1 + ray = ray / cv::norm(ray); // 3x1 + + // Set up Ray + Ray r((cv::Point3f)c_op, (cv::Point3f)ray); + + // A vector to store the intersections found + std::vector intersections_list; + + // Loop for all the triangles and check the intersection + for(size_t i = 0; i < triangles_list.size(); ++i) + { + cv::Point3f V0 = mesh->getVertex(triangles_list[i][0]); + cv::Point3f V1 = mesh->getVertex(triangles_list[i][1]); + cv::Point3f V2 = mesh->getVertex(triangles_list[i][2]); + + Triangle t(i, V0, V1, V2); + + double out; + if(intersectMollerTrumbore(r, t, out)) + { + cv::Point3f tmp_pt = r.getP0() + out*r.getP1(); // P = O + t*D + intersections_list.push_back(tmp_pt); + } + } + + // If there are intersection, find the nearest one + if (!intersections_list.empty()) + { + point3d = getNearest3DPoint(intersections_list, r.getP0()); + return true; + } + else + { + return false; + } + } + + // Möller–Trumbore intersection algorithm + bool PnPProblem::intersectMollerTrumbore(Ray & ray, Triangle & triangle, double & out) + { + const double EPSILON = 0.000001; + + cv::Point3f e1, e2; + cv::Point3f P, Q, T; + double det, inv_det, u, v; + double t; + + cv::Point3f V1 = triangle.getV0(); // Triangle vertices + cv::Point3f V2 = triangle.getV1(); + cv::Point3f V3 = triangle.getV2(); + + cv::Point3f O = ray.getP0(); // Ray origin + cv::Point3f D = ray.getP1(); // Ray direction + + //Find vectors for two edges sharing V1 + e1 = SUB(V2, V1); + e2 = SUB(V3, V1); + + // Begin calculation determinant - also used to calculate U parameter + P = CROSS(D, e2); + + // If determinant is near zero, ray lie in plane of triangle + det = DOT(e1, P); + + //NOT CULLING + if(det > -EPSILON && det < EPSILON) + return false; + + inv_det = 1.f / det; + + //calculate distance from V1 to ray origin + T = SUB(O, V1); + + //Calculate u parameter and test bound + u = DOT(T, P) * inv_det; + + //The intersection lies outside of the triangle + if(u < 0.f || u > 1.f) + return false; + + //Prepare to test v parameter + Q = CROSS(T, e1); + + //Calculate V parameter and test bound + v = DOT(D, Q) * inv_det; + + //The intersection lies outside of the triangle + if(v < 0.f || u + v > 1.f) + return false; + + t = DOT(e2, Q) * inv_det; + + if(t > EPSILON) { //ray intersection + out = t; + return true; + } + + // No hit, no win + return false; + } + + } + +} \ No newline at end of file diff --git a/detectors/src/local2D/simple_ransac_detection/RobustMatcher.cpp b/detectors/src/local2D/simple_ransac_detection/RobustMatcher.cpp new file mode 100644 index 00000000..c5b4b265 --- /dev/null +++ b/detectors/src/local2D/simple_ransac_detection/RobustMatcher.cpp @@ -0,0 +1,322 @@ +/* + * RobustMatcher.cpp + * + * Created on: Jun 4, 2014 + * Author: eriba + */ + +#include "od/detectors/local2D/simple_ransac_detection/RobustMatcher.h" + +namespace od { + + namespace l2d { + +/* + void convertToUnsignedSiftGPU(const cv::Mat & cv_des, std::vector & siftgpu_des) + { + siftgpu_des.resize(cv_des.rows * 128); + + int desi = 0; + + for (int i = 0; i < cv_des.rows; i++){ + for (int j = 0; j < 128; j++, desi++) + siftgpu_des[desi] = (unsigned char)cv_des.at(i,j); + } + } + + void convertToDmatch(int siftgpu_matches[][2], unsigned int num_match, std::vector & cv_matches) + { + cv_matches.resize(num_match); + for(size_t i = 0; i < num_match; ++i) + { + //How to get the feature matches: + //SiftGPU::SiftKeypoint & key1 = keys1[match_buf[i][0]]; + //SiftGPU::SiftKeypoint & key2 = keys2[match_buf[i][1]]; + //key1 in the first image matches with key2 in the second image + cv_matches[i].trainIdx = siftgpu_matches[i][0]; //Assigned first at init + cv_matches[i].queryIdx = siftgpu_matches[i][1]; + } + } + + void getGoodMatches(const std::vector > & matches, std::vector & goodMatches) + { + for (std::vector >::const_iterator + matchIterator1 = matches.begin(); matchIterator1 != matches.end(); ++matchIterator1) + { + // ignore deleted matches + if (matchIterator1->empty() || matchIterator1->size() < 2) + continue; + if ((*matchIterator1)[0].distance < (*matchIterator1)[1].distance) + goodMatches.push_back((*matchIterator1)[0]); + } + } +*/ + + // Set the feature detector + void RobustMatcher::setFeatureDetector(shared_ptr detect) + { + detector_ = detect; + } + + // Set the descriptor extractor + void RobustMatcher::setDescriptorExtractor(shared_ptr desc) + { + extractor_ = desc; + } + + // Set the matcher + void RobustMatcher::setDescriptorMatcher(shared_ptr match) + { + matcher_ = match; + } + + void RobustMatcher::instantiateMatcher(const Model & model, bool use_gpu) + { + + if (use_gpu_ == true) { + + //####GPU + + //1. for SIFT + matcher_gpu_ = cv::cuda::DescriptorMatcher::createBFMatcher(cv::NORM_L2); + cv::cuda::GpuMat train_descriptors(model.getDescriptors()); + matcher_gpu_->add(std::vector(1, train_descriptors)); + std::cout << "GPU matcher instantiated ..." << std::endl; + + } + else + { + matcher_ = make_shared(); + } + } + + RobustMatcher::RobustMatcher(const Model & model, bool use_gpu, bool use_gpu_match) + { + + use_gpu_ = use_gpu_match; + + // ORB is the default feature + ratio_ = 0.8f; + detector_ = shared_ptr(cv::ORB::create().get()); + extractor_ = shared_ptr(cv::ORB::create().get()); + + instantiateMatcher(model, use_gpu_match); + + // // BruteFroce matcher with Norm Hamming is the default matcher + // //matcher_ = cv::makePtr((int)cv::NORM_HAMMING, false); + // //matcher_ = cv::makePtr((int)cv::NORM_L2, false); + // + // + // //####################TEMPORARY CE BELOW!!!!!!!!!!!!!!!!!!!!!!!! + // + // cv::Ptr indexParams = cv::makePtr(6, 12, 1); // instantiate LSH index parameters + // cv::Ptr searchParams = cv::makePtr(50); // instantiate flann search parameters + // // instantiate FlannBased matcher + // //Ptr matcher = makePtr(indexParams, searchParams); + // //matcher_ = cv::makePtr(indexParams, searchParams); + // matcher_ = cv::makePtr(); + + } + + RobustMatcher::~RobustMatcher() + { + // TO Auto-generated destructor stub + } + + void RobustMatcher::computeKeyPoints(const cv::Mat & image, std::vector & keypoints) + { + detector_->detect(image, keypoints); + } + + void RobustMatcher::computeDescriptors(const cv::Mat & image, std::vector & keypoints, cv::Mat & descriptors) + { + extractor_->compute(image, keypoints, descriptors); + } + + int RobustMatcher::ratioTest(std::vector > & matches) + { + int removed = 0; + // for all matches + for(auto & match : matches) + { + // if 2 NN have been identified + if(match.size() > 1) + { + // check distance ratio + if(match[0].distance / match[1].distance > ratio_) + { + match.clear(); // remove match + removed++; + } + } + else + { // does not have 2 neighbours + match.clear(); // remove match + removed++; + } + } + return removed; + } + + void RobustMatcher::setRatio(float rat) + { + ratio_ = rat; + } + + void RobustMatcher::symmetryTest(const std::vector > & matches1, + const std::vector >& matches2, + std::vector & symMatches ) + { + + // for all matches image 1 -> image 2 + for(auto & match1 : matches1) + { + // ignore deleted matches + if(match1.empty() || match1.size() < 2) + continue; + + // for all matches image 2 -> image 1 + for(auto & match2 : matches2) + { + // ignore deleted matches + if(match2.empty() || match2.size() < 2) + continue; + + // Match symmetry test + if(match1[0].queryIdx == match2[0].trainIdx && match2[0].queryIdx == match1[0].trainIdx) + { + // add symmetrical match + symMatches.push_back(cv::DMatch(match1[0].queryIdx, match1[0].trainIdx, match1[0].distance)); + break; // next match in image 1 -> image 2 + } + } + } + + } + + void RobustMatcher::match(const cv::Mat & descriptors_frame, const cv::Mat & descriptors_model, std::vector & good_matches) + { + std::vector > matches; + + if(use_gpu_) + { + matcher_gpu_->knnMatch(cv::cuda::GpuMat(descriptors_frame), matches, 2); // return 2 nearest neighbours + }else{ + matcher_->knnMatch(descriptors_frame, descriptors_model, matches, 2); // return 2 nearest neighbours + } + + ratioTest(matches); + // 4. Fill good matches container + for(auto & match : matches) + { + good_matches.push_back(match[0]); + } + + } + + void RobustMatcher::matchNormalized(cv::Mat & descriptors_frame, cv::Mat & descriptors_model, std::vector & good_matches) + { + od::normL2(descriptors_frame); + od::normL2(descriptors_model); + match(descriptors_frame, descriptors_model, good_matches); + } + + void RobustMatcher::robustMatch(const cv::Mat & frame, std::vector & good_matches, + std::vector & keypoints_frame, const cv::Mat & descriptors_model ) + { + // 1a. Detection of the ORB features + //this->computeKeyPoints(frame, keypoints_frame); + + // 1b. Extraction of the ORB descriptors + cv::Mat descriptors_frame; + //this->computeDescriptors(frame, keypoints_frame, descriptors_frame); + + featureDetector_->computeKeypointsAndDescriptors(frame, descriptors_frame, keypoints_frame); + //cout << "After Restacking: \n" << descriptors_frame << endl; + // 2. Match the two image descriptors + std::vector > matches12, matches21; + + // 2a. From image 1 to image 2 + matcher_->knnMatch(descriptors_frame, descriptors_model, matches12, 2); // return 2 nearest neighbours + + // 2b. From image 2 to image 1 + matcher_->knnMatch(descriptors_model, descriptors_frame, matches21, 2); // return 2 nearest neighbours + + // 3. Remove matches for which NN ratio is > than threshold + // clean image 1 -> image 2 matches + ratioTest(matches12); + // clean image 2 -> image 1 matches + ratioTest(matches21); + + //get_good_matches(matches12, good_matches); + + // 4. Remove non-symmetrical matches + symmetryTest(matches12, matches21, good_matches); + } + + void RobustMatcher::findFeatureAndMatch(const cv::Mat & frame, std::vector & good_matches, + std::vector & keypoints_frame, + const cv::Mat & descriptors_model ) + { + good_matches.clear(); + + // 1b. Extraction of the ORB descriptors + cv::Mat descriptors_frame; + featureDetector_->computeKeypointsAndDescriptors(frame, descriptors_frame, keypoints_frame); + + std::cout << "df " << descriptors_model.rows << std::endl; + std::cout << "kf" << descriptors_frame.rows << std::endl; + + match(descriptors_frame, descriptors_model, good_matches); + + } + + + void RobustMatcher::fastRobustMatch(const cv::Mat & frame, std::vector & good_matches, + std::vector & keypoints_frame, + const cv::Mat & descriptors_model ) + { + good_matches.clear(); + + cv::Mat d_f, d_m; + // 1a. Detection of the ORB features + //this->computeKeyPoints(frame, keypoints_frame); + + // 1b. Extraction of the ORB descriptors + cv::Mat descriptors_frame; + //this->computeDescriptors(frame, keypoints_frame, descriptors_frame); + + featureDetector_->computeKeypointsAndDescriptors(frame, descriptors_frame, keypoints_frame); + + if(descriptors_frame.type() != CV_32F) { + descriptors_frame.convertTo(d_f, CV_32F); + } + else{ + d_f = descriptors_frame; + } + if(descriptors_model.type() != CV_32F) { + descriptors_model.convertTo(d_f, CV_32F); + } + else + { + d_m = descriptors_model; + } + + // 2. Match the two image descriptors + std::vector > matches; + matcher_->knnMatch(d_f, d_m, matches, 2); + + // 3. Remove matches for which NN ratio is > than threshold + ratioTest(matches); + + // 4. Fill good matches container + for(auto & match : matches) + { + good_matches.push_back(match[0]); + } + } + + } + +} + diff --git a/detectors/src/local2D/simple_ransac_detection/Utils.cpp b/detectors/src/local2D/simple_ransac_detection/Utils.cpp new file mode 100644 index 00000000..a4ef573e --- /dev/null +++ b/detectors/src/local2D/simple_ransac_detection/Utils.cpp @@ -0,0 +1,305 @@ +/* + * Utils.cpp + * + * Created on: Mar 28, 2014 + * Author: Edgar Riba + */ + +#include "od/detectors/local2D/simple_ransac_detection/Utils.h" + +namespace od { + + namespace l2d { + // For text + int fontFace = cv::FONT_ITALIC; + double fontScale = 0.75; + int thickness_font = 2; + + // For circles + int lineType = 16; + int radius = 1; + double thickness_circ = -1; + + void viewImage(const cv::Mat & image, const std::vector & keypoints) + { + cv::Mat outimage = image; + cv::drawKeypoints(image, keypoints, outimage, cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); + + cv::namedWindow( "Keypoints", cv::WINDOW_NORMAL); // Create a window for display. + cv::resizeWindow("Keypoints", 800, 600); + + cv::imshow("Keypoints", outimage); + cv::waitKey(0); + } + + // Draw a text with the question point + void drawQuestion(cv::Mat & image, const cv::Point3f & point, const cv::Scalar & color) + { + std::string x = std::to_string((int)point.x); + std::string y = std::to_string((int)point.y); + std::string z = std::to_string((int)point.z); + + std::string text = "Where is point (" + x + "," + y + "," + z + ") ?"; + cv::putText(image, text, cv::Point(25,50), fontFace, fontScale, color, thickness_font, 8); + } + + // Draw a text with the number of entered points + void drawText(cv::Mat & image, const std::string & text, const cv::Scalar & color) + { + cv::putText(image, text, cv::Point(25,50), fontFace, fontScale, color, thickness_font, 8); + } + + // Draw a text with the number of entered points + void drawText2(cv::Mat & image, const std::string & text, const cv::Scalar & color) + { + cv::putText(image, text, cv::Point(25,75), fontFace, fontScale, color, thickness_font, 8); + } + + // Draw a text with the frame ratio + void drawFPS(cv::Mat & image, double fps, const cv::Scalar & color) + { + std::string fps_str = std::to_string((int)fps); + std::string text = fps_str + " FPS"; + cv::putText(image, text, cv::Point(500,50), fontFace, fontScale, color, thickness_font, 8); + } + + // Draw a text with the frame ratio + void drawConfidence(cv::Mat & image, double confidence, const cv::Scalar & color) + { + std::string conf_str = std::to_string((int)confidence); + std::string text = conf_str + std::string(" %"); + cv::putText(image, text, cv::Point(500,75), fontFace, fontScale, color, thickness_font, 8); + } + + // Draw a text with the number of entered points + void drawCounter(cv::Mat & image, int n, int n_max, const cv::Scalar & color) + { + std::string n_str = std::to_string(n); + std::string n_max_str = std::to_string(n_max); + std::string text = n_str + " of " + n_max_str + " points"; + cv::putText(image, text, cv::Point(500,50), fontFace, fontScale, color, thickness_font, 8); + } + + // Draw the points and the coordinates + void drawPoints(cv::Mat & image, const std::vector & list_points_2d, const std::vector & list_points_3d, + const cv::Scalar & color) + { + for(size_t i = 0; i < list_points_2d.size(); ++i) + { + cv::Point2f point_2d = list_points_2d[i]; + cv::Point3f point_3d = list_points_3d[i]; + + // Draw Selected points + cv::circle(image, point_2d, radius, color, -1, lineType ); + + std::string idx = std::to_string(i+1); + std::string x = std::to_string((int)point_3d.x); + std::string y = std::to_string((int)point_3d.y); + std::string z = std::to_string((int)point_3d.z); + std::string text = "P" + idx + " (" + x + "," + y + "," + z +")"; + + point_2d.x = point_2d.x + 10; + point_2d.y = point_2d.y - 10; + cv::putText(image, text, point_2d, fontFace, fontScale*0.5, color, thickness_font, 8); + } + } + + // Draw only the 2D points + void draw2DPoints(cv::Mat & image, const std::vector & list_points, const cv::Scalar & color) + { + for(size_t i = 0; i < list_points.size(); i++) + { + cv::Point2f point_2d = list_points[i]; + + // Draw Selected points + cv::circle(image, point_2d, radius, color, -1, lineType ); + } + } + + // Draw an arrow into the image + void drawArrow(cv::Mat & image, cv::Point2i & p, const cv::Point2i & q, const cv::Scalar & color, + int arrowMagnitude, int thickness, int line_type, int shift) + { + //Draw the principle line + cv::line(image, p, q, color, thickness, line_type, shift); + const double PI = CV_PI; + //compute the angle alpha + const double angle = atan2((double)p.y-q.y, (double)p.x-q.x); + //compute the coordinates of the first segment + p.x = (int) ( q.x + arrowMagnitude * cos(angle + PI/4)); + p.y = (int) ( q.y + arrowMagnitude * sin(angle + PI/4)); + //Draw the first segment + cv::line(image, p, q, color, thickness, line_type, shift); + //compute the coordinates of the second segment + p.x = (int) ( q.x + arrowMagnitude * cos(angle - PI/4)); + p.y = (int) ( q.y + arrowMagnitude * sin(angle - PI/4)); + //Draw the second segment + cv::line(image, p, q, color, thickness, line_type, shift); + } + + // Draw the 3D coordinate axes + void draw3DCoordinateAxes(cv::Mat & image, const std::vector & list_points2d) + { + cv::Scalar red(0, 0, 255); + cv::Scalar green(0,255,0); + cv::Scalar blue(255,0,0); + cv::Scalar black(0,0,0); + + cv::Point2i origin = list_points2d[0]; + cv::Point2i pointX = list_points2d[1]; + cv::Point2i pointY = list_points2d[2]; + cv::Point2i pointZ = list_points2d[3]; + + drawArrow(image, origin, pointX, red, 9, 2); + drawArrow(image, origin, pointY, blue, 9, 2); + drawArrow(image, origin, pointZ, green, 9, 2); + cv::circle(image, origin, radius/2, black, -1, lineType ); + + } + + // Draw the object mesh + void drawObjectMesh(cv::Mat image, const Mesh & mesh, PnPProblem & pnpProblem, const cv::Scalar & color) + { + std::vector > list_triangles = mesh.getTrianglesList(); + // if (pnpProblem->get_A_matrix().at(0,2) < 300 && list_triangles.size() > 1000) + // skip = 10; + + for(size_t i = 0; i < list_triangles.size(); ++i) + { + std::vector tmp_triangle = list_triangles.at(i); + + const cv::Point3f point_3d_0 = mesh.getVertex(tmp_triangle[0]); + const cv::Point3f point_3d_1 = mesh.getVertex(tmp_triangle[1]); + cv::Point3f point_3d_2 = mesh.getVertex(tmp_triangle[2]); + + //std::cout << point_3d_0 << std::endl << point_3d_1 << std::endl << point_3d_2 << std::endl << std::endl; + + const cv::Point2f point_2d_0 = pnpProblem.backproject3DPoint(point_3d_0); + const cv::Point2f point_2d_1 = pnpProblem.backproject3DPoint(point_3d_1); + const cv::Point2f point_2d_2 = pnpProblem.backproject3DPoint(point_3d_2); + + cv::line(image, point_2d_0, point_2d_1, color, 1); + cv::line(image, point_2d_1, point_2d_2, color, 1); + cv::line(image, point_2d_2, point_2d_0, color, 1); + } + } + + void drawModel(cv::Mat & image, const Model & model, const PnPProblem & pnpProblem, const cv::Scalar & color) + { + std::vector img_points; + cv::projectPoints(model.getPoints3d(), pnpProblem.getRVect(), pnpProblem.getTMatrix(), pnpProblem.getAMatrix(), + pnpProblem.getDistCoef(), img_points); + draw2DPoints(image, img_points, color); + + } + + void drawModel(cv::Mat & image, const Model & model, cv::Mat r_vect, + cv::Mat t_mat, cv::Mat a_mat, cv::Mat dist, const cv::Scalar & color) + { + std::vector img_points; + cv::projectPoints(model.getPoints3d(), r_vect, t_mat, a_mat, dist, img_points); + draw2DPoints(image, img_points, color); + + } + + // Computes the norm of the translation error + double getTranslationError(const cv::Mat & t_true, const cv::Mat & t) + { + return cv::norm( t_true - t ); + } + + // Computes the norm of the rotation error + double getRotationError(const cv::Mat & r_true, const cv::Mat & r) + { + cv::Mat error_vec, error_mat; + error_mat = r_true * cv::Mat(r.inv()).mul(-1); + cv::Rodrigues(error_mat, error_vec); + + return cv::norm(error_vec); + } + + // Converts a given Rotation Matrix to Euler angles + cv::Mat rot2euler(const cv::Mat & rotation_matrix) + { + cv::Mat euler(3,1,CV_64F); + + const double m00 = rotation_matrix.at(0,0); + const double m02 = rotation_matrix.at(0,2); + const double m10 = rotation_matrix.at(1,0); + const double m11 = rotation_matrix.at(1,1); + const double m12 = rotation_matrix.at(1,2); + const double m20 = rotation_matrix.at(2,0); + const double m22 = rotation_matrix.at(2,2); + + double x, y, z; + + // Assuming the angles are in radians. + if (m10 > 0.998) { // singularity at north pole + x = 0; + y = CV_PI/2; + z = atan2(m02,m22); + } + else if (m10 < -0.998) { // singularity at south pole + x = 0; + y = -CV_PI/2; + z = atan2(m02,m22); + } + else + { + x = atan2(-m12,m11); + y = asin(m10); + z = atan2(-m20,m00); + } + + euler.at(0) = x; + euler.at(1) = y; + euler.at(2) = z; + + return euler; + } + + // Converts a given Euler angles to Rotation Matrix + cv::Mat euler2rot(const cv::Mat & euler) + { + cv::Mat rotation_matrix(3, 3, CV_64F); + + const double x = euler.at(0); + const double y = euler.at(1); + const double z = euler.at(2); + + // Assuming the angles are in radians. + const double ch = cos(z); + const double sh = sin(z); + const double ca = cos(y); + const double sa = sin(y); + const double cb = cos(x); + const double sb = sin(x); + + double m00, m01, m02, m10, m11, m12, m20, m21, m22; + + m00 = ch * ca; + m01 = sh*sb - ch*sa*cb; + m02 = ch*sa*sb + sh*cb; + m10 = sa; + m11 = ca*cb; + m12 = -ca*sb; + m20 = -sh*ca; + m21 = sh*sa*cb + ch*sb; + m22 = -sh*sa*sb + ch*cb; + + rotation_matrix.at(0,0) = m00; + rotation_matrix.at(0,1) = m01; + rotation_matrix.at(0,2) = m02; + rotation_matrix.at(1,0) = m10; + rotation_matrix.at(1,1) = m11; + rotation_matrix.at(1,2) = m12; + rotation_matrix.at(2,0) = m20; + rotation_matrix.at(2,1) = m21; + rotation_matrix.at(2,2) = m22; + + return rotation_matrix; + } + + } + +} \ No newline at end of file diff --git a/detectors/local2D/training/ODCADRecogTrainerSnapshotBased.cpp b/detectors/src/local2D/training/CADRecogTrainerSnapshotBased.cpp similarity index 60% rename from detectors/local2D/training/ODCADRecogTrainerSnapshotBased.cpp rename to detectors/src/local2D/training/CADRecogTrainerSnapshotBased.cpp index 3570df57..031dc559 100644 --- a/detectors/local2D/training/ODCADRecogTrainerSnapshotBased.cpp +++ b/detectors/src/local2D/training/CADRecogTrainerSnapshotBased.cpp @@ -18,197 +18,41 @@ 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 COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOS 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. */ -#include "ODCADRecogTrainerSnapshotBased.h" -//simplecube/newcube.obj simplecube/flower.jpeg -//Lion/Final.obj Lion/Texture.png -//BigDaddy/Param.obj BigDaddy/Parameterization.png - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -//opencv -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -//extra -//xml -#include "pugixml.hpp" - - -using namespace std; +#include "od/detectors/local2D/training/CADRecogTrainerSnapshotBased.h" namespace od { namespace l2d { - class vtkTimerCallbackSnapshot : public vtkCommand + int CADRecogTrainerSnapshotBased::train() { - public: - static vtkTimerCallbackSnapshot *New() - { - vtkTimerCallbackSnapshot *cb = new vtkTimerCallbackSnapshot; - cb->snap_count = 0; - cb->snap_mode = true; - cb->feature_type = "SIFT"; - return cb; - } - - virtual void Execute(vtkObject *caller, unsigned long eventId, void * vtkNotUsed(callData)) - { - vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::SafeDownCast(caller); - - - if(!this->snap_mode) return; - - if(vtkCommand::TimerEvent == eventId) - { - ++this->snap_count; - } - - //no need to do extra processing if we have enough snaps - if(this->snap_count >= NO_SNAPSHOTS) - { - this->snap_mode = false; - //after getting all snaps, write everything together - cout << "Processing finished... Writing the final descriptors" << endl; - - string filename = boost::filesystem::path(input_file).filename().replace_extension(feature_type + "." + output_extension).c_str(); - FileUtils::createTrainingDir(output_dir); - - write_pairs(pairs_3d_2d, common_descriptors, output_dir + "/" + filename); - write_pairs_xml(pairs_3d_2d, common_descriptors, output_dir + "/" + filename); - - //delete and remove everything - iren->TerminateApp(); - pairs_3d_2d.clear(); - } - - - - //MAIN CALLBACK, take snapshot, find features for the data from current actor - process(iren, actor, renderer, snap_count); - - //update data with the actor - actor->RotateY(360 / NO_SNAPSHOTS); - iren->GetRenderWindow()->Render(); - } - - private: - int snap_count; - public: - - string takeSnapshot(vtkRenderWindow *renderWindow, int snap_no); - - void write_pairs(vector > pairs, cv::Mat descriptors, string filename); - - void write_pairs_xml(vector > pairs, cv::Mat descriptors, string filename); - - void process_image(string imgname, vtkRenderer *ren, vtkActor *actor, int ino); - - void process(vtkRenderWindowInteractor *iren, vtkActor *actor, vtkRenderer *renderer, int ino); - - - //some local variables used - - struct fcomp3d_euclidian - { - bool operator()(const cv::Point3f &lhs, const cv::Point3f &rhs) const - { return lhs.x < rhs.x; } - }; - - vector > pairs_3d_2d; - cv::Mat common_descriptors; - map map_3d_2d; - string feature_type; - string input_file, input_dir, output_dir, output_extension; - - - vtkActor *actor; - vtkRenderer *renderer; - bool snap_mode; - }; - - int ODCADRecogTrainerSnapshotBased::train() - { - FileUtils::createTrainingDir(trained_data_location_); + fileutils::createTrainingDir(trained_data_location_); //get models in the directory std::vector files; - std::string start = ""; + std::string start = std::string(""); std::string ext = std::string("obj"); - bf::path dir = training_input_location_; - FileUtils::getFilesInDirectory(dir, start, files, ext); + boost::filesystem::path dir = training_input_location_; + fileutils::getFilesInDirectory(dir, start, files, ext); //for each models in the train_input_directory, train them and put them on the training_directory - for(size_t i = 0; i < files.size(); i++) + for(size_t i = 0; i < files.size(); ++i) { - trainSingleModel(training_input_location_ + "/" + files[i]); + trainSingleModel(training_input_location_ + std::string("/") + files[i]); } return 1; } - void ODCADRecogTrainerSnapshotBased::trainSingleModel(std::string objname) + void CADRecogTrainerSnapshotBased::trainSingleModel(const std::string & objname) { ///////////setup object @@ -218,7 +62,7 @@ namespace od boost::filesystem::path p(objname); cb->input_dir = boost::filesystem::path(objname).parent_path().c_str(); cb->output_dir = getSpecificTrainingDataLocation(); - cb->output_extension = TRAINED_DATA_ID_; + cb->output_extension = trained_data_id_; vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(objname.c_str()); @@ -226,9 +70,9 @@ namespace od //texture // Read texture file - string texfilename = getTexfileinObj(objname); + std::string texfilename = getTexfileinObj(objname); vtkSmartPointer readerFactory = vtkSmartPointer::New(); - vtkImageReader2 *imageReader = readerFactory->CreateImageReader2(texfilename.c_str()); + vtkImageReader2 * imageReader = readerFactory->CreateImageReader2(texfilename.c_str()); imageReader->SetFileName(texfilename.c_str()); imageReader->Update(); @@ -259,7 +103,7 @@ namespace od //Set up the camera at a very proper location and angle (about 30) renderer->ResetCamera(); - vtkCamera *camera = renderer->GetActiveCamera(); + vtkCamera * camera = renderer->GetActiveCamera(); camera->Elevation(VIEW_ANGLE); //////////////////// @@ -287,43 +131,44 @@ namespace od } - std::string vtkTimerCallbackSnapshot::takeSnapshot(vtkRenderWindow *renderWindow, int snap_no) + std::string vtkTimerCallbackSnapshot::takeSnapshot(vtkRenderWindow * render_window, int snap_no) { // Screenshot vtkSmartPointer windowToImageFilter = vtkSmartPointer::New(); - windowToImageFilter->SetInput(renderWindow); + windowToImageFilter->SetInput(render_window); //windowToImageFilter->SetMagnification(3); //set the resolution of the output image (3 times the current resolution of vtk render window) //windowToImageFilter->SetInputBufferTypeToRGBA(); //also record the alpha (transparency) channel //windowToImageFilter->ReadFrontBufferOff(); // read from the back buffer windowToImageFilter->Update(); vtkSmartPointer writer = vtkSmartPointer::New(); - std::string filename; + std::string file_name; - filename = input_dir + "/" + string("snapshot") + toString(snap_no) + ".jpg"; + file_name = input_dir + std::string("/") + std::string("snapshot") + std::to_string(snap_no) + std::string(".jpg"); - writer->SetFileName(filename.c_str()); + writer->SetFileName(file_name.c_str()); writer->SetInputConnection(windowToImageFilter->GetOutputPort()); - renderWindow->Render(); + render_window->Render(); writer->Write(); - return filename; + + return file_name; } - void vtkTimerCallbackSnapshot::write_pairs(vector > pairs, cv::Mat descriptors, - string filename) + void vtkTimerCallbackSnapshot::write_pairs(const std::vector > & pairs, const cv::Mat & descriptors, + const std::string & file_name) { - ofstream fout; - fout.open(filename.c_str()); + std::ofstream fout; + fout.open(file_name.c_str()); //headers fout << pairs.size() << endl; fout << 3 << " " << descriptors.cols << endl; - for(int i = 0; i < pairs.size(); i++) + for(size_t i = 0; i < pairs.size(); i++) { fout << pairs[i].first.x << " " << pairs[i].first.y << " " << pairs[i].first.z << endl; fout << pairs[i].second.pt.x << " " << pairs[i].second.pt.y << " " << pairs[i].second.octave << " " << pairs[i].second.angle << " " << pairs[i].second.response << " " << pairs[i].second.size << endl; - for(int j = 0; j < descriptors.cols; j++) + for(int j = 0; j < descriptors.cols; ++j) { fout << descriptors.at(i, j) << " "; } @@ -332,21 +177,21 @@ namespace od fout.close(); } - void vtkTimerCallbackSnapshot::write_pairs_xml(vector > pairs, cv::Mat descriptors, - string filename) + void vtkTimerCallbackSnapshot::write_pairs_xml(const std::vector > & pairs, const cv::Mat & descriptors, + const std::string & file_name) { pugi::xml_document doc; pugi::xml_node root = doc.append_child("Model"); - root.append_attribute("name") = filename.c_str(); + root.append_attribute("name") = file_name.c_str(); //root.append_attribute("objid") = "1"; pugi::xml_node points_node = root.append_child("Points"); - for(int i = 0; i < pairs.size(); i++) + for(size_t i = 0; i < pairs.size(); i++) { pugi::xml_node p_node = points_node.append_child("Point"); - ostringstream ss; + std::ostringstream ss; ss << pairs[i].first.x << " " << pairs[i].first.y << " " << pairs[i].first.z; p_node.append_attribute("p3d") = ss.str().c_str(); p_node.append_attribute("nviews") = "1"; @@ -370,49 +215,50 @@ namespace od p_node.append_attribute("desc") = ss.str().c_str(); } //save - doc.save_file(filename.c_str()); + doc.save_file(file_name.c_str()); } bool valid_3D_point(double *pt) { - if((pt[0] == 0) && (pt[1] == 0) && (pt[2] == 0)) return false; + if((pt[0] == 0) && (pt[1] == 0) && (pt[2] == 0)) + return false; return true; } //1. find interesting 2d points, 2. find their corresponding 3d points corresponding to the transformation defined by the "actor" //3. transform the 3d points to the original by using the inverse of the "actor" - void vtkTimerCallbackSnapshot::process_image(string imgname, vtkRenderer *ren, vtkActor *actor, int ino) + void vtkTimerCallbackSnapshot::process_image(const std::string & img_name, vtkRenderer * ren, vtkActor * actor, int ino) { //1. find interesting 2d location - cv::Mat img = cv::imread(imgname); - vector kpts; + cv::Mat img = cv::imread(img_name); + std::vector kpts; cv::Mat descriptors_local, descriptors_local_good; cv::Ptr fdetector = cv::xfeatures2d::SIFT::create(); fdetector->detect(img, kpts); fdetector->compute(img, kpts, descriptors_local); //2. find the corresponding 3d points for each 2d location - vector > pairs_local; - for(int i = 0; i < kpts.size(); i++) + std::vector > pairs_local; + for(size_t i = 0; i < kpts.size(); ++i) { //find 2d vtkSmartPointer picker = vtkSmartPointer::New(); picker->Pick(kpts[i].pt.x, img.rows - kpts[i].pt.y, 0, ren); //IMPORTANT: note that the y coordinate is converted from pixel coordinates to picking coordinates //find transformed 3d - double *pos = picker->GetPickPosition(); + double * pos = picker->GetPickPosition(); //3 find original 3d - vtkMatrix4x4 *curr_transform_inv = vtkMatrix4x4::New(); + vtkMatrix4x4 * curr_transform_inv = vtkMatrix4x4::New(); vtkMatrix4x4::Invert(actor->GetMatrix(), curr_transform_inv); - double *pos_model = curr_transform_inv->MultiplyDoublePoint(pos); + double * pos_model = curr_transform_inv->MultiplyDoublePoint(pos); //std::cout << "2D position is: " << kpts[i].pt.x << " " << kpts[i].pt.x << std::endl; //std::cout << "3d position (world coordinates) is: " << pos[0] << " " << pos[1] << " " << pos[2] << std::endl << endl; if(valid_3D_point(pos)) { - pairs_local.push_back(make_pair(cv::Point3f(pos_model[0], pos_model[1], pos_model[2]), kpts[i])); + pairs_local.push_back(std::make_pair(cv::Point3f(pos_model[0], pos_model[1], pos_model[2]), kpts[i])); descriptors_local_good.push_back(descriptors_local.row(i)); //updating extra globals! @@ -424,18 +270,18 @@ namespace od common_descriptors.push_back(descriptors_local_good); //writing a local set - write_pairs(pairs_local, descriptors_local_good, input_dir + "/" + "local" + toString(ino) + ".pairs"); - write_pairs_xml(pairs_local, descriptors_local_good, input_dir + "/" + "local" + toString(ino) + ".xml"); - cout << "Processed view " << ino << endl; + write_pairs(pairs_local, descriptors_local_good, input_dir + std::string("/local") + std::to_string(ino) + std::string(".pairs")); + write_pairs_xml(pairs_local, descriptors_local_good, input_dir + std::string("/local") + std::to_string(ino) + std::string(".xml")); + std::cout << "Processed view " << ino << std::endl; } - void vtkTimerCallbackSnapshot::process(vtkRenderWindowInteractor *iren, vtkActor *actor, vtkRenderer *renderer, int ino) + void vtkTimerCallbackSnapshot::process(vtkRenderWindowInteractor * iren, vtkActor * actor, vtkRenderer * renderer, int ino) { vtkRenderWindow *win = iren->GetRenderWindow(); //snap - string snapname = takeSnapshot(win, ino); + std::string snapname = takeSnapshot(win, ino); //save process_image(snapname, renderer, actor, ino); @@ -445,13 +291,14 @@ namespace od class MouseInteractorStyle2 : public vtkInteractorStyleTrackballCamera { public: - static MouseInteractorStyle2 *New(); + + static MouseInteractorStyle2 * New(); vtkTypeMacro(MouseInteractorStyle2, vtkInteractorStyleTrackballCamera); virtual void OnLeftButtonDown() { - int *clickPos = this->GetInteractor()->GetEventPosition(); + int * clickPos = this->GetInteractor()->GetEventPosition(); // Pick from this location. /*vtkSmartPointer picker = @@ -485,12 +332,50 @@ namespace od vtkInteractorStyleTrackballCamera::OnLeftButtonDown(); } - private: - }; vtkStandardNewMacro(MouseInteractorStyle2) + void vtkTimerCallbackSnapshot::Execute(vtkObject * caller, unsigned long eventId, void * vtkNotUsed(callData)) + { + vtkRenderWindowInteractor * iren = vtkRenderWindowInteractor::SafeDownCast(caller); + + + if(!this->snap_mode) return; + + if(vtkCommand::TimerEvent == eventId) + { + ++this->snap_count_; + } + + //no need to do extra processing if we have enough snaps + if(this->snap_count_ >= NO_SNAPSHOTS) + { + this->snap_mode = false; + //after getting all snaps, write everything together + cout << "Processing finished... Writing the final descriptors" << endl; + + std::string filename = boost::filesystem::path(input_file).filename().replace_extension(feature_type + "." + output_extension).c_str(); + fileutils::createTrainingDir(output_dir); + + write_pairs(pairs_3d_2d, common_descriptors, output_dir + "/" + filename); + write_pairs_xml(pairs_3d_2d, common_descriptors, output_dir + "/" + filename); + + //delete and remove everything + iren->TerminateApp(); + pairs_3d_2d.clear(); + } + + + + //MAIN CALLBACK, take snapshot, find features for the data from current actor + process(iren, actor, renderer, snap_count_); + + //update data with the actor + actor->RotateY(360 / NO_SNAPSHOTS); + iren->GetRenderWindow()->Render(); + } + } } \ No newline at end of file diff --git a/detectors/src/misc/CMakeLists.txt b/detectors/src/misc/CMakeLists.txt new file mode 100644 index 00000000..6eb6c07b --- /dev/null +++ b/detectors/src/misc/CMakeLists.txt @@ -0,0 +1,26 @@ +set(SUBSYS_NAME misc_detector) +set(LIB_NAME od_${SUBSYS_NAME}) +set(SUBSYS_DESC "Multi algorithm detector") +set(SUBSYS_DEPS od_common od_global_image_detector od_pointcloud_global_detector) + +if(BUILD_MISC_DETECTION) + if(TARGET od_global_image_detector AND TARGET od_pointcloud_global_detector) + set(SOURCES + "detection/DetectorMultiAlgo.cpp" + ) + + include_directories(${DETECTORS_IMPL_DIR}) + include_directories(${DETECTORS_INCLUDE_DIR}) + include_directories(${COMMON_INCLUDE_DIR}) + include_directories(${COMMON_IMPL_DIR}) + include_directories(${OpenCV_INCLUDE_DIRS}) + include_directories(${CMAKE_3RDPARTY_DIR}/svmlightlib/) + include_directories(${PCL_INCLUDE_DIRS}) + + OD_ADD_LIBRARY("${SUBSYS_NAME}" SRCS ${SOURCES} LINK_WITH ${SUBSYS_DEPS}) + + else() + message("!!! BUILD_MISC_DETECTION is set to on but BUILD_GLOBAL_2D_DETECTION and BUILD_GLOBAL_3D_DETECTION is necessary to build BUILD_MISC_DETECTION") + endif(TARGET od_global_image_detector AND TARGET od_pointcloud_global_detector) + +endif(BUILD_MISC_DETECTION) \ No newline at end of file diff --git a/detectors/src/misc/detection/DetectorMultiAlgo.cpp b/detectors/src/misc/detection/DetectorMultiAlgo.cpp new file mode 100644 index 00000000..8e557861 --- /dev/null +++ b/detectors/src/misc/detection/DetectorMultiAlgo.cpp @@ -0,0 +1,107 @@ +#include "od/detectors/misc/detection/DetectorMultiAlgo.hpp" + + +namespace od +{ + + template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + template + void DetectorMultiAlgo2D::init(); + + + + template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + template + void DetectorMultiAlgo2D::init(); + + + + template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detect(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo2D::detectOmni(shared_ptr scene); + + template + void DetectorMultiAlgo2D::init(); + + + + template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo::detect(shared_ptr scene); + + template + void DetectorMultiAlgo::init(); + + template + shared_ptr DetectorMultiAlgo::detect(shared_ptr > scene); + + template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr > scene); + + + + template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo::detect(shared_ptr scene); + + template + void DetectorMultiAlgo::init(); + + template + shared_ptr DetectorMultiAlgo::detect(shared_ptr > scene); + + template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr > scene); + + + + template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr scene); + + template + shared_ptr DetectorMultiAlgo::detect(shared_ptr scene); + + template + void DetectorMultiAlgo::init(); + + template + shared_ptr DetectorMultiAlgo::detect(shared_ptr > scene); + + template + shared_ptr DetectorMultiAlgo::detectOmni(shared_ptr > scene); + +} \ No newline at end of file diff --git a/doc/doxygen/doxyfile.in b/doc/doxygen/doxyfile.in index 43feda79..df7a034a 100644 --- a/doc/doxygen/doxyfile.in +++ b/doc/doxygen/doxyfile.in @@ -116,12 +116,11 @@ FILE_PATTERNS = *.h \ *.md RECURSIVE = YES EXCLUDE = "@OD_SOURCE_DIR@/cmake" \ + "@OD_SOURCE_DIR@/build" \ + "@OD_SOURCE_DIR@/3rdparty" EXCLUDE_SYMLINKS = YES -EXCLUDE_PATTERNS = "@OD_SOURCE_DIR@/detectors/*/detection/*/*" \ - "@OD_SOURCE_DIR@/detectors/*/training/*/*" \ - "@OD_SOURCE_DIR@/3rdparty/*" \ - "@OD_SOURCE_DIR@/README.md" +EXCLUDE_PATTERNS = "@OD_SOURCE_DIR@/README.md" EXCLUDE_SYMBOLS = EXAMPLE_PATH = "@OD_SOURCE_DIR@/examples" EXAMPLE_PATTERNS = * @@ -168,9 +167,9 @@ HTML_EXTRA_FILES = "@OD_SOURCE_DIR@/doc/doxygen/css/tabs.css" \ "@OD_SOURCE_DIR@/doc/doxygen/images/face_business.jpg" \ "@OD_SOURCE_DIR@/doc/doxygen/images/snap_hog3.png" HTML_EXTRA_STYLESHEET = "@OD_SOURCE_DIR@/doc/doxygen/css/customdoxygen.css" -HTML_COLORSTYLE_HUE =218 -HTML_COLORSTYLE_SAT =82 -HTML_COLORSTYLE_GAMMA =15 +HTML_COLORSTYLE_HUE = 218 +HTML_COLORSTYLE_SAT = 82 +HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = YES HTML_DYNAMIC_SECTIONS = NO GENERATE_DOCSET = YES @@ -280,7 +279,8 @@ INCLUDE_FILE_PATTERNS = *.h PREDEFINED = = "HAVE_QHULL=1" \ "HAVE_OPENNI=1" \ "HAVE_ENSENSO=1" \ - "PCL_DEPRECATED(x)=" + "PCL_DEPRECATED(x)=" \ + DOXYGEN_SHOULD_SKIP_THIS EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES diff --git a/doc/doxygen/od_root.md b/doc/doxygen/od_root.md index 174187b0..94dfb8e9 100644 --- a/doc/doxygen/od_root.md +++ b/doc/doxygen/od_root.md @@ -90,7 +90,7 @@ We will be presenting our library at FOSSASIA 2016, Singapore - an annual confer
\endhtmlonly - \link od::l2d::ODCADRecognizer2DLocal + \link od::l2d::CADRecognizer2DLocal \htmlonly