Example #1
0
void fsExperiments::setupVbo()
{
	GlobalData& data = GlobalData::get();
	TriMesh neutralMesh = data.mFaceShift.getNeutralMesh();
	size_t numVertices = neutralMesh.getNumVertices();
	size_t numBlendShapes = data.mFaceShift.getNumBlendshapes();

	gl::VboMesh::Layout layout;

	layout.setStaticPositions();
	layout.setStaticIndices();
	layout.setStaticNormals();
	layout.setStaticTexCoords2d();

	// TODO: int attribute
	layout.mCustomStatic.push_back( std::make_pair( gl::VboMesh::Layout::CUSTOM_ATTR_FLOAT, 0 ) );

	data.mVboMesh = gl::VboMesh( neutralMesh.getNumVertices(),
							neutralMesh.getNumIndices(), layout, GL_TRIANGLES );

	data.mVboMesh.bufferPositions( neutralMesh.getVertices() );
	data.mVboMesh.bufferIndices( neutralMesh.getIndices() );
	if ( !neutralMesh.hasNormals() )
		neutralMesh.recalculateNormals();
	data.mVboMesh.bufferNormals( neutralMesh.getNormals() );
	data.mVboMesh.bufferTexCoords2d( 0, neutralMesh.getTexCoords() );
	data.mVboMesh.unbindBuffers();

	vector< float > vertexIndices( numVertices, 0.f );
	for ( uint32_t i = 0; i < numVertices; ++i )
		vertexIndices[ i ] = static_cast< float >( i );

	data.mVboMesh.getStaticVbo().bind();
	size_t offset = sizeof( GLfloat ) * ( 3 + 3 + 2 ) * neutralMesh.getNumVertices();
	data.mVboMesh.getStaticVbo().bufferSubData( offset,
			numVertices * sizeof( float ),
			&vertexIndices[ 0 ] );
	data.mVboMesh.getStaticVbo().unbind();

	// blendshapes texture
	gl::Texture::Format format;
	format.setTargetRect();
	format.setWrap( GL_CLAMP, GL_CLAMP );
	format.setMinFilter( GL_NEAREST );
	format.setMagFilter( GL_NEAREST );
	format.setInternalFormat( GL_RGB32F_ARB );

	int verticesPerRow = 32;
	int txtWidth = verticesPerRow * numBlendShapes;
	int txtHeight = math< float >::ceil( numVertices / (float)verticesPerRow );

	Surface32f blendshapeSurface = Surface32f( txtWidth, txtHeight, false );
	float *ptr = blendshapeSurface.getData();

	size_t idx = 0;
	for ( int j = 0; j < txtHeight; j++ )
	{
		for ( int s = 0; s < verticesPerRow; s++ )
		{
			for ( size_t i = 0; i < numBlendShapes; i++ )
			{
				*( reinterpret_cast< Vec3f * >( ptr ) ) = data.mFaceShift.getBlendshapeMesh( i ).getVertices()[ idx ] - neutralMesh.getVertices()[ idx ];
				ptr += 3;
			}
			idx++;
		}
	}

	data.mBlendshapeTexture = gl::Texture( blendshapeSurface, format );
}
	bool exactProbability(const context::inputGraph& inputGraph, std::vector<mpfr_class>& probabilities, mpfr_class& result, std::string& error)
	{
		error = "";
		const std::size_t nVertices = boost::num_vertices(inputGraph);
		if(probabilities.size() == 1)
		{
			probabilities.insert(probabilities.begin(), nVertices - 1, probabilities.front());
		}
		if(nVertices > 36)
		{
			error = "Maximum allowable number of vertices is 36.";
			return false;
		}
		if(probabilities.size() != nVertices)
		{
			error = "Length of input probabilities was different from the number of vertices";
			return false;
		}
		std::vector<mpfr_class> complementaryProbabilities;
		for(std::vector<mpfr_class>::iterator i = probabilities.begin(); i != probabilities.end(); i++)
		{
			complementaryProbabilities.push_back(1 - *i);
		}
		const counterType maximumState = 1LL << nVertices;
	
		result = 0;
#ifdef USE_OPENMP
		#pragma omp parallel 
#endif
		{		
			mpfr_class privateResult = 0;

			std::vector<int> connectedComponents(nVertices);
			std::vector<int> vertexIndices(nVertices);
			typedef boost::adjacency_matrix<boost::undirectedS> graphType;
			graphType graph(nVertices, boost::no_property());
#ifdef USE_OPENMP
			#pragma omp for
#endif
			for(counterType state = 0; state < maximumState; state++)
			{
				//first the vertices
				int nVerticesSubgraph = 0;
				for(int vertexCounter = 0; vertexCounter < (int)nVertices; vertexCounter++)
				{
					if(state & (1LL << vertexCounter)) 
					{
						vertexIndices[vertexCounter] = nVerticesSubgraph++;
					}
				}
				graph.m_matrix.clear();
				graph.m_matrix.resize(nVerticesSubgraph * (nVerticesSubgraph+ 1) / 2);
				graph.m_vertex_set = graphType::VertexList(0, nVerticesSubgraph);
				
				graph.m_vertex_properties.clear();
				graph.m_vertex_properties.resize(nVerticesSubgraph);
				graph.m_num_edges = 0;

				//now the edges
				context::inputGraph::edge_iterator start, end;
				boost::tie(start, end) = boost::edges(inputGraph);
				while(start != end)
				{
					if((state & (1LL << start->m_source)) && (state & (1LL << start->m_target)))
					{
						boost::add_edge(vertexIndices[start->m_source], vertexIndices[start->m_target], graph);
					}
					start++;
				}
				int nComponents = boost::connected_components(graph, &(connectedComponents[0]));
				if(nComponents <= 1)
				{
					mpfr_class currentTerm = 1;
					for(int vertexCounter = 0; vertexCounter < (int)nVertices; vertexCounter++)
					{
						if(state & (1LL << vertexCounter)) currentTerm *= probabilities[vertexCounter];
						else currentTerm *= complementaryProbabilities[vertexCounter];
					}
					privateResult += currentTerm;
				}
			}
#ifdef USE_OPENMP
			#pragma omp critical
#endif
			{
				result += privateResult;
			}
		}
		return true;
	}