//#pragma hdrstop

#include <GL/glew.h> //Должен стоять до "wx/gl...h"
#include <GL/glu.h>

#include <wx/glcanvas.h>
#include <wx/string.h>

#include "object3d.h"
#include "texture.h"
#include "mathTools.h"
//#include "tools/debug.h"

//---------------------------------------------------------------------------
TTriMat::TTriMat()
{
	textureid=0;
	ColorAmbientRGB.r=0.2f; // 0.2 по умолчанию в OpenGL
	ColorAmbientRGB.g=0.2f;
	ColorAmbientRGB.b=0.2f;
	ColorAmbientRGB.a=1.0f;
	ColorDiffuseRGB.r=0.8f; // 0.8 по умолчанию в OpenGL
	ColorDiffuseRGB.g=0.8f;
	ColorDiffuseRGB.b=0.8f;
	ColorDiffuseRGB.a=1.0f;
	ColorSpecularRGB.r=0.0f; // 0.0 по умолчанию в OpenGL
	ColorSpecularRGB.g=0.0f;
	ColorSpecularRGB.b=0.0f;
	ColorSpecularRGB.a=1.0f;
	USCALE=1.0f;
	VSCALE=1.0f;
}
//---------------------------------------------------------------------------
void TTriMat::Release()
{
	//прозрачность
	glDisable(GL_COLOR_MATERIAL);
	glEnable(GL_LIGHTING);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&ColorAmbientRGB);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&ColorDiffuseRGB);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&ColorSpecularRGB);
	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f); //яркость источника цвета от 0 до 128

	//если текстурированна
	if(textureid!=0)
	{
		glBindTexture(GL_TEXTURE_2D, textureid);
		glEnable(GL_TEXTURE_2D);
		//чтобы цвет не воздействовал на текстуру если она есть
		glEnable(GL_COLOR_MATERIAL);
		glColor4f(1,1,1,ColorDiffuseRGB.a);
		glDisable(GL_COLOR_MATERIAL);
	} else glDisable(GL_TEXTURE_2D);
}
//---------------------------------------------------------------------------
TTriangles::TTriangles()
{
	del=false;
	bSmooth=false;
	CountVertex=0;
	CountFaces=0;
	//countMapPoint=0;
	Vertices=NULL;
	SmoothNormals=NULL;
	faces=NULL;
	TexVertices=NULL;
	SmoothG=NULL;
	bInit=false;
	//разбивка по материалам
	countMF=0;
	MatFaces=NULL;
	//материал (после разбивки)
	TriMat=NULL;

}
//------------------------------------------------------------------------------
TTriangles::~TTriangles()
{
	if (Vertices!=NULL) delete[] Vertices;
	Vertices=NULL;
	if (SmoothNormals!=NULL) delete[] SmoothNormals;
	SmoothNormals=NULL;
	if (faces!=NULL) delete[] faces;
	faces=NULL;
	if (TexVertices!=NULL) delete[] TexVertices;
	TexVertices=NULL;
	if (SmoothG!=NULL) delete[] SmoothG;
	SmoothG=NULL;
	if (bInit)
	{
		glDeleteBuffersARB(1,&vbov);
		glDeleteBuffersARB(1,&vbot);
		glDeleteBuffersARB(1,&vbon);
		glDeleteBuffersARB(1,&vbof);
	}

	for(unsigned int i=0;i<countMF;i++)
	{
		delete[] MatFaces[i].name;
		delete[] MatFaces[i].faces;
	}
	if(MatFaces!=NULL) delete[] MatFaces;
	MatFaces=NULL;
}
//------------------------------------------------------------------------------
//TODO предусмотреть загрузку в видео память как 1го объекта так и группы (если группой то здесь сохраняется указатель и смещение к нужному объекту)
void TTriangles::render()
{
	if(TexVertices==NULL) TexVertices = new RfPointXY[CountVertex];
	//if(Material!=NULL) Material.Release();

	if(!bSmooth) glShadeModel(GL_FLAT); else glShadeModel(GL_SMOOTH);

	//передаём указатели на массивы и рендерим
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	/*RdPointXYZ *d=new RdPointXYZ[CountVertex];
	for(unsigned int i=0;i<CountVertex;i++)
	{
		d[i].x=Vertices[i].x;
		d[i].y=Vertices[i].y;
		d[i].z=Vertices[i].z;
	}
	glVertexPointer(3,GL_DOUBLE,0,&d[0]);*/

	glVertexPointer(3,GL_FLOAT,0,&Vertices[0]);
	glNormalPointer(GL_FLOAT, 0, &SmoothNormals[0]);
	glTexCoordPointer(2,GL_FLOAT, 0, &TexVertices[0]);
	glDrawElements(GL_TRIANGLES, CountFaces*3, GL_UNSIGNED_SHORT, &faces[0]);
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);


	//delete[] d;
