Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute texture patch #988

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion apps/Viewer/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ void Scene::TogleSceneBox()
}


void Scene::CastRay(const Ray3& ray, int action)
void Scene::CastRay(const Ray3& ray, int action, int mods)
{
if (!IsOctreeValid())
return;
Expand Down Expand Up @@ -747,6 +747,19 @@ void Scene::CastRay(const Ray3& ray, int action)
face[1], window.selectionPoints[1].x, window.selectionPoints[1].y, window.selectionPoints[1].z,
face[2], window.selectionPoints[2].x, window.selectionPoints[2].y, window.selectionPoints[2].z
);
if ((mods&(GLFW_MOD_CONTROL|GLFW_MOD_SHIFT)) && scene.mesh.HasTexture()) {
String dbgOut;
cv::Mat dbgImg;
scene.mesh.ListIncidenteFaces();
scene.mesh.ListIncidenteFaceFaces();
const bool bSaveToFile = (mods&GLFW_MOD_ALT);
dbgOut = scene.mesh.PlotTexturePatch((MVS::Mesh::FIndex)intRay.pick.idx, face_patch_ids, dbgImg, bSaveToFile);
if (!dbgOut.IsEmpty()) {
DEBUG_EXTRA("Saved texture patch as %s", dbgOut.c_str());
} else {
cv::imshow(dbgOut, dbgImg);
}
}
} else {
window.selectionType = Window::SEL_NA;
}
Expand Down
3 changes: 2 additions & 1 deletion apps/Viewer/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Scene
Window window;
ImageArr images; // scene photos
ImageArr textures; // mesh textures
MVS::Mesh::FaceIdxArr face_patch_ids;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why placing it here as you seem to be using it only in Scene::CastRay?


OctreePoints octPoints;
OctreeMesh octMesh;
Expand Down Expand Up @@ -97,7 +98,7 @@ class Scene

void Center();
void TogleSceneBox();
void CastRay(const Ray3&, int);
void CastRay(const Ray3&, int, int);
protected:
static void* ThreadWorker(void*);
};
Expand Down
4 changes: 2 additions & 2 deletions apps/Viewer/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ void Window::Key(GLFWwindow* window, int k, int scancode, int action, int mod)
g_mapWindows[window]->Key(k, scancode, action, mod);
}

