2020-05-17 08:42:43 -07:00
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "VoxConvert.h"
|
|
|
|
#include "core/Color.h"
|
|
|
|
#include "core/Var.h"
|
|
|
|
#include "core/command/Command.h"
|
|
|
|
#include "core/io/Filesystem.h"
|
|
|
|
#include "core/metric/Metric.h"
|
|
|
|
#include "core/EventBus.h"
|
|
|
|
#include "core/TimeProvider.h"
|
|
|
|
#include "voxel/MaterialColor.h"
|
2020-08-04 09:02:29 -07:00
|
|
|
#include "voxelformat/VolumeFormat.h"
|
2020-05-17 08:42:43 -07:00
|
|
|
#include "voxelformat/VoxFileFormat.h"
|
2020-05-22 11:53:28 -07:00
|
|
|
#include "voxelutil/VolumeRescaler.h"
|
2020-05-17 08:42:43 -07:00
|
|
|
|
|
|
|
VoxConvert::VoxConvert(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider) :
|
|
|
|
Super(metric, filesystem, eventBus, timeProvider) {
|
|
|
|
init(ORGANISATION, "voxconvert");
|
|
|
|
_initialLogLevel = SDL_LOG_PRIORITY_ERROR;
|
|
|
|
}
|
|
|
|
|
2020-05-18 06:38:44 -07:00
|
|
|
core::AppState VoxConvert::onConstruct() {
|
|
|
|
const core::AppState state = Super::onConstruct();
|
|
|
|
registerArg("--merge").setShort("-m").setDescription("Merge layers into one volume");
|
2020-05-22 11:53:28 -07:00
|
|
|
registerArg("--scale").setShort("-s").setDescription("Scale layer to 50% of its original size");
|
2020-06-11 10:37:59 -07:00
|
|
|
registerArg("--force").setShort("-f").setDescription("Overwrite existing files");
|
2020-06-07 11:12:08 -07:00
|
|
|
|
|
|
|
_palette = core::Var::get("palette", voxel::getDefaultPaletteName());
|
|
|
|
_palette->setHelp("Specify the palette base name or absolute png file to use (1x256)");
|
|
|
|
|
2020-05-18 06:38:44 -07:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2020-05-17 08:42:43 -07:00
|
|
|
core::AppState VoxConvert::onInit() {
|
|
|
|
const core::AppState state = Super::onInit();
|
|
|
|
if (state != core::AppState::Running) {
|
|
|
|
Log::error("Failed to init application");
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_argc < 2) {
|
|
|
|
_logLevelVar->setVal(SDL_LOG_PRIORITY_INFO);
|
|
|
|
Log::init();
|
|
|
|
usage();
|
|
|
|
return core::AppState::InitFailure;
|
|
|
|
}
|
|
|
|
|
2020-06-07 11:12:08 -07:00
|
|
|
io::FilePtr paletteFile = filesystem()->open(core::string::format("palette-%s.png", _palette->strVal().c_str()));
|
|
|
|
if (!paletteFile->exists()) {
|
|
|
|
paletteFile = filesystem()->open(_palette->strVal());
|
|
|
|
}
|
|
|
|
if (!voxel::initMaterialColors(paletteFile, io::FilePtr())) {
|
2020-05-17 08:42:43 -07:00
|
|
|
Log::error("Failed to init default material colors");
|
|
|
|
return core::AppState::InitFailure;
|
|
|
|
}
|
|
|
|
|
|
|
|
const core::String infile = _argv[_argc - 2];
|
|
|
|
const core::String outfile = _argv[_argc - 1];
|
|
|
|
|
|
|
|
Log::debug("infile: %s", infile.c_str());
|
|
|
|
Log::debug("outfile: %s", outfile.c_str());
|
|
|
|
|
2020-06-28 11:11:04 -07:00
|
|
|
const io::FilePtr inputFile = filesystem()->open(infile, io::FileMode::SysRead);
|
2020-05-17 08:42:43 -07:00
|
|
|
if (!inputFile->exists()) {
|
|
|
|
Log::error("Given input file '%s' does not exist", infile.c_str());
|
2020-05-19 15:04:00 -07:00
|
|
|
_exitCode = 127;
|
2020-05-17 08:42:43 -07:00
|
|
|
return core::AppState::InitFailure;
|
|
|
|
}
|
|
|
|
|
2020-06-28 11:11:04 -07:00
|
|
|
const io::FilePtr outputFile = filesystem()->open(outfile, io::FileMode::SysWrite);
|
2020-06-11 10:37:59 -07:00
|
|
|
if (!outputFile->validHandle()) {
|
|
|
|
Log::error("Could not open target file: %s", outfile.c_str());
|
2020-05-17 08:42:43 -07:00
|
|
|
return core::AppState::InitFailure;
|
|
|
|
}
|
|
|
|
if (outputFile->length() > 0) {
|
2020-06-11 10:37:59 -07:00
|
|
|
if (!hasArg("--force") && !hasArg("-f")) {
|
|
|
|
Log::error("Given output file '%s' already exists", outfile.c_str());
|
|
|
|
return core::AppState::InitFailure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
voxel::VoxelVolumes volumes;
|
|
|
|
if (!voxelformat::loadVolumeFormat(inputFile, volumes)) {
|
|
|
|
Log::error("Failed to load given input file");
|
2020-05-17 08:42:43 -07:00
|
|
|
return core::AppState::InitFailure;
|
|
|
|
}
|
|
|
|
|
2020-05-22 11:53:28 -07:00
|
|
|
if (hasArg("--merge") || hasArg("-m")) {
|
2020-05-18 06:38:44 -07:00
|
|
|
voxel::RawVolume* merged = volumes.merge();
|
2020-05-19 15:15:31 -07:00
|
|
|
if (merged == nullptr) {
|
|
|
|
Log::error("Failed to merge volumes");
|
|
|
|
return core::AppState::InitFailure;
|
|
|
|
}
|
2020-05-18 06:38:44 -07:00
|
|
|
voxelformat::clearVolumes(volumes);
|
|
|
|
volumes.push_back(voxel::VoxelVolume(merged));
|
|
|
|
}
|
|
|
|
|
2020-05-22 11:53:28 -07:00
|
|
|
if (hasArg("--scale") || hasArg("-s")) {
|
|
|
|
for (auto& v : volumes) {
|
|
|
|
const voxel::Region srcRegion = v.volume->region();
|
|
|
|
const glm::ivec3& targetDimensionsHalf = (srcRegion.getDimensionsInVoxels() / 2) - 1;
|
|
|
|
const voxel::Region destRegion(srcRegion.getLowerCorner(), srcRegion.getLowerCorner() + targetDimensionsHalf);
|
2020-08-04 07:47:34 -07:00
|
|
|
if (destRegion.isValid()) {
|
|
|
|
voxel::RawVolume* destVolume = new voxel::RawVolume(destRegion);
|
|
|
|
rescaleVolume(*v.volume, *destVolume);
|
|
|
|
delete v.volume;
|
|
|
|
v.volume = destVolume;
|
|
|
|
}
|
2020-05-22 11:53:28 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-17 08:42:43 -07:00
|
|
|
if (!voxelformat::saveVolumeFormat(outputFile, volumes)) {
|
|
|
|
voxelformat::clearVolumes(volumes);
|
|
|
|
Log::error("Failed to write to output file '%s'", outfile.c_str());
|
|
|
|
return core::AppState::InitFailure;
|
|
|
|
}
|
2020-06-11 10:37:59 -07:00
|
|
|
Log::info("Wrote output file %s", outputFile->name().c_str());
|
2020-05-17 08:42:43 -07:00
|
|
|
|
|
|
|
voxelformat::clearVolumes(volumes);
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
const core::EventBusPtr& eventBus = std::make_shared<core::EventBus>();
|
|
|
|
const io::FilesystemPtr& filesystem = std::make_shared<io::Filesystem>();
|
|
|
|
const core::TimeProviderPtr& timeProvider = std::make_shared<core::TimeProvider>();
|
|
|
|
const metric::MetricPtr& metric = std::make_shared<metric::Metric>();
|
|
|
|
VoxConvert app(metric, filesystem, eventBus, timeProvider);
|
|
|
|
return app.startMainLoop(argc, argv);
|
|
|
|
}
|