Hacky texture map editor using libigl

Alec Jacobson

January 07, 2016

weblog/

Here's a little program that reads a texture mapped mesh from an .obj with UVs and a texture map from a .png and visualizes them.

Before every frame is drawn, I reload the .png file. So if you've saved a newly edited version, say in photoshop with a window open next to the viewer window, then it will be loaded. The bottleneck currently is for sure me hitting the save key.

#include <igl/readOBJ.h>
#include <igl/viewer/Viewer.h>
#include <igl/unzip_corners.h>
#include <YImage.hpp>
#include <iostream>
int main(int argc, char * argv[])
{
  using namespace std;
  Eigen::MatrixXd V, TC, N;
  Eigen::MatrixXi F,FTC,FN;
  igl::readOBJ(argv[1],V,TC,N,F,FTC,FN);
  if(FTC.size() == 0)
  {
    FTC = F;
  }
  igl::viewer::Viewer viewer;
  typedef Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic> MatrixXuc;
  MatrixXuc R,G,B;
  const auto & update_texture = [&]()
  {
    YImage yimg;
    yimg.load(argv[2]);
    R.resize(yimg.width(),yimg.height());
    B.resize(R.rows(),R.cols());
    G.resize(R.rows(),R.cols());
    for(int i = 0;i<yimg.width();i++)
    {
      for(int j = 0;j<yimg.height();j++)
      {
        const auto & p = yimg.at(i,j);
        R(i,yimg.height()-1-j) = p.r;
        G(i,yimg.height()-1-j) = p.g;
        B(i,yimg.height()-1-j) = p.b;
      }
    }
  };
  viewer.callback_pre_draw = [&](igl::viewer::Viewer &)->bool
  {
    update_texture();
    viewer.data.set_texture(R,G,B);
    return false;
  };
  viewer.data.set_mesh(V,F);
  viewer.data.set_colors((Eigen::MatrixXd(1,3) << 1,1,1).finished());
  viewer.data.set_uv(TC,FTC);
  viewer.core.show_texture = true;
  viewer.core.is_animating = true;
  viewer.launch();
}