void Window::MouseButton(int button, int action, int /*mods*/)
void Window::MouseButton(int button, int action, int mods)
{
switch (button) {
case GLFW_MOUSE_BUTTON_LEFT: {
Expand Down Expand Up @@ -394,7 +394,7 @@ void Window::MouseButton(int button, int action, int /*mods*/)
const Eigen::Vector3d start(invV.topRightCorner<3,1>());
const Eigen::Vector4d ray_wor(invV*ray_eye);
const Eigen::Vector3d dir(ray_wor.topRows<3>().normalized());
clbkRayScene(Ray3d(start, dir), action);
clbkRayScene(Ray3d(start, dir), action, mods);
}
} break;
case GLFW_MOUSE_BUTTON_MIDDLE: {
Expand Down
2 changes: 1 addition & 1 deletion apps/Viewer/Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class Window
ClbkExportScene clbkExportScene;
typedef DELEGATE<void (void)> ClbkCenterScene;
ClbkCenterScene clbkCenterScene;
typedef DELEGATE<void (const Ray3&, int)> ClbkRayScene;
typedef DELEGATE<void (const Ray3&, int, int)> ClbkRayScene;
ClbkRayScene clbkRayScene;
typedef DELEGATE<void (void)> ClbkCompilePointCloud;
ClbkCompilePointCloud clbkCompilePointCloud;
Expand Down
3 changes: 2 additions & 1 deletion libs/IO/OBJ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ bool ObjModel::Save(const String& fileName, unsigned precision, bool texLossless
bool ObjModel::Load(const String& fileName)
{
ASSERT(vertices.empty() && groups.empty() && material_lib.materials.empty());
const String path(Util::getFilePath(fileName));
std::ifstream fin(fileName.c_str());
String line, keyword;
std::istringstream in;
Expand Down Expand Up @@ -254,7 +255,7 @@ bool ObjModel::Load(const String& fileName)
} else
if (keyword == "mtllib") {
in >> keyword;
if (!material_lib.Load(keyword))
if (!material_lib.Load(MAKE_PATH_FULL(path, keyword)))
return false;
} else
if (keyword == "usemtl") {
Expand Down
88 changes: 88 additions & 0 deletions libs/MVS/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,54 @@ void Mesh::ComputeNormalVertices()
}
#endif

uint32_t Mesh::ComputeTexturePatchFaces(FaceIdxArr& face_patch_ids) const {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

short description of what the fucntion does and what returns

ASSERT(faceTexcoords.size() == faces.size() * 3);
face_patch_ids.Resize(faces.GetSize());
face_patch_ids.MemsetValue(NO_ID);
std::stack<FIndex> stack_faces;
uint32_t patch_id = 0;
FOREACH(idx_face, faces) {
if (face_patch_ids[idx_face] != NO_ID)
continue;
face_patch_ids[idx_face] = patch_id;
stack_faces.push(idx_face);
do {
FIndex iF = stack_faces.top();
stack_faces.pop();
const Mesh::FaceFaces& ffaces = faceFaces[iF];
for (int i = 0; i < 3; ++i) {
const FIndex iFAdj = ffaces[i];
if (iFAdj == NO_ID || face_patch_ids[iFAdj] != NO_ID)
continue;
VIndex iV0, iV1; //indexes of a common vertex
for (int v0 = 0; v0 < 3; ++v0) {
const Face& f = faces[iF];
const Face& fAdj = faces[iFAdj];
bool bCommon = false;
for (int v1 = 0; v1 < 3; ++v1) {
if (f[v0] == fAdj[v1]) {
iV0 = v0;
iV1 = v1;
bCommon = true;
break;
}
}
if (bCommon)
break;
}
const TexCoord tcV = faceTexcoords[iF * 3 + iV0];
const TexCoord tcAdj = faceTexcoords[iFAdj * 3 + iV1];
if (tcV.x == tcAdj.x && tcV.y == tcAdj.y) {
face_patch_ids[iFAdj] = patch_id;
stack_faces.push(iFAdj);
}
}
} while (!stack_faces.empty());
++patch_id;
}
return patch_id;
} // ComputeTexturePatchFaces

// Smoothen the normals for each face
// - fMaxGradient: maximum angle (in degrees) difference between neighbor normals that is
// allowed to take into consideration; higher angles are ignored
Expand Down Expand Up @@ -4086,6 +4134,46 @@ REAL Mesh::ComputeVolume() const
volume += ComputeTriangleVolume(vertices[face[0]], vertices[face[1]], vertices[face[2]]);
return volume;
}

String Mesh::PlotTexturePatch(const FIndex dbgFaceId, FaceIdxArr& face_patch_ids, cv::Mat& imgOut, const bool bSaveToFile) const {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you probably want const face_patch_ids

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

short description of what the fucntion does and what returns

// split texture in patches
if (face_patch_ids.size() != faces.size()) {
ComputeTexturePatchFaces(face_patch_ids);
}
// get the list of all faces from the same patch as debug face
cList<Mesh::FIndex> patchFaces;
const uint32_t dbgPatchId(face_patch_ids[dbgFaceId]);
FOREACH(idx_face, face_patch_ids) {
if (dbgPatchId == face_patch_ids[idx_face])
patchFaces.emplace_back(idx_face);
}
const Mesh::Face fDbg = faces[dbgFaceId];
cv::Mat imgDbg;
textureDiffuse.copyTo(imgDbg);
AABB2f boundingBox(true);
FOREACH(fIdx, patchFaces) {
const Mesh::FIndex& fId = patchFaces[fIdx];
const Mesh::TexCoord& texDbgCoordsV0 = faceTexcoords[fId * 3]; boundingBox.Insert(texDbgCoordsV0);
const Mesh::TexCoord& texDbgCoordsV1 = faceTexcoords[fId * 3 + 1]; boundingBox.Insert(texDbgCoordsV1);
const Mesh::TexCoord& texDbgCoordsV2 = faceTexcoords[fId * 3 + 2]; boundingBox.Insert(texDbgCoordsV2);
cv::line(imgDbg, texDbgCoordsV0, texDbgCoordsV1, cv::Scalar(50, 50, 250));
cv::line(imgDbg, texDbgCoordsV0, texDbgCoordsV2, cv::Scalar(50, 50, 250));
cv::line(imgDbg, texDbgCoordsV2, texDbgCoordsV1, cv::Scalar(50, 50, 250));
if (fId == dbgFaceId) {
cv::circle(imgDbg, texDbgCoordsV0, 3, cv::Scalar(100, 150, 250), 2);
cv::circle(imgDbg, texDbgCoordsV1, 3, cv::Scalar(100, 150, 250), 2);
cv::circle(imgDbg, texDbgCoordsV2, 3, cv::Scalar(100, 150, 250), 2);
}
}
cv::Rect sourceRect(FLOOR(boundingBox.ptMin.x()), FLOOR(boundingBox.ptMin.y()), CEIL(boundingBox.ptMax.x() - boundingBox.ptMin.x()), CEIL(boundingBox.ptMax.y() - boundingBox.ptMin.y())); // ROI of the patch
imgDbg(sourceRect).copyTo(imgOut);
if (bSaveToFile) {
String sImgName = String::FormatString("dbgPatch_%d_%d.jpg", dbgPatchId, dbgFaceId);
cv::imwrite(MAKE_PATH_SAFE(sImgName), imgOut);
return sImgName;
}
return String();
}
/*----------------------------------------------------------------*/


Expand Down
3 changes: 3 additions & 0 deletions libs/MVS/Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ class MVS_API Mesh
void ListBoundaryVertices();
void ComputeNormalFaces();
void ComputeNormalVertices();
uint32_t ComputeTexturePatchFaces(FaceIdxArr& face_patch_ids) const;

void SmoothNormalFaces(float fMaxGradient=25.f, float fOriginalWeight=0.5f, unsigned nIterations=3);

Expand Down Expand Up @@ -209,6 +210,8 @@ class MVS_API Mesh
REAL ComputeArea() const;
REAL ComputeVolume() const;

String PlotTexturePatch(const FIndex dbgFaceId, FaceIdxArr& face_patch_ids=FaceIdxArr(), cv::Mat& imgOut=cv::Mat(), const bool bSaveToFile=true) const;

void SamplePoints(unsigned numberOfPoints, PointCloud&) const;
void SamplePoints(REAL samplingDensity, PointCloud&) const;
void SamplePoints(REAL samplingDensity, unsigned mumPointsTheoretic, PointCloud&) const;
Expand Down