Skip to content

Commit

Permalink
commited
Browse files Browse the repository at this point in the history
  • Loading branch information
alifiroozidev authored Oct 20, 2022
0 parents commit 552d84f
Show file tree
Hide file tree
Showing 36 changed files with 38,229 additions and 0 deletions.
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM ubuntu:latest

WORKDIR /app

RUN apt-get update && \
apt-get install -y python3-pip python3-dev libgssapi-krb5-2 && \
pip3 install --upgrade pip

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

COPY . .

# CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# meshroom-web
Web client to interact with the meshroom cli

# Commands
Start the flask webclient by running `python -m flask run` or `python -m flask run --host="0.0.0.0"` when running inside the container to make sure it is exposed to the host.
Start the websocket server by running `python websocket.py`.
Build the docker image by running `docker build -t <yourtag>`.
Run the docker image by running `docker -p 5000:5000 -p 5678:5678 -it run <yourtag>`. This runs the image interactively in which you can call the commands mentioned above. Port 5000 is exposed for the flask application. Port 5678 is exposed for the websocket server. Thus, `localhost:5000` for the web client, and `ws://127.0.0.1:5678` for the websocket.
Binary file added __pycache__/main.cpython-38.pyc
Binary file not shown.
2 changes: 2 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Include our application
from app import app
11 changes: 11 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Dependencies
from flask import Flask

# Define the application and port
# Flask accepts a static folder parameter in which the static js and css is located
# You can refer to it using the static_url_path parameter which is the href
# used in templates, e.g. static_url_path = '/app' can be referred to as /app/main.js
app = Flask(__name__, static_folder='static', static_url_path='/static')

# Import all views, these are all the pages or endpoints the application handles
from app import views
Binary file added app/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file added app/__pycache__/__init__.cpython-36.pyc
Binary file not shown.
Binary file added app/__pycache__/__init__.cpython-37.pyc
Binary file not shown.
Binary file added app/__pycache__/__init__.cpython-38.pyc
Binary file not shown.
Binary file added app/__pycache__/views.cpython-36.pyc
Binary file not shown.
Binary file added app/__pycache__/views.cpython-37.pyc
Binary file not shown.
Binary file added app/__pycache__/views.cpython-38.pyc
Binary file not shown.
Empty file added app/lib/__init__.py
Empty file.
Binary file added app/lib/__pycache__/__init__.cpython-36.pyc
Binary file not shown.
Binary file added app/lib/__pycache__/__init__.cpython-37.pyc
Binary file not shown.
Binary file added app/lib/__pycache__/meshroom.cpython-36.pyc
Binary file not shown.
Binary file added app/lib/__pycache__/meshroom.cpython-37.pyc
Binary file not shown.
65 changes: 65 additions & 0 deletions app/lib/meshroom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from os import path
import subprocess
import shutil

class Meshroom(object):

def __init__(self, inputdir, outputdir):
"""
Constructor.
---
inputdir: Path to input folder where the images of the model should be.
outputdir: Path where meshroom will place its output.
"""
if not path.isdir(inputdir):
raise Exception(f"{inputdir} is not a directory")
if not path.isdir(outputdir):
raise Exception(f"{outputdir} is not a directory")

# Store the references to the input and output directories
self._input = inputdir
self._output = outputdir

async def run(self, config, pipe):
"""
Run a simulation with a given configuration file.
raises: Exception
---
config: Path to JSON file that holds the configuration of a meshroom simulation.
pipe: Function that receives the output of the program.
"""

# Check if the given config file exists
if not path.isfile(config):
raise Exception(f"Config file {config} does not exist")

# Check if it's a json file
if not config.endswith('.json'):
raise Exception(f"Config file {config} is not a JSON file")

# Check if meshroom exec is available
if not path.isfile(path.join('.', 'meshroom', 'meshroom_batch')):
raise Exception("Meshroom executable is not available")

# Run the meshroom cli
process = subprocess.Popen([
path.join(".", "meshroom", "meshroom_batch"),
"--inputRecursive", self._input,
"--output", self._output,
"--overrides", config,
"--save", path.join(self._output, "project")
], stdout=subprocess.PIPE)

# Print the output
while True:

# Read the current line of the process' output
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break

# Output the current line
if output:
await pipe(output)
Empty file added app/static/app.css
Empty file.
103 changes: 103 additions & 0 deletions app/static/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Wait until the content of the DOM has loaded and parsed. This does
// not wait on stylesheets, images, or subframes
window.addEventListener('DOMContentLoaded', () => {

// Find the container and form
const container = document.querySelector('.uk-container');
const form = document.querySelector('form');
const stdout = document.querySelector('code');

// Start a websocket connection. This websocket connection allows us to
// ping the backend and start an actual meshroom process. This process
// also streams the process' stdout over the connection
const websocket = new WebSocket('ws://127.0.0.1:5678');

// Listen to incoming messages, which we want to stream the stdout element
websocket.onmessage = (event) => {

// Get the text from the blob
event.data.text().then((text) => {

// And update the stdout
stdout.textContent = stdout.textContent + text;
});
};

// Fetch the default configuration of meshroom from the API
fetch('/config').then((res) => {

// Fetch the text and load it into the form
res.text().then((text) => {

// Set the text on the form field that holds the json configuration
form.querySelector('textarea').textContent = text;
});
});

// Listen until the user submits the form
form.addEventListener('submit', (event) => {

// Prevent the default behavior as we don't want the browser
// redirect the user
event.preventDefault();

// Create form data from the form
const formdata = new FormData(form);
form.classList.remove('uk-form-danger');

// Show a loading animation
const overlay = container.appendChild(document.createElement('div'));
overlay.classList.add('uk-overlay', 'uk-position-center');
const loader = overlay.appendChild(document.createElement('div'));
loader.setAttribute('uk-spinner', true);

// List of promises that are required to run meshroom
const promises = [
fetch('/upload', {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
body: formdata
}),
fetch('/config', {
method: 'POST',
mode: 'cors',
credentials: 'same-origin',
body: formdata
})
];

// Make a post request to upload the images
Promise.all(promises).then(() => {

// Remove the loader
overlay.remove();

// Inform the user
UIkit.notification({
message: 'Meshroom has started',
status: 'success',
pos: 'bottom-right',
timeout: 3000
});

// Refresh the view to show the progress of the meshroom progress
websocket.send(JSON.stringify({ type: 'run' }));
}).catch((err) => {

console.log(err);
// Remove the loader
overlay.remove();

// Something went wrong, so we need to inform the user
form.classList.add('uk-form-danger');
UIkit.notification({
message: 'Files could not be uploaded',
status: 'danger',
pos: 'bottom-right',
timeout: 3000
});
});
});
});
Loading

0 comments on commit 552d84f

Please sign in to comment.