DualVertexRenderer::DualVertexRenderer(const HMesh::Manifold& m, VertexAttributeVector<Vec4d>& field) { // Create the program static GLuint prog = glCreateProgram(); static bool was_here = false; if(!was_here) { was_here = true; // Create s haders directly from file static GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, vss); static GLuint gs = create_glsl_shader(GL_GEOMETRY_SHADER_EXT, gss); static GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, fss); // Attach all shaders if(vs) glAttachShader(prog, vs); if(gs) glAttachShader(prog, gs); if(fs) glAttachShader(prog, fs); // Specify input and output for the geometry shader. Note that this must be // done before linking the program. glProgramParameteriEXT(prog,GL_GEOMETRY_INPUT_TYPE_EXT,GL_TRIANGLES); glProgramParameteriEXT(prog,GL_GEOMETRY_VERTICES_OUT_EXT,3); glProgramParameteriEXT(prog,GL_GEOMETRY_OUTPUT_TYPE_EXT,GL_TRIANGLE_STRIP); // Link the program object and print out the info log glLinkProgram(prog); } GLint old_prog; glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog); glNewList(display_list,GL_COMPILE); glUseProgram(prog); for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f) { if(no_edges(m, *f) != 3) continue; else glBegin(GL_TRIANGLES); for(Walker w = m.walker(*f); !w.full_circle(); w = w.circulate_face_ccw()) { Vec3d n(normal(m, w.vertex())); glNormal3dv(n.get()); glColor4dv(field[w.vertex()].get()); glVertex3dv(m.pos(w.vertex()).get()); } glEnd(); } glUseProgram(old_prog); glEndList(); }
void dual(HMesh::Manifold& m) { FaceAttributeVector<Vec3d> face_center(m.no_faces()); for (auto f : m.faces()) { // find mid point Vec3d mpt(0.0, 0.0, 0.0); int nb_p = 0; for (auto hw = m.walker(f); !hw.full_circle(); hw = hw.circulate_face_ccw()) { mpt += m.pos(hw.vertex()); nb_p++; } mpt = mpt / nb_p; face_center[f] = mpt; } Manifold newMesh; for (auto v : m.vertices()) { vector<Vec3d> pts; for (auto hw = m.walker(v); !hw.full_circle(); hw = hw.circulate_vertex_ccw()) { // if (hw.opp().face() == InvalidFaceID) // { // pts.push_back((m.pos(hw.vertex()) + m.pos(hw.opp().vertex()))/2.0); // pts.push_back(face_center[hw.face()]); // } // else if(hw.face() == InvalidFaceID) // { // pts.push_back((m.pos(hw.vertex()) + m.pos(hw.opp().vertex()))/2.0); // } // else if (m.in_use(hw.face())) { pts.push_back(face_center[hw.face()]); } } newMesh.add_face(pts); } stitch_mesh(newMesh, 0.01); m = newMesh; }
void volume_polygonize(const XForm& xform, const Geometry::RGrid<float>& grid, HMesh::Manifold& mani, float tau, bool make_triangles) { mani.clear(); vector<Vec3d> quad_vertices; polygonize(xform, grid, quad_vertices, tau); vector<int> indices; vector<int> faces(quad_vertices.size()/4,4); for(int i=0;i<quad_vertices.size();++i) indices.push_back(i); build(mani, quad_vertices.size(), quad_vertices[0].get(), faces.size(), &faces[0], &indices[0]); stitch_more(mani, 1e-5); if(make_triangles) triangulate(mani); float avg_edge_len=0; for(HalfEdgeIDIterator h = mani.halfedges_begin(); h != mani.halfedges_end();++h) avg_edge_len += length(mani, *h); avg_edge_len /= mani.no_halfedges(); VolumetricImplicit imp(xform, grid); for(int iter=0;iter<4;++iter) { TAL_smoothing(mani, .25, 1); for(auto v: mani.vertices()) if(mani.in_use(v)) { Vec3d p = mani.pos(v); if(!std::isnan(p[0])) imp.push_to_surface(p,0,avg_edge_len*0.5); if(std::isnan(p[0])) mani.remove_vertex(v); else mani.pos(v) = p; } } mani.cleanup(); cout << "Produced " << mani.no_faces() << " faces " << endl; }