Refactored Task.js to move postprocessing code in a bash script for ease of maintenance, fix existing problem with failing tasks when assets are not in the right place

pull/14/head
Piero Toffanin 2017-05-17 20:16:45 -04:00
rodzic 2a9591347b
commit 1deff5ec6c
4 zmienionych plików z 84 dodań i 115 usunięć

Wyświetl plik

@ -286,57 +286,22 @@ module.exports = class Task{
};
};
const handleProcessExit = (done) => {
return (err, code, signal) => {
if (err) done(err);
else{
// Don't evaluate if we caused the process to exit via SIGINT?
if (code === 0) done();
else done(new Error(`Process exited with code ${code}`));
}
};
};
const handleOutput = output => {
this.output.push(output);
};
const generateTiles = (inputFile, outputDir) => {
const runPostProcessingScript = () => {
return (done) => {
const inputFilePath = path.join(this.getProjectFolderPath(), inputFile);
// Not all datasets generate an orthophoto, so we skip
// tiling if the orthophoto is missing
if (fs.existsSync(inputFilePath)){
this.runningProcesses.push(processRunner.runTiler({
zoomLevels: "12-21",
inputFile: inputFilePath,
outputDir: path.join(this.getProjectFolderPath(), outputDir)
}, handleProcessExit(done), handleOutput));
}else{
handleOutput(`${inputFilePath} file not found, skipping tiles generation\n`);
done();
}
};
};
const generatePotreeCloud = (inputFile, outputDir) => {
return (done) => {
this.runningProcesses.push(processRunner.runPotreeConverter({
inputFile: path.join(this.getProjectFolderPath(), inputFile),
outputDir: path.join(this.getProjectFolderPath(), outputDir)
}, handleProcessExit(done), handleOutput));
};
};
const pdalTranslate = (inputPath, outputPath, filters) => {
return (done) => {
this.runningProcesses.push(processRunner.runPdalTranslate({
inputFile: inputPath,
outputFile: outputPath,
filters: filters
}, handleProcessExit(done), handleOutput));
};
this.runningProcesses.push(
processRunner.runPostProcessingScript({
projectFolderPath: this.getProjectFolderPath()
}, (err, code, signal) => {
if (err) done(err);
else{
if (code === 0) done();
else done(new Error(`Process exited with code ${code}`));
}
}, output => {
this.output.push(output);
})
);
}
};
// All paths are relative to the project directory (./data/<uuid>/)
@ -351,35 +316,10 @@ module.exports = class Task{
});
}
let orthophotoPath = path.join('odm_orthophoto', 'odm_orthophoto.tif'),
lasPointCloudPath = path.join('odm_georeferencing', 'odm_georeferenced_model.las'),
plyPointCloudPath = path.join('odm_georeferencing', 'odm_georeferenced_model.ply'),
projectFolderPath = this.getProjectFolderPath();
let commands = [
generateTiles(orthophotoPath, 'orthophoto_tiles'),
generatePotreeCloud(plyPointCloudPath, 'potree_pointcloud'),
async.series([
runPostProcessingScript(),
createZipArchive('all.zip', allFolders)
];
// If point cloud file does not exist, it's likely because location (GPS/GPC) information
// was missing and the file was not generated.
let fullPlyPointCloudPath = path.join(projectFolderPath, plyPointCloudPath);
if (!fs.existsSync(fullPlyPointCloudPath)){
let unreferencedPointCloudPath = path.join(projectFolderPath, "opensfm", "depthmaps", "merged.ply");
if (fs.existsSync(unreferencedPointCloudPath)){
logger.info(`${plyPointCloudPath} is missing, will attempt to generate it from ${unreferencedPointCloudPath}`);
commands.unshift(pdalTranslate(unreferencedPointCloudPath, fullPlyPointCloudPath, [
{
// opensfm's ply files map colors with the diffuse_ prefix
dimensions: "diffuse_red = red, diffuse_green = green, diffuse_blue = blue",
type: "filters.ferry"
}
]));
}
}
async.series(commands, (err) => {
], (err) => {
if (!err){
this.setStatus(statusCodes.COMPLETED);
finished();

Wyświetl plik

@ -69,42 +69,10 @@ function makeRunner(command, args, requiredOptions = [], outputTestFile = null){
};
}
module.exports = {
runTiler: makeRunner("gdal2tiles.py",
function(options){
return ["-z", options.zoomLevels,
"-n",
"-w", "none",
options.inputFile,
options.outputDir
];
},
["zoomLevels", "inputFile", "outputDir"],
path.join("..", "tests", "gdal2tiles_output.txt")),
runPotreeConverter: makeRunner("PotreeConverter",
function(options){
return [options.inputFile,
"-o", options.outputDir];
},
["inputFile", "outputDir"],
path.join("..", "tests", "potree_output.txt")),
runPdalTranslate: makeRunner("/code/SuperBuild/build/pdal/bin/pdal",
function(options){
let opts = ["translate",
"-i", options.inputFile,
"-o", options.outputFile];
if (options.filters){
opts = opts.concat([
"--json",
JSON.stringify(options.filters)
]);
}
return opts;
},
["inputFile", "outputFile"])
runPostProcessingScript: makeRunner(os.path.join(__dirname, "..", "scripts", "postprocess.sh"),
function(options){
return [options.projectFolderPath];
},
["projectFolderPath"])
};

Wyświetl plik

@ -0,0 +1,57 @@
#!/bin/bash
# This file executes the post-processing steps for a task after a dataset
# has been processed by OpenDroneMap. It generates derivative computations.
#
# As a general rule, post-processing commands should never fail the task
#(for example, if a point cloud could not be generated, the PotreeConverter
# step will fail, but the script should still continue processing the rest and
# return a 0 code). The idea is to post-process as much as possible, knowing
# that some parts might fail and that partial results should be returned in such cases.
if [ -z "$1" ]; then
echo "Usage: $0 <projectPath>"
exit 0
fi
# Switch to project path folder (data/<uuid>/)
cd "$(dirname "$0")/../$1"
echo "Postprocessing: $(pwd)"
# Generate Tiles
if hash gdal2tiles.py 2>/dev/null; then
orthophoto_path="odm_orthophoto/odm_orthophoto.tif"
if [ -e "$orthophoto_path" ]; then
gdal2tiles.py -z 12-21 -n -w none $orthophoto_path orthophoto_tiles
else
echo "No orthophoto found at $orthophoto_path: will skip tiling"
fi
else
echo "gdal2tiles.py is not installed, will skip tiling"
fi
# Generate Potree point cloud (if PotreeConverter is available)
if hash PotreeConverter 2>/dev/null; then
potree_input_path=""
for path in "odm_georeferencing/odm_georeferenced_model.ply" \
"opensfm/depthmaps/merged.ply" \
"pmvs/recon0/models/option-0000.ply"; do
if [ -e $path ]; then
echo "Found suitable point cloud for PotreeConverter: $path"
potree_input_path=$path
break
fi
done
if [ ! -z "$potree_input_path" ]; then
PotreeConverter $potree_input_path -o potree_pointcloud
else
echo "Potree point cloud will not be generated (no suitable input files found)"
fi
else
echo "PotreeConverter is not installed, will skip generation of Potree point cloud"
fi
echo "Postprocessing: done (•̀ᴗ•́)و!"
exit 0

4
scripts/test.sh 100644
Wyświetl plik

@ -0,0 +1,4 @@
h=""
if [ ! -z "$h" ]; then
echo "OK"
fi