double cosSim(const SparseArray& a, const SparseArray& b) { double ab = 0, a2 = 0, b2 = 0; auto i = a.begin(), j = b.begin(); while(i != a.end() || j != b.end()) { if(i == a.end()) { b2 += j->value * j->value; ++j; } else if(j == b.end()) { a2 += i->value * i->value; ++i; } else if((*i) < (*j)) { a2 += i->value * i->value; ++i; } else if((*j) < (*i)) { b2 += j->value * j->value; ++j; } else { a2 += i->value * i->value; b2 += j->value * j->value; ab += i->value * j->value; ++i; ++j; } } if(a2 == 0 || b2 == 0) { return 1.0; } else { //cout << "ab=" << ab << " a2=" << a2 << " b2=" << b2 << endl; return ab / sqrt(a2*b2); } }
void ExpMapGenerator::GetVertexFaceUVs( std::vector<unsigned int> & vIDs, std::vector<float> & vU, std::vector<float> & vV, std::vector<unsigned int> & vFaces, rms::VFTriangleMesh * pMesh ) { SparseArray<IMesh::TriangleID> vTris; vTris.resize(pMesh->GetMaxTriangleID()); // mark triangles that have at least one vertex UV set size_t nLastCount = m_vLastParticles.size(); for ( unsigned int k = 0; k < nLastCount; ++k ) { ExpMapParticle * pParticle = m_vLastParticles[k]; if ( pParticle->VertexID() == IMesh::InvalidID || pParticle->SurfaceDistance() == std::numeric_limits<float>::max() ) continue; IMesh::VtxNbrItr itr(pParticle->VertexID()); pMesh->BeginVtxTriangles(itr); IMesh::TriangleID tID = pMesh->GetNextVtxTriangle(itr); while ( tID != IMesh::InvalidID ) { vTris.set(tID, tID); tID = pMesh->GetNextVtxTriangle(itr); } } // generate list of triangles with all vertex UVs set, and mark vertices SparseArray<IMesh::VertexID> vVerts; vVerts.resize(pMesh->GetMaxVertexID()); SparseArray<IMesh::TriangleID>::iterator curf(vTris.begin()), endf(vTris.end()); while ( curf != endf ) { IMesh::TriangleID tID = curf.index(); curf++; IMesh::VertexID nTri[3]; pMesh->GetTriangle(tID, nTri); bool b1 = m_vParticles[ m_vVtxToParticleMap[nTri[0]] ]->SurfaceDistance() != std::numeric_limits<float>::max(); bool b2 = m_vParticles[ m_vVtxToParticleMap[nTri[1]] ]->SurfaceDistance() != std::numeric_limits<float>::max(); bool b3 = m_vParticles[ m_vVtxToParticleMap[nTri[2]] ]->SurfaceDistance() != std::numeric_limits<float>::max(); if ( b1 && b2 && b3 ) { vVerts.set(nTri[0], nTri[0]); vVerts.set(nTri[2], nTri[1]); vVerts.set(nTri[1], nTri[2]); vFaces.push_back(tID); } } // generate list of vertices and UVs who are contained in at least one triangle SparseArray<IMesh::VertexID>::iterator curv(vVerts.begin()), endv(vVerts.end()); while ( curv != endv ) { IMesh::VertexID vID = curv.index(); ++curv; int nIndex = m_vVtxToParticleMap[vID]; vIDs.push_back(vID); vU.push_back( m_vParticles[nIndex]->SurfaceVector().X() ); vV.push_back( m_vParticles[nIndex]->SurfaceVector().Y() ); } }
/** * Read a topic vector file * The format of these files are such that each line is: * idx1 idx2 ... idxN ||| val1 val2 ... valN * Which represents a coordinate form sparse array * @param t Vector to write to * @param fname The file name to read from */ void readTopicFile(vector<SparseArray>& t, const char *fname) { cerr << "Reading " << fname << endl; int linesRead = 1; ifstream topic1file(fname,ifstream::in); if(topic1file.fail()) { cerr << "Failed to read " << fname << endl; return; } string line; while(getline(topic1file,line)) { stringstream ss(line); ss.exceptions(ifstream::failbit); if(linesRead % 10 == 0) { cerr << "."; } cerr.flush(); linesRead++; SparseArray arr; while(ss.peek() != '|') { SparseArrayElem e; ss >> e.idx; arr.push_back(e); while(ss.peek() == ' ') { ss.get(); } } while(ss.peek() == '|' || ss.peek() == ' ') { ss.get(); } unsigned vals = 0; for(auto it = arr.begin(); it != arr.end(); ++it) { if(++vals > arr.size()) { throw runtime_error("Index and value length differ (too many values)"); } ss >> it->value; } if(vals != arr.size()) { throw runtime_error("Index and value length differ (too few values)"); } sort(arr.begin(),arr.end()); t.push_back(arr); } cerr << "OK" << endl; }