Raw File
#include "query_coarse_to_fine.h"

void query_coarse_to_fine(
  const std::vector<single_collapse_data> & decInfo,
  const Eigen::VectorXi & IM,
  const std::vector<std::vector<int>> & decIM,
  const Eigen::VectorXi & IMF,
  Eigen::MatrixXd & BC,
  Eigen::MatrixXi & BF,
  Eigen::VectorXi & FIdx)
{
  using namespace std;
  using namespace Eigen;
  bool verbose = false;

  int numQuery = BF.rows();
  int decLength = decInfo.size();

  VectorXi queryCounts(BC.rows());
  queryCounts.setZero();

  // convert vertex indices from V to VO
  {
    // change BF to be on fine mesh indices
    for (int r=0; r<BF.rows(); r++){
      for (int c=0; c<BF.cols(); c++){
        BF(r,c) = IM(BF(r,c));
      }
    }
  }

  // convert vertex indices from V to VO
  {
    for (int ii=0; ii<FIdx.size(); ii++)
      FIdx(ii) = IMF(FIdx(ii));
  }

  // for (int qIdx=0; qIdx<numQuery; qIdx++)
  igl::parallel_for(
    numQuery,
    [&verbose, &FIdx, &BC, &BF, &decIM, &decInfo, &queryCounts](const int qIdx)
  {
    // // print progress
    // if (qIdx % 1 == 0 && verbose) 
    //   cout << "coarse to fine : " << qIdx << "/" << BF.rows() << endl;

    // go through the decInfo 
    int dIdx = decInfo.size();

    while (true)
    {
      // get query FIdx 
      int queryFIdx = FIdx(qIdx);

      // find the dIdx
      vector<int> dIdxList = decIM[queryFIdx];
      bool if_find_dIdx = false;
      for (int ii=dIdxList.size()-1; ii>-1; ii--)
      {
        if (dIdx > dIdxList[ii])
        {
          dIdx = dIdxList[ii];
          if_find_dIdx = true;
          break;
        }
      }

      // if not dIdx left, break
      if (!if_find_dIdx)
        break;

      ///////// start query /////////
      if (verbose)
        cout << "qIdx: " << qIdx << ", dIdx: " << dIdx << endl; 

      // get vi and vj
      int vi = decInfo[dIdx].subsetVIdx(decInfo[dIdx].b(0));
      int vj = decInfo[dIdx].subsetVIdx(decInfo[dIdx].b(1));

      VectorXi f = BF.row(qIdx);

      // find f in subsetVIdx
      int v0, v1, v2; // such that subsetVIdx(v0) == f(0)
      {
        // PROFC_NODE("query: find local vIdx");
        VectorXi v0_vec, v1_vec, v2_vec;
        igl::find((decInfo[dIdx].subsetVIdx.array() == f(0)).eval(), v0_vec);
        igl::find((decInfo[dIdx].subsetVIdx.array() == f(1)).eval(), v1_vec);
        igl::find((decInfo[dIdx].subsetVIdx.array() == f(2)).eval(), v2_vec);

        assert(v0_vec.size() == 1);
        assert(v1_vec.size() == 1);
        assert(v2_vec.size() == 1);

        v0 = v0_vec(0);
        v1 = v1_vec(0);
        v2 = v2_vec(0);
      }

      // get query UV
      VectorXd queryUV = 
          BC(qIdx,0) * decInfo[dIdx].UV_post.row(v0)  
        + BC(qIdx,1) * decInfo[dIdx].UV_post.row(v1)
        + BC(qIdx,2) * decInfo[dIdx].UV_post.row(v2);

      Eigen::MatrixXd B;
      {
        // PROFC_NODE("query: compute barycentric");
        compute_barycentric(queryUV, decInfo[dIdx].UV_pre, decInfo[dIdx].FUV_pre,B);
        if (verbose)
          cout << "B: \n" << B << endl; 
      }

      // snap to the closest one
      VectorXd distToValid = -B.rowwise().minCoeff();
      double minD = 1.0;
      int idxToFUV;
      for (int bb=0;bb<distToValid.size(); bb++)
      { 
        if (distToValid(bb) < minD)
        {
          minD = distToValid(bb);
          idxToFUV = bb;
        }
      }

      // avoid numerical error of barycentric coordinate
      B(idxToFUV, 0) = max(0.0, B(idxToFUV, 0));
      B(idxToFUV, 1) = max(0.0, B(idxToFUV, 1));
      B(idxToFUV, 2) = max(0.0, B(idxToFUV, 2));
      B.row(idxToFUV) = B.row(idxToFUV).array() / B.row(idxToFUV).sum();

      BC.row(qIdx) = B.row(idxToFUV);

      BF(qIdx, 0) = decInfo[dIdx].subsetVIdx(decInfo[dIdx].FUV_pre(idxToFUV,0));
      BF(qIdx, 1) = decInfo[dIdx].subsetVIdx(decInfo[dIdx].FUV_pre(idxToFUV,1));
      BF(qIdx, 2) = decInfo[dIdx].subsetVIdx(decInfo[dIdx].FUV_pre(idxToFUV,2));
      FIdx(qIdx) = decInfo[dIdx].FIdx_pre(idxToFUV);
    }
  // };
  },1000);

  if (verbose)
    cout << "finish query points\n";

}
back to top