VOXCONVERT: new commandline tool to convert between supported volume formats

master
Martin Gerhardy 2020-05-17 17:42:43 +02:00
parent 048b9d7d18
commit 9d11f77891
18 changed files with 192 additions and 16 deletions

View File

@ -58,6 +58,7 @@ jobs:
cmake --build .
cmake --install . --component voxedit --prefix voxedit
cmake --install . --component mapview --prefix mapview
cmake --install . --component voxconvert --prefix voxconvert
ctest -V -C Debug -R tests-animation
ctest -V -C Debug -R tests-computeshadertool
ctest -V -C Debug -R tests-math
@ -68,9 +69,14 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: voxedit
path: build/voxedit
path: build/voxedit/
- name: Upload the mapview artifacts
uses: actions/upload-artifact@v2
with:
name: mapview
path: build/mapview
path: build/mapview/
- name: Upload the voxconvert artifacts
uses: actions/upload-artifact@v2
with:
name: voxconvert
path: build/voxconvert/

View File

@ -53,6 +53,7 @@ option(SERVER "Builds with server" ON)
option(CLIENT "Builds with client" ON)
option(VOXEDIT "Builds voxedit" ON)
option(THUMBNAILER "Builds thumbnailer" ON)
option(VOXCONVERT "Builds voxconvert" ON)
option(MAPVIEW "Builds mapview" ON)
option(NOISETOOL "Builds noisetool" ON)
option(VOXEDIT_ONLY "Builds voxedit only" OFF)

View File

