| 1062 | #undef PrintOption |
| 1063 | |
| 1064 | MeshTextureMappingResult MeshTextureMapping( |
| 1065 | const PlyMesh& mesh, |
| 1066 | const std::vector<Image>& images, |
| 1067 | const MeshTextureMappingOptions& options) { |
| 1068 | THROW_CHECK(options.Check()); |
| 1069 | |
| 1070 | #if !defined(COLMAP_CGAL_ENABLED) |
| 1071 | LOG(WARNING) << "CGAL is disabled; occlusion testing will be skipped. " |
| 1072 | "Some faces may be textured from views where they are " |
| 1073 | "occluded by other geometry."; |
| 1074 | #endif |
| 1075 | |
| 1076 | MeshTextureMappingResult result; |
| 1077 | |
| 1078 | if (mesh.faces.empty() || mesh.vertices.empty()) { |
| 1079 | result.face_view_ids.assign(mesh.faces.size(), -1); |
| 1080 | result.face_uvs.assign(mesh.faces.size() * 6, 0.0f); |
| 1081 | return result; |
| 1082 | } |
| 1083 | |
| 1084 | LOG(INFO) << "Computing face normals..."; |
| 1085 | const std::vector<Eigen::Vector3f> face_normals = ComputeFaceNormals(mesh); |
| 1086 | |
| 1087 | LOG(INFO) << "Building face adjacency..."; |
| 1088 | const FaceAdjacencyMap adjacency = BuildFaceAdjacency(mesh); |
| 1089 | |
| 1090 | LOG(INFO) << "Selecting views for " << mesh.faces.size() << " faces from " |
| 1091 | << images.size() << " images..."; |
| 1092 | const std::vector<int> view_per_face = |
| 1093 | SelectViews(mesh, face_normals, images, adjacency, options); |
| 1094 | result.face_view_ids = view_per_face; |
| 1095 | |
| 1096 | const size_t num_assigned = std::count_if(view_per_face.begin(), |
| 1097 | view_per_face.end(), |
| 1098 | [](const int v) { return v >= 0; }); |
| 1099 | if (num_assigned == 0) { |
| 1100 | LOG(WARNING) << "No faces were assigned to any view"; |
| 1101 | result.face_uvs.assign(mesh.faces.size() * 6, 0.0f); |
| 1102 | return result; |
| 1103 | } |
| 1104 | LOG(INFO) << num_assigned << " / " << mesh.faces.size() |
| 1105 | << " faces assigned to views"; |
| 1106 | |
| 1107 | LOG(INFO) << "Extracting face regions..."; |
| 1108 | const std::vector<FaceRegion> regions = |
| 1109 | ExtractFaceRegions(view_per_face, adjacency, mesh.faces.size()); |
| 1110 | LOG(INFO) << "Found " << regions.size() << " regions"; |
| 1111 | |
| 1112 | LOG(INFO) << "Computing region projections..."; |
| 1113 | std::vector<RegionProjection> projections = |
| 1114 | ComputeRegionProjections(mesh, regions, images); |
| 1115 | |
| 1116 | if (options.texture_scale_factor != 1.0) { |
| 1117 | LOG(INFO) << "Scaling region projections by factor " |
| 1118 | << options.texture_scale_factor << "..."; |
| 1119 | ScaleRegionProjections(projections, options.texture_scale_factor); |
| 1120 | } |
| 1121 | |