VOXCONVERT: new commandline tool to convert between supported volume formats
parent
048b9d7d18
commit
9d11f77891
|
@ -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/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
usr/bin
|
||||
usr/share/vengi-voxconvert
|
|
@ -0,0 +1 @@
|
|||
debian/install/voxconvert/* usr
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -11,6 +11,9 @@ if (TOOLS)
|
|||
if (THUMBNAILER)
|
||||
add_subdirectory(thumbnailer)
|
||||
endif()
|
||||
if (VOXCONVERT)
|
||||
add_subdirectory(voxconvert)
|
||||
endif()
|
||||
if (MAPVIEW)
|
||||
add_subdirectory(mapview)
|
||||
endif()
|
||||
|
|
|
@ -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)
|
|
@ -0,0 +1,5 @@
|
|||
# Vox-Convert
|
||||
|
||||
## Purpose
|
||||
|
||||
Convert voxel volume formats between each other.
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
};
|
Loading…
Reference in New Issue