From 26ad42cdc2be6ec2f63902194f8e02262198cb34 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Sat, 5 Nov 2016 14:46:32 -0400 Subject: [PATCH] Added more assets download options, added test processing files, small API change --- README.md | 6 +- docs/index.adoc | 4 +- docs/swagger.json | 2 +- index.js | 16 ++- libs/Task.js | 124 ++++++++++++++---- libs/odmOptions.js | 2 +- package.json | 3 +- public/index.html | 8 +- public/js/main.js | 5 +- .../odm_georeferenced_model.csv | 0 .../odm_georeferenced_model.ply | 0 .../odm_georeferenced_model.ply.las | 0 .../odm_orthophoto/odm_orthophoto.png | 0 .../odm_orthophoto/odm_orthophoto.tif | 0 .../non_visible_faces_texture.jpg | 0 .../odm_texturing/odm_textured_model.obj | 0 .../odm_texturing/odm_textured_model_geo.mtl | 0 .../odm_texturing/odm_textured_model_geo.obj | 0 .../odm_texturing/texture_0.jpg | 0 .../odm_texturing/texture_1.jpg | 0 20 files changed, 134 insertions(+), 36 deletions(-) create mode 100644 tests/processing_results/odm_georeferencing/odm_georeferenced_model.csv create mode 100644 tests/processing_results/odm_georeferencing/odm_georeferenced_model.ply create mode 100644 tests/processing_results/odm_georeferencing/odm_georeferenced_model.ply.las create mode 100644 tests/processing_results/odm_orthophoto/odm_orthophoto.png create mode 100644 tests/processing_results/odm_orthophoto/odm_orthophoto.tif create mode 100644 tests/processing_results/odm_texturing/non_visible_faces_texture.jpg create mode 100644 tests/processing_results/odm_texturing/odm_textured_model.obj create mode 100644 tests/processing_results/odm_texturing/odm_textured_model_geo.mtl create mode 100644 tests/processing_results/odm_texturing/odm_textured_model_geo.obj create mode 100644 tests/processing_results/odm_texturing/texture_0.jpg create mode 100644 tests/processing_results/odm_texturing/texture_1.jpg diff --git a/README.md b/README.md index a93f8e4..421069a 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,10 @@ While in test mode all calls to OpenDroneMap's code will be simulated (see the / You can find some test drone images [here](https://github.com/dakotabenjamin/odm_data). +## What if I need more functionality? + +node-OpenDroneMap is meant to be a lightweight API. If you are looking for a more comprehensive solution to drone mapping, check out [WebODM](https://github.com/OpenDroneMap/WebODM), which uses node-OpenDroneMap for processing. + ## Contributing Make a pull request small contributions. For big contributions, please open a discussion first. Please use ES6 syntax while writing new Javascript code so that we can keep the code base uniform. @@ -119,7 +123,7 @@ Make a pull request small contributions. For big contributions, please open a di - [X] Command line options for OpenDroneMap - [X] GPC List support -- [ ] Autoremove Abandoned Tasks +- [ ] Video support when the [SLAM module](https://github.com/OpenDroneMap/OpenDroneMap/pull/317) becomes available - [ ] Continuous Integration Setup - [X] Documentation - [ ] Unit Testing diff --git a/docs/index.adoc b/docs/index.adoc index fe1dd64..4e0ae70 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -8,7 +8,7 @@ REST API to access OpenDroneMap === Version information [%hardbreaks] -_Version_ : 1.0.0 +_Version_ : 1.0.1 === Contact information @@ -257,7 +257,7 @@ Retrieves an asset (the output of OpenDroneMap's processing) associated with a t |=== |Type|Name|Description|Schema|Default |*Path*|*asset* + -_required_|Type of asset to download. Use "all" for zip file containing all assets. Other options are not yet available|enum (all)| +_required_|Type of asset to download. Use "all.zip" for zip file containing all assets. Other options are not yet available|enum (all.zip, georeferenced_model.ply.zip, georeferenced_model.las.zip, georeferenced_model.csv.zip, orthophoto.png, orthophoto.tif, textured_model.zip)| |*Path*|*uuid* + _required_|UUID of the task|string| |=== diff --git a/docs/swagger.json b/docs/swagger.json index 5650e24..93a361c 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1 +1 @@ -{"info":{"title":"node-opendronemap","version":"1.0.0","description":"REST API to access OpenDroneMap","license":{"name":"GPL-3.0"},"contact":{"name":"Piero Toffanin"}},"consumes":["application/json"],"produces":["application/json","application/zip"],"basePath":"/","schemes":["http"],"swagger":"2.0","paths":{"/task/new":{"post":{"description":"Creates a new task and places it at the end of the processing queue","tags":["task"],"consumes":["multipart/form-data"],"parameters":[{"name":"images","in":"formData","description":"Images to process, plus an optional GPC file. If included, the GPC file should have .txt extension","required":true,"type":"file"},{"name":"name","in":"formData","description":"An optional name to be associated with the task","required":false,"type":"string"},{"name":"options","in":"formData","description":"Serialized JSON string of the options to use for processing, as an array of the format: [{name: option1, value: value1}, {name: option2, value: value2}, ...]. For example, [{\"name\":\"cmvs-maxImages\",\"value\":\"500\"},{\"name\":\"time\",\"value\":true}]. For a list of all options, call /options","required":false,"type":"string"}],"responses":{"200":{"description":"Success","schema":{"type":"object","required":["uuid"],"properties":{"uuid":{"type":"string","description":"UUID of the newly created task"}}}},"default":{"description":"Error","schema":{"$ref":"#/definitions/Error"}}}}},"/task/{uuid}/info":{"get":{"description":"Gets information about this task, such as name, creation date, processing time, status, command line options and number of images being processed. See schema definition for a full list.","tags":["task"],"parameters":[{"name":"uuid","in":"path","description":"UUID of the task","required":true,"type":"string"}],"responses":{"200":{"description":"Task Information","schema":{"title":"TaskInfo","type":"object","required":["uuid","name","dateCreated","processingTime","status","options","imagesCount"],"properties":{"uuid":{"type":"string","description":"UUID"},"name":{"type":"string","description":"Name"},"dateCreated":{"type":"integer","description":"Timestamp"},"processingTime":{"type":"integer","description":"Milliseconds that have elapsed since the task started being processed."},"status":{"type":"integer","description":"Status code (10 = QUEUED, 20 = RUNNING, 30 = FAILED, 40 = COMPLETED, 50 = CANCELED)","enum":[10,20,30,40,50]},"options":{"type":"array","description":"List of options used to process this task","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string","description":"Option name (example: \"odm_meshing-octreeDepth\")"},"value":{"type":"string","description":"Value (example: 9)"}}}},"imagesCount":{"type":"integer","description":"Number of images"}}}},"default":{"description":"Error","schema":{"$ref":"#/definitions/Error"}}}}},"/task/{uuid}/output":{"get":{"description":"Retrieves the console output of the OpenDroneMap's process. Useful for monitoring execution and to provide updates to the user.","tags":["task"],"parameters":[{"name":"uuid","in":"path","description":"UUID of the task","required":true,"type":"string"},{"name":"line","in":"query","description":"Optional line number that the console output should be truncated from. For example, passing a value of 100 will retrieve the console output starting from line 100. Defaults to 0 (retrieve all console output).","default":0,"required":false,"type":"integer"}],"responses":{"200":{"description":"Console Output","schema":{"type":"string"}},"default":{"description":"Error","schema":{"$ref":"#/definitions/Error"}}}}},"/task/{uuid}/download/{asset}":{"get":{"description":"Retrieves an asset (the output of OpenDroneMap's processing) associated with a task","tags":["task"],"produces":["application/zip"],"parameters":[{"name":"uuid","in":"path","type":"string","description":"UUID of the task","required":true},{"name":"asset","in":"path","type":"string","description":"Type of asset to download. Use \"all\" for zip file containing all assets. Other options are not yet available","required":true,"enum":["all"]}],"responses":{"200":{"description":"Asset File","schema":{"type":"file"}},"default":{"description":"Error message","schema":{"$ref":"#/definitions/Error"}}}}},"/task/cancel":{"post":{"description":"Cancels a task (stops its execution, or prevents it from being executed)","parameters":[{"name":"uuid","in":"body","description":"UUID of the task","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Command Received","schema":{"$ref":"#/definitions/Response"}}}}},"/task/remove":{"post":{"description":"Removes a task and deletes all of its assets","parameters":[{"name":"uuid","in":"body","description":"UUID of the task","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Command Received","schema":{"$ref":"#/definitions/Response"}}}}},"/task/restart":{"post":{"description":"Restarts a task that was previously canceled or that had failed to process","parameters":[{"name":"uuid","in":"body","description":"UUID of the task","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Command Received","schema":{"$ref":"#/definitions/Response"}}}}},"/options":{"get":{"description":"Retrieves the command line options that can be passed to process a task","tags":["server"],"responses":{"200":{"description":"Options","schema":{"type":"array","items":{"title":"Option","type":"object","required":["name","type","value","domain","help"],"properties":{"name":{"type":"string","description":"Command line option (exactly as it is passed to the OpenDroneMap process, minus the leading '--')"},"type":{"type":"string","description":"Datatype of the value of this option","enum":["int","float","string","bool"]},"value":{"type":"string","description":"Default value of this option"},"domain":{"type":"string","description":"Valid range of values (for example, \"positive integer\" or \"float > 0.0\")"},"help":{"type":"string","description":"Description of what this option does"}}}}}}}},"/info":{"get":{"description":"Retrieves information about this node","tags":["server"],"responses":{"200":{"description":"Info","schema":{"type":"object","required":["version","taskQueueCount"],"properties":{"version":{"type":"string","description":"Current version"},"taskQueueCount":{"type":"integer","description":"Number of tasks currently being processed or waiting to be processed"}}}}}}}},"definitions":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Description of the error"}}},"Response":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","description":"true if the command succeeded, false otherwise"},"error":{"type":"string","description":"Error message if an error occured"}}}},"responses":{},"parameters":{},"securityDefinitions":{},"tags":[]} \ No newline at end of file +{"info":{"title":"node-opendronemap","version":"1.0.1","description":"REST API to access OpenDroneMap","license":{"name":"GPL-3.0"},"contact":{"name":"Piero Toffanin"}},"consumes":["application/json"],"produces":["application/json","application/zip"],"basePath":"/","schemes":["http"],"swagger":"2.0","paths":{"/task/new":{"post":{"description":"Creates a new task and places it at the end of the processing queue","tags":["task"],"consumes":["multipart/form-data"],"parameters":[{"name":"images","in":"formData","description":"Images to process, plus an optional GPC file. If included, the GPC file should have .txt extension","required":true,"type":"file"},{"name":"name","in":"formData","description":"An optional name to be associated with the task","required":false,"type":"string"},{"name":"options","in":"formData","description":"Serialized JSON string of the options to use for processing, as an array of the format: [{name: option1, value: value1}, {name: option2, value: value2}, ...]. For example, [{\"name\":\"cmvs-maxImages\",\"value\":\"500\"},{\"name\":\"time\",\"value\":true}]. For a list of all options, call /options","required":false,"type":"string"}],"responses":{"200":{"description":"Success","schema":{"type":"object","required":["uuid"],"properties":{"uuid":{"type":"string","description":"UUID of the newly created task"}}}},"default":{"description":"Error","schema":{"$ref":"#/definitions/Error"}}}}},"/task/{uuid}/info":{"get":{"description":"Gets information about this task, such as name, creation date, processing time, status, command line options and number of images being processed. See schema definition for a full list.","tags":["task"],"parameters":[{"name":"uuid","in":"path","description":"UUID of the task","required":true,"type":"string"}],"responses":{"200":{"description":"Task Information","schema":{"title":"TaskInfo","type":"object","required":["uuid","name","dateCreated","processingTime","status","options","imagesCount"],"properties":{"uuid":{"type":"string","description":"UUID"},"name":{"type":"string","description":"Name"},"dateCreated":{"type":"integer","description":"Timestamp"},"processingTime":{"type":"integer","description":"Milliseconds that have elapsed since the task started being processed."},"status":{"type":"integer","description":"Status code (10 = QUEUED, 20 = RUNNING, 30 = FAILED, 40 = COMPLETED, 50 = CANCELED)","enum":[10,20,30,40,50]},"options":{"type":"array","description":"List of options used to process this task","items":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string","description":"Option name (example: \"odm_meshing-octreeDepth\")"},"value":{"type":"string","description":"Value (example: 9)"}}}},"imagesCount":{"type":"integer","description":"Number of images"}}}},"default":{"description":"Error","schema":{"$ref":"#/definitions/Error"}}}}},"/task/{uuid}/output":{"get":{"description":"Retrieves the console output of the OpenDroneMap's process. Useful for monitoring execution and to provide updates to the user.","tags":["task"],"parameters":[{"name":"uuid","in":"path","description":"UUID of the task","required":true,"type":"string"},{"name":"line","in":"query","description":"Optional line number that the console output should be truncated from. For example, passing a value of 100 will retrieve the console output starting from line 100. Defaults to 0 (retrieve all console output).","default":0,"required":false,"type":"integer"}],"responses":{"200":{"description":"Console Output","schema":{"type":"string"}},"default":{"description":"Error","schema":{"$ref":"#/definitions/Error"}}}}},"/task/{uuid}/download/{asset}":{"get":{"description":"Retrieves an asset (the output of OpenDroneMap's processing) associated with a task","tags":["task"],"produces":["application/zip"],"parameters":[{"name":"uuid","in":"path","type":"string","description":"UUID of the task","required":true},{"name":"asset","in":"path","type":"string","description":"Type of asset to download. Use \"all.zip\" for zip file containing all assets. Other options are not yet available","required":true,"enum":["all.zip","georeferenced_model.ply.zip","georeferenced_model.las.zip","georeferenced_model.csv.zip","orthophoto.png","orthophoto.tif","textured_model.zip"]}],"responses":{"200":{"description":"Asset File","schema":{"type":"file"}},"default":{"description":"Error message","schema":{"$ref":"#/definitions/Error"}}}}},"/task/cancel":{"post":{"description":"Cancels a task (stops its execution, or prevents it from being executed)","parameters":[{"name":"uuid","in":"body","description":"UUID of the task","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Command Received","schema":{"$ref":"#/definitions/Response"}}}}},"/task/remove":{"post":{"description":"Removes a task and deletes all of its assets","parameters":[{"name":"uuid","in":"body","description":"UUID of the task","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Command Received","schema":{"$ref":"#/definitions/Response"}}}}},"/task/restart":{"post":{"description":"Restarts a task that was previously canceled or that had failed to process","parameters":[{"name":"uuid","in":"body","description":"UUID of the task","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Command Received","schema":{"$ref":"#/definitions/Response"}}}}},"/options":{"get":{"description":"Retrieves the command line options that can be passed to process a task","tags":["server"],"responses":{"200":{"description":"Options","schema":{"type":"array","items":{"title":"Option","type":"object","required":["name","type","value","domain","help"],"properties":{"name":{"type":"string","description":"Command line option (exactly as it is passed to the OpenDroneMap process, minus the leading '--')"},"type":{"type":"string","description":"Datatype of the value of this option","enum":["int","float","string","bool"]},"value":{"type":"string","description":"Default value of this option"},"domain":{"type":"string","description":"Valid range of values (for example, \"positive integer\" or \"float > 0.0\")"},"help":{"type":"string","description":"Description of what this option does"}}}}}}}},"/info":{"get":{"description":"Retrieves information about this node","tags":["server"],"responses":{"200":{"description":"Info","schema":{"type":"object","required":["version","taskQueueCount"],"properties":{"version":{"type":"string","description":"Current version"},"taskQueueCount":{"type":"integer","description":"Number of tasks currently being processed or waiting to be processed"}}}}}}}},"definitions":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Description of the error"}}},"Response":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","description":"true if the command succeeded, false otherwise"},"error":{"type":"string","description":"Error message if an error occured"}}}},"responses":{},"parameters":{},"securityDefinitions":{},"tags":[]} \ No newline at end of file diff --git a/index.js b/index.js index dcc1dad..24202ed 100644 --- a/index.js +++ b/index.js @@ -290,10 +290,16 @@ app.get('/task/:uuid/output', getTaskFromUuid, (req, res) => { * - name: asset * in: path * type: string -* description: Type of asset to download. Use "all" for zip file containing all assets. Other options are not yet available +* description: Type of asset to download. Use "all.zip" for zip file containing all assets. Other options are not yet available * required: true * enum: -* - all +* - all.zip +* - georeferenced_model.ply.zip +* - georeferenced_model.las.zip +* - georeferenced_model.csv.zip +* - orthophoto.png +* - orthophoto.tif +* - textured_model.zip * responses: * 200: * description: Asset File @@ -305,8 +311,10 @@ app.get('/task/:uuid/output', getTaskFromUuid, (req, res) => { * $ref: '#/definitions/Error' */ app.get('/task/:uuid/download/:asset', getTaskFromUuid, (req, res) => { - if (!req.params.asset || req.params.asset === "all"){ - res.download(req.task.getAssetsArchivePath(), "all.zip", err => { + let asset = req.params.asset !== undefined ? req.params.asset : "all.zip"; + let filePath = req.task.getAssetsArchivePath(asset); + if (filePath){ + res.download(filePath, filePath, err => { if (err) res.json({error: "Asset not ready"}); }); }else{ diff --git a/libs/Task.js b/libs/Task.js index 747f71a..7c27fcd 100644 --- a/libs/Task.js +++ b/libs/Task.js @@ -22,6 +22,7 @@ let async = require('async'); let assert = require('assert'); let logger = require('./logger'); let fs = require('fs'); +let glob = require("glob"); let path = require('path'); let rmdir = require('rimraf'); let odmRunner = require('./odmRunner'); @@ -118,8 +119,26 @@ module.exports = class Task{ // Get the path of the archive where all assets // outputted by this task are stored. - getAssetsArchivePath(){ - return path.join(this.getProjectFolderPath(), "all.zip"); + getAssetsArchivePath(filename){ + switch(filename){ + case "all.zip": + case "georeferenced_model.ply.zip": + case "georeferenced_model.las.zip": + case "georeferenced_model.csv.zip": + case "textured_model.zip": + // OK + break; + case "orthophoto.png": + case "orthophoto.tif": + // Append missing pieces to the path + filename = path.join('odm_orthophoto', `odm_${filename}`); + break; + default: + // Invalid + return false; + } + + return path.join(this.getProjectFolderPath(), filename); } // Deletes files and folders related to this task @@ -198,32 +217,89 @@ module.exports = class Task{ }; const postProcess = () => { - let output = fs.createWriteStream(this.getAssetsArchivePath()); - let archive = archiver.create('zip', {}); + const createZipArchive = (outputFilename, files) => { + return (done) => { + let output = fs.createWriteStream(this.getAssetsArchivePath(outputFilename)); + let archive = archiver.create('zip', {}); - archive.on('finish', () => { - // TODO: is this being fired twice? - this.setStatus(statusCodes.COMPLETED); - finished(); - }); + archive.on('finish', () => { + // TODO: is this being fired twice? + done(); + }); - archive.on('error', err => { - this.setStatus(statusCodes.FAILED); - logger.error(`Could not archive .zip file: ${err.message}`); - finished(err); - }); + archive.on('error', err => { + logger.error(`Could not archive .zip file: ${err.message}`); + done(err); + }); - archive.pipe(output); - ['odm_orthophoto', 'odm_georeferencing', 'odm_texturing', 'odm_meshing'].forEach(folderToArchive => { - let sourcePath = !config.test ? - this.getProjectFolderPath() : - path.join("tests", "processing_results"); - - archive.directory( - path.join(sourcePath, folderToArchive), - folderToArchive); + archive.pipe(output); + let globs = []; + + // Process files and directories first + files.forEach(file => { + let sourcePath = !config.test ? + this.getProjectFolderPath() : + path.join("tests", "processing_results"); + let filePath = path.join(sourcePath, file), + isGlob = /\*/.test(file), + isDirectory = !isGlob && fs.lstatSync(filePath).isDirectory(); + + if (isDirectory){ + archive.directory(filePath, file); + }else if (isGlob){ + globs.push(filePath); + }else{ + archive.file(filePath, {name: path.basename(file)}); + } + }); + + // Check for globs + if (globs.length !== 0){ + let pending = globs.length; + + globs.forEach(pattern => { + glob(pattern, (err, files) => { + if (err) done(err); + else{ + files.forEach(file => { + if (fs.lstatSync(file).isFile()){ + archive.file(file, {name: path.basename(file)}); + }else{ + logger.debug(`Could not add ${file} from glob`); + } + }); + + if (--pending === 0){ + archive.finalize(); + } + } + }); + }); + }else{ + archive.finalize() + } + }; + }; + + async.series([ + createZipArchive("all.zip", ['odm_orthophoto', 'odm_georeferencing', 'odm_texturing', 'odm_meshing']), + createZipArchive("georeferenced_model.ply.zip", [path.join('odm_georeferencing', 'odm_georeferenced_model.ply')]), + createZipArchive("georeferenced_model.las.zip", [path.join('odm_georeferencing', 'odm_georeferenced_model.ply.las')]), + createZipArchive("georeferenced_model.csv.zip", [path.join('odm_georeferencing', 'odm_georeferenced_model.csv')]), + createZipArchive("textured_model.zip", [ + path.join("odm_texturing", "*.jpg"), + path.join("odm_texturing", "odm_textured_model_geo.obj"), + path.join("odm_texturing", "odm_textured_model_geo.mtl") + ]) + ], (err) => { + if (!err){ + this.setStatus(statusCodes.COMPLETED); + finished(); + }else{ + this.setStatus(statusCodes.FAILED); + finished(err); + } }); - archive.finalize(); }; if (this.status.code === statusCodes.QUEUED){ diff --git a/libs/odmOptions.js b/libs/odmOptions.js index af3a263..9419a5e 100644 --- a/libs/odmOptions.js +++ b/libs/odmOptions.js @@ -39,7 +39,7 @@ module.exports = { for (let option in json){ // Not all options are useful to the end user // (num cores can be set programmatically, so can gcpFile, etc.) - if (["-h", "--project-path", + if (["-h", "--project-path", "--cmvs-maxImages", "--time", "--zip-results", "--pmvs-num-cores", "--odm_georeferencing-useGcp", "--start-with", "--odm_georeferencing-gcpFile", "--end-with"].indexOf(option) !== -1) continue; diff --git a/package.json b/package.json index dc0dda7..291a9f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-opendronemap", - "version": "1.0.0", + "version": "1.0.1", "description": "REST API to access OpenDroneMap", "main": "index.js", "scripts": { @@ -24,6 +24,7 @@ "async": "^2.0.0-rc.6", "body-parser": "^1.15.2", "express": "^4.14.0", + "glob": "^7.1.1", "minimist": "^1.2.0", "morgan": "^1.7.0", "multer": "^1.1.0", diff --git a/public/index.html b/public/index.html index a780b51..b9e7632 100644 --- a/public/index.html +++ b/public/index.html @@ -82,6 +82,7 @@

Retrieving ...

+
UUID:
Name:
Images:
Status:
@@ -93,7 +94,11 @@
+ +
diff --git a/public/js/main.js b/public/js/main.js index 87f5971..3f76a0d 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -259,7 +259,10 @@ $(function(){ task.resetOutput(); }); Task.prototype.download = function(){ - location.href = "/task/" + this.uuid + "/download/all"; + location.href = "/task/" + this.uuid + "/download/all.zip"; + }; + Task.prototype.downloadOrthophoto = function(){ + location.href = "/task/" + this.uuid + "/download/orthophoto.tif"; }; var taskList = new TaskList(); diff --git a/tests/processing_results/odm_georeferencing/odm_georeferenced_model.csv b/tests/processing_results/odm_georeferencing/odm_georeferenced_model.csv new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_georeferencing/odm_georeferenced_model.ply b/tests/processing_results/odm_georeferencing/odm_georeferenced_model.ply new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_georeferencing/odm_georeferenced_model.ply.las b/tests/processing_results/odm_georeferencing/odm_georeferenced_model.ply.las new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_orthophoto/odm_orthophoto.png b/tests/processing_results/odm_orthophoto/odm_orthophoto.png new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_orthophoto/odm_orthophoto.tif b/tests/processing_results/odm_orthophoto/odm_orthophoto.tif new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_texturing/non_visible_faces_texture.jpg b/tests/processing_results/odm_texturing/non_visible_faces_texture.jpg new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_texturing/odm_textured_model.obj b/tests/processing_results/odm_texturing/odm_textured_model.obj new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_texturing/odm_textured_model_geo.mtl b/tests/processing_results/odm_texturing/odm_textured_model_geo.mtl new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_texturing/odm_textured_model_geo.obj b/tests/processing_results/odm_texturing/odm_textured_model_geo.obj new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_texturing/texture_0.jpg b/tests/processing_results/odm_texturing/texture_0.jpg new file mode 100644 index 0000000..e69de29 diff --git a/tests/processing_results/odm_texturing/texture_1.jpg b/tests/processing_results/odm_texturing/texture_1.jpg new file mode 100644 index 0000000..e69de29