/*

Description: Functions collection; use tensorfields
             
Author:      Raimundo Sierra
             www.rsierra.com

Copyright:   Copyright (c) 2000 Raimundo Sierra. All rights reserved.
LICENSE:     This program is free software; you can redistribute it and/or modify
             it under the terms of the GNU General Public License as published by
             the Free Software Foundation; either version 2 of the License, or
             (at your option) any later version.

             This program is distributed in the hope that it will be useful,
             but WITHOUT ANY WARRANTY; without even the implied warranty of
             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
             GNU General Public License for more details.

             You should have received a copy of the GNU General Public License
             along with this program; if not, write to the Free Software
             Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Institution: Surgical Planning Laboratory
             Department of Radiology
             Brigham and Women's Hospital
             Harvard Medical School
             MA 02115
             USA

Date:        11.2000 - 3.2001

Modifications:
<Date>   <Init>    <Version>    <Description>

*/

#include "tensorfield.h"
#include "display.h"
#include "eigenfield.h"
#include "vtkScalars.h"
#include "kfunctions.h"

//////////////////////////////////////////
// Point extraction
//////////////////////////////////////////

                                        // outer product of derivatives of image "inarray" placed in 
                                        // tensorfield "correlationmatrix" (equation 7.7 in report)
void creatOuterProdDerivative(float * inarray, tensorfield & correlationMatrix, const int dimx=256, const int dimy=256, const int dimz=1, const int neighbourhood=0);

                                        // find points with high local structure in array "inarray" and 
                                        // set them in "pointarray" (equations 7.11, 7.12, 7.13 and 7.14 in report
void findPointsInFloatArray(float * inarray, float * pointarray, const int dimx=256, const int dimy=256, const int dimz=1, const int neighbourhood=3, const float sigmathresh=0.01, const int pointmethod=0);

                                        // pointextraction for tensorfield: use function nr. 2, first one was a test
void findPointsInTensorfield(tensorfield * t_field_ptr, float * pointarray, const int neighbourhood=3, const float sigmathresh=0.01, const int pointmethod=0, const int searchwindowsize=7, const int movingwindowsize=7, const int matchmethod=0, const int matchwindowweighting=0);
void findPointsInTensorfield2(tensorfield * t_field_ptr, float * pointarray, const int neighbourhood=3, const float sigmathresh=0.01, const int pointmethod=0, const int searchwindowsize=7, const int movingwindowsize=7, const int matchmethod=0, const int matchwindowweighting=0);


//////////////////////////////////////////
// Applying displacements and local transformations
//////////////////////////////////////////

                                        // Displace a tensorfield without any local transformation: 
                                        // apply a displacement field "dx, dy, dz" to each component of the tensor
void displaceTensorField( tensorfield * t_field_input_ptr, tensorfield * t_field_out_ptr, float * dx, float * dy, float * dz);

                                        // Apply a local transformation on a tensorfield, 
                                        // after displacement field "dx, dy, dz" has been applied
                                        // allowScaling = 0 no scaling with warping, 
                                        //                use SVD decomposition and apply only rotation
                                        // allowScaling = 1 apply transformation but remove scaling by deviding with det^1/3
                                        // allowScaling = else    apply transformation and allow scaling of tensors
void localWarpTensorField(tensorfield * t_field_out_ptr, float * dx, float * dy, float * dz, const int allowScaling=0);



                                        // local rigid transformation of a tensorfield:
                                        // after applying rigid transformation on each component independent 
                                        // local transformation of tensors: as suggested in the report only displacement
                                        // "dx, dy, dz" and rotation by "pitch, roll, yaw"

                                        // only "yaw" is implemented: make sure to test when adding "roll, pitch"
                                        // alternative: addapt function "localWarpTensorField" for the rigid case
void resampleTensorData( tensorfield & t_field, const float dx, const float dy, const float dz, const float pitch, const float roll, const float yaw);


//////////////////////////////////////////
// Synthetic examples
//////////////////////////////////////////

                                        // synthetic examples, used in program ./test to verify functions
void makeSynthField3D( eigenfield & e_field, tensorfield &t_field);
void makeSynthField2D( eigenfield & e_field, tensorfield &t_field);

void makeSynthSimple2D(eigenfield & e_field, tensorfield &t_field);
void makeSynthCircle2D(eigenfield & e_field, tensorfield &t_field);
