Skip to content

Commit

Permalink
Merge branch 'main' of github.com:cnr-isti-vclab/openlime
Browse files Browse the repository at this point in the history
  • Loading branch information
ponchio committed Dec 14, 2023
2 parents e5b1df3 + 1d18a85 commit f422146
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 40 deletions.
2 changes: 1 addition & 1 deletion dist/examples/annotation-editor/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ <h1 class="headline">OpenLIME - Annotation Editor</h1>
}

// Create an annotation layer and add it to the canvans
const anno = new OpenLIME.Layer(aOptions);
const anno = new OpenLIME.LayerAnnotation(aOptions);
lime.addLayer('anno', anno);

// If editorEnable, create a SVG annotation Editor
Expand Down
2 changes: 1 addition & 1 deletion src/BoundingBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class BoundingBox {
* @returns {number} The center value.
*/
center() {
return [(this.xLow+this.xHigh)/2, (this.yLow+this.yHigh)/2];
return { x: (this.xLow+this.xHigh)/2, y: (this.yLow+this.yHigh)/2 };
}

/**
Expand Down
31 changes: 30 additions & 1 deletion src/Cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class _Cache {

maxRequest: 6, //max number of concurrent HTTP requests
requested: 0,
maxRequestsRate: 0, //max number of requests per second, 0 means no rate.
requestRateTimeout: null, //calls update when a new slot is available due to request rate.
lastRequestTimestamp: performance.now(), //holdls last requests timestamps.
maxPrefetch: 8*(1<<20), //max amount of prefetched tiles.
prefetched: 0 //amount of currently prefetched GPU ram.
});
Expand All @@ -37,9 +40,34 @@ class _Cache {
}

/** @ignore */
update() {
rateLimited() {
if(this.requested > this.maxRequest)
return true;

if(this.maxRequestsRate == 0)
return false;

let now = performance.now();
let period = 1000/this.maxRequestsRate;
let diff = now - this.lastRequestTimestamp;
if(diff > period)
return false;


if(!this.requestRateTimeout) {
this.requestRateTimeout = setTimeout(() => {
this.requestRateTimeout = null;
this.update();
}, period -diff + 10);
}
return true;
}

/** @ignore */
update() {
if(this.rateLimited())
return;


let best = this.findBestCandidate();
if(!best) return;
Expand All @@ -56,6 +84,7 @@ class _Cache {
}
console.assert(best != best.layer.queue[0]);
best.layer.queue.shift();
this.lastRequestTimestamp = performance.now();
this.loadTile(best.layer, best.tile);
}

Expand Down
27 changes: 16 additions & 11 deletions src/EditorSvgAnnotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,11 @@ class EditorSvgAnnotation {
updateCallback: null,
deleteCallback: null
}, options);

layer.style += Object.entries(this.classes).map((g) => `[data-class=${g[0]}] { stroke:${g[1].style.stroke}; }`).join('\n');

layer.style += Object.entries(this.classes).map((g) => {
console.assert(g[1].hasOwnProperty('stroke'), "Classes needs a stroke property");
return `[data-class=${g[0]}] { stroke:${g[1].stroke}; }`;
}).join('\n');
//at the moment is not really possible to unregister the events registered here.
viewer.pointerManager.onEvent(this);
document.addEventListener('keyup', (e) => this.keyUp(e), false);
Expand Down Expand Up @@ -240,7 +243,7 @@ class EditorSvgAnnotation {
edit.classList.remove('hidden');
let button = edit.querySelector('.openlime-select-button');
button.textContent = this.classes[anno.class].label;
button.style.background = this.classes[anno.class].style.stroke;
button.style.background = this.classes[anno.class].stroke;
}

/** @ignore */
Expand Down Expand Up @@ -279,7 +282,7 @@ class EditorSvgAnnotation {
<div class="openlime-select-button"></div>
<ul class="openlime-select-menu">
${Object.entries(this.classes).map((c) =>
`<li data-class="${c[0]}" style="background:${c[1].style.stroke};">${c[1].label}</li>`).join('\n')}
`<li data-class="${c[0]}" style="background:${c[1].stroke};">${c[1].label}</li>`).join('\n')}
</ul>
</div>
<label for="idx">Index:</label> <input name="idx" type="text"><br>
Expand Down Expand Up @@ -324,7 +327,7 @@ class EditorSvgAnnotation {

input.value = e.srcElement.getAttribute('data-class');
input.dispatchEvent(new Event('change'));
button.style.background = this.classes[input.value].style.stroke;
button.style.background = this.classes[input.value].stroke;
button.textContent = e.srcElement.textContent;

select.classList.toggle('active');
Expand Down Expand Up @@ -419,7 +422,7 @@ class EditorSvgAnnotation {
anno.class = select.value || '';

let button = edit.querySelector('.openlime-select-button');
button.style.background = this.classes[anno.class].style.stroke;
button.style.background = this.classes[anno.class].stroke;

for (let e of this.annotation.elements)
e.setAttribute('data-class', anno.class);
Expand Down Expand Up @@ -759,11 +762,13 @@ class EditorSvgAnnotation {
const p = {x:e.offsetX, y: e.offsetY};
const layerT = this.layer.transform;
const useGL = false;
console.log(layerT);
const layerbb = this.layer.boundingBox();
const layerSize = {w:layerbb.width(), h:layerbb.height()};
//compute also size of an image pixel on screen and store in pixelSize.
let pos = CoordinateSystem.fromCanvasHtmlToImage(p, this.viewer.camera, layerT, layerSize, useGL);

p.x += 1;
let pos1 = CoordinateSystem.fromCanvasHtmlToImage(p, this.viewer.camera, layerT, layerSize, useGL);
pos.pixelSize = Math.abs(pos1.x - pos.x);
return pos;
}
}
Expand Down Expand Up @@ -886,7 +891,7 @@ class Line {
for (let e of this.annotation.elements) {
if (!e.points || e.points.length < 2)
continue;
if (Line.distance(e.points[0], pos) * pos.z < 5) {
if (Line.distance(e.points[0], pos) / pos.pixelSize < 5) {
e.points.reverse();
this.path = e;
this.path.setAttribute('d', Line.svgPath(e.points));
Expand Down Expand Up @@ -956,7 +961,7 @@ class Line {

adjust(pos) {
let gap = Line.distanceToLast(this.path.points, pos);
if (gap * pos.z < 4) return false;
if (gap / pos.pixelSize < 4) return false;

this.path.points.push(pos);

Expand Down Expand Up @@ -984,7 +989,7 @@ class Line {
static svgPath(points) {
//return points.map((p, i) => `${(i == 0? "M" : "L")}${p.x} ${p.y}`).join(' ');

let tolerance = 1.5 / points[0].z;
let tolerance = 1.5 * points[0].pixelSize;
let tmp = simplify(points, tolerance);

let smoothed = smooth(tmp, 90, true);
Expand Down
3 changes: 2 additions & 1 deletion src/Layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ class Layer {

// Set signal to acknowledge change of bbox when it is known. Let this signal go up to canvas
this.layout.addEvent('updateSize', () => {
this.shader.setTileSize(this.layout.getTileSize());
if(this.shader)
this.shader.setTileSize(this.layout.getTileSize());
this.emit('updateSize');
});
}
Expand Down
1 change: 1 addition & 0 deletions src/LayerAnnotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class LayerAnnotation extends Layer { //FIXME CustomData Object template {name:
this.createAnnotationsList();

this.emit('update');
this.status = 'ready';
this.emit('ready');
this.emit('loaded');
}
Expand Down
6 changes: 3 additions & 3 deletions src/LayerSvgAnnotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ class LayerSvgAnnotation extends LayerAnnotation {
svgGroup: null,
onClick: null, //callback function
classes: {
'': { style: { stroke: '#000' }, label: '' },
'': { stroke: '#000', label: '' },
},
annotationUpdate: null
}, options);
super(options);
for(const [key, value] of Object.entries(this.classes)) {
this.style += `[data-class=${key}] { ` + Object.entries(value.style).map( g => `${g[0]}: ${g[1]};`).join('\n') + '}';
this.style += `[data-class=${key}] { ` + Object.entries(value).map( g => `${g[0]}: ${g[1]};`).join('\n') + '}';
}
//this.createOverlaySVGElement();
//this.setLayout(this.layout);
Expand Down Expand Up @@ -160,7 +160,7 @@ class LayerSvgAnnotation extends LayerAnnotation {
if (typeof (this.annotations) == "string") return; //FIXME Is it right? Should we use this.status?

const bBox = this.boundingBox();
this.svgElement.setAttribute('viewBox', `${bBox.xLow} ${bBox.yLow} ${bBox.xHigh - bBox.xLow} ${bBox.yHigh - bBox.yLow}`);
//this.svgElement.setAttribute('viewBox', `${bBox.xLow} ${bBox.yLow} ${bBox.xHigh - bBox.xLow} ${bBox.yHigh - bBox.yLow}`);

//find which annotations needs to be added to the ccanvas, some
//indexing whould be used, for the moment we just iterate all of them.
Expand Down
2 changes: 1 addition & 1 deletion src/LayoutTiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ class LayoutTiles extends Layout {
}
let c = box.center();
//sort tiles by distance to the center TODO: check it's correct!
tmp.sort(function (a, b) { return Math.abs(a.x - c[0]) + Math.abs(a.y - c[1]) - Math.abs(b.x - c[0]) - Math.abs(b.y - c[1]); });
tmp.sort(function (a, b) { return Math.abs(a.x - c.x) + Math.abs(a.y - c.y) - Math.abs(b.x - c.x) - Math.abs(b.y - c.y); });
needed = needed.concat(tmp);
}
return needed;
Expand Down
6 changes: 5 additions & 1 deletion src/UIBasic.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,12 @@ class UIBasic {
};
if(modes.length > 1) layerEntry.list = modes;

if (layer.annotations) {
if (layer.annotations ) {
layerEntry.list = [];
//setTimeout(() => {
layerEntry.list.push(layer.annotationsEntry());
//this.updateMenu();
//}, 1000);
//TODO: this could be a convenience, creating an editor which can be
//customized later using layer.editor.
//if(layer.editable)
Expand Down
46 changes: 26 additions & 20 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ let lime = new Viewer('.openlime', { background: 'black', canvas: { preserveDraw
//imageTest('google'); // image google deepzoom deepzoom1px zoomify iiif tarzoon itarzoom
//flipTest();
//brdfTest();
rtiTest('rbf');
//rtiTest('rbf');
//tomeTest();
//testUIBasic();

Expand All @@ -32,7 +32,7 @@ rtiTest('rbf');

//testMedicalAnnotations();

//testAnnotationEditor();
testAnnotationEditor();

//testNeural();

Expand Down Expand Up @@ -64,18 +64,21 @@ function dstretchTest() {
}

function testAnnotationEditor() {


Skin.setUrl('skin/skin.svg');
let layer0 = new Layer({
label: 'Coin 10',
layout: 'image',
type:'rti',
url: 'assets/rti/hsh/info.json',
url: 'assets/rti/eloi/info.json',
normals: false
});
lime.canvas.addLayer('hsh', layer0);

let layer1 = new LayerSvgAnnotation({
label: 'Annotations',
viewBox: "0 0 256 256",
layout: layer0.layout,
style:`
.openlime-annotation { pointer-events:all; opacity: 0.7; }
.openlime-annotation:hover { cursor:pointer; opacity: 1.0; }
Expand All @@ -94,26 +97,29 @@ function testAnnotationEditor() {
<p>${annotation.description}</p>
`; },
annotations: 'assets/medical/PH1101-1.json',
annotations: 'assets/medical/test.json',
editable: true,

});
lime.canvas.addLayer('anno', layer1); //here the overlayelement created and attached to layer1
Skin.setUrl('skin/skin.svg');


let editor = new EditorSvgAnnotation(lime, layer1, { lime: lime,
classes: {
'': { stroke: '#000', label: '' },
'class1': { stroke: "#00FF00", label: "Vert" },
'class2': { stroke: '#707', label: '' },
'class3': { stroke: '#777', label: '' },
'class4': { stroke: '#070', label: '' },
'class5': { stroke: '#007', label: '' },
'class6': { stroke: '#077', label: '' },
}
});

let editor = new EditorSvgAnnotation(lime, layer1, { lime: lime });
editor.classes = {
'': { color: '#000', label: '' },
'class1': { color: '#770', label: '' },
'class2': { color: '#707', label: '' },
'class3': { color: '#777', label: '' },
'class4': { color: '#070', label: '' },
'class5': { color: '#007', label: '' },
'class6': { color: '#077', label: '' },
};

let ui = new UIBasic(lime);
lime.camera.maxFixedZoom = 4;

ui.actions.help.display = true;
ui.actions.help.html = "Help text could be here.";
ui.actions.snapshot.display = true;
Expand All @@ -123,7 +129,7 @@ function testAnnotationEditor() {
editor.deleteCallback = (annotation) => { console.log("Deleted annotation: ", annotation); return true; };
editor.updateCallback = (annotation) => { console.log("Updated annotation: ", annotation); return true; };

editor.multiple = true;
editor.multiple = true;

}

Expand Down Expand Up @@ -152,7 +158,6 @@ function testMedicalAnnotations() {
infoTemplate: (annotation) => { return `
<h3>${annotation.class}</h3>
<p>${annotation.description}</p>
`; },
annotations: 'assets/medical/PH1101-1.json',
editable: true,
Expand Down Expand Up @@ -257,12 +262,13 @@ function flipTest() {

function rtiTest(dataset) {

Cache.maxRequestRate = 30;
let layer0 = new Layer({
label: '4',
layout: 'deepzoom',
type:'rti',
// url: 'assets/rti/hsh/info.json',
url: 'assets/rti/tablets_ptm/info.json',
url: 'assets/rti/hsh/info.json',
normals: false
});
layer0.layout.cachelevels = 0;
Expand Down

0 comments on commit f422146

Please sign in to comment.