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; }