Skip to content

Commit

Permalink
Now each constrained edges keeps a linked list of edge constraints, so
Browse files Browse the repository at this point in the history
that one keeps the information of several constraints that land on the
same edges.
It will be useful for the upcoming 2D CSG operations between polygons.
  • Loading branch information
BrunoLevy committed Nov 6, 2023
1 parent 1213e22 commit 560e732
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 41 deletions.
38 changes: 21 additions & 17 deletions src/lib/geogram/delaunay/CDT_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ namespace GEO {
Tadj_.resize(0);
v2T_.resize(0);
Tflags_.resize(0);
Tecnstr_.resize(0);
Tecnstr_first_.resize(0);
ecnstr_val_.resize(0);
ecnstr_next_.resize(0);
Tnext_.resize(0);
Tprev_.resize(0);
}
Expand Down Expand Up @@ -453,7 +455,7 @@ namespace GEO {
// Edge is flagged as constraint here, because
// it will not be seen by constraint enforcement.
index_t le_cnstr_edge = (v1 == W.j) ? (le+2)%3 : (le+1)%3;
Tset_edge_cnstr_with_neighbor(
Tadd_edge_cnstr_with_neighbor(
t_around_v, le_cnstr_edge, ncnstr_-1
);
CDT_LOG(
Expand All @@ -479,13 +481,13 @@ namespace GEO {
geo_debug_assert(o1 != ZERO || o2 != ZERO);
if(o1 == ZERO && o3*o4 < 0 && v1 != W.v_prev) {
v_next = v1;
Tset_edge_cnstr_with_neighbor(
Tadd_edge_cnstr_with_neighbor(
t_around_v, (le + 2)%3, ncnstr_-1
);
return true;
} else if(o2 == ZERO && o3*o4 < 0 && v2 != W.v_prev) {
v_next = v2;
Tset_edge_cnstr_with_neighbor(
Tadd_edge_cnstr_with_neighbor(
t_around_v, (le + 1)%3, ncnstr_-1
);
return true;
Expand Down Expand Up @@ -530,13 +532,13 @@ namespace GEO {
CDT_LOG(" Cnstr isect with:" << v1 << "-" << v2);
v_next = create_intersection(
ncnstr()-1, W.i, W.j,
Tedge_cnstr(W.t,0), v1, v2
edge_cnstr(Tedge_cnstr_first(W.t,0)), v1, v2
);
insert_vertex_in_edge(v_next,W.t,0);
// Mark new edge as constraint if walker was previously
// on a vertex.
if(W.v_prev != index_t(-1)) {
Tset_edge_cnstr_with_neighbor(W.t,2,ncnstr_-1);
Tadd_edge_cnstr_with_neighbor(W.t,2,ncnstr_-1);
}
} else {
CDT_LOG(" Isect: t=" << W.t <<" E=" << v1 <<"-"<< v2);
Expand Down Expand Up @@ -579,7 +581,7 @@ namespace GEO {
(Tv(t,1) == j && Tv(t,2) == i)
) {
// Set constraint flag if the new edge is the constrained edge
Tset_edge_cnstr_with_neighbor(t,0,ncnstr_-1);
Tadd_edge_cnstr_with_neighbor(t,0,ncnstr_-1);
} else {
// Memorize new edge as "to be Delaunayized"
if(N.initialized()) {
Expand Down Expand Up @@ -885,7 +887,9 @@ namespace GEO {
t_new,
Tv(t,0), Tv(t,1), Tv(t,2),
adj0, adj1, adj2,
Tedge_cnstr(t,0), Tedge_cnstr(t,1), Tedge_cnstr(t,2)
Tedge_cnstr_first(t,0),
Tedge_cnstr_first(t,1),
Tedge_cnstr_first(t,2)
);
Tflags_[t_new] = 0;
}
Expand All @@ -894,7 +898,7 @@ namespace GEO {
T_.resize(3*nT_new);
Tadj_.resize(3*nT_new);
Tflags_.resize(nT_new);
Tecnstr_.resize(3*nT_new);
Tecnstr_first_.resize(3*nT_new);
Tnext_.resize(nT_new);
Tprev_.resize(nT_new);

Expand All @@ -912,7 +916,7 @@ namespace GEO {
void CDTBase2d::insert_vertex_in_edge(
index_t v, index_t t, index_t le1, DList& S
) {
index_t cnstr = Tedge_cnstr(t,le1);
index_t cnstr_first = Tedge_cnstr_first(t,le1);
index_t t1 = t;
index_t t2 = Tadj(t1,le1);
index_t v1 = Tv(t1,le1);
Expand Down Expand Up @@ -942,10 +946,10 @@ namespace GEO {
Tadj_back_connect(t2,0,t2);
Tadj_back_connect(t3,0,t2);
Tadj_back_connect(t4,0,t1);
Tset_edge_cnstr(t1,1,cnstr);
Tset_edge_cnstr(t2,2,cnstr);
Tset_edge_cnstr(t3,1,cnstr);
Tset_edge_cnstr(t4,2,cnstr);
Tset_edge_cnstr_first(t1,1,cnstr_first);
Tset_edge_cnstr_first(t2,2,cnstr_first);
Tset_edge_cnstr_first(t3,1,cnstr_first);
Tset_edge_cnstr_first(t4,2,cnstr_first);
if(S.initialized()) {
S.push_back(t1);
S.push_back(t2);
Expand All @@ -962,8 +966,8 @@ namespace GEO {
Tset(t2,v,v3,v1,t1_adj2,t1,index_t(-1));
Tadj_back_connect(t1,0,t1);
Tadj_back_connect(t2,0,t1);
Tset_edge_cnstr(t1,1,cnstr);
Tset_edge_cnstr(t2,2,cnstr);
Tset_edge_cnstr_first(t1,1,cnstr_first);
Tset_edge_cnstr_first(t2,2,cnstr_first);
if(S.initialized()) {
S.push_back(t1);
S.push_back(t2);
Expand Down Expand Up @@ -1226,7 +1230,7 @@ namespace GEO {
(E.first == i && E.second == j) ||
(E.first == j && E.second == i)
) {
Tset_edge_cnstr_with_neighbor(eT(E),0,ncnstr_-1);
Tadd_edge_cnstr_with_neighbor(eT(E),0,ncnstr_-1);
} else {
N.push_back(E);
}
Expand Down
87 changes: 64 additions & 23 deletions src/lib/geogram/delaunay/CDT_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -671,9 +671,9 @@ namespace GEO {
Tadj_[3*t ] = adj1;
Tadj_[3*t+1] = adj2;
Tadj_[3*t+2] = adj3;
Tecnstr_[3*t] = e1cnstr;
Tecnstr_[3*t+1] = e2cnstr;
Tecnstr_[3*t+2] = e3cnstr;
Tecnstr_first_[3*t] = e1cnstr;
Tecnstr_first_[3*t+1] = e2cnstr;
Tecnstr_first_[3*t+2] = e3cnstr;
v2T_[v1] = t;
v2T_[v2] = t;
v2T_[v3] = t;
Expand All @@ -697,7 +697,7 @@ namespace GEO {
t,
T_[i], T_[j], T_[k],
Tadj_[i], Tadj_[j], Tadj_[k],
Tecnstr_[i], Tecnstr_[j], Tecnstr_[k]
Tecnstr_first_[i], Tecnstr_first_[j], Tecnstr_first_[k]
);
}
}
Expand Down Expand Up @@ -766,7 +766,7 @@ namespace GEO {
}
index_t le2 = Tadj_find(t2,prev_t2_adj_e2);
Tadj_set(t2,le2,t1);
Tset_edge_cnstr(t1,le1,Tedge_cnstr(t2,le2));
Tset_edge_cnstr_first(t1,le1,Tedge_cnstr_first(t2,le2));
}

/**
Expand All @@ -778,7 +778,7 @@ namespace GEO {
index_t nc = (t+1)*3; // new number of corners
T_.resize(nc, index_t(-1));
Tadj_.resize(nc, index_t(-1));
Tecnstr_.resize(nc, index_t(-1));
Tecnstr_first_.resize(nc, index_t(-1));
Tflags_.resize(t+1,0);
Tnext_.resize(t+1,index_t(-1));
Tprev_.resize(t+1,index_t(-1));
Expand All @@ -789,45 +789,84 @@ namespace GEO {
* \brief Gets the constraint associated with an edge
* \param[in] t a triangle
* \param[in] le local edge index, in 0,1,2
* \return the constraint associated with this edge, or
* index_t(-1) if there is no such constraint.
* \return the edge constraints iterator associated with this edge or
* index_t(-1) if the edge is not constrained.
*/
index_t Tedge_cnstr(index_t t, index_t le) const {
index_t Tedge_cnstr_first(index_t t, index_t le) const {
geo_debug_assert(t < nT());
geo_debug_assert(le < 3);
return Tecnstr_[3*t+le];
return Tecnstr_first_[3*t+le];
}

/**
* \brief Sets the constraints list associated with an edge
* \param[in] t a triangle
* \param[in] le local edge index, in 0,1,2
* \param[in] ecit the edge constraint iterator that points to
* the first constraint associated with the edge
*/
void Tset_edge_cnstr_first(
index_t t, index_t le, index_t ecit
) {
geo_debug_assert(t < nT());
geo_debug_assert(le < 3);
Tecnstr_first_[3*t+le] = ecit;
}


/**
* \brief Sets an edge as constrained
* \brief Gets the successor of an edge constraint iterator
* \param[in] ecit the edge constraint iterator
* \return the edge constraint iterator to the successor of \p ecit
* or index_t(-1) if \p ecit is the last of the list.
*/
index_t edge_cnstr_next(index_t ecit) const {
return ecnstr_next_[ecit];
}

/**
* \brief Gets an edge constraint fro an edge constraint iterator
* \param[in] ecit the edge constraint iterator. Needs to be a valid
* iterator, different from index_t(-1).
* \return the edge constraint associated with the iterator.
*/
index_t edge_cnstr(index_t ecit) const {
return ecnstr_val_[ecit];
}

/**
* \brief Adds a constraint to a triangle edge
* \param[in] t a triangle
* \param[in] le local edge index, in 0,1,2
* \param[in] cnstr_id identifier of the constrained edge
* \param[in] cnstr_id the constraint
*/
void Tset_edge_cnstr(
index_t t, index_t le, index_t cnstr_id
void Tadd_edge_cnstr(
index_t t, index_t le, index_t cnstr_id
) {
geo_debug_assert(t < nT());
geo_debug_assert(le < 3);
Tecnstr_[3*t+le] = cnstr_id;
ecnstr_val_.push_back(cnstr_id);
ecnstr_next_.push_back(Tedge_cnstr_first(t,le));
Tset_edge_cnstr_first(t,le, ecnstr_val_.size()-1);
}

/**
* \brief Sets an edge as constrained in triangle and in neighbor
* \brief Adds a constraint to a triangle edge and to the neighboring
* edge if it exists
* \param[in] t a triangle
* \param[in] le local edge index, in 0,1,2
* \param[in] cnstr_id identifier of the constrained edge
* \param[in] cnstr_id the constraint
*/
void Tset_edge_cnstr_with_neighbor(
index_t t, index_t le, index_t cnstr_id
void Tadd_edge_cnstr_with_neighbor(
index_t t, index_t le, index_t cnstr_id
) {
geo_debug_assert(t < nT());
geo_debug_assert(le < 3);
Tset_edge_cnstr(t, le, cnstr_id);
Tadd_edge_cnstr(t, le, cnstr_id);
index_t t2 = Tadj(t,le);
if(t2 != index_t(-1)) {
index_t le2 = Tadj_find(t2,t);
Tset_edge_cnstr(t2,le2,cnstr_id);
Tadd_edge_cnstr(t2,le2,cnstr_id);
}
}

Expand All @@ -839,7 +878,7 @@ namespace GEO {
* \retval false otherwise
*/
bool Tedge_is_constrained(index_t t, index_t le) const {
return (Tedge_cnstr(t,le) != index_t(-1));
return (Tedge_cnstr_first(t,le) != index_t(-1));
}

/**
Expand Down Expand Up @@ -1195,7 +1234,9 @@ namespace GEO {
vector<index_t> Tadj_; /**< triangles adjacency array */
vector<index_t> v2T_; /**< vertex to triangle back pointer */
vector<uint8_t> Tflags_; /**< triangle flags */
vector<index_t> Tecnstr_; /**< triangle edge constraint */
vector<index_t> Tecnstr_first_; /**< index in edge constraints list */
vector<index_t> ecnstr_val_; /**< edge constraints list, indices */
vector<index_t> ecnstr_next_; /**< edge constraints list, links */
vector<index_t> Tnext_; /**< doubly connected triangle list */
vector<index_t> Tprev_; /**< doubly connected triangle list */
bool delaunay_; /**< if set, compute a CDT, else just a CT */
Expand Down
2 changes: 1 addition & 1 deletion src/lib/geogram/numerics/interval_nt.h
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ namespace GEO {
intervalRN result = a;
return result *= b;
}

typedef intervalRN interval_nt; // Seems that valgrind does not support RU
//typedef intervalRU interval_nt;

Expand Down

0 comments on commit 560e732

Please sign in to comment.