//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// impsurface.h
//
// Vincent LE PRINCE <vincentleprince@users.sourceforge.net>
// Copyright (C) 2000-2005 Vincent LE PRINCE
// This file is part of the TRUEVISION Package

//   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.  */
//*******************************************************************************************
#ifndef TV_IMPSURF_H
#define TV_IMPSURF_H
using namespace std;
#include <vector>
#include "include/main.h"

#define VOXEL_TYPE_A 1
#define VOXEL_TYPE_B 2

const int ImpSurfSubdivision = 12;  // max 30
//const int GridSubdivision= 3;  Now defined in preferences
const int IntersectRecursion = 14;
const int GridRecursion = 1;

class ImplicitSurface;

class Voxel {
	private:
		int type;
		bool value;
		int coordi[3];
		float coordf[3];
		bool vertices_intersects_calc[18];
		float vertices_intersects[18][3];
		float vertices_intersects_norm[18][3];
		int vertices_intersects_norm_avg[18];
		int triangles_num;
		int triangles[10][3];
		ImplicitSurface * surface;
		Voxel **edges;
		static bool(*TestFunc)(gpointer, float, float, float );
		static gpointer obj;
	
	public :
		~Voxel() {}
			
		void set( int a, int b, int c, float x, float y, float z, int type,  bool(*test_func)( gpointer, float, float, float ), gpointer obj, ImplicitSurface *surf );
		void get_triangles();
		void render_triangles();
			
		void set_triangle( int vertices[3], int *edges_in, bool invert );
		void set_vertice_intersect( int vertice, float *coords, float *norm, int norm_avg );
};


class ImplicitSurface	{
	
	private:
		Voxel voxels[ImpSurfSubdivision+3][ImpSurfSubdivision+3][ImpSurfSubdivision+3];
		//float step;
		bool(*TestFunc)(gpointer, float, float, float );
		gpointer obj;
		float *min, *max;
		int GridSubdivision;
	
	public:
		ImplicitSurface( app_objs *appref, bool(*test_func)(gpointer, float , float , float), gpointer obj, float *min, float *max );
		~ImplicitSurface();
	
		Voxel * get_voxel( int x, int y, int z ) { if ( x < 0 || x > ImpSurfSubdivision+3 || y < 0 || y > ImpSurfSubdivision+3 || z < 0 || z > ImpSurfSubdivision+3 ) return NULL; return & voxels[x][y][z]; }
};

#endif
