Skip to content

Instantly share code, notes, and snippets.

@roxlu
Created May 26, 2012 16:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roxlu/2794471 to your computer and use it in GitHub Desktop.
Save roxlu/2794471 to your computer and use it in GitHub Desktop.
OpenMesh
#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;
}
#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
@roxlu
Copy link
Author

roxlu commented May 26, 2012

Wrong, using OpenMesh normal()

Correct (custom function)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment