/*------------------------------------------------------------------------------*
 *	File Name: 	ocTriCtr.h														*
 *	Purpose:	Triangulation Contour access from OC							*
 *	Creation:	CPY 3/10/2008													*
 *  Copyright OriginLab Corp. 2008												*
 *------------------------------------------------------------------------------*/
#ifndef _OC_TRI_CTR_H
#define _OC_TRI_CTR_H

// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the _OC3DXDLL__
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// OCUTILS_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.

#ifdef __AFX_H__

	#ifdef OCCONTOUR_DLL
		#define OC_API __declspec(dllexport)
	/// TD 06-19-2008 QA80-10844 TRICTR_IN_VIEWER
	#elif  defined(MIN_OK_VERSION)
		#define OC_API
	/// end QA80-10844 TRICTR_IN_VIEWER
	#else
		#define OC_API __declspec(dllimport)
	#endif

	#include "OCtoVC.h"
	extern "C" {
		///////////////////////////////////////////////////////////////////////
		// the following functions are used in VC level only
		///////////////////////////////////////////////////////////////////////

		///////////////////////////////////////////////////////////////////////
		// end VC level functions
		///////////////////////////////////////////////////////////////////////


#else
	#define OC_API
	#pragma dll(ocContour)	// Associate all functions below to oc3dx70.dll which must be in the Origin EXE folder
#endif	//__AFX_H__

typedef struct tagContourSelect
{
	// -1 to indicate no need to test 
	int		minPts;
	int		maxPts;
	double 	minArea; // in fraction of total contour area bounding rect
	double	maxArea; // in fraction of total contour area bounding rect
	double	minRoundness;
	double	maxRoundness;
 	double	minEllipseRatio;
 	double	maxEllipseRatio;
 	int		minSmoothedSegmentPts;
 	int		nCurvatureStepPts;
 	float	maxSegmentMinSD;  // curvature measured in segment, smoothed region will yield small SD
 	float	minIntensitySD;// intensity distribution of area covered by contour, use this to indicate some features must existed
 	int		nPeakValley; // = 0 if no test, 1 if interior intensity at least 1 higher then contour, -1 if at least -1 less then contour
	char	close; // close contour only, 0 = don't care, 1 = close only

	// the followings are for higher level selection, like Peak
	DWORD	dwCtrl; // = POSITIVE_DIRECTION, NEGATIVE_DIRECTION etc
	double	minHeight; // -1 if ignore, otherwise measured from base contour
	double	maxHeight; // -1 if ignore, otherwise measured from base contour


} ContourSelect;


typedef void*  MatContourPtr;

/**
	Find peaks from xyz surface using contour consolidation algorithm
	Parameters:
		pmat = [input]  Matrix data
		nRows = [input] Row Size
		nCols = [input] Column Size
		pLevels = [input] levels data
		nLevels = [input] number of levels
		pXYmap = [input] holds xy mapping min max in the form of [0] = xmin, [1] = ymin, [2] = xmax, [3] = ymax
	Examples:
		void test_mat_contours_ex(int nLevels=9)
		{
			
			MatrixLayer ml(Project.ActiveLayer());
    
			if(ml)
			{
    			Matrix    mm(ml);

    			MatContourPtr pmatContour;
    			int nRows = mm.GetNumRows(), nCols = mm.GetNumCols();
    			
    			double max = mm.GetMax(), min = mm.GetMin();
    			
    			vector Levels = {0, 100, 200, 300, 400, 500, 1000, 10000, 88000};
    			//vector Levels;
    			//Levels.Data(min, max, (max-min)/(nLevels-1));
    			
    			double pXYmap[4];
				pXYmap[0] = mm.GetXMin();
				pXYmap[1] = mm.GetYMin();
				pXYmap[2] = mm.GetXMax();
				pXYmap[3] = mm.GetYMax();			
    			pmatContour = occ_create_mat_contours(mm, nRows, nCols, Levels, nLevels, pXYmap);
    			
    			int nLines, size;
    			ASSERT(occ_get_num_levels(pmatContour) == nLevels);
    			for(int ii=0; ii<nLevels ; ++ii)
    			{
    				nLines = occ_get_num_lines(pmatContour, ii);
    				printf("level %d: %d lines\n", ii, nLines);
    				
    				double *px, *py;
    				for(int jj=0; jj<nLines; ++jj)
    				{
    					printf("Line %d: ", jj);
    					size = occ_get_line(pmatContour, ii, jj, &px, &py);
    					for(int kk=0; kk<size; ++kk)
    						printf("(%.2f, %.2f) ", px[kk], py[kk]);
    					printf("\n");
    				}
    				printf("\n");
    			}
    			
    			occ_release_mat_contours(pmatContour);
				
    			return;
			}

			printf("ERROR");
		}
*/
OC_API MatContourPtr occ_create_mat_contours(const double* pmat, uint nRows, uint nCols, const double* pLevels, uint nLevels, const double *pXYMap = NULL);

OC_API int occ_get_num_levels(MatContourPtr pmatContour);

OC_API int occ_get_num_lines(MatContourPtr pmatContour, int nLevel);

OC_API int occ_get_line(MatContourPtr pmatContour, int nLevel, int nLinesInLevel, double **ppx, double **ppy );

OC_API int occ_release_mat_contours(MatContourPtr pmatContour);



OC_API int find_tri_contours(const double* px, const double* py, const double* pz, uint nSize, const double* pLevels, uint nLevels, TreeNode* pTrContours, ContourSelect* pSelect=NULL);

/**
	Parameters:
		pXYmap = [input] holds xy mapping min max in the form of [0] = xmin, [1] = ymin, [2] = xmax, [3] = ymax
	Examples:
		void test_mat_contours(int nLevels=10)
		{
			
			MatrixLayer ml(Project.ActiveLayer());
    
			if(ml) 	
			{
    			Matrix    mm(ml);
    			Tree tr;
    			ContourSelect Select;
    			int nRows = mm.GetNumRows(), nCols = mm.GetNumCols();
    			
    			double max = mm.GetMax(), min = mm.GetMin();
    			vector Levels;
    			Levels.Data(min, max, (max-min)/(nLevels-1));
    			
    			int nRet = find_mat_contours(mm, nRows, nCols, Levels, nLevels, &tr, NULL);
    			printf("Ret=%d\n", nRet);
				
    			return;
			}

			printf("ERROR");
		}
*/
OC_API int find_mat_contours(const double* lpData, uint nRows, uint nCols, const double* pLevels, uint nLevels, TreeNode* pTrContours, ContourSelect* pSelect, const double *pXYmap = NULL);

/**
	Find peaks from xyz surface using contour consolidation algorithm
	Parameters:
		px, py, py, nSize = [input]  XYZ surface data
		pLevels = [input] z levels for contour generation
		nLevels = [input] number of z values in pLevels
		ppkx, ppky = [output] found peak centers
		ppkw = [output] found peak width estimates
		nMaxPeaks = [input] buffer size of ppkx, ppky, ppkwx, ppkwy
		pSelect = [input] optional contour selection parameters
*/
OC_API int find_peaks_by_tri_contour_consolidation(const double* px, const double* py, const double* pz, uint nSize, const double* pLevels, uint nLevels, double* ppkx, double* ppky, double* ppkw, double* ppkwy, double* ppkh, uint nMaxPeaks, ContourSelect* pSelect=NULL, int nConsolidateMethod = 0);

/**
	Find peaks from matrix surface using contour consolidation algorithm
	Parameters:
		pmat = [input]  matrix surface data
		nRows, nCols = [input] matrix dimensions
		pXYMap = [input] matrix XY mapping, [0] = xmin, [1] = ymin, [2] = xmax, [3] = ymax
		pLevels = [input] z levels for contour generation
		nLevels = [input] number of z values in pLevels
		ppkx, ppky = [output] found peak centers
		ppkw = [output] found peak width X estimates
		ppkwy = [output] found peak width Y estimates
		nMaxPeaks = [input] buffer size of ppkx, ppky, ppkwx, ppkwy
		pSelect = [input] optional contour selection parameters
*/
OC_API int find_peaks_by_contour_consolidation(const double* pmat, uint nRows, uint nCols, const double *pXYmap, const double* pLevels, uint nLevels, double* ppkx, double* ppky, double* ppkw, double* ppkwy, double* ppkh, uint nMaxPeaks, ContourSelect* pSelect=NULL);

#ifdef __AFX_H__
	}  // end extern "C"
#endif	//__AFX_H__

#endif //_OC_TRI_CTR_H


