Working
This commit is contained in:
parent
aa55934bf0
commit
31610f6100
|
|
@ -1,6 +1,7 @@
|
||||||
db.sqlite
|
db.sqlite
|
||||||
.device
|
.device
|
||||||
data
|
data
|
||||||
|
data-keep
|
||||||
node_modules
|
node_modules
|
||||||
static/calibration-visualiser.*
|
static/calibration-visualiser.*
|
||||||
|
|
||||||
|
|
|
||||||
17
app.py
17
app.py
|
|
@ -21,6 +21,12 @@ def get_calibration(conn: sqlite3.Connection) -> Optional[db.Calibration]:
|
||||||
return db.Calibration.get_from_id(calibration_id, conn)
|
return db.Calibration.get_from_id(calibration_id, conn)
|
||||||
|
|
||||||
|
|
||||||
|
@app.context_processor
|
||||||
|
def inject_stage_and_region():
|
||||||
|
conn = db.get()
|
||||||
|
return dict(calibration=get_calibration(conn))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def hello_world():
|
def hello_world():
|
||||||
conn = db.get()
|
conn = db.get()
|
||||||
|
|
@ -40,7 +46,7 @@ def create_object():
|
||||||
def object(id: int):
|
def object(id: int):
|
||||||
conn = db.get()
|
conn = db.get()
|
||||||
object = db.Object.get_from_id(id, conn)
|
object = db.Object.get_from_id(id, conn)
|
||||||
return render_template('object.html', object=object, calibration=get_calibration(conn))
|
return render_template('object.html', object=object)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/scan/<id>')
|
@app.route('/scan/<id>')
|
||||||
|
|
@ -90,10 +96,17 @@ def scan_calibration(id: int):
|
||||||
@app.route("/api/calibrate/<id>")
|
@app.route("/api/calibrate/<id>")
|
||||||
def run_calibration(id: int):
|
def run_calibration(id: int):
|
||||||
conn = db.get()
|
conn = db.get()
|
||||||
db.Calibration.get_from_id(id, conn)
|
calib = db.Calibration.get_from_id(id, conn)
|
||||||
|
if calib is None:
|
||||||
|
return 'oops', 404
|
||||||
|
|
||||||
calibration_json = calibration.calibrate(join(config.CALIBRATION_DIR, str(id)))
|
calibration_json = calibration.calibrate(join(config.CALIBRATION_DIR, str(id)))
|
||||||
with open(join(config.CALIBRATION_DIR, str(id), 'calibration.json'), 'w') as f:
|
with open(join(config.CALIBRATION_DIR, str(id), 'calibration.json'), 'w') as f:
|
||||||
json.dump(calibration_json, f, indent=4)
|
json.dump(calibration_json, f, indent=4)
|
||||||
|
with conn:
|
||||||
|
calib.state = db.CalibrationState.IsComputed
|
||||||
|
calib.save(conn)
|
||||||
|
|
||||||
return 'ok'
|
return 'ok'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
from os.path import join
|
from os.path import join
|
||||||
|
|
||||||
|
MODE = 'debug'
|
||||||
DATA_DIR = 'data'
|
DATA_DIR = 'data'
|
||||||
CALIBRATION_DIR = join(DATA_DIR, 'calibration')
|
CALIBRATION_DIR = join(DATA_DIR, 'calibrations')
|
||||||
|
OBJECT_DIR = join(DATA_DIR, 'objects')
|
||||||
|
|
||||||
LEDS_UUIDS = [
|
LEDS_UUIDS = [
|
||||||
'ac59350e-3787-46d2-88fa-743c1d34fe86',
|
'ac59350e-3787-46d2-88fa-743c1d34fe86',
|
||||||
|
|
|
||||||
65
db.py
65
db.py
|
|
@ -3,9 +3,17 @@
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from flask import g
|
from flask import g
|
||||||
import os
|
import os
|
||||||
|
from os.path import join
|
||||||
|
import shutil
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
import sys
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
if __name__ != '__main__':
|
||||||
|
from . import config
|
||||||
|
else:
|
||||||
|
import config
|
||||||
|
|
||||||
|
|
||||||
def get() -> sqlite3.Connection:
|
def get() -> sqlite3.Connection:
|
||||||
if 'db' not in g:
|
if 'db' not in g:
|
||||||
|
|
@ -40,7 +48,8 @@ def init_app(app):
|
||||||
class CalibrationState(IntEnum):
|
class CalibrationState(IntEnum):
|
||||||
Empty = 0
|
Empty = 0
|
||||||
HasData = 1
|
HasData = 1
|
||||||
IsValidated = 2
|
IsComputed = 2
|
||||||
|
IsValidated = 3
|
||||||
|
|
||||||
|
|
||||||
class Calibration:
|
class Calibration:
|
||||||
|
|
@ -59,7 +68,9 @@ class Calibration:
|
||||||
'INSERT INTO calibration(state) VALUES (?) RETURNING ' + Calibration.select_args() + ';',
|
'INSERT INTO calibration(state) VALUES (?) RETURNING ' + Calibration.select_args() + ';',
|
||||||
[int(CalibrationState.Empty)]
|
[int(CalibrationState.Empty)]
|
||||||
)
|
)
|
||||||
return Calibration.from_row(response.fetchone())
|
calibration = Calibration.from_row(response.fetchone())
|
||||||
|
os.makedirs(join(config.CALIBRATION_DIR, str(calibration.id)))
|
||||||
|
return calibration
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_row(row: sqlite3.Row) -> 'Calibration':
|
def from_row(row: sqlite3.Row) -> 'Calibration':
|
||||||
|
|
@ -96,7 +107,7 @@ class Acquisition:
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute(
|
cur.execute(
|
||||||
'UPDATE acquisition SET calibration_id = ?, object_id = ? WHERE id = ?',
|
'UPDATE acquisition SET calibration_id = ?, object_id = ? WHERE id = ?',
|
||||||
[self.calibration_id, self.objct_id, self.id]
|
[self.calibration_id, self.object_id, self.id]
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -146,7 +157,9 @@ class Object:
|
||||||
'INSERT INTO object(name) VALUES (?) RETURNING ' + Object.select_args() + ';',
|
'INSERT INTO object(name) VALUES (?) RETURNING ' + Object.select_args() + ';',
|
||||||
[name]
|
[name]
|
||||||
)
|
)
|
||||||
return Object.from_row(response.fetchone())
|
object = Object.from_row(response.fetchone())
|
||||||
|
os.makedirs(join(config.OBJECT_DIR, str(object.id)))
|
||||||
|
return object
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_from_id(object_id: int, db: sqlite3.Connection) -> Optional['Object']:
|
def get_from_id(object_id: int, db: sqlite3.Connection) -> Optional['Object']:
|
||||||
|
|
@ -176,6 +189,10 @@ class Object:
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
if config.MODE != 'debug':
|
||||||
|
print('Can only reset db in debug mode')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
db = sqlite3.connect(
|
db = sqlite3.connect(
|
||||||
os.environ.get('DATABASE_PATH', 'db.sqlite'),
|
os.environ.get('DATABASE_PATH', 'db.sqlite'),
|
||||||
detect_types=sqlite3.PARSE_DECLTYPES,
|
detect_types=sqlite3.PARSE_DECLTYPES,
|
||||||
|
|
@ -183,28 +200,32 @@ def main():
|
||||||
db.row_factory = sqlite3.Row
|
db.row_factory = sqlite3.Row
|
||||||
init(db)
|
init(db)
|
||||||
|
|
||||||
|
if os.path.isdir(config.DATA_DIR):
|
||||||
|
shutil.rmtree(config.DATA_DIR)
|
||||||
|
|
||||||
# Create a new object
|
# Create a new object
|
||||||
with db:
|
with db:
|
||||||
object = Object.create('Mon premier objet', db)
|
Object.create('Mon premier objet', db)
|
||||||
calibration = Calibration.create(db)
|
# calibration = Calibration.create(db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
calibration = Calibration.create(db)
|
# calibration = Calibration.create(db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
|
|
||||||
object = Object.create('Mon deuxième objet', db)
|
Object.create('Mon deuxième objet', db)
|
||||||
calibration = Calibration.create(db)
|
# calibration = Calibration.create(db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
calibration = Calibration.create(db)
|
# calibration = Calibration.create(db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
object.add_acquisition(calibration.id, db)
|
# object.add_acquisition(calibration.id, db)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1] == 'reset':
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ def scan(output_dir: str):
|
||||||
|
|
||||||
# capture(img)
|
# capture(img)
|
||||||
# For debug purposes
|
# For debug purposes
|
||||||
shutil.copyfile(join(config.DATA_DIR, 'small', led + '.jpg'), img)
|
shutil.copyfile(join('data-keep/small', led + '.jpg'), img)
|
||||||
|
|
||||||
delta = time.time() - start
|
delta = time.time() - start
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,28 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="navbarBasicExample" class="navbar-menu">
|
<div id="navbarBasicExample" class="navbar-menu">
|
||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
<a class="navbar-item" href="/">
|
<a class="navbar-item" href="#">
|
||||||
Page 1
|
{% if calibration is none or calibration.state == 0 %}
|
||||||
|
<span class="tags has-addons">
|
||||||
|
<span class="tag is-dark">étalonnage</span>
|
||||||
|
<span class="tag is-danger">aucune donnée</span>
|
||||||
|
</span>
|
||||||
|
{% elif calibration.state == 1 %}
|
||||||
|
<span class="tags has-addons">
|
||||||
|
<span class="tag is-dark">étalonnage</span>
|
||||||
|
<span class="tag is-warning">non calculé</span>
|
||||||
|
</span>
|
||||||
|
{% elif calibration.state == 2 %}
|
||||||
|
<span class="tags has-addons">
|
||||||
|
<span class="tag is-dark">étalonnage</span>
|
||||||
|
<span class="tag is-warning">non validé</span>
|
||||||
|
</span>
|
||||||
|
{% elif calibration.state == 3 %}
|
||||||
|
<a href="/calibration/{{ object.id }}" class="tags has-addons">
|
||||||
|
<span class="tag is-dark">étalonnage</span>
|
||||||
|
<span class="tag is-success">fait</span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<progress id="progress-bar" class="progress is-link" style="display: none;" value="0" max="1000"></progress>
|
<progress id="progress-bar" class="progress is-link" style="display: none;" value="0" max="1000"></progress>
|
||||||
<div id="calibrate" style="display: none;">
|
<div id="calibrate" {% if calibration.state == 0 %}style="display: none;" {% endif %}>
|
||||||
<p>Si les données d'étalonnage conviennent, appuyez sur le bouton ci-dessous pour procéder à l'étalonnage du scanner</p>
|
<p>Si les données d'étalonnage conviennent, appuyez sur le bouton ci-dessous pour procéder à l'étalonnage du scanner.</p>
|
||||||
<button id="calibrate-button" class="button is-link">Étalonner le scanner</button>
|
<button id="calibrate-button" class="button is-link">Étalonner le scanner</button>
|
||||||
<p id="calibration-info"></p>
|
<p id="calibration-info"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -74,6 +74,20 @@
|
||||||
buttons.forEach(x => x.removeAttribute('disabled'));
|
buttons.forEach(x => x.removeAttribute('disabled'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If we already have calibration images, we show them right now
|
||||||
|
if ({% if calibration.state > 0 %}true{% else %}false{% endif %}) {
|
||||||
|
let cell, img;
|
||||||
|
{% for led in leds %}
|
||||||
|
cell = document.createElement('div');
|
||||||
|
cell.classList.add('cell');
|
||||||
|
img = document.createElement('img');
|
||||||
|
img.classList.add('is-loading');
|
||||||
|
img.src = '/data/calibration/{{ calibration.id }}/{{ led }}.jpg?v=0';
|
||||||
|
cell.appendChild(img);
|
||||||
|
grid.appendChild(cell);
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
|
||||||
scanButton.addEventListener('click', async () => {
|
scanButton.addEventListener('click', async () => {
|
||||||
scanIndex++;
|
scanIndex++;
|
||||||
progress = 0;
|
progress = 0;
|
||||||
|
|
@ -103,7 +117,7 @@
|
||||||
cell.classList.add('cell');
|
cell.classList.add('cell');
|
||||||
let img = document.createElement('img');
|
let img = document.createElement('img');
|
||||||
img.classList.add('is-loading');
|
img.classList.add('is-loading');
|
||||||
img.src = '/data/calibration/{{ calibration.id }}/' + uuid + '.jpg?v=' + scanIndex;
|
img.src = '/data/calibrations/{{ calibration.id }}/' + uuid + '.jpg?v=' + scanIndex;
|
||||||
cell.appendChild(img);
|
cell.appendChild(img);
|
||||||
grid.appendChild(cell);
|
grid.appendChild(cell);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Nom de l'objet</label>
|
<label class="label">Nom de l'objet</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" type="text" name="name" placeholder="Nom de l'objet">
|
<input class="input" type="text" name="name" placeholder="Nom de l'objet" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,34 +4,6 @@
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="title">{{ object.name }}</h1>
|
<h1 class="title">{{ object.name }}</h1>
|
||||||
{#
|
|
||||||
<div class="field is-grouped is-grouped-multiline">
|
|
||||||
<div class="control">
|
|
||||||
{% if calibration is none or calibration.state == 0 %}
|
|
||||||
<span class="tags has-addons">
|
|
||||||
<span class="tag is-dark">étalonnage</span>
|
|
||||||
<span class="tag is-danger">aucune donnée</span>
|
|
||||||
</span>
|
|
||||||
{% elif calibration.state == 1 %}
|
|
||||||
<span class="tags has-addons">
|
|
||||||
<span class="tag is-dark">étalonnage</span>
|
|
||||||
<span class="tag is-warning">pas fait</span>
|
|
||||||
</span>
|
|
||||||
{% elif calibration.state == 2 %}
|
|
||||||
<a href="/calibration/{{ object.id }}" class="tags has-addons">
|
|
||||||
<span class="tag is-dark">étalonnage</span>
|
|
||||||
<span class="tag is-success">fait</span>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if calibration is none or calibration.state == 0 %}
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<a href="/calibrate/{{ object.id }}" class="button is-link">Étalonner le scanner</a>
|
|
||||||
<a href="#" title="Non implémenté" disabled="disabled" class="button is-link">Utiliser le dernier étalonnage connu</a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
#}
|
|
||||||
{% if calibration %}
|
{% if calibration %}
|
||||||
<a href="/scan/{{ object.id }}" class="button is-link">Faire un scan</a>
|
<a href="/scan/{{ object.id }}" class="button is-link">Faire un scan</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
||||||
15
ts/Engine.ts
15
ts/Engine.ts
|
|
@ -44,7 +44,7 @@ function getImageElementById(id: string): HTMLImageElement {
|
||||||
*/
|
*/
|
||||||
export class Engine {
|
export class Engine {
|
||||||
/** The id of the object to scan. */
|
/** The id of the object to scan. */
|
||||||
objectId: number;
|
calibrationId: number;
|
||||||
|
|
||||||
/** HTML element on which the renderer will be added. */
|
/** HTML element on which the renderer will be added. */
|
||||||
domElement: HTMLElement;
|
domElement: HTMLElement;
|
||||||
|
|
@ -105,15 +105,15 @@ export class Engine {
|
||||||
|
|
||||||
/** Initialises the engine. */
|
/** Initialises the engine. */
|
||||||
static async create(domId: string) {
|
static async create(domId: string) {
|
||||||
let objectId = parseInt(window.location.pathname.split('/')[2], 10);
|
let calibrationId = parseInt(window.location.pathname.split('/')[2], 10);
|
||||||
|
|
||||||
let domElement = getElementById(domId);
|
let domElement = getElementById(domId);
|
||||||
let engine = new Engine();
|
let engine = new Engine();
|
||||||
engine.objectId = objectId;
|
engine.calibrationId = calibrationId;
|
||||||
engine.domElement = domElement;
|
engine.domElement = domElement;
|
||||||
engine.initHtml();
|
engine.initHtml();
|
||||||
|
|
||||||
let request = await fetch('/data/calibration/' + objectId + '/calibration.json');
|
let request = await fetch(engine.dataPath('calibration.json'));
|
||||||
let calibration = await request.json();
|
let calibration = await request.json();
|
||||||
engine.initScene(calibration);
|
engine.initScene(calibration);
|
||||||
engine.initListeners();
|
engine.initListeners();
|
||||||
|
|
@ -130,6 +130,11 @@ export class Engine {
|
||||||
return this.domElement === document.body ? window.innerHeight : this.domElement.offsetHeight;
|
return this.domElement === document.body ? window.innerHeight : this.domElement.offsetHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the url of calibration assets. */
|
||||||
|
dataPath(path: string): string {
|
||||||
|
return '/data/calibrations/' + this.calibrationId + '/' + path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the HTML components of the engine.
|
* Initialises the HTML components of the engine.
|
||||||
*/
|
*/
|
||||||
|
|
@ -296,7 +301,7 @@ export class Engine {
|
||||||
showImage(led: Led): void {
|
showImage(led: Led): void {
|
||||||
if (led.on) {
|
if (led.on) {
|
||||||
this.selectedObject.innerText = led.name.split('.')[0] + ' (' + (<number> this.leds.currentLedIndex + 1) + '/' + this.leds.leds.length + ')';
|
this.selectedObject.innerText = led.name.split('.')[0] + ' (' + (<number> this.leds.currentLedIndex + 1) + '/' + this.leds.leds.length + ')';
|
||||||
this.ledView.src = '/data/calibration/' + this.objectId + '/' + led.name;
|
this.ledView.src = this.dataPath(led.name);
|
||||||
this.ledView.style.display = 'block';
|
this.ledView.style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
this.selectedObject.innerText = 'aucune';
|
this.selectedObject.innerText = 'aucune';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue