diff --git a/src/mesh_processor.cpp b/src/mesh_processor.cpp index 9e58898..40cba6b 100644 --- a/src/mesh_processor.cpp +++ b/src/mesh_processor.cpp @@ -4,15 +4,17 @@ #include -static std::vector findHoles(MyMesh &mesh) { - std::vector holes; +static std::vector> findHoles(MyMesh &mesh) { + std::vector> holes; std::set ignore; for (HalfedgeHandle it : mesh.halfedges()) { if (mesh.is_boundary(it) && ignore.find(it) == ignore.end()) { - holes.push_back(it); + holes.emplace_back(); + holes.back().push_back(it); ignore.insert(it); for (HalfedgeHandle it2 : HalfedgeLoopRange(mesh, it)) { + holes.back().push_back(it2); ignore.insert(it2); } } @@ -33,14 +35,14 @@ MeshProcessor::MeshProcessor(const QString &path) { } -void fillHoleDumb(MyMesh &mesh, HalfedgeHandle &hole) { +void fillHoleDumb(MyMesh &mesh, std::vector &hole) { mesh.request_vertex_status(); mesh.request_edge_status(); mesh.request_face_status(); Point center(0, 0, 0); size_t length = 0; - for (HalfedgeHandle it : HalfedgeLoopRange(mesh, hole)) { + for (HalfedgeHandle it : hole) { VertexHandle vert = mesh.to_vertex_handle(it); center += mesh.point(vert); length++; @@ -48,13 +50,10 @@ void fillHoleDumb(MyMesh &mesh, HalfedgeHandle &hole) { center /= length; VertexHandle center_handle = mesh.new_vertex_dirty(center); - for (HalfedgeHandle it = hole; - mesh.to_vertex_handle(it) != center_handle;) { - HalfedgeHandle next = mesh.next_halfedge_handle(it); + for (HalfedgeHandle it : hole) { mesh.add_face(mesh.from_vertex_handle(it), mesh.to_vertex_handle(it), center_handle); - it = next; } } diff --git a/src/mesh_processor.h b/src/mesh_processor.h index 0e31e69..489114d 100644 --- a/src/mesh_processor.h +++ b/src/mesh_processor.h @@ -12,7 +12,7 @@ class MeshProcessor : public QObject { public: MyMesh mesh; - std::vector holes; + std::vector> holes; MeshProcessor(const QString &path); diff --git a/src/mesh_view.cpp b/src/mesh_view.cpp index a656b35..171df4c 100644 --- a/src/mesh_view.cpp +++ b/src/mesh_view.cpp @@ -7,10 +7,12 @@ MeshView::MeshView(const MeshProcessor &mesh_processor, QOpenGLShaderProgram &program) :vertex_buffer(QOpenGLBuffer::VertexBuffer), index_buffer(QOpenGLBuffer::IndexBuffer), + holes_index_buffer(QOpenGLBuffer::IndexBuffer), n_faces(mesh_processor.mesh.n_faces()), n_vertices(mesh_processor.mesh.n_vertices()), mesh_processor(mesh_processor) { const MyMesh &mesh = mesh_processor.mesh; + QVector vertices(n_vertices * 3); size_t i = 0; for (const VertexHandle it : mesh.vertices()) { @@ -19,6 +21,7 @@ MeshView::MeshView(const MeshProcessor &mesh_processor, QOpenGLShaderProgram &pr vertices[3*i + 2] = mesh.point(it)[2]; i++; } + QVector indices(n_faces * 3); i = 0; for (const FaceHandle it : mesh.faces()) { @@ -31,6 +34,16 @@ MeshView::MeshView(const MeshProcessor &mesh_processor, QOpenGLShaderProgram &pr i++; } + QVector holes_indices; + n_boundary_halfedges = 0; + for (std::vector hole : mesh_processor.holes) { + for (HalfedgeHandle it : hole) { + holes_indices.push_back(mesh.from_vertex_handle(it).idx()); + holes_indices.push_back(mesh.to_vertex_handle(it).idx()); + n_boundary_halfedges++; + } + } + vao.create(); {QOpenGLVertexArrayObject::Binder binder(&vao); vertex_buffer.create(); @@ -41,6 +54,10 @@ MeshView::MeshView(const MeshProcessor &mesh_processor, QOpenGLShaderProgram &pr index_buffer.bind(); index_buffer.setUsagePattern(QOpenGLBuffer::StreamDraw); index_buffer.allocate(indices.constData(), n_faces * 3 * sizeof (GLuint)); + holes_index_buffer.create(); + holes_index_buffer.bind(); + holes_index_buffer.setUsagePattern(QOpenGLBuffer::StreamDraw); + holes_index_buffer.allocate(holes_indices.constData(), n_boundary_halfedges * 2 * sizeof (GLuint)); program.setAttributeBuffer("pos", GL_FLOAT, 0, 3); program.enableAttributeArray("pos"); } @@ -74,22 +91,21 @@ void MeshView::paint(QOpenGLShaderProgram &program) { glf->glDrawElements(GL_TRIANGLES, n_faces * 3, GL_UNSIGNED_INT, 0); glf->glDisable(GL_POLYGON_OFFSET_FILL); - /* Wireframe */ - glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glf->glLineWidth(2); program.setUniformValue("wireframe", 1); - glf->glDrawElements(GL_TRIANGLES, n_faces * 3, GL_UNSIGNED_INT, 0); - glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - program.setUniformValue("wireframe", 0); + /* Wireframe */ + glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glf->glDepthMask(GL_FALSE); + glf->glLineWidth(2); + glf->glDrawElements(GL_TRIANGLES, n_faces * 3, GL_UNSIGNED_INT, 0); + glf->glDepthMask(GL_TRUE); + glf21->glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - // program.setUniformValue("wf_col", QVector3D(1, 0, 1)); - // for (HalfedgeHandle hole : mesh_processor.holes) { - // for (HalfedgeHandle it : ConstHalfedgeLoopRange(mesh, hole)) { - // int v0 = mesh.from_vertex_handle(it).idx(); - // int v1 = mesh.to_vertex_handle(it).idx(); - // glf->glDrawArrays(GL_LINES, std::min(v0, v1), std::max(v0, v1)); - // } - // } - // program.setUniformValue("wf_col", QVector3D(0, 0, 0)); + /* Holes */ + program.setUniformValue("wf_col", QVector3D(1, 0, 1)); + holes_index_buffer.bind(); + glf->glDrawElements(GL_LINES, n_boundary_halfedges * 2, GL_UNSIGNED_INT, 0); + index_buffer.bind(); + program.setUniformValue("wf_col", QVector3D(0, 0, 0)); + program.setUniformValue("wireframe", 0); } } diff --git a/src/mesh_view.h b/src/mesh_view.h index f092874..48f4bb8 100644 --- a/src/mesh_view.h +++ b/src/mesh_view.h @@ -12,8 +12,10 @@ class MeshView { QOpenGLVertexArrayObject vao; QOpenGLBuffer vertex_buffer; QOpenGLBuffer index_buffer; + QOpenGLBuffer holes_index_buffer; unsigned n_faces; unsigned n_vertices; + unsigned n_boundary_halfedges; public: const MeshProcessor &mesh_processor;