Commit eef92432 by Max Lyon

add vertex face iterator to iterate over all faces incident to a vertex

parent ad72f214
Pipeline #3523 passed with stage
in 9 minutes 37 seconds
......@@ -277,6 +277,85 @@ HalfEdgeHalfFaceIter& HalfEdgeHalfFaceIter::operator++() {
}
////================================================================================================
//// VertexFaceIter
////================================================================================================
VertexFaceIter::VertexFaceIter(const VertexHandle& _ref_h,
const TopologyKernel* _mesh, int _max_laps) :
BaseIter(_mesh, _ref_h, _max_laps) {
if(!_mesh->has_full_bottom_up_incidences()) {
#ifndef NDEBUG
std::cerr << "This iterator needs bottom-up incidences!" << std::endl;
#endif
BaseIter::valid(false);
return;
}
if((unsigned int)_ref_h.idx() >= BaseIter::mesh()->outgoing_hes_per_vertex_.size()) {
BaseIter::valid(false);
return;
}
// Build up face list
const std::vector<HalfEdgeHandle>& incidentHalfedges = BaseIter::mesh()->outgoing_hes_per_vertex_[_ref_h.idx()];
for(std::vector<HalfEdgeHandle>::const_iterator it = incidentHalfedges.begin(); it != incidentHalfedges.end(); ++it) {
if(*it < 0 || (unsigned int)it->idx() >= BaseIter::mesh()->incident_hfs_per_he_.size()) continue;
const std::vector<HalfFaceHandle>& incidentHalfFaces = BaseIter::mesh()->incident_hfs_per_he_[it->idx()];
for (std::vector<HalfFaceHandle>::const_iterator hf_it = incidentHalfFaces.begin();
hf_it != incidentHalfFaces.end(); ++hf_it) {
faces_.push_back(BaseIter::mesh()->face_handle(*hf_it));
}
}
// Remove all duplicate entries
std::sort(faces_.begin(), faces_.end());
faces_.resize(std::unique(faces_.begin(), faces_.end()) - faces_.begin());
// Remove invalid handles
if ((faces_.size() > 0) && !faces_.front().is_valid())
faces_.erase(faces_.begin());
cur_index_ = 0;
BaseIter::valid(faces_.size() > 0);
if(BaseIter::valid()) {
BaseIter::cur_handle(faces_[cur_index_]);
}
}
VertexFaceIter& VertexFaceIter::operator--() {
if(cur_index_ == 0) {
cur_index_ = faces_.size()-1;
--lap_;
if (lap_ < 0) {
BaseIter::valid(false);
}
} else {
--cur_index_;
}
BaseIter::cur_handle(faces_[cur_index_]);
return *this;
}
VertexFaceIter& VertexFaceIter::operator++() {
++cur_index_;
if(cur_index_ == faces_.size()) {
cur_index_ = 0;
++lap_;
if (lap_ >= max_laps_) {
BaseIter::valid(false);
}
}
BaseIter::cur_handle(faces_[cur_index_]);
return *this;
}
////================================================================================================
//// VertexCellIter
////================================================================================================
......
......@@ -420,6 +420,64 @@ private:
//===========================================================================
class VertexFaceIter : public BaseCirculator<
VertexHandle,
FaceHandle> {
public:
typedef BaseCirculator<
VertexHandle,
FaceHandle> BaseIter;
VertexFaceIter(const VertexHandle& _vIdx, const TopologyKernel* _mesh, int _max_laps = 1);
// Post increment/decrement operator
VertexFaceIter operator++(int) {
VertexFaceIter cpy = *this;
++(*this);
return cpy;
}
VertexFaceIter operator--(int) {
VertexFaceIter cpy = *this;
--(*this);
return cpy;
}
VertexFaceIter operator+(int _n) {
VertexFaceIter cpy = *this;
for(int i = 0; i < _n; ++i) {
++cpy;
}
return cpy;
}
VertexFaceIter operator-(int _n) {
VertexFaceIter cpy = *this;
for(int i = 0; i < _n; ++i) {
--cpy;
}
return cpy;
}
VertexFaceIter& operator+=(int _n) {
for(int i = 0; i < _n; ++i) {
++(*this);
}
return *this;
}
VertexFaceIter& operator-=(int _n) {
for(int i = 0; i < _n; ++i) {
--(*this);
}
return *this;
}
VertexFaceIter& operator++();
VertexFaceIter& operator--();
private:
std::vector<FaceHandle> faces_;
size_t cur_index_;
};
//===========================================================================
class VertexCellIter : public BaseCirculator<
VertexHandle,
CellHandle> {
......
......@@ -87,6 +87,7 @@ public:
friend class VertexOHalfEdgeIter;
friend class VertexVertexIter;
friend class HalfEdgeHalfFaceIter;
friend class VertexFaceIter;
friend class VertexCellIter;
friend class HalfEdgeCellIter;
friend class CellVertexIter;
......@@ -146,6 +147,15 @@ public:
return std::make_pair(begin, make_end_circulator(begin));
}
VertexFaceIter vf_iter(const VertexHandle& _h, int _max_laps = 1) const {
return VertexFaceIter(_h, this, _max_laps);
}
std::pair<VertexFaceIter, VertexFaceIter> vertex_faces(const VertexHandle& _h, int _max_laps = 1) const {
VertexFaceIter begin = vf_iter(_h, _max_laps);
return std::make_pair(begin, make_end_circulator(begin));
}
VertexCellIter vc_iter(const VertexHandle& _h, int _max_laps = 1) const {
return VertexCellIter(_h, this, _max_laps);
}
......
......@@ -79,6 +79,63 @@ TEST_F(TetrahedralMeshBase, VertexVertexIteratorTest) {
}
TEST_F(TetrahedralMeshBase, VertexFaceIteratorTest) {
generateTetrahedralMesh(mesh_);
{
VertexFaceIter vf_it = mesh_.vf_iter(VertexHandle(0));
EXPECT_TRUE(vf_it.valid());
std::set<FaceHandle> incident_faces;
int valence = 0;
while (vf_it.valid())
{
++valence;
incident_faces.insert(*vf_it);
++vf_it;
}
// check that there have been three adjacent vertices
EXPECT_EQ(3, valence);
// check that no vertex was visited twice
EXPECT_EQ(3u, incident_faces.size());
// check that no invalid vertex was adjacent
EXPECT_EQ(incident_faces.end(), std::find(incident_faces.begin(), incident_faces.end(), FaceHandle(-1)));
}
#if __cplusplus >= 201103L // C++11
{
std::set<VertexHandle> onering;
int valence = 0;
for (auto vh : mesh_.vertex_vertices(VertexHandle(0)))
{
++valence;
onering.insert(vh);
}
// check that there have been three adjacent vertices
EXPECT_EQ(3, valence);
// check that no vertex was visited twice
EXPECT_EQ(3u, onering.size());
// check that no invalid vertex was adjacent
EXPECT_EQ(onering.end(), std::find(onering.begin(), onering.end(), VertexHandle(-1)));
}
#endif
}
#if __cplusplus >= 201103L // C++11
TEST_F(HexahedralMeshBase, RangeForTest) {
// no EXPECTs here, if it compiles, it'll work.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment