
#include "FacetBaseData.h"



using namespace jbxl;




///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Facet Base Data
//

void  FacetBaseData::init(int idx, int num)
{
	num_index = idx;
	num_data  = num;
	vcount	  = 3;

	index  	  = NULL;
	vertex 	  = NULL;
	normal 	  = NULL;
	texcrd 	  = NULL;
}


void  FacetBaseData::free(void)
{
	freeNull(index);

	freeNull(vertex);
	freeNull(normal);
	freeNull(texcrd);

	init();
}


bool  FacetBaseData::getm(void)
{
	index = (int*)malloc(sizeof(int)*num_index);

	vertex = (Vector<double>*)malloc(sizeof(Vector<double>)*num_data);
	normal = (Vector<double>*)malloc(sizeof(Vector<double>)*num_data);
	texcrd = (UVMap<double>*) malloc(sizeof(UVMap<double>) *num_data);

	if (index==NULL || vertex==NULL || normal==NULL || texcrd==NULL) {
		this->free();
		return false;
	}

	return true;
}


void  FacetBaseData::dup(FacetBaseData a)
{
	num_index = a.num_index;
	num_data  = a.num_data;
	vcount    = a.vcount;

	if (getm()) {
		for (int i=0; i<num_index; i++) index[i] = a.index[i];
		for (int i=0; i<num_data;  i++) {
			vertex[i] = a.vertex[i];
			normal[i] = a.normal[i];
			texcrd[i] = a.texcrd[i];
		}
	}
	return;
}


void  FacetBaseData::execScale(Vector<double> scale)
{
	for (int i=0; i<num_data;  i++) {
		vertex[i].x *= scale.x;
		vertex[i].y *= scale.y;
		vertex[i].z *= scale.z;
	}
}


void  FacetBaseData::execShift(Vector<double> shift)
{
	for (int i=0; i<num_data; i++) {
		vertex[i].x += shift.x;
		vertex[i].y += shift.y;
		vertex[i].z += shift.z;
	}
}


void  FacetBaseData::execRotate(Quaternion quat)
{
	for (int i=0; i<num_data; i++) {
		vertex[i] = VectorRotation(vertex[i], quat);
		normal[i] = VectorRotation(normal[i], quat);
	}
}




///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Triangle Polygon Data
//

void  TriPolyData::init(void)
{
	facetNum   = -1;
	has_normal = false;
	has_texcrd = false;
}


void  TriPolyData::dup(TriPolyData a)
{
	*this = a;
}


void  TriPolyData::execScale(Vector<double> scale)
{
	for (int i=0; i<3; i++) {
		vertex[i].x *= scale.x;
		vertex[i].y *= scale.y;
		vertex[i].z *= scale.z;
	}
}


void  TriPolyData::execShift(Vector<double> shift)
{
	for (int i=0; i<3; i++) {
		vertex[i].x += shift.x;
		vertex[i].y += shift.y;
		vertex[i].z += shift.z;
	}
}


void  TriPolyData::execRotate(Quaternion quat)
{
	for (int i=0; i<3; i++) {
		vertex[i] = VectorRotation(vertex[i], quat);
		normal[i] = VectorRotation(normal[i], quat);
	}
}




//////////////////////////////////////////////////////////////////////////////////
//

TriPolyData* jbxl::dupTriPolyData(TriPolyData* data, int num)
{
	if (data==NULL) return NULL;

	TriPolyData* dup = (TriPolyData*)malloc(num*sizeof(TriPolyData));
	if (dup==NULL) return NULL;

	for (int i=0; i<num; i++) dup[i].dup(data[i]);
	return dup;
}



TriPolyData*  jbxl::joinTriPolyData(TriPolyData*& first, int num_f, TriPolyData*& next, int num_n)
{
	if (first==NULL) return next;
	if (next ==NULL) return first;

	TriPolyData* join = (TriPolyData*)malloc((num_f+num_n)*sizeof(TriPolyData));
	if (join==NULL) return NULL;
	
	int fnum = 0;
	for (int i=0; i<num_f; i++) {
		join[i].dup(first[i]);
		if (join[i].facetNum>fnum) fnum = join[i].facetNum;
	}
	fnum += 1;

	for (int i=0; i<num_n; i++) {
		join[num_f+i].dup(next[i]);
		join[num_f+i].facetNum += fnum;
	}

	freeTriPolyData(first, num_f);
	freeTriPolyData(next,  num_n);

	return join;
}



void  jbxl::freeTriPolyData(TriPolyData*& tridata, int n)
{
	if (tridata!=NULL) {
		for (int i=0; i<n; i++) {
			tridata[i].free();
		}
 		::free(tridata);
 		tridata = NULL;
	}
}




