TEX_NAMESPACE_BEGIN

void
find_seam_edges(UniGraph const & graph, mve::TriangleMesh::ConstPtr mesh,
    std::vector<MeshEdge> * seam_edges) {
    mve::TriangleMesh::FaceList const & faces = mesh->get_faces();

    seam_edges->clear();

    // Is it possible that a single edge is part of more than three faces whichs' label is non zero???

    for (std::size_t node = 0; node < graph.num_nodes(); ++node) {
        std::vector<std::size_t> const & adj_nodes = graph.get_adj_nodes(node);
        for (std::size_t adj_node : adj_nodes) {
            /* Add each edge only once. */
            if (node > adj_node) continue;

            int label1 = graph.get_label(node);
            int label2 = graph.get_label(adj_node);
            /* Add only seam edges. */
            //if (label1 == 0 || label2 == 0 || label1 == label2) continue;
            if (label1 == label2) continue;

            /* Find shared edge of the faces. */
            std::vector<std::size_t> shared_edge;
            for (int i = 0; i < 3; ++i){
                std::size_t v1 = faces[3 * node + i];

                for (int j = 0; j < 3; j++){
                    std::size_t v2 = faces[3 * adj_node + j];

                    if (v1 == v2) shared_edge.push_back(v1);
                }
            }

            assert(shared_edge.size() == 2);
            std::size_t v1 = shared_edge[0];
            std::size_t v2 = shared_edge[1];

            assert(v1 != v2);
            if (v1 > v2) std::swap(v1, v2);

            MeshEdge seam_edge = {v1, v2};
            seam_edges->push_back(seam_edge);
        }
    }
}
/** Setup the neighborhood of the MRF. */
void
set_neighbors(UniGraph const & graph, std::vector<FaceInfo> const & face_infos,
    std::vector<mrf::Graph::Ptr> const & mrfs) {
    for (std::size_t i = 0; i < graph.num_nodes(); ++i) {
        std::vector<std::size_t> adj_faces = graph.get_adj_nodes(i);
        for (std::size_t j = 0; j < adj_faces.size(); ++j) {
            std::size_t adj_face = adj_faces[j];
            /* The solver expects only one call of setNeighbours for two neighbours a and b. */
            if (i < adj_face) {
                assert(face_infos[i].component == face_infos[adj_face].component);
                const std::size_t component = face_infos[i].component;
                const std::size_t cid1 = face_infos[i].id;
                const std::size_t cid2 = face_infos[adj_face].id;
                mrfs[component]->set_neighbors(cid1, cid2);
            }
        }
    }
}