Exemple #1
0
int main(int argc, char *argv[])
{
  using namespace Eigen;
  using namespace std;

  cout<<"Usage:"<<endl;
  cout<<"[space]  toggle showing surface."<<endl;
  cout<<"'.'/','  push back/pull forward slicing plane."<<endl;
  cout<<endl;

  // Load mesh: (V,T) tet-mesh of convex hull, F contains original surface
  // triangles
  igl::readMESH("../shared/bunny.mesh",V,T,F);


  // Encapsulated call to point_mesh_squared_distance to determine bounds
  {
    VectorXd sqrD;
    VectorXi I;
    MatrixXd C;
    igl::point_mesh_squared_distance(V,V,F,sqrD,I,C);
    max_distance = sqrt(sqrD.maxCoeff());
  }

  // Precompute signed distance AABB tree
  tree.init(V,F);
  // Precompute vertex,edge and face normals
  igl::per_face_normals(V,F,FN);
  igl::per_vertex_normals(
    V,F,igl::PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE,FN,VN);
  igl::per_edge_normals(
    V,F,igl::PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM,FN,EN,E,EMAP);

  // Plot the generated mesh
  igl::viewer::Viewer viewer;
  update_visualization(viewer);
  viewer.callback_key_down = &key_down;
  viewer.core.show_lines = false;
  viewer.launch();
}
void mexFunction(
  int nlhs, mxArray *plhs[], 
  int nrhs, const mxArray *prhs[])
{
  using namespace std;
  using namespace Eigen;
  using namespace igl;
  using namespace igl::matlab;

  igl::matlab::MexStream mout;        
  std::streambuf *outbuf = cout.rdbuf(&mout);
  //mexPrintf("Compiled at %s on %s\n",__TIME__,__DATE__);

  MatrixXd P,V,C,N;
  MatrixXi F;
  VectorXi I;
  VectorXd S;
  SignedDistanceType type;
  parse_rhs(nrhs,prhs,P,V,F,type);

  if(F.rows() > 0)
  {
    switch(V.cols())
    {
      case 2:
      {
        // Persistent data not supported for 2D
        signed_distance(P,V,F,type,S,I,C,N);
        break;
      }
      case 3:
      {
        if(g_sign_type != type || g_V != V || g_F != F)
        {
          g_V = V;
          g_F = F;
          g_sign_type = type;
          // Clear the tree
          g_tree.deinit();

          // Prepare distance computation
          g_tree.init(V,F);
          switch(type)
          {
            default:
              assert(false && "Unknown SignedDistanceType");
            case SIGNED_DISTANCE_TYPE_DEFAULT:
            case SIGNED_DISTANCE_TYPE_WINDING_NUMBER:
              g_hier.set_mesh(V,F);
              g_hier.grow();
              break;
            case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
              // "Signed Distance Computation Using the Angle Weighted Pseudonormal"
              // [Bærentzen & Aanæs 2005]
              per_face_normals(V,F,g_FN);
              per_vertex_normals(V,F,PER_VERTEX_NORMALS_WEIGHTING_TYPE_ANGLE,
                g_FN,g_VN);
              per_edge_normals(
                V,F,PER_EDGE_NORMALS_WEIGHTING_TYPE_UNIFORM,
                g_FN,g_EN,g_E,g_EMAP);
              break;
          }
        }

        N.resize(P.rows(),3);
        S.resize(P.rows(),1);
        I.resize(P.rows(),1);
        C.resize(P.rows(),3);
        //for(int p = 0;p<P.rows();p++)
        igl::parallel_for(P.rows(),[&](const int p)
        {
          const Eigen::RowVector3d q(P(p,0),P(p,1),P(p,2));
          double s,sqrd;
          Eigen::RowVector3d c;
          int i;
          switch(type)
          {
            default:
              assert(false && "Unknown SignedDistanceType");
            case SIGNED_DISTANCE_TYPE_DEFAULT:
            case SIGNED_DISTANCE_TYPE_WINDING_NUMBER:
              signed_distance_winding_number(
                g_tree,g_V,g_F,g_hier,q,s,sqrd,i,c);
              break;
            case SIGNED_DISTANCE_TYPE_PSEUDONORMAL:
            {
              RowVector3d n(0,0,0);
              signed_distance_pseudonormal(
                g_tree,g_V,g_F,g_FN,g_VN,g_EN,g_EMAP,
                q,s,sqrd,i,c,n);
              N.row(p) = n;
              break;
            }
          }
          I(p) = i;
          S(p) = s*sqrt(sqrd);
          C.row(p) = c;
        },10000);
        break;
      }
    }
  }

  switch(nlhs)
  {
    default:
    {
      mexErrMsgTxt(false,"Too many output parameters.");
    }
    case 4:
    {
      prepare_lhs_double(N,plhs+3);
      // Fall through
    }
    case 3:
    {
      prepare_lhs_double(C,plhs+2);
      // Fall through
    }
    case 2:
    {
      prepare_lhs_index(I,plhs+1);
      // Fall through
    }
    case 1:
    {
      prepare_lhs_double(S,plhs+0);
      // Fall through
    }
    case 0: break;
  }

  // Restore the std stream buffer Important!
  std::cout.rdbuf(outbuf);
}