double EigenSolverPoissonImageEditing::solve(const NamedParameters& solverParameters, const NamedParameters& problemParameters, bool profileSolve, std::vector<SolverIteration>& iters)
{
    int numUnknowns = 0;
    std::unordered_map<vec2i, int, vec2iHash> pixelLocationsToIndex;
    std::vector<vec2i> pixelLocations;
    size_t pixelCount = m_dims[0] * m_dims[1];
    std::vector<float4> h_unknownFloat(pixelCount);
    std::vector<float4> h_target(pixelCount);
    std::vector<float>  h_mask(pixelCount);

    findAndCopyArrayToCPU("X", h_unknownFloat, problemParameters);
    findAndCopyArrayToCPU("T", h_target, problemParameters);
    findAndCopyArrayToCPU("M", h_mask, problemParameters);

    for (int y = 0; y < (int)m_dims[1]; ++y) {
        for (int x = 0; x < (int)m_dims[0]; ++x) {
            if (h_mask[y*m_dims[0] + x] == 0.0f) {
                ++numUnknowns;
                vec2i p(x, y);
                pixelLocationsToIndex[p] =(int)pixelLocations.size();
                pixelLocations.push_back(p);
            }
        }
    }
    printf("# Unknowns: %d\n", numUnknowns);
    int numResiduals = (int)pixelLocations.size() * 4;

    Eigen::VectorXf x_r(numUnknowns), b_r(numResiduals);
    Eigen::VectorXf x_g(numUnknowns), b_g(numResiduals);
    Eigen::VectorXf x_b(numUnknowns), b_b(numResiduals);
    Eigen::VectorXf x_a(numUnknowns), b_a(numResiduals);

    b_r.setZero();
    b_g.setZero();
    b_b.setZero();
    b_a.setZero();

    for (int i = 0; i < pixelLocations.size(); ++i) {
        vec2i p = pixelLocations[i];
        float4 color = sampleImage(h_unknownFloat.data(), p, m_dims[0]);
        x_r[i] = color.x;
        //printf("%f\n", color.x);
        x_g[i] = color.y;
        x_b[i] = color.z;
        x_a[i] = color.w;
    }
    SpMatrixf A(numResiduals, numUnknowns);
    A.setZero();
    printf("Constructing Matrix\n");
    std::vector<Tripf> entriesA;

    std::vector<vec2i> offsets;
    offsets.push_back(vec2i(-1, 0));
    offsets.push_back(vec2i(1, 0));
    offsets.push_back(vec2i(0, -1));
    offsets.push_back(vec2i(0, 1));

    for (int i = 0; i < pixelLocations.size(); ++i) {
        vec2i p = pixelLocations[i];
        int numInternalNeighbors = 0;
        float4 g_p = sampleImage(h_target.data(), p, m_dims[0]);
        int j = 0;

        for (vec2i off : offsets) {
            vec2i q = p + off;
            if (q.x >= 0 && q.y >= 0 && q.x < (int)m_dims[0] && q.y < (int)m_dims[1]) {
                auto it = pixelLocationsToIndex.find(q);
                int row = 4 * i + j;
                if (it == pixelLocationsToIndex.end()) {
                    float4 f_q = sampleImage(h_unknownFloat.data(), q, m_dims[0]);
                    b_r[row] += f_q.x;
                    b_g[row] += f_q.y;
                    b_b[row] += f_q.z;
                    b_a[row] += f_q.w;
                }
                else {
                    entriesA.push_back(Tripf(row, it->second, -1.0f));
                }
                entriesA.push_back(Tripf(row, i, 1.0f));

                float4 g_q = sampleImage(h_target.data(), q, m_dims[0]);
                b_r[row] += (g_p.x - g_q.x);
                b_g[row] += (g_p.y - g_q.y);
                b_b[row] += (g_p.z - g_q.z);
                b_a[row] += (g_p.w - g_q.w);
            }
            ++j;
            
        }
    }
    

    printf("Entries Set\n");
    A.setFromTriplets(entriesA.begin(), entriesA.end());
    printf("Sparse Matrix Constructed\n");
    A.makeCompressed();
    printf("Matrix Compressed\n");
    {
        float totalCost = 0.0f;
        
        float cost_r = (A*x_r - b_r).squaredNorm();
        float cost_g = (A*x_g - b_g).squaredNorm();
        float cost_b = (A*x_b - b_b).squaredNorm();
        float cost_a = (A*x_a - b_a).squaredNorm();
        totalCost = cost_r + cost_g + cost_b + cost_a;
        printf("Initial Cost: %f : (%f, %f, %f, %f)\n", totalCost, cost_r, cost_g, cost_b, cost_a);

    }
    

    AxEqBSolver solver;
    solver.setMaxIterations(97);
    printf("Solvers Initialized\n");

    clock_t start = clock(), diff;
    
    solver.compute(A);
    //printf("solver.compute(A)\n");
    solveAxEqb(solver, b_r, x_r);
    //printf("Red solve done\n");
    solveAxEqb(solver, b_g, x_g);
    //printf("Green solve done\n");
    solveAxEqb(solver, b_b, x_b);
    //printf("Blue solve done\n");
    solveAxEqb(solver, b_a, x_a);

    diff = clock() - start;
    printf("Time taken %f ms\n", diff*1000.0 / double(CLOCKS_PER_SEC));

    float totalCost = 0.0f;
 
    float cost_r = (A*x_r - b_r).squaredNorm(); 
    float cost_g = (A*x_g - b_g).squaredNorm();
    float cost_b = (A*x_b - b_b).squaredNorm();
    float cost_a = (A*x_a - b_a).squaredNorm();
    totalCost = cost_r + cost_g + cost_b + cost_a;
    printf("Final Cost: %f : (%f, %f, %f, %f)\n", totalCost, cost_r, cost_g, cost_b, cost_a);

    for (int i = 0; i < pixelLocations.size(); ++i) {
        setPixel(h_unknownFloat.data(), pixelLocations[i], m_dims[0], x_r[i], x_g[i], x_b[i]);
    }
    findAndCopyToArrayFromCPU("X", h_unknownFloat, problemParameters);;
    return (double)totalCost;

}
Example #2
0
void obliqueangle_engine::render(level_ptr level, boost::shared_ptr<image_operations> oper)
{
  pos_t iw, ih;
  part_c.get_obliqueangle_limits(iw, ih);
  
  BlockRotation b_r(s, level->get_blocks());
  BlockRotation b_d(s, level->get_data());
  BlockRotation bl_r(s, level->get_blocklight());
  BlockRotation sl_r(s, level->get_skylight());
  BlockRotation hm_r(s, level->get_heightmap());

  pos_t bmt = iw * ih;
  
  boost::scoped_array<bool> blocked(new bool[bmt]);
  memset(blocked.get(), 0x0, sizeof(bool) * bmt);
  
  oper->set_limits(iw + 1, ih);
  
  for (int z = mc::MapZ - 1; z >= 0; z--) {
    for (int x = mc::MapX - 1; x >= 0; x--) {
      bool cave_initial = true;
      bool hell_initial = true;
      bool hell_solid = true;
      
      hm_r.set_xz(x, z);
      b_r.set_xz(x, z);
      b_d.set_xz(x, z);
      bl_r.set_xz(x, z);
      sl_r.set_xz(x, z);
      
      int hmval = hm_r.get8();
      
      if (s.hellmode) {
        for (int y = s.top; y >= s.bottom && hell_solid; y--) { hell_solid = !is_open(b_r.get8(y)); }
      }
      
      for (int y = s.top; y >= s.bottom; y--) {
        int bt = b_r.get8(y);
        
        if (s.cavemode && cave_ignore_block(s, y, bt, b_r, cave_initial)) {
          continue;
        }
        
        if (s.hellmode && !hell_solid && hell_ignore_block(s, y, bt, b_r, hell_initial)) {
          continue;
        }
        
        if (s.excludes[bt]) {
          continue;
        }
        
        point p(x, y, z);
        
        pos_t px, py;
        part_c.project_obliqueangle(p, px, py);
        
        color top, side;
        if (bt == mc::Wool) {
          int md = b_d.get4(y);
          top = mc::WoolColor[md];
          side = mc::WoolColor[md];
        } else if ((bt == mc::Step) || (bt == mc::DoubleStep)) {
          int md = b_d.get4(y);
          top = mc::StepColor[md];
          side = mc::StepColor[md];
        } else {
          top = mc::MaterialColor[bt];
          side = mc::MaterialSideColor[bt];
        }
        
        if (mc::MaterialModes[bt] == mc::Block) {
          int bp = px + iw * py;
          
          if (blocked[bp]) {
            continue;
          }
          
          blocked[bp] = top.is_opaque();
        }
        
        int bl = bl_r.get4(y + 1);
        
        apply_shading(s, bl, sl_r.get4(y + 1), hmval, y, top);
        apply_shading(s, bl, -1, hmval, y, side);
        
        switch(mc::MaterialModes[bt]) {
        case mc::Block:
          oper->add_pixel(px, py, top);
          oper->add_pixel(px + 1, py, top);
          oper->add_pixel(px, py + 1, side);
          
          side.lighten(0x20);
          oper->add_pixel(px + 1, py + 1, side);
          break;
        case mc::HalfBlock:
          oper->add_pixel(px, py + 1, top);
          oper->add_pixel(px + 1, py + 1, top);
          break;
        case mc::TorchBlock:
          oper->add_pixel(px, py, top);

          top.lighten(0x20);
          top.a -= 0xb0;
          oper->add_pixel(px - 1, py, top);
          oper->add_pixel(px + 2, py, top);
          oper->add_pixel(px, py - 1, top);
          oper->add_pixel(px, py + 1, top);
          
          oper->add_pixel(px, py + 1, side);
          break;
        }
      }
    }
  }
}
Example #3
0
void fatiso_engine::render(level_ptr level, boost::shared_ptr<image_operations> oper)
{
  BlockRotation b_r(s, level->get_blocks());
  BlockRotation b_d(s, level->get_data());
  BlockRotation bl_r(s, level->get_blocklight());
  BlockRotation sl_r(s, level->get_skylight());
  BlockRotation hm_r(s, level->get_heightmap());

  pos_t iw, ih;
  
  part_c.get_fatiso_limits(iw, ih);
  pos_t bmt = iw * ih;
  
  boost::scoped_array<bool> blocked(new bool[bmt]);
  memset(blocked.get(), 0x0, sizeof(bool) * bmt);
  
  oper->set_limits(iw + 1, ih);
  
  for (int z = mc::MapZ - 1; z >= 0; z--) {
    for (int x = mc::MapX - 1; x >= 0; x--) {
      bool cave_initial = true;
      bool hell_initial = true;
      bool hell_solid = true;
      
      hm_r.set_xz(x, z);
      b_r.set_xz(x, z);
      b_d.set_xz(x, z);
      bl_r.set_xz(x, z);
      sl_r.set_xz(x, z);
      
      int hmval = hm_r.get8();
      
      if (s.hellmode) {
        for (int y = s.top; y >= s.bottom && hell_solid; y--) { hell_solid = !is_open(b_r.get8(y)); }
      }
      
      for (int y = s.top; y >= s.bottom; y--) {
        int bt = b_r.get8(y);
        
        if (s.cavemode && cave_ignore_block(s, y, bt, b_r, cave_initial)) {
          continue;
        }
        
        if (s.hellmode && !hell_solid && hell_ignore_block(s, y, bt, b_r, hell_initial)) {
          continue;
        }
        
        if (s.excludes[bt]) {
          continue;
        }
        
        point p(x, y, z);
        
        pos_t px, py;
        part_c.project_fatiso(p, px, py);
        
        color top = blockColor_top(bt, y, b_d),
             side = blockColor_side(bt, y, b_d);
        
        if (mc::MaterialModes[bt] == mc::Block) {
          int bp = px + iw * py;
          
          if (blocked[bp]) {
            continue;
          }
          
          blocked[bp] = top.is_opaque() && bt != mc::Fence;
        }
        
        
        int bl = bl_r.get4(y + 1);
        
        apply_shading(s, bl, sl_r.get4(y + 1), hmval, y, top);
        apply_shading(s, bl, -1, hmval, y, side);

        color topdark(top);
        color toplight(top);
        color sidelight(side);

        if (bt == mc::Grass) {
          topdark.darken(0x20);
          toplight.darken(0x10);
          sidelight.lighten(0x20);
        }
        else {
          toplight = color(side);
          topdark = color(side);
        }

        oper->add_pixel(px + 0, py + 0, side);
        oper->add_pixel(px + 0, py + 1, side);
        oper->add_pixel(px + 0, py + 2, side);
        oper->add_pixel(px + 1, py - 1, side);
        oper->add_pixel(px + 1, py + 0, side);
        oper->add_pixel(px + 1, py + 1, side);
        oper->add_pixel(px + 2, py - 1, side);
        oper->add_pixel(px + 2, py + 0, side);
        oper->add_pixel(px + 2, py + 1, side);
        oper->add_pixel(px + 3, py - 2, side);
        oper->add_pixel(px + 3, py - 1, side);
        oper->add_pixel(px + 3, py + 0, side);

        oper->add_pixel(px - 1, py + 0, sidelight);
        oper->add_pixel(px - 1, py + 1, sidelight);
        oper->add_pixel(px - 1, py + 2, sidelight);
        oper->add_pixel(px - 2, py - 1, sidelight);
        oper->add_pixel(px - 2, py + 0, sidelight);
        oper->add_pixel(px - 2, py + 1, sidelight);
        oper->add_pixel(px - 3, py - 1, sidelight);
        oper->add_pixel(px - 3, py + 0, sidelight);
        oper->add_pixel(px - 3, py + 1, sidelight);
        oper->add_pixel(px - 4, py - 2, sidelight);
        oper->add_pixel(px - 4, py - 1, sidelight);
        oper->add_pixel(px - 4, py + 0, sidelight);

        oper->add_pixel(px + 0, py - 2, topdark);
        oper->add_pixel(px + 0, py - 1, topdark);
        oper->add_pixel(px + 1, py - 3, topdark);
        oper->add_pixel(px + 1, py - 2, topdark);
        oper->add_pixel(px + 2, py - 3, topdark);
        oper->add_pixel(px + 2, py - 2, topdark);
        oper->add_pixel(px + 3, py - 4, topdark);
        oper->add_pixel(px + 3, py - 3, topdark);

        oper->add_pixel(px - 1, py - 2, toplight);
        oper->add_pixel(px - 1, py - 1, toplight);
        oper->add_pixel(px - 2, py - 3, toplight);
        oper->add_pixel(px - 2, py - 2, toplight);
        oper->add_pixel(px - 3, py - 3, toplight);
        oper->add_pixel(px - 3, py - 2, toplight);
        oper->add_pixel(px - 4, py - 4, toplight);
        oper->add_pixel(px - 4, py - 3, toplight);

        oper->add_pixel(px - 3, py - 5, top);
        oper->add_pixel(px - 3, py - 4, top);
        oper->add_pixel(px - 2, py - 5, top);
        oper->add_pixel(px - 2, py - 4, top);
        oper->add_pixel(px - 1, py - 6, top);
        oper->add_pixel(px - 1, py - 5, top);
        oper->add_pixel(px - 1, py - 4, top);
        oper->add_pixel(px - 1, py - 3, top);
        oper->add_pixel(px + 0, py - 6, top);
        oper->add_pixel(px + 0, py - 5, top);
        oper->add_pixel(px + 0, py - 4, top);
        oper->add_pixel(px + 0, py - 3, top);
        oper->add_pixel(px + 1, py - 5, top);
        oper->add_pixel(px + 1, py - 4, top);
        oper->add_pixel(px + 2, py - 5, top);
        oper->add_pixel(px + 2, py - 4, top);
      }
    }
  }
  
  return;
}