Skip to content

Commit

Permalink
texture: add multi texture support (#1074)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdcseacave committed Oct 23, 2023
1 parent f711e4a commit 95decea
Show file tree
Hide file tree
Showing 10 changed files with 545 additions and 411 deletions.
6 changes: 4 additions & 2 deletions apps/TextureMesh/TextureMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ unsigned nOrthoMapResolution;
unsigned nArchiveType;
int nProcessPriority;
unsigned nMaxThreads;
int nMaxTextureSize;
String strExportType;
String strConfigFileName;
boost::program_options::variables_map vm;
Expand Down Expand Up @@ -125,6 +126,7 @@ bool Initialize(size_t argc, LPCTSTR* argv)
("sharpness-weight", boost::program_options::value(&OPT::fSharpnessWeight)->default_value(0.5f), "amount of sharpness to be applied on the texture (0 - disabled)")
("orthographic-image-resolution", boost::program_options::value(&OPT::nOrthoMapResolution)->default_value(0), "orthographic image resolution to be generated from the textured mesh - the mesh is expected to be already geo-referenced or at least properly oriented (0 - disabled)")
("ignore-mask-label", boost::program_options::value(&OPT::nIgnoreMaskLabel)->default_value(-1), "label value to ignore in the image mask, stored in the MVS scene or next to each image with '.mask.png' extension (-1 - auto estimate mask for lens distortion, -2 - disabled)")
("max-texture-size", boost::program_options::value(&OPT::nMaxTextureSize)->default_value(8192), "maximum texture size, split it in multiple textures of this size if needed (0 - unbounded)")
;

// hidden options, allowed both on command line and
Expand Down Expand Up @@ -286,7 +288,7 @@ int main(int argc, LPCTSTR* argv)
return EXIT_FAILURE;
}
const String baseFileName(MAKE_PATH_SAFE(Util::getFileFullName(OPT::strOutputFileName)));
if (OPT::nOrthoMapResolution && !scene.mesh.textureDiffuse.empty()) {
if (OPT::nOrthoMapResolution && !scene.mesh.HasTexture()) {
// the input mesh is already textured and an orthographic projection was requested
goto ProjectOrtho;
}
Expand All @@ -311,7 +313,7 @@ int main(int argc, LPCTSTR* argv)
TD_TIMER_START();
if (!scene.TextureMesh(OPT::nResolutionLevel, OPT::nMinResolution, OPT::minCommonCameras, OPT::fOutlierThreshold, OPT::fRatioDataSmoothness,
OPT::bGlobalSeamLeveling, OPT::bLocalSeamLeveling, OPT::nTextureSizeMultiple, OPT::nRectPackingHeuristic, Pixel8U(OPT::nColEmpty),
OPT::fSharpnessWeight, OPT::nIgnoreMaskLabel, views))
OPT::fSharpnessWeight, OPT::nIgnoreMaskLabel, OPT::nMaxTextureSize, views))
return EXIT_FAILURE;
VERBOSE("Mesh texturing completed: %u vertices, %u faces (%s)", scene.mesh.vertices.GetSize(), scene.mesh.faces.GetSize(), TD_TIMER_GET_FMT().c_str());

