Skip to content

Commit

Permalink
Mesh.facets.connect() now has a version that takes a facets sequence.
Browse files Browse the repository at this point in the history
  • Loading branch information
BrunoLevy committed Sep 23, 2024
1 parent ea5c45b commit af6ce6c
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 34 deletions.
91 changes: 59 additions & 32 deletions src/lib/geogram/mesh/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,10 +651,16 @@ namespace GEO {
}

void MeshFacets::connect() {
connect(0, nb());
}

void MeshFacets::connect(index_t f_begin, index_t f_end) {

// Sanity check: no facet is incident to same vertex
// several times
#ifdef GEO_DEBUG
{
for(index_t f: *this) {
for(index_t f = f_begin; f != f_end; ++f) {
for(index_t lv1=0; lv1<nb_vertices(f); ++lv1) {
for(index_t lv2=lv1+1; lv2<nb_vertices(f); ++lv2) {
geo_debug_assert(vertex(f,lv1) != vertex(f,lv2));
Expand All @@ -664,45 +670,62 @@ namespace GEO {
}
#endif

// Chains the corners around each vertex.
vector<index_t> next_corner_around_vertex(
facet_corners_.nb(), NO_CORNER
);
// Get facet corners slice
index_t c_begin = corners_begin(f_begin);
index_t c_end = corners_end(f_end-1);

// Get vertices slices indexed by facets in slice
index_t v_begin = NO_INDEX;
index_t v_end = NO_INDEX;

if(c_begin == 0 && c_end == facet_corners_.nb()) {
v_begin = 0;
v_end = vertices_.nb();
} else {
v_begin = facet_corners_.vertex(c_begin);
v_end = v_begin;
for(index_t c=c_begin; c!=c_end; ++c) {
index_t v = facet_corners_.vertex(c);
v_begin = std::min(v_begin,v);
v_end = std::max(v_end,v);
}
++v_end;
}

// Gives for each corner the facet incident to it
// (or use c/3 if the surface is triangulated).
vector<index_t> c2f;
if(!is_simplicial_) {
c2f.assign(c_end - c_begin, NO_FACET);
for(index_t f = f_begin; f < f_end; ++f) {
for(index_t c = corners_begin(f); c < corners_end(f); ++c) {
geo_debug_assert(c >= c_begin);
c2f[c-c_begin] = f;
}
}
}

for(index_t c: facet_corners_) {
for(index_t c = c_begin; c < c_end; ++c) {
facet_corners_.set_adjacent_facet(c, NO_FACET);
}

// Gives for each vertex a corner incident to it.
vector<index_t> v2c(vertices_.nb(), NO_CORNER);
vector<index_t> v2c(v_end - v_begin, NO_CORNER);

// Gives for each corner the facet incident to it
// (or use c/3 if the surface is triangulated).
GEO::vector<index_t> c2f;
if(!is_simplicial_) {
c2f.assign(facet_corners_.nb(), NO_FACET);
}
// Chains the corners around each vertex.
vector<index_t> next_corner_around_vertex(c_end - c_begin, NO_CORNER);

// Step 1: chain corners around vertices and compute v2c
for(index_t f = 0; f < nb(); ++f) {
for(index_t f = f_begin; f < f_end; ++f) {
for(index_t c = corners_begin(f); c < corners_end(f); ++c) {
index_t v = facet_corners_.vertex(c);
next_corner_around_vertex[c] = v2c[v];
v2c[v] = c;
}
}

// compute c2f if needed
if(!is_simplicial_) {
for(index_t f = 0; f < nb(); ++f) {
for(index_t c = corners_begin(f); c < corners_end(f); ++c) {
c2f[c] = f;
}
next_corner_around_vertex[c - c_begin] = v2c[v - v_begin];
v2c[v - v_begin] = c;
}
}

// Step 2: connect
for(index_t f1 = 0; f1 < nb(); ++f1) {
for(index_t f1 = f_begin; f1 < f_end; ++f1) {
for(index_t c1 = corners_begin(f1); c1 < corners_end(f1); ++c1) {
if(facet_corners_.adjacent_facet(c1) == NO_FACET) {

Expand All @@ -717,11 +740,13 @@ namespace GEO {
// Traverse all the corners c2 incident to v1, and
// find among them the one(s) that is opposite to c1
for(
index_t c2 = v2c[v1];
c2 != NO_CORNER; c2 = next_corner_around_vertex[c2]
index_t c2 = v2c[v1 - v_begin];
c2 != NO_CORNER;
c2 = next_corner_around_vertex[c2 - c_begin]
) {
if(c2 != c1) {
index_t f2 = is_simplicial_ ? c2/3 : c2f[c2];
index_t f2 =
is_simplicial_ ? c2/3 : c2f[c2 - c_begin];
index_t c2_prev = prev_corner_around_facet(f2, c2);

index_t v3 = facet_corners_.vertex(c2);
Expand All @@ -730,8 +755,10 @@ namespace GEO {
geo_assert(v1 == v3);

if(
v4 == v2 &&
facet_corners_.adjacent_facet(c2_prev) == NO_FACET
v4 == v2 && (
facet_corners_.adjacent_facet(c2_prev) ==
NO_FACET
)
) {
c_candidate = c2_prev;
++nb_candidates;
Expand All @@ -741,7 +768,7 @@ namespace GEO {
// If there were more than 1 candidate, do not connect.
if(nb_candidates == 1) {
index_t c2 = c_candidate;
index_t f2 = is_simplicial_ ? (c2/3) : c2f[c2];
index_t f2 = is_simplicial_ ? (c2/3) : c2f[c2 - c_begin];
facet_corners_.set_adjacent_facet(c1,f2);
facet_corners_.set_adjacent_facet(c2,f1);
}
Expand Down
10 changes: 9 additions & 1 deletion src/lib/geogram/mesh/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -1347,9 +1347,17 @@ namespace GEO {

/**
* \brief Connects the facets
* \details Finds the adjacent_facet() links based on vertex indices
*/
void connect();
void connect();

/**
* \brief Connects a contiguous sequence of facets
* \details Finds the adjacent_facet() links based on vertex indices
* \param[in] facets_begin first facet to connect
* \param[in] facets_end one position past the last facet to connect
*/
void connect(index_t facets_begin, index_t facets_end);

/**
* \brief Triangulates the facets
Expand Down
2 changes: 1 addition & 1 deletion src/lib/geogram/mesh/mesh_subdivision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ namespace GEO {
M.facets.set_vertex(nf0+3*(f-facets_begin)+2,1,v23);
M.facets.set_vertex(nf0+3*(f-facets_begin)+2,2,v3);
}
M.facets.connect();
M.facets.connect(facets_begin, M.facets.nb());
}


Expand Down

0 comments on commit af6ce6c

Please sign in to comment.