Example #1
0
void RealtimeMF_openni::normals_cb(float* d_normals, uint8_t* haveData,
    uint32_t w, uint32_t h)
{
  tLog_.tic(-1); // reset all timers
  int32_t nComp = 0;
  float* d_nComp = this->normalExtract->d_normalsComp(nComp);
  Matrix3f kRwBefore = kRw_;
  tLog_.toctic(0,1);

  optSO3_->updateExternalGpuNormals(d_nComp,nComp,3,0);
  double residual = optSO3_->conjugateGradientCUDA(kRw_,nCGIter_);
  double D_KL = optSO3_->D_KL_axisUnif();
  tLog_.toctic(1,2);

  {
    boost::mutex::scoped_lock updateLock(this->updateModelMutex);
    this->normalsImg_ = this->normalExtract->normalsImg();
    if(z_.rows() != w*h) z_.resize(w*h);
    this->normalExtract->uncompressCpu(optSO3_->z().data(), optSO3_->z().rows(),
        z_.data(), z_.rows());

    mfAxes_ = MatrixXf::Zero(3,6);
    for(uint32_t k=0; k<6; ++k){
      int j = k/2; // which of the rotation columns does this belong to
      float sign = (- float(k%2) +0.5f)*2.0f; // sign of the axis
      mfAxes_.col(k) = sign*kRw_.col(j);
    }
    D_KL_= D_KL;
    residual_ = residual;
    this->update_ = true;
    updateLock.unlock();
  }

  tLog_.toc(2); // total time
  tLog_.logCycle();
  cout<<"delta rotation kRw_ = \n"<<kRwBefore*kRw_.transpose()<<endl;
  cout<<"---------------------------------------------------------------------------"<<endl;
  tLog_.printStats();
  cout<<" residual="<<residual_<<"\t D_KL="<<D_KL_<<endl;
  cout<<"---------------------------------------------------------------------------"<<endl;
  fout_<<D_KL_<<" "<<residual_<<endl; fout_.flush();

////  return kRw_;
//  {
//    boost::mutex::scoped_lock updateLock(this->updateModelMutex);
////    pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr nDispPtr =
////      normalExtract->normalsPc();
////    nDisp_ = pcl::PointCloud<pcl::PointXYZRGB>::Ptr( new
////        pcl::PointCloud<pcl::PointXYZRGB>(*nDispPtr));
////    this->normalsImg_ = this->normalExtract->normalsImg();
//    this->update_ = true;
//  }
};
Example #2
0
void build_dedge(const MatrixXu &F, const MatrixXf &V, VectorXu &V2E,
                         VectorXu &E2E, VectorXb &boundary, VectorXb &nonManifold,
                         const ProgressCallback &progress, bool quiet) {
    if (!quiet) {
        cout << "Building a directed edge data structure .. ";
        cout.flush();
    }
    Timer<> timer;

    if (progress && !quiet)
        progress("Building directed edge data structure", 0.0f);

    V2E.resize(V.cols());
    V2E.setConstant(INVALID);

    uint32_t deg = F.rows();
    std::vector<std::pair<uint32_t, uint32_t>> tmp(F.size());

    tbb::parallel_for(
        tbb::blocked_range<uint32_t>(0u, (uint32_t) F.cols(), GRAIN_SIZE),
        [&](const tbb::blocked_range<uint32_t> &range) {
            for (uint32_t f = range.begin(); f != range.end(); ++f) {
                for (uint32_t i = 0; i < deg; ++i) {
                    uint32_t idx_cur = F(i, f),
                             idx_next = F((i+1)%deg, f),
                             edge_id = deg * f + i;
                    if (idx_cur >= V.cols() || idx_next >= V.cols())
                        throw std::runtime_error("Mesh data contains an out-of-bounds vertex reference!");
                    if (idx_cur == idx_next)
                        continue;

                    tmp[edge_id] = std::make_pair(idx_next, INVALID);
                    if (!atomicCompareAndExchange(&V2E[idx_cur], edge_id, INVALID)) {
                        uint32_t idx = V2E[idx_cur];
                        while (!atomicCompareAndExchange(&tmp[idx].second, edge_id, INVALID))
                            idx = tmp[idx].second;
                    }
                }
            }
            if (!quiet)
                SHOW_PROGRESS_RANGE(range, F.cols(), "Building directed edge data structure (1/3)");
        }
    );

    nonManifold.resize(V.cols());
    nonManifold.setConstant(false);

    E2E.resize(F.cols() * deg);
    E2E.setConstant(INVALID);

    tbb::parallel_for(
        tbb::blocked_range<uint32_t>(0u, (uint32_t) F.cols(), GRAIN_SIZE),
        [&](const tbb::blocked_range<uint32_t> &range) {
            for (uint32_t f = range.begin(); f != range.end(); ++f) {
                for (uint32_t i = 0; i < deg; ++i) {
                    uint32_t idx_cur = F(i, f),
                             idx_next = F((i+1)%deg, f),
                             edge_id_cur = deg * f + i;

                    if (idx_cur == idx_next)
                        continue;

                    uint32_t it = V2E[idx_next], edge_id_opp = INVALID;
                    while (it != INVALID) {
                        if (tmp[it].first == idx_cur) {
                            if (edge_id_opp == INVALID) {
                                edge_id_opp = it;
                            } else {
                                nonManifold[idx_cur] = true;
                                nonManifold[idx_next] = true;
                                edge_id_opp = INVALID;
                                break;
                            }
                        }
                        it = tmp[it].second;
                    }

                    if (edge_id_opp != INVALID && edge_id_cur < edge_id_opp) {
                        E2E[edge_id_cur] = edge_id_opp;
                        E2E[edge_id_opp] = edge_id_cur;
                    }
                }
            }
            if (!quiet)
                SHOW_PROGRESS_RANGE(range, F.cols(), "Building directed edge data structure (2/3)");
        }
    );

    std::atomic<uint32_t> nonManifoldCounter(0), boundaryCounter(0), isolatedCounter(0);

    boundary.resize(V.cols());
    boundary.setConstant(false);

    /* Detect boundary regions of the mesh and adjust vertex->edge pointers*/
    tbb::parallel_for(
        tbb::blocked_range<uint32_t>(0u, (uint32_t) V.cols(), GRAIN_SIZE),
        [&](const tbb::blocked_range<uint32_t> &range) {
            for (uint32_t i = range.begin(); i != range.end(); ++i) {
                uint32_t edge = V2E[i];
                if (edge == INVALID) {
                    isolatedCounter++;
                    continue;
                }
                if (nonManifold[i]) {
                    nonManifoldCounter++;
                    V2E[i] = INVALID;
                    continue;
                }

                /* Walk backwards to the first boundary edge (if any) */
                uint32_t start = edge, v2e = INVALID;
                do {
                    v2e  = std::min(v2e, edge);
                    uint32_t prevEdge = E2E[dedge_prev(edge, deg)];
                    if (prevEdge == INVALID) {
                        /* Reached boundary -- update the vertex->edge link */
                        v2e = edge;
                        boundary[i] = true;
                        boundaryCounter++;
                        break;
                    }
                    edge = prevEdge;
                } while (edge != start);
                V2E[i] = v2e;
            }
            if (!quiet)
                SHOW_PROGRESS_RANGE(range, V.cols(), "Building directed edge data structure (3/3)");
        }
    );

    if (!quiet) {
        cout << "done. (";
        if (nonManifoldCounter)
            cout << nonManifoldCounter << " non-manifold vertices, ";
        if (boundaryCounter)
            cout << boundaryCounter << " boundary vertices, ";
        if (isolatedCounter)
            cout << isolatedCounter << " isolated vertices, ";
        cout << "took " << timeString(timer.value()) << ")" << endl;
    }
}