Commit 04a01c9e authored by Jan Möbius's avatar Jan Möbius

Merge branch 'fix-nonmanifold-no-collect' into 'master'

Not collecting failed faces but directly processing them

**Problem description:**

I encountered severe problems in my application because OpenMesh does not load attributes, such as face texture index, for failed faces (non-manifold geometry).
Instead of directly handling them, the Importer class defers the handling of failed faces to a post process - but at that point, the attribute information is not available any more, since it is read and applied in the reader, which only deals with the non-failed faces.


**Solution:**

My simple solution was to remove the list of failed faces and instead directly handle failed faces inside the "add_face" function of the Importer class.


**Discussion:**

I didn't see any drawback, compared to the previous code. It would be interesting to know why the list of failed faces was maintained - was this legacy code, or was there some idea to extend this concept, which was just  never realized? The only functional point that has changed is that I removed the code that adds degenerate faces to the mesh (line 129), since, in my opinion, this makes things just more complicated for some applications, and the benefit of being able to import degenerate faces seems marginal. But that's a design decision, it will be very easy to encapsulate the code that adds a separate face (line 140) into a separate function and use it also for degenerate faces.

It would be great to receive your feedback on this issue, and to know if it is possible to include this change (or something similar).

See merge request !51
parents eda7782a 4918d2f3
Pipeline #1254 failed with stage
......@@ -17,6 +17,7 @@
<b>IO</b>
<ul>
<li>Obj reader: added texCoord3d functions to objloader</li>
<li>Importer: Integrate non-manifold faces while importing and not at the end. Fixes missing properties on non-manifolds. (Thanks to Max Limper for the patch, Merge Request 51)<li>
</ul>
<b>VectorT</b>
......
......@@ -131,17 +131,45 @@ public:
if (*it == *it2)
{
omerr() << "ImporterT: Face has equal vertices\n";
failed_faces_.push_back(_indices);
return fh;
}
// try to add face
fh = mesh_.add_face(_indices);
// separate non-manifold faces and mark them
if (!fh.is_valid())
{
failed_faces_.push_back(_indices);
return fh;
VHandles vhandles(_indices.size());
// double vertices
for (unsigned int j=0; j<_indices.size(); ++j)
{
// DO STORE p, reference may not work since vertex array
// may be relocated after adding a new vertex !
Point p = mesh_.point(_indices[j]);
vhandles[j] = mesh_.add_vertex(p);
// Mark vertices of failed face as non-manifold
if (mesh_.has_vertex_status()) {
mesh_.status(vhandles[j]).set_fixed_nonmanifold(true);
}
}
// add face
FaceHandle fh = mesh_.add_face(vhandles);
// Mark failed face as non-manifold
if (mesh_.has_face_status())
mesh_.status(fh).set_fixed_nonmanifold(true);
// Mark edges of failed face as non-two-manifold
if (mesh_.has_edge_status()) {
typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh);
for(; fe_it.is_valid(); ++fe_it) {
mesh_.status(*fe_it).set_fixed_nonmanifold(true);
}
}
}
//write the half edge normals
......@@ -358,60 +386,15 @@ public:
size_t n_edges() const { return mesh_.n_edges(); }
void prepare() { failed_faces_.clear(); }
void prepare() { }
void finish()
{
if (!failed_faces_.empty())
{
omerr() << failed_faces_.size()
<< " faces failed, adding them as isolated faces\n";
for (unsigned int i=0; i<failed_faces_.size(); ++i)
{
VHandles& vhandles = failed_faces_[i];
// double vertices
for (unsigned int j=0; j<vhandles.size(); ++j)
{
Point p = mesh_.point(vhandles[j]);
vhandles[j] = mesh_.add_vertex(p);
// DO STORE p, reference may not work since vertex array
// may be relocated after adding a new vertex !
// Mark vertices of failed face as non-manifold
if (mesh_.has_vertex_status()) {
mesh_.status(vhandles[j]).set_fixed_nonmanifold(true);
}
}
// add face
FaceHandle fh = mesh_.add_face(vhandles);
// Mark failed face as non-manifold
if (mesh_.has_face_status())
mesh_.status(fh).set_fixed_nonmanifold(true);
// Mark edges of failed face as non-two-manifold
if (mesh_.has_edge_status()) {
typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh);
for(; fe_it.is_valid(); ++fe_it) {
mesh_.status(*fe_it).set_fixed_nonmanifold(true);
}
}
}
failed_faces_.clear();
}
}
void finish() { }
private:
Mesh& mesh_;
std::vector<VHandles> failed_faces_;
// stores normals for halfedges of the next face
std::map<VertexHandle,Normal> halfedgeNormals_;
};
......
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 to comment