Created
May 26, 2012 16:10
-
-
Save roxlu/2794471 to your computer and use it in GitHub Desktop.
OpenMesh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "OMesh.h" | |
OMesh::OMesh() { | |
} | |
OMesh::~OMesh() { | |
} | |
bool OMesh::save(const string& filepath) { | |
try { | |
OpenMesh::IO::Options opt; | |
opt += OpenMesh::IO::Options::VertexNormal; | |
opt += OpenMesh::IO::Options::FaceNormal; | |
if(!OpenMesh::IO::write_mesh(mesh, filepath),opt) { | |
return false; | |
} | |
} | |
catch(std::exception& x) { | |
printf("Cannot write mesh: %s, %s\n", filepath.c_str(), x.what()); | |
return false; | |
} | |
return true; | |
} | |
bool OMesh::load(const string& filepath) { | |
try { | |
OpenMesh::IO::Options opt; | |
opt += OpenMesh::IO::Options::VertexNormal; | |
opt += OpenMesh::IO::Options::FaceNormal; | |
if(!OpenMesh::IO::read_mesh(mesh, filepath, opt)) { | |
return false; | |
} | |
} | |
catch(std::exception& x) { | |
printf("Cannot read mesh: %s, %s\n", filepath.c_str(), x.what()); | |
return false; | |
} | |
return true; | |
} | |
void OMesh::debugDraw() { | |
glEnable(GL_CULL_FACE); | |
glEnable(GL_BLEND); | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
// draw faces. | |
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
glColor4f(0.2f, 0.3f, 0.4f, 0.5f); | |
glBegin(GL_TRIANGLES); | |
std::for_each(mesh.faces_begin(), mesh.faces_end(), OMesh_FaceDrawer(*this)); | |
glEnd(); | |
// draw triangles. | |
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
glColor4f(8.0f, 0.3f, 0.05f, 0.8f); | |
glBegin(GL_TRIANGLES); | |
std::for_each(mesh.faces_begin(), mesh.faces_end(), OMesh_FaceDrawer(*this)); | |
glEnd(); | |
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
// draw face normals. | |
glColor3f(0.1, 0.8, 0.7); | |
if(mesh.has_face_normals()) { | |
glBegin(GL_LINES); | |
MeshType::FaceIter face_it = mesh.faces_begin(); | |
while(face_it != mesh.faces_end()) { | |
// It seems that mesh.normal(face_it.handle()) returns an incorrect normal! | |
//MeshType::Normal norm = mesh.normal(face_it.handle()); | |
MeshType::Normal norm = getFaceNormal(face_it.handle()); | |
MeshType::Point center = getFaceCenter(face_it.handle()); | |
MeshType::Point end = center + norm; | |
glVertex3fv(center.data()); | |
glVertex3fv(end.data()); | |
++face_it; | |
} | |
glEnd(); | |
} | |
}a | |
// assuming trimesh | |
MeshType::Normal OMesh::getFaceNormal(const MeshType::FaceHandle& faceHandle) { | |
MeshType::HalfedgeHandle heh_a, heh_b, heh_c; | |
heh_a = mesh.halfedge_handle(faceHandle); | |
heh_b = mesh.next_halfedge_handle(heh_a); | |
heh_c = mesh.next_halfedge_handle(heh_b); | |
MeshType::Point a = mesh.point(mesh.to_vertex_handle(heh_a)); | |
MeshType::Point b = mesh.point(mesh.to_vertex_handle(heh_b)); | |
MeshType::Point c = mesh.point(mesh.to_vertex_handle(heh_c)); | |
MeshType::Point ab = b - a; | |
MeshType::Point ac = c - a; | |
MeshType::Normal norm = ab % ac; | |
return norm; | |
} | |
// we assume a trimesh! | |
MeshType::Point OMesh::getFaceCenter(const MeshType::FaceHandle& faceHandle) { | |
MeshType::HalfedgeHandle heh_a, heh_b, heh_c; | |
heh_a = mesh.halfedge_handle(faceHandle); | |
heh_b = mesh.next_halfedge_handle(heh_a); | |
heh_c = mesh.next_halfedge_handle(heh_b); | |
MeshType::Point a = mesh.point(mesh.to_vertex_handle(heh_a)); | |
MeshType::Point b = mesh.point(mesh.to_vertex_handle(heh_b)); | |
MeshType::Point c = mesh.point(mesh.to_vertex_handle(heh_c)); | |
MeshType::Point ab = b - a; | |
MeshType::Point ac = c - a; | |
MeshType::Point ba = a - b; | |
MeshType::Point bc = c - b; | |
MeshType::Point bisect_a = ab+ac; | |
MeshType::Point bisect_b = ba+bc; | |
MeshType::Point intersection = lineIntersection(a,bisect_a,b,bisect_b); | |
return intersection; | |
} | |
// assuming given vectors cross, we return the intersection point. | |
MeshType::Point OMesh::lineIntersection( | |
const MeshType::Point& originA | |
,const MeshType::Point& dirA | |
,const MeshType::Point& originB | |
,const MeshType::Point& dirB | |
) | |
{ | |
MeshType::Point dir_a = dirA; | |
MeshType::Point dir_b = dirB; | |
dir_a.normalize(); | |
dir_b.normalize(); | |
MeshType::Point n = dir_a % dir_b; | |
MeshType::Point sr = originA - originB; | |
MeshType::Scalar abs_x = std::abs(n[0]); | |
MeshType::Scalar abs_y = std::abs(n[1]); | |
MeshType::Scalar abs_z = std::abs(n[2]); | |
float t; | |
if(abs_z > abs_x && abs_z > abs_y) { | |
t = (sr[0] * dir_b[1] - sr[1] * dir_b[0]) / n[2]; | |
} | |
else if(abs_x > abs_y) { | |
t = (sr[1] * dir_b[2] - sr[2] * dir_b[1]) / n[0]; | |
} | |
else { | |
t = (sr[2] * dir_b[0] - sr[0] * dir_b[2]) / n[1]; | |
} | |
return originA - t * dir_a; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ROXLU_OPEN_MESHH | |
#define ROXLU_OPEN_MESHH | |
#include "ofMain.h" | |
#include <string> | |
#include <vector> | |
using std::string; | |
#undef check | |
#include <OpenMesh/Core/IO/writer/OBJWriter.hh> | |
#include <OpenMesh/Core/IO/MeshIO.hh> // include before kernel type! | |
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh> | |
#include <OpenMesh/Tools/Utils/Timer.hh> | |
struct MyTraits : public OpenMesh::DefaultTraits { | |
VertexAttributes( | |
OpenMesh::Attributes::Normal | |
| OpenMesh::Attributes::Color | |
); | |
FaceAttributes( | |
OpenMesh::Attributes::Normal | |
); | |
}; | |
typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MeshType; | |
class OMesh { | |
public: | |
OMesh(); | |
~OMesh(); | |
MeshType::VertexHandle addVertex(const float& x, const float& y, const float& z); | |
MeshType::FaceHandle addFace(const MeshType::VertexHandle& a, const MeshType::VertexHandle& b, const MeshType::VertexHandle& c); | |
MeshType::FaceHandle addFace(const MeshType::VertexHandle& a, const MeshType::VertexHandle& b, const MeshType::VertexHandle& c, const MeshType::VertexHandle& d); | |
MeshType::FaceHandle addFace(const MeshType::VertexHandle* verts, const unsigned int& a, const unsigned int& b, const unsigned int& c); | |
MeshType::FaceHandle addFace(const MeshType::VertexHandle* verts, const unsigned int& a, const unsigned int& b, const unsigned int& c, const unsigned int& d); | |
MeshType::Point getFaceCenter(const MeshType::FaceHandle& faceHandle); | |
MeshType::Normal getFaceNormal(const MeshType::FaceHandle& faceHandle); | |
void debugDraw(); | |
bool save(const string& filepath); | |
bool load(const string& filepath); | |
MeshType mesh; | |
// utils | |
MeshType::Point lineIntersection( | |
const MeshType::Point& originA | |
,const MeshType::Point& directionA | |
,const MeshType::Point& originB | |
,const MeshType::Point& directionB | |
); | |
}; | |
inline MeshType::VertexHandle OMesh::addVertex(const float& x, const float& y, const float& z) { | |
return mesh.add_vertex(MeshType::Point(x,y,z)); | |
} | |
inline MeshType::FaceHandle OMesh::addFace(const MeshType::VertexHandle& a, const MeshType::VertexHandle& b, const MeshType::VertexHandle& c) { | |
std::vector<MeshType::VertexHandle> handles; | |
handles.push_back(a); | |
handles.push_back(b); | |
handles.push_back(c); | |
return mesh.add_face(handles); | |
} | |
inline MeshType::FaceHandle OMesh::addFace(const MeshType::VertexHandle& a, const MeshType::VertexHandle& b, const MeshType::VertexHandle& c, const MeshType::VertexHandle& d) { | |
std::vector<MeshType::VertexHandle> handles; | |
handles.push_back(a); | |
handles.push_back(b); | |
handles.push_back(c); | |
handles.push_back(d); | |
return mesh.add_face(handles); | |
} | |
inline MeshType::FaceHandle OMesh::addFace(const MeshType::VertexHandle* verts, const unsigned int& a, const unsigned int& b, const unsigned int& c) { | |
return addFace(verts[a], verts[b], verts[c]); | |
} | |
inline MeshType::FaceHandle OMesh::addFace(const MeshType::VertexHandle* verts, const unsigned int& a, const unsigned int& b, const unsigned int& c, const unsigned int& d) { | |
return addFace(verts[a], verts[b], verts[c], verts[d]); | |
} | |
struct OMesh_FaceDrawer { | |
OMesh_FaceDrawer(OMesh& mesh) | |
:mesh(mesh) | |
{ | |
} | |
void operator()(MeshType::Face& f) { | |
MeshType::FaceVertexIter face_vert = mesh.mesh.fv_iter(mesh.mesh.handle(f)); | |
while(face_vert) { | |
MeshType::Point p = mesh.mesh.point(face_vert); | |
glVertex3fv(p.data()); | |
++face_vert; | |
} | |
} | |
OMesh& mesh; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wrong, using OpenMesh normal()
Correct (custom function)