bool compute(const float* verticesIn,int verticesInLength,const int* indicesIn,int indicesInLength,float decimationPercentage,std::vector<float>& verticesOut,std::vector<int>& indicesOut)
{
		Mesh mesh;
		Decimater   decimater(mesh);

		HModQuadric hModQuadric;
		decimater.add(hModQuadric);
		decimater.module(hModQuadric).unset_max_err();
	

//		HModRoundness hModRoundness; 
//		decimater.add(hModRoundness);
//		decimater.module(hModRoundness).set_binary(false);

//		HModHausdorff hModHausdorff; 
//		decimater.add(hModHausdorff);
//		decimater.module(hModHausdorff).set_binary(false);

//		HModAspectRatio hModAspectRatio; 
//		decimater.add(hModAspectRatio);
//		decimater.module(hModAspectRatio).set_binary(false);

//		HModNormalDeviation hModNormalDeviation; 
//		decimater.add(hModNormalDeviation);
//		decimater.module(hModNormalDeviation).set_binary(false);


		std::vector<Mesh::VertexHandle> vhandles;
		for (int i=0;i<verticesInLength/3;i++)
			vhandles.push_back(mesh.add_vertex(Mesh::Point(verticesIn[3*i+0],verticesIn[3*i+1],verticesIn[3*i+2])));

		std::vector<Mesh::VertexHandle> face_vhandles;
		for (int i=0;i<indicesInLength/3;i++)
		{
			face_vhandles.clear();
			face_vhandles.push_back(vhandles[indicesIn[3*i+0]]);
			face_vhandles.push_back(vhandles[indicesIn[3*i+1]]);
			face_vhandles.push_back(vhandles[indicesIn[3*i+2]]);
			mesh.add_face(face_vhandles);
		}

		decimater.initialize();
		decimater.decimate_to_faces(0,int(decimationPercentage*float(indicesInLength/3)));
		mesh.garbage_collection();

		verticesOut.clear();
		Mesh::VertexHandle vh;
		OpenMesh::Vec3f v;
		for (int i=0;i<int(mesh.n_vertices());i++)
		{
			vh = Mesh::VertexHandle(i);
			v  = mesh.point(vh);
			verticesOut.push_back(v[0]);
			verticesOut.push_back(v[1]);
			verticesOut.push_back(v[2]);
		}

		indicesOut.clear();
		Mesh::FaceHandle fh;
		OpenMesh::ArrayItems::Face f;
		for (int i=0;i<int(mesh.n_faces());i++)
		{
			fh = Mesh::FaceHandle(i);
			mesh.cfv_iter(fh);
			OpenMesh::PolyConnectivity::ConstFaceVertexIter cfv_it=mesh.cfv_iter(fh);
			indicesOut.push_back(cfv_it->idx());
			++cfv_it;
			indicesOut.push_back(cfv_it->idx());
			++cfv_it;
			indicesOut.push_back(cfv_it->idx());
		}
		return((verticesOut.size()>=9)&&(indicesOut.size()>=3));
}
Exemple #2
0
void	CBuild::BuildCForm	()
{
	Phase			("CFORM: construction...");
	//Status		("Building base mesh : vertices...");

	_mesh			mesh;						// a mesh object
	_decimater		decimater(mesh);			// a decimater object, connected to a mesh
	_HModQuadric	hModQuadric;				// use a quadric module
	decimater.add	(hModQuadric);				// register module at the decimater
	decimater.module(hModQuadric).set_max_err	(0.0001,false);	// error-limit 0.0001

	// Initializing mesh
	Status			("Building base mesh : vertices[%d]...",g_vertices.size());
	for (vecVertexIt _v=g_vertices.begin(); _v!=g_vertices.end(); _v++)	(*_v)->handle	= _mesh::InvalidVertexHandle.idx();

	Status			("Building base mesh : base faces[%d]...",g_faces.size());
	std::vector <_mesh::VertexHandle>	fhandles;
	xr_vector	<cform_FailFace>		failedfaces;
	cform_mergeprops					fmergeprops;

	for (vecFaceIt I=g_faces.begin(); I!=g_faces.end(); I++)
	{
		Progress	(float(I-g_faces.begin())/float(g_faces.size()));
		Face* F		= *I;
		if (F->Shader().flags.bCollision) 
		{
			// test correctness
			TestEdge	(F->v[0],F->v[1],F);
			TestEdge	(F->v[1],F->v[2],F);
			TestEdge	(F->v[2],F->v[0],F);

			// add vertices
			fhandles.clear	();
			for (u32 v=0; v<3; v++)
			{
				_mesh::VertexHandle	h	= _mesh::VertexHandle(F->v[v]->handle);
				if (_mesh::InvalidVertexHandle == h)	{ 
					Fvector& p			= F->v[v]->P; 
					h					= mesh.add_vertex	(_mesh::Point(p.x,p.y,p.z));
					F->v[v]->handle		= h.idx();
				}
				fhandles.push_back	(h);
			}

			// add face
			fmergeprops.material		= F->dwMaterialGame;
			fmergeprops.sector			= materials[F->dwMaterial].sector;
			_mesh::FaceHandle	hface	= mesh.add_face		(fhandles);
			if (hface == _mesh::InvalidFaceHandle)	{
				failedfaces.push_back		(cform_FailFace());
				failedfaces.back().P[0]		= F->v[0]->P;
				failedfaces.back().P[1]		= F->v[1]->P;
				failedfaces.back().P[2]		= F->v[2]->P;
				failedfaces.back().props	= fmergeprops.props;
			}
			else				mesh.face(hface).set_props	(fmergeprops.props);
		}
	}
	if (bCriticalErrCnt) {
		err_save	();
		clMsg		("MultipleEdges: %d faces",bCriticalErrCnt);
	}

	Status			("Building base mesh : models[%d]...",mu_refs.size());
	mesh.garbage_collection		();
	for (u32 ref=0; ref<mu_refs.size(); ref++)
		mu_refs[ref]->export_cform_game(mesh,failedfaces);

	Status			("Building base mesh : normals...");
	mesh.garbage_collection		();
	mesh.request_vertex_normals	();
	mesh.update_vertex_normals	();

	// Decimate
	Status			("Reconstructing mesh-topology...");
	clMsg			("%d faces failed topology check",	failedfaces.size());
	clMsg			("%f%% geometry/artist quality",	100.f * (1-float(failedfaces.size())/float(mesh.n_faces())));

	decimater.initialize	();      // let the decimater initialize the mesh and the modules

	int		nf_before		= int	(mesh.n_faces());
	int		nv_before		= int	(mesh.n_vertices());
	int		nc				= decimater.decimate	(nv_before);	// do decimation, as large, as possible
							mesh.garbage_collection	();
	int		nf_after		= int	(mesh.n_faces());
	int		nv_after		= int	(mesh.n_vertices());
	clMsg					("vertices: was[%d], now[%d] => %f %% left",nv_before,nv_after, 100.f*float(nv_after)/float(nv_before) );
	clMsg					("   faces: was[%d], now[%d] => %f %% left",nf_before,nf_after, 100.f*float(nf_after)/float(nf_before) );

	// Decimate
	Status			("Refactoring CFORM...");
	Fbox BB;	BB.invalidate();
	_mesh::VertexIter	vit	=mesh.vertices_begin(),vend=mesh.vertices_end();
	for (; vit!=vend; ++vit)
		BB.modify( reinterpret_cast<Fvector&>(mesh.point(vit)) );

	CDB::CollectorPacked	CL(BB,mesh.n_vertices(),mesh.n_faces());
	_mesh::FaceIter			fit=mesh.faces_begin(),fend=mesh.faces_end();
	for (; fit!=fend; ++fit){
		// get vertex-handles
		fhandles.clear	();
		for (_mesh::CFVIter fv_it=mesh.cfv_iter(fit); fv_it; ++fv_it)
			fhandles.push_back	(fv_it.handle());
		CL.add_face_D	(
			reinterpret_cast<Fvector&>(mesh.point	(fhandles[0])),
			reinterpret_cast<Fvector&>(mesh.point	(fhandles[1])),
			reinterpret_cast<Fvector&>(mesh.point	(fhandles[2])),
			fit->props	()
			);
	}
	Status			("Restoring fail-faces...");
	for (u32 it=0; it<failedfaces.size(); it++)		{
		cform_FailFace&	F	= failedfaces[it];
		CL.add_face_D		( F.P[0], F.P[1], F.P[2], F.props );
	}

	// Saving
	Status			("Saving...");
			nf_after		= int	(CL.getTS());
			nv_after		= int	(CL.getVS());
	clMsg					("vertices: was[%d], now[%d] => %f %% left",nv_before,nv_after, 100.f*float(nv_after)/float(nv_before) );
	clMsg					("   faces: was[%d], now[%d] => %f %% left",nf_before,nf_after, 100.f*float(nf_after)/float(nf_before) );
	string512		fn;
	IWriter*		MFS	= FS.w_open	(strconcat(fn,pBuild->path,"level.cform"));
	
	// Header
	hdrCFORM		hdr;
	hdr.version		= CFORM_CURRENT_VERSION;
	hdr.vertcount	= (u32)CL.getVS();
	hdr.facecount	= (u32)CL.getTS();
	hdr.aabb		= BB;
	MFS->w			(&hdr,sizeof(hdr));
	// Data
	MFS->w			(CL.getV(),(u32)CL.getVS()*sizeof(Fvector));
	MFS->w			(CL.getT(),(u32)CL.getTS()*sizeof(CDB::TRI));
	// Clear pDeflector (it is stored in the same memory space with dwMaterialGame)
	for (vecFaceIt I=g_faces.begin(); I!=g_faces.end(); I++)	{
		Face* F			= *I;
		F->pDeflector	= NULL;
	}
	FS.w_close		(MFS);
}