<commit_before>#include <test_common.h>

#include <algorithm>
#include <iostream>
#include <vector>

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <igl/cgal/order_facets_around_edges.h>
#include <igl/unique_edge_map.h>
#include <igl/readDMAT.h>
#include <igl/per_face_normals.h>

namespace order_facets_around_edges_test {

typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;

template<typename T>
size_t index_of(const std::vector<T>& array, T val) {
    auto loc = std::find(array.begin(), array.end(), val);
    assert(loc != array.end());
    return loc - array.begin();
}

void assert_consistently_oriented(size_t num_faces,
        const std::vector<int>& expected_face_order,
        const std::vector<int>& e_order) {
    const size_t num_items = expected_face_order.size();
    ASSERT_EQ(num_items, e_order.size());

    std::vector<int> order(num_items);
    std::transform(e_order.begin(), e_order.end(), order.begin(),
            [=](int val) { return val % num_faces; });

    size_t ref_start = index_of(order, expected_face_order[0]);
    for (size_t i=0; i<num_items; i++) {
        ASSERT_EQ(expected_face_order[i], order[(ref_start + i) % num_items]);
    }
}

template<typename DerivedV, typename DerivedF>
void assert_order(
        const Eigen::PlainObjectBase<DerivedV>& V,
        const Eigen::PlainObjectBase<DerivedF>& F,
        size_t v0, size_t v1,
        std::vector<int> expected_order, const std::string& normal="") {
    Eigen::MatrixXi E, uE, EMAP;
    std::vector<std::vector<int> > uE2E;
    igl::unique_edge_map(F, E, uE, EMAP, uE2E);

    std::vector<std::vector<int> > uE2oE;
    std::vector<std::vector<bool> > uE2C;

    if (normal != "") {
        Eigen::MatrixXd N;
        //igl::per_face_normals_stable(V, F, N);
        //igl::per_face_normals(V, F, N);
        test_common::load_matrix(normal, N);
        igl::cgal::order_facets_around_edges(V, F, N, E, uE, EMAP, uE2E, uE2oE, uE2C);
    } else {
        igl::cgal::order_facets_around_edges(V, F, E, uE, EMAP, uE2E, uE2oE, uE2C);
    }

    const size_t num_uE = uE.rows();
    for (size_t i=0; i<num_uE; i++) {
        const auto& order = uE2oE[i];
        const auto& cons  = uE2C[i];
        Eigen::VectorXi e = uE.row(i);
        if (order.size() <= 1) continue;
        if (e[0] != v0 && e[0] != v1) continue;
        if (e[1] != v0 && e[1] != v1) continue;
        if (e[0] == v1 && e[1] == v0) {
            std::reverse(expected_order.begin(), expected_order.end());
        }
        assert_consistently_oriented(F.rows(), expected_order, order);
    }
}

TEST(OrderFacetsAroundEdges, Simple) {
    Eigen::MatrixXd V(4, 3);
    V << 0.0, 0.0, 0.0,
         1.0, 0.0, 0.0,
         0.0, 1.0, 0.0,
         1.0, 1.0, 0.0;<commit_msg>Updated API for order_facets_around_edges().<commit_after>#include <test_common.h>

#include <algorithm>
#include <iostream>
#include <vector>

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <igl/cgal/order_facets_around_edges.h>
#include <igl/unique_edge_map.h>
#include <igl/readDMAT.h>
#include <igl/per_face_normals.h>

namespace order_facets_around_edges_test {

typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;

template<typename T>
size_t index_of(const std::vector<T>& array, T val) {
    auto loc = std::find(array.begin(), array.end(), val);
    assert(loc != array.end());
    return loc - array.begin();
}

void assert_consistently_oriented(size_t num_faces,
        const std::vector<int>& expected_face_order,
        const std::vector<int>& e_order) {
    const size_t num_items = expected_face_order.size();
    ASSERT_EQ(num_items, e_order.size());

    std::vector<int> order(num_items);
    std::transform(e_order.begin(), e_order.end(), order.begin(),
            [=](int val) { return val % num_faces; });

    size_t ref_start = index_of(order, expected_face_order[0]);
    for (size_t i=0; i<num_items; i++) {
        ASSERT_EQ(expected_face_order[i], order[(ref_start + i) % num_items]);
    }
}

template<typename DerivedV, typename DerivedF>
void assert_order(
        const Eigen::PlainObjectBase<DerivedV>& V,
        const Eigen::PlainObjectBase<DerivedF>& F,
        size_t v0, size_t v1,
        std::vector<int> expected_order, const std::string& normal="") {
    Eigen::MatrixXi E, uE, EMAP;
    std::vector<std::vector<int> > uE2E;
    igl::unique_edge_map(F, E, uE, EMAP, uE2E);

    std::vector<std::vector<int> > uE2oE;
    std::vector<std::vector<bool> > uE2C;

    if (normal != "") {
        Eigen::MatrixXd N;
        //igl::per_face_normals_stable(V, F, N);
        //igl::per_face_normals(V, F, N);
        test_common::load_matrix(normal, N);
        igl::cgal::order_facets_around_edges(V, F, N, uE, uE2E, uE2oE, uE2C);
    } else {
        igl::cgal::order_facets_around_edges(V, F, uE, uE2E, uE2oE, uE2C);
    }

    const size_t num_uE = uE.rows();
    for (size_t i=0; i<num_uE; i++) {
        const auto& order = uE2oE[i];
        const auto& cons  = uE2C[i];
        Eigen::VectorXi e = uE.row(i);
        if (order.size() <= 1) continue;
        if (e[0] != v0 && e[0] != v1) continue;
        if (e[1] != v0 && e[1] != v1) continue;
        if (e[0] == v1 && e[1] == v0) {
            std::reverse(expected_order.begin(), expected_order.end());
        }
        assert_consistently_oriented(F.rows(), expected_order, order);
    }
}

TEST(OrderFacetsAroundEdges, Simple) {
    Eigen::MatrixXd V(4, 3);
    V << 0.0, 0.0, 0.0,
         1.0, 0.0, 0.0,
         0.0, 1.0, 0.0,
         1.0, 1.0, 0.0;
{'fraction_non_alphanumeric': 0.16137138754263147, 'fraction_numerical': 0.02010411057260815, 'mean_word_length': 3.3977900552486187, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5316876', 'n_tokens_mistral': 2226, 'n_tokens_neox': 2144, 'n_words': 416}