@ -29,6 +29,7 @@ Download latest windows binaries at [github action artifacts](https://github.com
* [Shader tool](src/tools/shadertool/README.md)
* [Compute Shader tool](src/tools/computeshadertool/README.md)
* [Visual test applications](src/tests/README.md)
* [Volume convert tool](src/tools/voxconvert/README.md)
## General

View File

@ -36,4 +36,4 @@ Get a list of all cvars with details printed
https://github.com/mgerhardy/engine
.SH COPYRIGHT
Copyright \[co] 2015\-2019 by Martin Gerhardy.
Copyright \[co] 2015\-2020 by Martin Gerhardy.

View File

@ -0,0 +1,31 @@
.\" This man page was written by Martin Gerhardy in May 2020. It is provided
.\" under the GNU General Public License 3 or (at your option) any later version.
.TH @COMMANDLINE@ 14 "May 2020" "@COMMANDLINE@" "games"
.SH NAME
@COMMANDLINE@ \- convert voxel volume formats
.SH SYNOPSIS
.PP
\fB@NAME@\fR [\fIoption\fR] infile outfile
.SH DESCRIPTION
\fB@COMMANDLINE@\fP is a command line application that can convert several voxel
volume formats into others. Supported formats are e.g. cub (CubeWorld), qb/qbt
(Qubicle), vox (MagicaVoxel), vmx (VoxEdit Sandbox), binvox and maybe others.
.SH OPTIONS
.TP
\fB\--trace|--debug\fR
Enable debug logging
.TP
\fB\--trace|--debug\fR
Enable debug logging
.TP
\fB\--help\fR
Print usage information
.SH HOMEPAGE
https://github.com/mgerhardy/engine
.SH COPYRIGHT
Copyright \[co] 2015\-2020 by Martin Gerhardy.

13
debian/control vendored
View File

@ -42,6 +42,19 @@ Description: Thumbnailer for voxel models
binvox
CubeWorld cub
Package: vengi-convert
Architecture: any
Multi-Arch: foreign
Recommends: vengi-voxedit vengi-thumbnailer
Depends: ${misc:Depends}, ${shlibs:Depends}, vengi-shared
Description: Converter for voxel models
Supported formats are:
Magicvoxel vox
Qubicle qbt and qb
Sandbox VoxEdit vxm
binvox
CubeWorld cub
Package: vengi-server
Architecture: any
Multi-Arch: foreign

2
debian/rules vendored
View File

@ -23,7 +23,7 @@ DEBTGZ = vengi_$(MAINVER).debian.tar.gz
get-orig-source: ../$(ORIGTGZ)
voxedit thumbnailer server client mapview:
voxedit thumbnailer voxconvert server client mapview:
dh_testdir
cmake -H. -Bdebian/build -DCMAKE_BUILD_TYPE=Release -DSANITIZE_FLAGS= -DPKGDATADIR=/usr/share/vengi-$@/
cmake --build debian/build --target $@ $(CMAKEFLAGS)

2
debian/vengi-voxconvert.dirs vendored Normal file
View File

@ -0,0 +1,2 @@
usr/bin
usr/share/vengi-voxconvert

1
debian/vengi-voxconvert.install vendored Normal file
View File

@ -0,0 +1 @@
debian/install/voxconvert/* usr

View File

@ -78,4 +78,10 @@ bool saveVolumeFormat(const io::FilePtr& filePtr, voxel::VoxelVolumes& volumes)
return false;
}
void clearVolumes(voxel::VoxelVolumes& volumes) {
for (auto& v : volumes) {
delete v.volume;
}
}
}

View File

@ -11,5 +11,6 @@ namespace voxelformat {
extern bool loadVolumeFormat(const io::FilePtr& filePtr, voxel::VoxelVolumes& newVolumes);
extern bool saveVolumeFormat(const io::FilePtr& filePtr, voxel::VoxelVolumes& volumes);
extern void clearVolumes(voxel::VoxelVolumes& volumes);
}

View File

@ -58,16 +58,12 @@ bool MeshCache::loadMesh(const char* fullPath, voxel::Mesh& mesh) {
voxel::VoxelVolumes volumes;
if (!voxelformat::loadVolumeFormat(file, volumes)) {
Log::error("Failed to load %s", file->name().c_str());
for (auto& v : volumes) {
delete v.volume;
}
voxelformat::clearVolumes(volumes);
return false;
}
if ((int)volumes.size() != 1) {
Log::error("More than one volume/layer found in %s", file->name().c_str());
for (auto& v : volumes) {
delete v.volume;
}
voxelformat::clearVolumes(volumes);
return false;
}

View File

@ -31,17 +31,14 @@ voxel::RawVolume* VolumeCache::loadVolume(const char* fullPath) {
voxel::VoxelVolumes volumes;
if (!voxelformat::loadVolumeFormat(file, volumes)) {
Log::error("Failed to load %s", file->name().c_str());
for (auto& v : volumes) {
delete v.volume;
}
voxelformat::clearVolumes(volumes);
core::ScopedLock lock(_mutex);
_volumes.put(filename, nullptr);
return nullptr;
}
voxel::RawVolume* v = volumes.merge();
for (auto& v : volumes) {
delete v.volume;
}
voxelformat::clearVolumes(volumes);
core::ScopedLock lock(_mutex);
_volumes.put(filename, v);
return v;

View File

@ -11,6 +11,9 @@ if (TOOLS)
if (THUMBNAILER)
add_subdirectory(thumbnailer)
endif()
if (VOXCONVERT)
add_subdirectory(voxconvert)
endif()
if (MAPVIEW)
add_subdirectory(mapview)
endif()

View File

@ -0,0 +1,7 @@
project(voxconvert)
set(SRCS
VoxConvert.h VoxConvert.cpp
)
engine_add_executable(TARGET ${PROJECT_NAME} SRCS ${SRCS})
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES voxelformat)

View File

@ -0,0 +1,5 @@
# Vox-Convert
## Purpose
Convert voxel volume formats between each other.

View File

@ -0,0 +1,85 @@
/**
* @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"
#include "voxelformat/Loader.h"
#include "voxelformat/VoxFileFormat.h"
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;
}
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;
}
if (!voxel::initDefaultMaterialColors()) {
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());
const io::FilePtr inputFile = filesystem()->open(infile, io::FileMode::Read);
if (!inputFile->exists()) {
Log::error("Given input file '%s' does not exist", infile.c_str());
return core::AppState::InitFailure;
}
voxel::VoxelVolumes volumes;
if (!voxelformat::loadVolumeFormat(inputFile, volumes)) {
Log::error("Failed to load given input file");
return core::AppState::InitFailure;
}
const io::FilePtr outputFile = filesystem()->open(outfile, io::FileMode::Write);
if (outputFile->length() > 0) {
voxelformat::clearVolumes(volumes);
Log::error("Given output file '%s' already exists", outfile.c_str());
return core::AppState::InitFailure;
}
if (!voxelformat::saveVolumeFormat(outputFile, volumes)) {
voxelformat::clearVolumes(volumes);
Log::error("Failed to write to output file '%s'", outfile.c_str());
return core::AppState::InitFailure;
}
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);
}

View File

@ -0,0 +1,21 @@
/**
* @file
*/
#pragma once
#include "core/CommandlineApp.h"
/**
* @brief This tool is able to convert voxel volumes between different formats
*
* @ingroup Tools
*/
class VoxConvert: public core::CommandlineApp {
private:
using Super = core::CommandlineApp;
public:
VoxConvert(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider);
core::AppState onInit() override;
};