/**/
  /*if (!bInit)
  {
	//огромные переделки:
	//однотипные обьекты должны храниться в одном vbov значит рендеринг должен быть преобразован в другой вид а именно
	//с начала идет цикл по всем созданным VBO он биндиться потом цикл по моделям(смещениям) в этом VBO здесь применяеться механизм отсечения потом
	//потом применяеться подходящяя текстура потом собственно glDrawElements

    glGenBuffersARB(1,&vbov);
	glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbov );
	glBufferDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*sizeof(RfPointXYZ), &fPointXYZ[0], GL_STATIC_DRAW_ARB);

    glGenBuffersARB(1,&vbot);
	glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbot );
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*sizeof(RfPointXY), &fMapPointXY[0], GL_STATIC_DRAW_ARB );

    glGenBuffersARB(1,&vbon);
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbon );
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*sizeof(RfPointXYZ), &fNormalXYZ[0], GL_STATIC_DRAW_ARB );

    glGenBuffersARB(1,&vbof);
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbof);
    glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, p_object->faces*sizeof(RsFacesABC), &face[0], GL_STATIC_DRAW_ARB);

    bInit=true;
  }
  //  vbov,vbon,vbot,vbof :TGLuint; //вершины,нормали,текстура,рёбра
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState( GL_NORMAL_ARRAY );
  glEnableClientState( GL_TEXTURE_COORD_ARRAY );

  glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbov);
  glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );

  glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbot);
  glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL );

  glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbon);
  glNormalPointer( GL_FLOAT, 0, (char *) NULL );

  glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbof);
  glDrawElements(GL_TRIANGLES, p_object->faces*3 ,GL_UNSIGNED_SHORT, NULL);

  //биндим нулевой буфер
  glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
  glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0);

  glDisableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_NORMAL_ARRAY);
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
/**/
}
//------------------------------------------------------------------------------
void TTriangles::CalcMinMaxPoint()
{
	if(CountVertex>0)
	{
		MaxPointXYZ.x=Vertices[0].x;
		MaxPointXYZ.y=Vertices[0].y;
		MaxPointXYZ.z=Vertices[0].z;
		MinPointXYZ.x=Vertices[0].x;
		MinPointXYZ.y=Vertices[0].y;
		MinPointXYZ.z=Vertices[0].z;
	}
	for(unsigned int i=1;i<CountVertex;i++)
	{
		if(MaxPointXYZ.x<Vertices[i].x) MaxPointXYZ.x=Vertices[i].x;
		if(MaxPointXYZ.y<Vertices[i].y) MaxPointXYZ.y=Vertices[i].y;
		if(MaxPointXYZ.z<Vertices[i].z) MaxPointXYZ.z=Vertices[i].z;

		if(MinPointXYZ.x>Vertices[i].x) MinPointXYZ.x=Vertices[i].x;
		if(MinPointXYZ.y>Vertices[i].y) MinPointXYZ.y=Vertices[i].y;
		if(MinPointXYZ.z>Vertices[i].z) MinPointXYZ.z=Vertices[i].z;
	}
	PointXYZCenter.x=(MinPointXYZ.x+MaxPointXYZ.x)/2.0f;
	PointXYZCenter.y=(MinPointXYZ.y+MaxPointXYZ.y)/2.0f;
	PointXYZCenter.z=(MinPointXYZ.z+MaxPointXYZ.z)/2.0f;


/*	//DOTO есть такие параметры как сдвиг вращения масштаб я здесь учитываю только масштаб и сдвиг
	MaxPointXYZ.x=(MaxPointXYZ.x*ScaleXYZ.x)+ShiftXYZ.x;
	MaxPointXYZ.y=(MaxPointXYZ.y*ScaleXYZ.y)+ShiftXYZ.y;
	MaxPointXYZ.z=(MaxPointXYZ.z*ScaleXYZ.z)+ShiftXYZ.z;
	MinPointXYZ.x=(MinPointXYZ.x*ScaleXYZ.x)+ShiftXYZ.x;
	MinPointXYZ.y=(MinPointXYZ.y*ScaleXYZ.y)+ShiftXYZ.y;
	MinPointXYZ.z=(MinPointXYZ.z*ScaleXYZ.z)+ShiftXYZ.z;

	//так как выделяем обьект по попаданию точки в нутырь куба для плоских обьектов немного расширем пространиство
	MaxPointXYZ.x=MaxPointXYZ.x+0.001;
	MaxPointXYZ.y=MaxPointXYZ.y+0.001;
	MaxPointXYZ.z=MaxPointXYZ.z+0.001;
	MinPointXYZ.x=MinPointXYZ.x-0.001;
	MinPointXYZ.y=MinPointXYZ.y-0.001;
	MinPointXYZ.z=MinPointXYZ.z-0.001;*/
}
//------------------------------------------------------------------------------
//просчитать сглаживающие нормали к поверхности
void TTriangles::CalcSmoothNormals()
{
	unsigned int j;
	if(SmoothNormals==NULL) SmoothNormals=new RfPointXYZ[CountVertex]; //память под нормали к точке
	//если отключенно сглаживание то учитываеться только последний вектор к грани
	if(!bSmooth)
	{
		for(j=0;j<CountVertex;j++)
		{
			SmoothNormals[j].x=0;
			SmoothNormals[j].y=0;
			SmoothNormals[j].z=0;
		}
		for(j=0;j<CountFaces;j++)
		{
			CalcNormals(Vertices[faces[j].a].x,Vertices[faces[j].a].y,Vertices[faces[j].a].z,Vertices[faces[j].b].x,Vertices[faces[j].b].y,Vertices[faces[j].b].z,Vertices[faces[j].c].x,Vertices[faces[j].c].y,Vertices[faces[j].c].z,SmoothNormals[faces[j].c].x,SmoothNormals[faces[j].c].y,SmoothNormals[faces[j].c].z);
		}
	}else
	{
		for(j=0;j<CountVertex;j++)
		{
			SmoothNormals[j].x=0;
			SmoothNormals[j].y=0;
			SmoothNormals[j].z=0;
		}
		unsigned int *mas=new unsigned int[CountVertex];
		for(j=0;j<CountVertex;j++) mas[j]=0; //для усреднения
		//подсчитываем нормали для каждой точки
		RfPointXYZ point;
		for(j=0;j<CountFaces;j++)
		{
			CalcNormals(Vertices[faces[j].a].x,Vertices[faces[j].a].y,Vertices[faces[j].a].z,Vertices[faces[j].b].x,Vertices[faces[j].b].y,Vertices[faces[j].b].z,Vertices[faces[j].c].x,Vertices[faces[j].c].y,Vertices[faces[j].c].z,point.x,point.y,point.z);
			SmoothNormals[faces[j].a].x=SmoothNormals[faces[j].a].x+point.x;
			SmoothNormals[faces[j].a].y=SmoothNormals[faces[j].a].y+point.y;
			SmoothNormals[faces[j].a].z=SmoothNormals[faces[j].a].z+point.z;
			mas[faces[j].a]++;
			SmoothNormals[faces[j].b].x=SmoothNormals[faces[j].b].x+point.x;
			SmoothNormals[faces[j].b].y=SmoothNormals[faces[j].b].y+point.y;
			SmoothNormals[faces[j].b].z=SmoothNormals[faces[j].b].z+point.z;
			mas[faces[j].b]++;
			SmoothNormals[faces[j].c].x=SmoothNormals[faces[j].c].x+point.x;
			SmoothNormals[faces[j].c].y=SmoothNormals[faces[j].c].y+point.y;
			SmoothNormals[faces[j].c].z=SmoothNormals[faces[j].c].z+point.z;
			mas[faces[j].c]++;
		}
		//нормализуем нормали
		for(j=0;j<CountVertex;j++)
		{
			SmoothNormals[j].x=SmoothNormals[j].x/mas[j];
			SmoothNormals[j].y=SmoothNormals[j].y/mas[j];
			SmoothNormals[j].z=SmoothNormals[j].z/mas[j];
			normalized(SmoothNormals[j]); //приведу к еденичной длине
		}
		delete[] mas;
	}
}
//------------------------------------------------------------------------------
void TTriangles::cutOnSmoothGroup()
{
	/*if(SmoothG==NULL)
	{*/
		//груп сглаживания нет то каждая грань имеет единоличные точки
		RfPointXYZ *vbuf=new RfPointXYZ[CountFaces*3];
		RfPointXY *tbuf=new RfPointXY[CountFaces*3];
		unsigned short count=0;
		for(unsigned int i=0;i<CountFaces;i++)
		{
			vbuf[count]=Vertices[faces[i].a];
			if(TexVertices!=NULL) tbuf[count]=TexVertices[faces[i].a];
			faces[i].a=count; //сохраняем новый номер точки
			count++;
			vbuf[count]=Vertices[faces[i].b];
			if(TexVertices!=NULL) tbuf[count]=TexVertices[faces[i].b];
			faces[i].b=count; //сохраняем новый номер точки
			count++;
			vbuf[count]=Vertices[faces[i].c];
			if(TexVertices!=NULL) tbuf[count]=TexVertices[faces[i].c];
			faces[i].c=count; //сохраняем новый номер точки
			count++;
		}
		delete[] Vertices;
		Vertices=vbuf;
		CountVertex=CountFaces*3;
		if(TexVertices!=NULL) delete[] TexVertices;
		TexVertices=tbuf;
	/*}else
	{

	}*/

	CalcSmoothNormals(); //просчитываем сглаживающие нормали к точкам
	delete[] SmoothG;
	SmoothG=NULL;
}
//------------------------------------------------------------------------------
//добавить материал
//название материала,колво элементов, список фейсов с этим материалом
void TTriangles::AddMaterial(char *name,unsigned short count,unsigned short *faces)
{
	RMatFaces *buf=new RMatFaces[countMF+1];
	for(unsigned int i=0;i<countMF;i++) buf[i]=MatFaces[i];
	buf[countMF].name=name;
	buf[countMF].count=count;
	buf[countMF].faces=faces;
	if(MatFaces!=NULL) delete[] MatFaces;
	MatFaces=buf;
	countMF++;
}
//******************************************************************************
TTrianglesList::TTrianglesList()
{
	count=0;
	List=NULL;
	countMat=0; //количество материалов
	ListMat=NULL; //массив материалов
}
//------------------------------------------------------------------------------
TTrianglesList::~TTrianglesList()
{
	for(unsigned int i=0;i<count;i++) delete List[i];
	if(List!=NULL) delete[] List;
	count=4294967295; //на всяк.

	for(unsigned int i=0;i<countMat;i++) delete ListMat[i];
	if(ListMat!=NULL) delete[] ListMat;
	countMat=4294967295; //на всяк.
}
//------------------------------------------------------------------------------
TTriangles* TTrianglesList::Add()
{
	TTriangles **buf = new TTriangles*[count+1];
	for(unsigned int i=0;i<count;i++) buf[i]=List[i];
	buf[count]=new TTriangles();
	if(List!=NULL) delete[] List;
	List=buf;
	return List[count++];
}
//------------------------------------------------------------------------------
//удалить обьект из массива
void TTrianglesList::DelTri(TTriangles* tri)
{
	for(unsigned int i=0;i<count;i++)
	{
		if(List[i]==tri)
		{
			TTriangles **buf = new TTriangles*[count-1];
			unsigned int pos=0;
			for(unsigned int j=0;j<count;j++)
			{
				if(i!=j){buf[pos]=List[j]; pos++;}
			}
			delete[] List;
			delete tri;
			List=buf;
			count--;
			break;
		}
	}
}
//------------------------------------------------------------------------------
//добавить новый метериал
TTriMat* TTrianglesList::AddMat()
{
	TTriMat **buf = new TTriMat*[countMat+1];
	for(unsigned int i=0;i<countMat;i++) buf[i]=ListMat[i];
	buf[countMat]=new TTriMat();
	if(ListMat!=NULL) delete[] ListMat;
	ListMat=buf;
	return ListMat[countMat++];
}
//------------------------------------------------------------------------------
void TTrianglesList::render()
{
	for(unsigned int i=0;i<count;i++)
	{
		TTriangles *tri=List[i];
		if(tri->TriMat!=NULL) tri->TriMat->Release();
		tri->render();
	}
}
//------------------------------------------------------------------------------
void TTrianglesList::CalcMinMaxPoint()
{
	for(unsigned int i=0;i<count;i++)
	{
		TTriangles *tri=List[i];
		tri->CalcMinMaxPoint();
		if(i==0) MinPointXYZ=tri->MinPointXYZ; else
		{
			if(MinPointXYZ.x>tri->MinPointXYZ.x) MinPointXYZ.x=tri->MinPointXYZ.x;
			if(MinPointXYZ.y>tri->MinPointXYZ.y) MinPointXYZ.y=tri->MinPointXYZ.y;
			if(MinPointXYZ.z>tri->MinPointXYZ.z) MinPointXYZ.z=tri->MinPointXYZ.z;
		}
		if(i==0) MaxPointXYZ=tri->MaxPointXYZ; else
		{
			if(MaxPointXYZ.x<tri->MaxPointXYZ.x) MaxPointXYZ.x=tri->MaxPointXYZ.x;
			if(MaxPointXYZ.y<tri->MaxPointXYZ.y) MaxPointXYZ.y=tri->MaxPointXYZ.y;
			if(MaxPointXYZ.z<tri->MaxPointXYZ.z) MaxPointXYZ.z=tri->MaxPointXYZ.z;
		}
	}
	CenterPointXYZ.x=(MaxPointXYZ.x+MinPointXYZ.x)/2.0f;
	CenterPointXYZ.y=(MaxPointXYZ.y+MinPointXYZ.y)/2.0f;
	CenterPointXYZ.z=(MaxPointXYZ.z+MinPointXYZ.z)/2.0f;
}
//------------------------------------------------------------------------------
void TTrianglesList::CalcSmoothNormals()
{
	for(unsigned int i=0;i<count;i++)
	{
		TTriangles *tri=List[i];
		tri->CalcSmoothNormals();
	}
}
//------------------------------------------------------------------------------
void TTrianglesList::cutOnSmoothGroup()
{
	for(unsigned int i=0;i<count;i++)
	{
		TTriangles *tri=List[i];
		tri->cutOnSmoothGroup();
	}
}
//------------------------------------------------------------------------------
TTriMat *TTrianglesList::FindMatOnName(char *name)
{
	for(unsigned int i=0;i<countMat;i++)
	{
		if(wxString::FromAscii(ListMat[i]->name).Lower()==wxString::FromAscii(name).Lower()) return ListMat[i];
	}
	return NULL;
}
//------------------------------------------------------------------------------
//разбить обьект по списку материалов (сколько материалов столшько и объектов будет)
//применять после разбения по группам сглаживания и просчёта нормалей а то на границе между разными материалами не будет сглаживания
void TTrianglesList::cutOnMaterials()
{
	for(unsigned int i=0;i<count;i++)
	{
		TTriangles *tri=List[i];
		if(tri->countMF==1)
		{
			tri->TriMat=FindMatOnName(tri->MatFaces[0].name);
		}else
		if(tri->countMF>1) //если несколько материалов то размножаем объекты
		{
			//в списке фейсов для этого материала раздные точки
			//составляем список уникальных точек затем копируем их
			//память выделяем под самый плохой вариант
			unsigned short *buf=new unsigned short[tri->CountVertex*2]; //уникальные номера точек
			for(unsigned int j=0;j<tri->countMF;j++)
			{
				//создаём новый объект и копируем туда точки в соответствии с материалом
				unsigned int cnt=0;
				for(unsigned int k=0;k<tri->MatFaces[j].count;k++)
				{
					if(tri->MatFaces[j].faces[k]>=tri->CountFaces)
						return;

					bool b=false;
					for(unsigned int q=0;q<cnt;q++)
						if(buf[q]==tri->faces[tri->MatFaces[j].faces[k]].a)
						{
							b=true;
							break;
						}
					if(!b){buf[cnt]=tri->faces[tri->MatFaces[j].faces[k]].a; cnt++;}
					b=false;
					for(unsigned int q=0;q<cnt;q++)
						if(buf[q]==tri->faces[tri->MatFaces[j].faces[k]].b)
						{
							b=true;
							break;
						}
					if(!b){buf[cnt]=tri->faces[tri->MatFaces[j].faces[k]].b; cnt++;}
					b=false;
					for(unsigned int q=0;q<cnt;q++)
						if(buf[q]==tri->faces[tri->MatFaces[j].faces[k]].c)
						{
							b=true;
							break;
						}
					if(!b){buf[cnt]=tri->faces[tri->MatFaces[j].faces[k]].c; cnt++;}
				}
				//выбрали список точек нужных для нового обьекта теперь копируем
				TTriangles* newTri=Add();
				newTri->TriMat=FindMatOnName(tri->MatFaces[j].name);
				newTri->CountVertex=cnt;
				newTri->Vertices=new RfPointXYZ[newTri->CountVertex];
				newTri->TexVertices=new RfPointXY[newTri->CountVertex];
				newTri->SmoothNormals=new RfPointXYZ[newTri->CountVertex];
				newTri->CountFaces=tri->MatFaces[j].count;
				newTri->faces=new RsFacesABC[newTri->CountFaces];
				for(unsigned int k=0;k<cnt;k++) //копируем точки
				{
					newTri->Vertices[k]=tri->Vertices[buf[k]];
					newTri->TexVertices[k]=tri->TexVertices[buf[k]];
					newTri->SmoothNormals[k]=tri->SmoothNormals[buf[k]];
				}
				for(unsigned int k=0;k<tri->MatFaces[j].count;k++)
				{
					newTri->faces[k]=tri->faces[tri->MatFaces[j].faces[k]];
					//ищем номер точки
					bool b=true;
					for(unsigned int q=0;q<cnt;q++){ if(newTri->faces[k].a==buf[q]) {newTri->faces[k].a=q; b=false; break;} }
					if(b||newTri->faces[k].a>=cnt)
						return;
					b=true;
					for(unsigned int q=0;q<cnt;q++){ if(newTri->faces[k].b==buf[q]) {newTri->faces[k].b=q; b=false; break;} }
					if(b||newTri->faces[k].b>=cnt)
						return;
					b=true;
					for(unsigned int q=0;q<cnt;q++){ if(newTri->faces[k].c==buf[q]) {newTri->faces[k].c=q; b=false; break;} }
					if(b||newTri->faces[k].c>=cnt)
						return;
				}
			}
			tri->del=true;
			delete[] buf;
		}
	}

	unsigned int i=0;
	while(i<count)
	{
		TTriangles *tri=List[i];
		//tri->CountVertex;
		if(tri->del)
			DelTri(tri);
		else i++;
	}

	//домножаем текущие координаты материала на USCALE и VSCALE текущего материала

	for(unsigned int i=0;i<count;i++)
	{
		TTriangles *tri=List[i];
		if(tri->TriMat!=NULL)
		for(unsigned int j=0;j<tri->CountVertex;j++)
		{
			tri->TexVertices[j].x*=tri->TriMat->USCALE;
            tri->TexVertices[j].y*=tri->TriMat->VSCALE;
		}
	}
}
//------------------------------------------------------------------------------
