@abi-software/scaffoldvuer 1.6.2 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/scaffoldvuer.js +9748 -9710
- package/dist/scaffoldvuer.umd.cjs +51 -51
- package/dist/style.css +1 -1
- package/package.json +3 -3
- package/src/App.vue +19 -0
- package/src/app/DropZone.vue +10 -2
- package/src/components/ScaffoldVuer.vue +22 -21
- package/src/scripts/OrgansRenderer.js +28 -6
- package/vite.web-component.js +36 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abi-software/scaffoldvuer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"*.js"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@abi-software/map-utilities": "^1.
|
|
44
|
+
"@abi-software/map-utilities": "^1.3.0",
|
|
45
45
|
"@abi-software/sparc-annotation": "^0.3.1",
|
|
46
46
|
"@abi-software/svg-sprite": "^1.0.1",
|
|
47
47
|
"@element-plus/icons-vue": "^2.3.1",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"vue": "^3.4.21",
|
|
55
55
|
"vue-router": "^4.2.5",
|
|
56
56
|
"vue3-component-svg-sprite": "^0.0.1",
|
|
57
|
-
"zincjs": "^1.11.
|
|
57
|
+
"zincjs": "^1.11.5"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@vitejs/plugin-vue": "^4.6.2",
|
package/src/App.vue
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
:marker-labels="markerLabels"
|
|
30
30
|
:enableLocalAnnotations="false"
|
|
31
31
|
@open-map="openMap"
|
|
32
|
+
@on-error="onError"
|
|
32
33
|
@on-ready="onReady"
|
|
33
34
|
@scaffold-selected="onSelected"
|
|
34
35
|
@scaffold-navigated="onNavigated"
|
|
@@ -184,6 +185,9 @@
|
|
|
184
185
|
<el-col :span="auto">
|
|
185
186
|
<el-switch v-model="renderInfoOn" active-text="Renderer Info" active-color="#8300bf" />
|
|
186
187
|
</el-col>
|
|
188
|
+
<el-button size="small" @click="PrintViewport()">
|
|
189
|
+
Print Viewport
|
|
190
|
+
</el-button>
|
|
187
191
|
</el-row>
|
|
188
192
|
|
|
189
193
|
<template v-if="renderInfoOn && rendererInfo">
|
|
@@ -597,6 +601,10 @@ export default {
|
|
|
597
601
|
this.$refs.scaffold.getDynamicSelectedCoordinates();
|
|
598
602
|
this.rendererInfo = this.$refs.scaffold.getRendererInfo();
|
|
599
603
|
},
|
|
604
|
+
PrintViewport: function() {
|
|
605
|
+
const scene = this.$refs.scaffold.$module.scene;
|
|
606
|
+
console.log(scene.getZincCameraControls().getCurrentViewport());
|
|
607
|
+
},
|
|
600
608
|
fetchSuggestions: function (term, cb) {
|
|
601
609
|
if (term === "" || !this.$refs.scaffold) {
|
|
602
610
|
cb([]);
|
|
@@ -640,6 +648,17 @@ export default {
|
|
|
640
648
|
}
|
|
641
649
|
});
|
|
642
650
|
},
|
|
651
|
+
onError: function(payload) {
|
|
652
|
+
if (payload?.type === "download-error") {
|
|
653
|
+
const dropZone = this.$refs.dropzone;
|
|
654
|
+
if (dropZone) {
|
|
655
|
+
const realFilename = dropZone.findRealFilename(payload.xhr.responseURL);
|
|
656
|
+
if (realFilename) {
|
|
657
|
+
console.error(`External Resource ${realFilename}`);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
},
|
|
643
662
|
onReady: function () {
|
|
644
663
|
if (this.consoleOn) console.log(this.$refs.scaffold)
|
|
645
664
|
if (this.readyCallback) {
|
package/src/app/DropZone.vue
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
<script>
|
|
15
15
|
/* eslint-disable no-alert, no-console */
|
|
16
|
+
import { markRaw } from 'vue';
|
|
16
17
|
import { SimpleDropzone } from "simple-dropzone";
|
|
17
18
|
import path from "path";
|
|
18
19
|
|
|
@@ -26,7 +27,8 @@ export default {
|
|
|
26
27
|
name: "DropZone",
|
|
27
28
|
data: function () {
|
|
28
29
|
return {
|
|
29
|
-
objectURLs: [],
|
|
30
|
+
objectURLs: markRaw([]),
|
|
31
|
+
filesMapping: markRaw({}),
|
|
30
32
|
};
|
|
31
33
|
},
|
|
32
34
|
mounted: function () {
|
|
@@ -39,6 +41,9 @@ export default {
|
|
|
39
41
|
});
|
|
40
42
|
},
|
|
41
43
|
methods: {
|
|
44
|
+
findRealFilename: function(objectURL) {
|
|
45
|
+
return this.filesMapping[objectURL]
|
|
46
|
+
},
|
|
42
47
|
processTextureFile: function(textureData, flatarray) {
|
|
43
48
|
if (textureData && textureData.images && textureData.images.source) {
|
|
44
49
|
const images = textureData.images.source;
|
|
@@ -50,6 +55,7 @@ export default {
|
|
|
50
55
|
const objectURL = URL.createObjectURL(flatarray[index][1]);
|
|
51
56
|
this.objectURLs.push(objectURL);
|
|
52
57
|
textureData.images.source[i] = objectURL;
|
|
58
|
+
this.filesMapping[objectURL] = images[i];
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
const content = JSON.stringify(textureData);
|
|
@@ -65,6 +71,7 @@ export default {
|
|
|
65
71
|
const re = new RegExp(key, "g");
|
|
66
72
|
content = content.replace(re, objectURL);
|
|
67
73
|
this.objectURLs.push(objectURL);
|
|
74
|
+
this.filesMapping[objectURL] = key;
|
|
68
75
|
}
|
|
69
76
|
}
|
|
70
77
|
const data = JSON.parse(content);
|
|
@@ -93,7 +100,8 @@ export default {
|
|
|
93
100
|
},
|
|
94
101
|
revokeURLs: function () {
|
|
95
102
|
this.objectURLs.forEach(objectURL => URL.revokeObjectURL(objectURL));
|
|
96
|
-
this.objectURLs =
|
|
103
|
+
this.objectURLs.length = 0;
|
|
104
|
+
this.filesMapping = markRaw({});
|
|
97
105
|
},
|
|
98
106
|
localDrop: function (fileMap) {
|
|
99
107
|
this.revokeURLs();
|
|
@@ -308,7 +308,7 @@
|
|
|
308
308
|
</template>
|
|
309
309
|
</div>
|
|
310
310
|
<el-row class="viewing-mode-description">
|
|
311
|
-
{{
|
|
311
|
+
{{ modeDescription }}
|
|
312
312
|
</el-row>
|
|
313
313
|
</el-row>
|
|
314
314
|
<el-row class="backgroundSpacer"></el-row>
|
|
@@ -805,7 +805,7 @@ export default {
|
|
|
805
805
|
viewingMode: "Exploration",
|
|
806
806
|
viewingModes: {
|
|
807
807
|
"Exploration": "View and explore detailed visualization of 3D scaffolds",
|
|
808
|
-
"Annotation":
|
|
808
|
+
"Annotation": ['View feature annotations', 'Add, comment on and view feature annotations'],
|
|
809
809
|
},
|
|
810
810
|
openMapRef: undefined,
|
|
811
811
|
backgroundIconRef: undefined,
|
|
@@ -918,24 +918,6 @@ export default {
|
|
|
918
918
|
}
|
|
919
919
|
this.previousMarkerLabels = markRaw({...labels});
|
|
920
920
|
},
|
|
921
|
-
annotationDisplay: function(value) {
|
|
922
|
-
if (this.annotationSidebar) {
|
|
923
|
-
if (value) {
|
|
924
|
-
const region = this.tData.region ? this.tData.region +"/" : "";
|
|
925
|
-
const annotationEntry = {
|
|
926
|
-
"featureId": region + this.tData.label,
|
|
927
|
-
"resourceId": this.url,
|
|
928
|
-
"resource": this.url,
|
|
929
|
-
};
|
|
930
|
-
this.$emit('annotation-open', {annotationEntry: annotationEntry,
|
|
931
|
-
commitCallback: this.commitAnnotationEvent});
|
|
932
|
-
} else {
|
|
933
|
-
if (!this.createData.toBeConfirmed || !this.createData.toBeDeleted) {
|
|
934
|
-
this.$emit("annotation-close");
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
921
|
},
|
|
940
922
|
beforeCreate: function () {
|
|
941
923
|
this.$module = new OrgansViewer();
|
|
@@ -977,7 +959,17 @@ export default {
|
|
|
977
959
|
annotationDisplay: function() {
|
|
978
960
|
return this.viewingMode === 'Annotation' && this.tData.active === true &&
|
|
979
961
|
(this.activeDrawMode !== "Point" && this.activeDrawMode !== 'LineString');
|
|
980
|
-
}
|
|
962
|
+
},
|
|
963
|
+
modeDescription: function () {
|
|
964
|
+
let description = this.viewingModes[this.viewingMode];
|
|
965
|
+
if (this.viewingMode === 'Annotation') {
|
|
966
|
+
if (this.userInformation) {
|
|
967
|
+
return description[1]
|
|
968
|
+
}
|
|
969
|
+
return description[0]
|
|
970
|
+
};
|
|
971
|
+
return description;
|
|
972
|
+
},
|
|
981
973
|
},
|
|
982
974
|
methods: {
|
|
983
975
|
/**
|
|
@@ -1337,6 +1329,7 @@ export default {
|
|
|
1337
1329
|
this.createData.shape = '';
|
|
1338
1330
|
this.$module.selectObjectOnPick = true;
|
|
1339
1331
|
} else if (type === 'tool') {
|
|
1332
|
+
if (this.annotationDisplay) return;
|
|
1340
1333
|
this.activeDrawTool = icon;
|
|
1341
1334
|
this.createData.shape = this.activeDrawTool ? this.activeDrawTool : '';
|
|
1342
1335
|
this.$module.selectObjectOnPick = false;
|
|
@@ -2209,6 +2202,11 @@ export default {
|
|
|
2209
2202
|
}
|
|
2210
2203
|
}
|
|
2211
2204
|
},
|
|
2205
|
+
downloadErrorCallback: function() {
|
|
2206
|
+
return (error) => {
|
|
2207
|
+
this.$emit('on-error', error);
|
|
2208
|
+
}
|
|
2209
|
+
},
|
|
2212
2210
|
setURLFinishCallback: function (options) {
|
|
2213
2211
|
return () => {
|
|
2214
2212
|
this.localAnnotationsList.length = 0;
|
|
@@ -2368,6 +2366,9 @@ export default {
|
|
|
2368
2366
|
this.isReady = false;
|
|
2369
2367
|
this.$_searchIndex.removeAll();
|
|
2370
2368
|
this.hideRegionTooltip();
|
|
2369
|
+
this.$module.setDownloadErrorCallback(
|
|
2370
|
+
this.downloadErrorCallback()
|
|
2371
|
+
);
|
|
2371
2372
|
this.$module.setFinishDownloadCallback(
|
|
2372
2373
|
this.setURLFinishCallback({
|
|
2373
2374
|
background: state?.background,
|
|
@@ -40,6 +40,7 @@ const OrgansSceneData = function() {
|
|
|
40
40
|
const organPartAddedCallbacks = new Array();
|
|
41
41
|
const organPartRemovedCallbacks = new Array();
|
|
42
42
|
let finishDownloadCallback = undefined;
|
|
43
|
+
let downloadErrorCallback = undefined;
|
|
43
44
|
const modelsLoader = ModelsLoaderIn;
|
|
44
45
|
this.NDCCameraControl = undefined;
|
|
45
46
|
_this.typeName = "Organ Viewer";
|
|
@@ -187,6 +188,16 @@ const OrgansSceneData = function() {
|
|
|
187
188
|
finishDownloadCallback = undefined;
|
|
188
189
|
}
|
|
189
190
|
|
|
191
|
+
|
|
192
|
+
this.setDownloadErrorCallback = function(callback) {
|
|
193
|
+
if (typeof(callback === "function"))
|
|
194
|
+
downloadErrorCallback = callback;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
this.unsetDownloadErrorCallback = function() {
|
|
198
|
+
downloadErrorCallback = undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
190
201
|
this.getNamedObjectsToScreenCoordinates = function(name, camera) {
|
|
191
202
|
const vector = new THREE.Vector3();
|
|
192
203
|
vector.setFromMatrixPosition( obj.matrixWorld );
|
|
@@ -435,11 +446,22 @@ const OrgansSceneData = function() {
|
|
|
435
446
|
finishDownloadCallback();
|
|
436
447
|
}
|
|
437
448
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
449
|
+
|
|
450
|
+
//The payload can either be a zinc object when the loading is successful or
|
|
451
|
+
//an object containg the details of error message on failure.
|
|
452
|
+
//We only use it to handle an error
|
|
453
|
+
const singleItemFinishCallback = function() {
|
|
454
|
+
return function(payload) {
|
|
455
|
+
|
|
456
|
+
if (payload?.type === "Error") {
|
|
457
|
+
if (downloadErrorCallback) {
|
|
458
|
+
const error = {
|
|
459
|
+
xhr: payload.xhr,
|
|
460
|
+
type: "download-error",
|
|
461
|
+
};
|
|
462
|
+
downloadErrorCallback(error);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
443
465
|
}
|
|
444
466
|
}
|
|
445
467
|
|
|
@@ -549,7 +571,7 @@ const OrgansSceneData = function() {
|
|
|
549
571
|
_this.sceneData.metaURL = url;
|
|
550
572
|
organScene.addZincObjectAddedCallbacks(_addOrganPartCallback(systemName, partName, false));
|
|
551
573
|
organScene.addZincObjectRemovedCallbacks(_removeOrganPartCallback(undefined, partName, false));
|
|
552
|
-
organScene.loadMetadataURL(url,
|
|
574
|
+
organScene.loadMetadataURL(url, singleItemFinishCallback(), downloadCompletedCallback());
|
|
553
575
|
_this.scene = organScene;
|
|
554
576
|
_this.zincRenderer.setCurrentScene(organScene);
|
|
555
577
|
_this.graphicsHighlight.reset();
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import rootConfig from './vite.config.js'
|
|
3
|
+
import { nodePolyfills } from 'vite-plugin-node-polyfills'
|
|
4
|
+
import vue from '@vitejs/plugin-vue'
|
|
5
|
+
|
|
6
|
+
// defineWorkspace provides a nice type hinting DX
|
|
7
|
+
export default defineConfig((configEnv) => {
|
|
8
|
+
const config = rootConfig(configEnv);
|
|
9
|
+
config.css.extract = false
|
|
10
|
+
config.plugins.push(
|
|
11
|
+
nodePolyfills({
|
|
12
|
+
// To add only specific polyfills, add them here. If no option is passed, adds all polyfills
|
|
13
|
+
include: ['path']
|
|
14
|
+
})
|
|
15
|
+
);
|
|
16
|
+
// config.plugins.push(
|
|
17
|
+
// cssInjectedByJsPlugin()
|
|
18
|
+
// );
|
|
19
|
+
config.plugins[0] = vue({
|
|
20
|
+
template: {
|
|
21
|
+
compilerOptions: {
|
|
22
|
+
isCustomElement: (tag) => tag.includes('scaffoldvuer-wc')
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}),
|
|
26
|
+
config.build = {
|
|
27
|
+
lib: {
|
|
28
|
+
entry: './src/ScaffoldVuer-wc.js',
|
|
29
|
+
name: 'scaffoldvuer-wc',
|
|
30
|
+
// the proper extensions will be added
|
|
31
|
+
fileName: 'scaffoldvuer-wc'
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return config;
|
|
36
|
+
})
|