Expand Down
104 changes: 58 additions & 46 deletions apps/Viewer/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ SEACAVE::Thread Scene::thread;
Scene::Scene(ARCHIVE_TYPE _nArchiveType)
:
nArchiveType(_nArchiveType),
listPointCloud(0),
listMesh(0)
listPointCloud(0)
{
}
Scene::~Scene()
Expand Down Expand Up @@ -171,9 +170,10 @@ void Scene::ReleasePointCloud()
}
void Scene::ReleaseMesh()
{
if (listMesh) {
glDeleteLists(listMesh, 1);
listMesh = 0;
if (!listMeshes.empty()) {
for (GLuint listMesh: listMeshes)
glDeleteLists(listMesh, 1);
listMeshes.Release();
}
}

Expand Down Expand Up @@ -294,18 +294,21 @@ bool Scene::Open(LPCTSTR fileName, LPCTSTR geometryFileName)

// init and load texture
if (scene.mesh.HasTexture()) {
Image& image = textures.AddEmpty();
ASSERT(image.idx == NO_ID);
#if 0
cv::flip(scene.mesh.textureDiffuse, scene.mesh.textureDiffuse, 0);
image.SetImage(scene.mesh.textureDiffuse);
scene.mesh.textureDiffuse.release();
#else // preserve texture, used only to be able to export the mesh
Image8U3 textureDiffuse;
cv::flip(scene.mesh.textureDiffuse, textureDiffuse, 0);
image.SetImage(textureDiffuse);
#endif
image.GenerateMipmap();
FOREACH(i, scene.mesh.texturesDiffuse) {
Image& image = textures.emplace_back();
ASSERT(image.idx == NO_ID);
#if 0
Image8U3& textureDiffuse = scene.mesh.texturesDiffuse[i];
cv::flip(textureDiffuse, textureDiffuse, 0);
image.SetImage(textureDiffuse);
textureDiffuse.release();
#else // preserve texture, used only to be able to export the mesh
Image8U3 textureDiffuse;
cv::flip(scene.mesh.texturesDiffuse[i], textureDiffuse, 0);
image.SetImage(textureDiffuse);
#endif
image.GenerateMipmap();
}
}

// init display lists
Expand Down Expand Up @@ -423,15 +426,15 @@ void Scene::CompilePointCloud()
glNewList(listPointCloud, GL_COMPILE);
ASSERT((window.sparseType&(Window::SPR_POINTS|Window::SPR_LINES)) != 0);
// compile point-cloud
if (!scene.pointcloud.IsEmpty() && (window.sparseType&Window::SPR_POINTS) != 0) {
if ((window.sparseType&Window::SPR_POINTS) != 0) {
ASSERT_ARE_SAME_TYPE(float, MVS::PointCloud::Point::Type);
glBegin(GL_POINTS);
glColor3f(1.f,1.f,1.f);
FOREACH(i, scene.pointcloud.points) {
if (!scene.pointcloud.pointViews.IsEmpty() &&
if (!scene.pointcloud.pointViews.empty() &&
scene.pointcloud.pointViews[i].size() < window.minViews)
continue;
if (!scene.pointcloud.colors.IsEmpty()) {
if (!scene.pointcloud.colors.empty()) {
const MVS::PointCloud::Color& c = scene.pointcloud.colors[i];
glColor3ub(c.r,c.g,c.b);
}
Expand All @@ -452,31 +455,37 @@ void Scene::CompileMesh()
scene.mesh.ComputeNormalFaces();
// translate, normalize and flip Y axis of the texture coordinates
MVS::Mesh::TexCoordArr normFaceTexcoords;
if (scene.mesh.HasTexture())
if (scene.mesh.HasTexture() && window.bRenderTexture)
scene.mesh.FaceTexcoordsNormalize(normFaceTexcoords, true);
listMesh = glGenLists(1);
glNewList(listMesh, GL_COMPILE);
// compile mesh
ASSERT_ARE_SAME_TYPE(float, MVS::Mesh::Vertex::Type);
ASSERT_ARE_SAME_TYPE(float, MVS::Mesh::Normal::Type);
ASSERT_ARE_SAME_TYPE(float, MVS::Mesh::TexCoord::Type);
glColor3f(1.f, 1.f, 1.f);
glBegin(GL_TRIANGLES);
FOREACH(i, scene.mesh.faces) {
const MVS::Mesh::Face& face = scene.mesh.faces[i];
const MVS::Mesh::Normal& n = scene.mesh.faceNormals[i];
glNormal3fv(n.ptr());
for (int j = 0; j < 3; ++j) {
if (!normFaceTexcoords.empty() && window.bRenderTexture) {
const MVS::Mesh::TexCoord& t = normFaceTexcoords[i * 3 + j];
glTexCoord2fv(t.ptr());
MVS::Mesh::TexIndex texIdx(0);
do {
GLuint& listMesh = listMeshes.emplace_back(glGenLists(1));
listMesh = glGenLists(1);
glNewList(listMesh, GL_COMPILE);
// compile mesh
ASSERT_ARE_SAME_TYPE(float, MVS::Mesh::Vertex::Type);
ASSERT_ARE_SAME_TYPE(float, MVS::Mesh::Normal::Type);
ASSERT_ARE_SAME_TYPE(float, MVS::Mesh::TexCoord::Type);
glColor3f(1.f, 1.f, 1.f);
glBegin(GL_TRIANGLES);
FOREACH(idxFace, scene.mesh.faces) {
if (!scene.mesh.faceTexindices.empty() && scene.mesh.faceTexindices[idxFace] != texIdx)
continue;
const MVS::Mesh::Face& face = scene.mesh.faces[idxFace];
const MVS::Mesh::Normal& n = scene.mesh.faceNormals[idxFace];
glNormal3fv(n.ptr());
for (int j = 0; j < 3; ++j) {
if (!normFaceTexcoords.empty()) {
const MVS::Mesh::TexCoord& t = normFaceTexcoords[idxFace*3 + j];
glTexCoord2fv(t.ptr());
}
const MVS::Mesh::Vertex& p = scene.mesh.vertices[face[j]];
glVertex3fv(p.ptr());
}
const MVS::Mesh::Vertex& p = scene.mesh.vertices[face[j]];
glVertex3fv(p.ptr());
}
}
glEnd();
glEndList();
glEnd();
glEndList();
} while (++texIdx < scene.mesh.texturesDiffuse.size());
}

void Scene::CompileBounds()
Expand Down Expand Up @@ -513,17 +522,20 @@ void Scene::Draw()
glCallList(listPointCloud);
}
// render mesh
if (listMesh) {
if (!listMeshes.empty()) {
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
if (!scene.mesh.faceTexcoords.empty() && window.bRenderTexture) {
glEnable(GL_TEXTURE_2D);
textures.front().Bind();
glCallList(listMesh);
FOREACH(i, listMeshes) {
textures[i].Bind();
glCallList(listMeshes[i]);
}
glDisable(GL_TEXTURE_2D);
} else {
glEnable(GL_LIGHTING);
glCallList(listMesh);
for (GLuint listMesh: listMeshes)
glCallList(listMesh);
glDisable(GL_LIGHTING);
}
}
Expand Down
2 changes: 1 addition & 1 deletion apps/Viewer/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class Scene
Point3fArr obbPoints;

GLuint listPointCloud;
GLuint listMesh;
CLISTDEF0IDX(GLuint,MVS::Mesh::TexIndex) listMeshes;

// multi-threading
static SEACAVE::EventQueue events; // internal events queue (processed by the working threads)
Expand Down
6 changes: 4 additions & 2 deletions libs/Common/Types.inl
Original file line number Diff line number Diff line change
Expand Up @@ -2617,9 +2617,11 @@ void TImage<TYPE>::RasterizeTriangleBary(const TPoint2<T>& v1, const TPoint2<T>&
ImageRef boxMinI(FLOOR2INT(boxMin));
ImageRef boxMaxI(CEIL2INT(boxMax));
Base::clip(boxMinI, boxMaxI, size);
// parse all pixels inside the bounding-box
// ignore back oriented triangles (negative area)
const T area(EdgeFunction(v1, v2, v3));
ASSERTM(area < 0, "UV triangle of negative area");
if (area <= 0)
return;
// parse all pixels inside the bounding-box
const T invArea(T(1) / area);
for (int y = boxMinI.y; y <= boxMaxI.y; ++y) {
for (int x = boxMinI.x; x <= boxMaxI.x; ++x) {
Expand Down

0 comments on commit 95decea

Please sign in to comment.