git.haldean.org subd / bf06a1d src / drawmesh.cpp
bf06a1d

Tree @bf06a1d (Download .tar.gz)

drawmesh.cpp @bf06a1draw · history · blame

#include <Eigen/Core>
#include <iostream>
#include <cstring>

#include "drawmesh.h"
#include "glinclude.h"

void drawString(string s) {
  glDisable(GL_LIGHTING);

  int matrixMode;
  glGetIntegerv(GL_MATRIX_MODE, &matrixMode);  /* matrix mode? */

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  gluOrtho2D(0.0, 1.0, 0.0, 1.0);

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  glPushAttrib(GL_COLOR_BUFFER_BIT);       /* save current colour */

  glRasterPos3f(0.01, 0.01, 0);
  glColor4f(1., 1., 1., 1.);
  for (unsigned int i = 0; i < s.length(); i++) {
    glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, s[i]);
  }

  glPopAttrib();
  glPopMatrix();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(matrixMode);

  glEnable(GL_LIGHTING);
}

void vector3ToGL(Vector3f v) {
  glVertex3f(v[0], v[1], v[2]);
}

void drawVertex(vertex &v, face *face, drawopts opts) {
  if (!v.normal.isZero()) {
    glNormal3f(v.normal[0], v.normal[1], v.normal[2]);
  } else {
    glNormal3f(face->normal[0], face->normal[1], face->normal[2]);
  }
  vector3ToGL(v.loc);
}

void drawFace(face* face, drawopts opts) {
  if (opts.drawFaces) {
    if (face->sides() == 3) glBegin(GL_TRIANGLES);
    //else if (face->sides() == 4) glBegin(GL_QUADS);
    else glBegin(GL_TRIANGLE_FAN);

    edge *e0 = face->e;
    edge *e = e0;
    do {
      drawVertex(*e->vert, face, opts);
      e = e->next;
    } while (e != e0);

    glEnd();
  }
}

void drawEdges(face* face, drawopts opts) {
  glBegin(GL_LINE_STRIP); {
    edge *e0 = face->e;
    edge *e = e0;
    do {
      vector3ToGL(e->vert->loc);
      e = e->next;
    } while (e != e0);
    vector3ToGL(e0->vert->loc);
  } glEnd();
}

void drawNormals(face* face, drawopts opts) {

  for (int i = 0; i < 3; i++) {
    edge *e0 = face->e;
    edge *e = e0;
    do {
      vertex *v = e->vert;
      glBegin(GL_LINE_STRIP); {
        vector3ToGL(v->loc);
        vector3ToGL(v->loc + v->normal);
      } glEnd();
      e = e->next;
    } while (e != e0);
  }
}

void drawHull(mesh &mesh, drawopts opts) {
  if (!opts.drawHull) return;

  glEnable(GL_POLYGON_OFFSET_FILL);
  glPolygonOffset(1.0, 1.0);
  glLineWidth(2.0);
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, opts.hullColor);

  for (auto fit = mesh.faces.begin(); fit != mesh.faces.end(); fit++) {
    drawEdges(*fit, opts);
  }

  glutWireCube(1.);
}

void drawMesh(mesh &mesh, drawopts opts) {
  glEnable(GL_POLYGON_OFFSET_FILL);
  glPolygonOffset(1.0, 1.0);
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, opts.meshColor);
  if (opts.drawFaces || opts.drawVerteces) {
    for (auto it = mesh.faces.begin(); it != mesh.faces.end(); it++) {
      face* face = (*it);
      drawFace(face, opts);
    }
  }

  if (opts.drawEdges) {
    glLineWidth(2.0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, opts.edgeColor);
    for (auto it = mesh.faces.begin(); it != mesh.faces.end(); it++) {
      drawEdges(*it, opts);
    }
  }

  if (opts.drawNormals) {
    glLineWidth(1.0);
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, opts.normalColor);
    for (auto v = mesh.verteces.begin(); v != mesh.verteces.end(); v++) {
      glBegin(GL_LINE_STRIP); {
        vector3ToGL((*v)->loc);
        vector3ToGL((*v)->loc + (*v)->normal);
      } glEnd();
    }
  }

  if (opts.drawVerteces) {
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, opts.meshColor);
    for (auto v = mesh.verteces.begin(); v != mesh.verteces.end(); v++) {
      glPushMatrix(); {
        glTranslatef((*v)->loc[0], (*v)->loc[1], (*v)->loc[2]);
        glutSolidSphere(0.1, 5, 5);
      } glPopMatrix();
    }
  }
}

drawopts defaultDrawOptions() {
  drawopts opts;
  opts.drawEdges = false;
  opts.drawNormals = false;
  opts.drawFaces = true;
  opts.drawVerteces = false;
  opts.drawHull = false;

  opts.useCelShader = true;
  opts.animate = true;

  opts.normalColor[0] = 1.;
  opts.normalColor[1] = .5;
  opts.normalColor[2] = .5;
  opts.normalColor[3] = 1.;

  for (int i=0; i<3; i++) opts.edgeColor[i] = 0.;
  opts.edgeColor[3] = 1.;

  opts.meshColor[0] = 1.;
  opts.meshColor[1] = .5;
  opts.meshColor[2] = 0.;
  opts.meshColor[3] = 1.;

  for (int i=0; i<3; i++) opts.hullColor[i] = 0.;
  opts.hullColor[3] = .3;

  return opts;
}