diff --git a/CMakeLists.txt b/CMakeLists.txt index 57c7880..3cb0e2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,9 +21,17 @@ set(${PROJECT_NAME}_MAJOR_VERSION 0) set(${PROJECT_NAME}_MINOR_VERSION 1) set(${PROJECT_NAME}_PATCH_LEVEL 0) -set(CMAKE_CXX_EXTENSIONS OFF) +if (DEFINED ENV{CXXFLAGS_STD}) + set(cmake_cxx_std $ENV{CXXFLAGS_STD}) + string(REPLACE "c++" "" cmake_cxx_std "$ENV{CXXFLAGS_STD}") + set(CMAKE_CXX_STANDARD ${cmake_cxx_std}) +else() + set(CMAKE_CXX_STANDARD 17) +endif() +set(CMAKE_CXX_EXTENSIONS FALSE) SET(CMAKE_VERBOSE_MAKEFILE TRUE) set(CMAKE_SKIP_BUILD_RPATH TRUE) +set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) set(CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS TRUE) set(OpenGL_GL_PREFERENCE GLVND) diff --git a/Makefile b/Makefile index 7f555a5..39ddfe5 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,9 @@ CMAKE_BUILD_DIR ?= build/$(prefix_base) # Add more variables here to force a rebuild when they change TRACK_FLAGS = $(prefix):$(FLAVOR) -all: install +default: install + +all: cmake compile_commands # Record build flags so that we can force cmake to reconfigure $(CMAKE_BUILD_DIR)/FLAGS: FORCE @@ -29,7 +31,11 @@ $(CMAKE_BUILD_DIR)/Makefile: CMakeLists.txt src/CMakeLists.txt $(CMAKE_BUILD_DIR cmake: $(CMAKE_BUILD_DIR)/Makefile -install: cmake +compile_commands: cmake + rm -f build/compile_commands.json + ln -s $(prefix_base)/compile_commands.json build/compile_commands.json + +install: all $(MAKE) --no-print-directory -C $(CMAKE_BUILD_DIR) install $(MFLAGS) .PHONY: all install cmake diff --git a/src/ptxconvert.cpp b/src/ptxconvert.cpp index cedb642..05e9f26 100644 --- a/src/ptxconvert.cpp +++ b/src/ptxconvert.cpp @@ -36,6 +36,7 @@ struct Options { Ptex::DataType dt; std::string envfaces[6]; bool src_is_envcube, dst_is_envcube; + bool all_faces{false}; std::string src, dst; std::map meta; @@ -250,6 +251,7 @@ void usage() << " -vmode (clamp|black|periodic)\n" << " -envcube pxfile nxfile pyfile nyfile pzfile nzfile\n" << " -meta key value\n" + << " -allfaces - convert each face to a separate file\n" << "\n" << "Note:\n" << " -envcube can be used in place of srcfile or dstfile\n" @@ -475,6 +477,16 @@ bool writeEnvcube(const std::string& path, Img images[6]) } +std::string extension(const std::string& filename) +{ + size_t pos = filename.rfind('.'); + if (pos == std::string::npos) { + return ""; + } + return filename.substr(pos); +} + + bool parseArgs(int argc, char** argv) { // parse args @@ -529,6 +541,9 @@ bool parseArgs(int argc, char** argv) if (arg == "-umode" || arg == "-mode") opt.uMode = mode; if (arg == "-vmode" || arg == "-mode") opt.vMode = mode; } + else if (arg == "-allfaces") { + opt.all_faces = true; + } else { badoption(arg); return 0; @@ -599,10 +614,57 @@ bool convertFile(const std::string& src, const std::string& dst) return copyEnvcube(); } - Img img; - if (!readImage(src, img)) return 0; - if (!writeImage(dst, img)) return 0; - return 1; + if (opt.all_faces) { + const std::string ext = extension(dst); + if (ext.empty() || dst.length() <= ext.length()) { + error("output filename does not contain a file extension"); + return false; + } + const std::string basename = dst.substr(0, dst.length() - ext.length()); + Ptex::String error; + PtexTexture* ptx = PtexTexture::open(src.c_str(), error); + if (!ptx) { + std::cerr << error << std::endl; + return false; + } + int faces = ptx->numFaces(); + bool result{true}; + int max_digits = int(floorf(log10f(float(faces)))); + + for (int faceid = 0; faceid < faces; ++faceid) { + Img img; + bool ok = PtexToImg(ptx, img, /*faceid*/ faceid, /*flip*/ true); + if (!ok) { + std::cerr << "Error: unable to read face id " << faceid << std::endl; + result = false; + continue; + } + const std::string number = std::to_string(faceid); + int pad_count = max_digits - number.length(); + + // Format the filename to include the faceid. "example.png" becomes "example.0001.png". + std::string output{basename}; + output += '.'; + for (int i = 0; pad_count > 0 && i < pad_count; ++i) { + output += '0'; + } + output += number; + output += ext; + + if (!writeImage(output, img)) { + return false; + } + } + + ptx->release(); + + return result; + } else { + Img img; + if (!readImage(src, img)) return 0; + if (!writeImage(dst, img)) return 0; + return 1; + } }