| 664 | } |
| 665 | |
| 666 | void BakeTexture(Bitmap* atlas, |
| 667 | std::vector<bool>* baked_mask, |
| 668 | const PlyMesh& mesh, |
| 669 | const std::vector<FaceRegion>& regions, |
| 670 | const std::vector<RegionProjection>& projections, |
| 671 | const AtlasLayout& layout, |
| 672 | const std::vector<Image>& images, |
| 673 | const MeshTextureMappingOptions& options) { |
| 674 | const int aw = layout.atlas_width; |
| 675 | const int ah = layout.atlas_height; |
| 676 | |
| 677 | baked_mask->assign(static_cast<size_t>(aw) * ah, false); |
| 678 | |
| 679 | for (size_t ri = 0; ri < regions.size(); ++ri) { |
| 680 | const FaceRegion& region = regions[ri]; |
| 681 | const RegionProjection& rp = projections[ri]; |
| 682 | const PackRect& placement = layout.placements[ri]; |
| 683 | const Image& img = images[region.view_id]; |
| 684 | const Bitmap& src_bmp = img.GetBitmap(); |
| 685 | |
| 686 | for (size_t i = 0; i < region.face_ids.size(); ++i) { |
| 687 | const std::array<Eigen::Vector2f, 3> atlas_verts = |
| 688 | ComputeAtlasVerts(rp, placement, i); |
| 689 | |
| 690 | // Bounding box with 1-pixel border for seam coverage. |
| 691 | const int min_px = std::max( |
| 692 | 0, |
| 693 | static_cast<int>(std::floor(std::min( |
| 694 | {atlas_verts[0].x(), atlas_verts[1].x(), atlas_verts[2].x()}))) - |
| 695 | 1); |
| 696 | const int min_py = std::max( |
| 697 | 0, |
| 698 | static_cast<int>(std::floor(std::min( |
| 699 | {atlas_verts[0].y(), atlas_verts[1].y(), atlas_verts[2].y()}))) - |
| 700 | 1); |
| 701 | const int max_px = std::min( |
| 702 | aw - 1, |
| 703 | static_cast<int>(std::ceil(std::max( |
| 704 | {atlas_verts[0].x(), atlas_verts[1].x(), atlas_verts[2].x()}))) + |
| 705 | 1); |
| 706 | const int max_py = std::min( |
| 707 | ah - 1, |
| 708 | static_cast<int>(std::ceil(std::max( |
| 709 | {atlas_verts[0].y(), atlas_verts[1].y(), atlas_verts[2].y()}))) + |
| 710 | 1); |
| 711 | |
| 712 | const float texture_inv_scale_factor = |
| 713 | static_cast<float>(1.0 / options.texture_scale_factor); |
| 714 | |
| 715 | for (int py = min_py; py <= max_py; ++py) { |
| 716 | for (int px = min_px; px <= max_px; ++px) { |
| 717 | const Eigen::Vector2f pixel_center(px + 0.5f, py + 0.5f); |
| 718 | const Eigen::Vector3f bary = Barycentric( |
| 719 | pixel_center, atlas_verts[0], atlas_verts[1], atlas_verts[2]); |
| 720 | |
| 721 | const float min_bary = std::min({bary.x(), bary.y(), bary.z()}); |
| 722 | if (min_bary < -1e-4f) continue; |
| 723 |
no test coverage detected