@abi-software/scaffoldvuer 0.1.3 → 0.1.5-1.beta.2

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.
@@ -0,0 +1,261 @@
1
+ const THREE = require('zincjs').THREE;
2
+
3
+ /**
4
+ * Create a {@link Zinc.Renderer} on the dom element with corresponding elementID.
5
+ * @param {String} elementID - id of the target dom element.
6
+ * @returns {Zinc.Renderer}
7
+ */
8
+ const createRenderer = function () {
9
+ const WEBGL = require('./WebGL').WEBGL;
10
+ const localContainer = document.createElement( 'div' );
11
+ let localRenderer = undefined;;
12
+ localContainer.style.height = "100%";
13
+ if (WEBGL.isWebGLAvailable()) {
14
+ const Zinc = require('zincjs');
15
+ localRenderer = new Zinc.Renderer(localContainer, window);
16
+ Zinc.defaultMaterialColor = 0xFFFF9C;
17
+ localRenderer.initialiseVisualisation();
18
+ localRenderer.playAnimation = false;
19
+ } else {
20
+ const warning = WEBGL.getWebGLErrorMessage();
21
+ localContainer.appendChild(warning);
22
+ }
23
+ return {"renderer":localRenderer, "container":localContainer};
24
+ }
25
+
26
+ const RendererModule = function() {
27
+ (require('./BaseModule').BaseModule).call(this);
28
+ this.scene = undefined;
29
+ this.rendererContainer = undefined;
30
+ this.displayArea = undefined;
31
+ this.graphicsHighlight = new (require("./graphicsHighlight").GraphicsHighlight)();
32
+ this.zincRenderer = null;
33
+ this.selectedScreenCoordinates = new THREE.Vector3();
34
+ this.selectedCenter = undefined;
35
+ }
36
+
37
+ RendererModule.prototype = Object.create((require('./BaseModule').BaseModule).prototype);
38
+
39
+ /**
40
+ * This function will get the the first intersected object with name or
41
+ * the first glyph object with name.
42
+ */
43
+ RendererModule.prototype.getIntersectedObject = function(intersects) {
44
+ if (intersects) {
45
+ for (let i = 0; i < intersects.length; i++) {
46
+ if (intersects[i] !== undefined) {
47
+ if (intersects[i].object &&
48
+ intersects[i].object.userData &&
49
+ intersects[i].object.userData.isZincObject &&
50
+ (intersects[i].object.name ||
51
+ intersects[i].object.userData.isMarker))
52
+ return intersects[i];
53
+ }
54
+ }
55
+ }
56
+ return undefined;
57
+ }
58
+
59
+ RendererModule.prototype.getAnnotationsFromObjects = function(objects) {
60
+ const annotations = [];
61
+ for (var i = 0; i < objects.length; i++) {
62
+ const zincObject = objects[i].userData;
63
+ let annotation = undefined;
64
+ if (zincObject) {
65
+ if (zincObject.isGlyph || zincObject.isGlyphset) {
66
+ const glyphset = zincObject;
67
+ if (zincObject.isGlyph)
68
+ glyphset = zincObject.getGlyphset();
69
+ annotation = glyphset.userData ? glyphset.userData[0] : undefined;
70
+ if (annotation && annotation.data) {
71
+ if (objects[i].name && objects[i].name != "")
72
+ annotation.data.id = objects[i].name;
73
+ else
74
+ annotation.data.id = glyphset.groupName;
75
+ }
76
+ } else {
77
+ annotation = zincObject.userData ? zincObject.userData[0] : undefined;
78
+ if (annotation && annotation.data){
79
+ annotation.data.id = objects[i].name;
80
+ }
81
+ }
82
+ }
83
+ annotations[i] = annotation;
84
+ }
85
+ return annotations;
86
+ }
87
+
88
+ RendererModule.prototype.setHighlightedByObjects = function(objects, propagateChanges) {
89
+ const changed = this.graphicsHighlight.setHighlighted(objects);
90
+ if (changed && propagateChanges) {
91
+ const eventType = require("./eventNotifier").EVENT_TYPE.HIGHLIGHTED;
92
+ const annotations = this.getAnnotationsFromObjects(objects);
93
+ this.publishChanges(annotations, eventType);
94
+ }
95
+ return changed;
96
+ }
97
+
98
+
99
+ RendererModule.prototype.setHighlightedByZincObject = function(
100
+ zincObject, propagateChanges) {
101
+ return this.setHighlightedByObjects([zincObject ? zincObject.morph : undefined], propagateChanges);
102
+ }
103
+
104
+ RendererModule.prototype.setupLiveCoordinates = function(zincObjects) {
105
+ if (zincObjects && (zincObjects.length > 0)) {
106
+ const boundingBox = this.scene.getBoundingBoxOfZincObjects(zincObjects);
107
+ let newSelectedCenter = new THREE.Vector3();
108
+ boundingBox.getCenter(newSelectedCenter);
109
+ if (this.selectedCenter == undefined)
110
+ this.selectedCenter = newSelectedCenter;
111
+ else {
112
+ this.selectedCenter.x = newSelectedCenter.x;
113
+ this.selectedCenter.y = newSelectedCenter.y;
114
+ }
115
+ } else {
116
+ this.selectedCenter = undefined;
117
+ }
118
+ }
119
+
120
+ RendererModule.prototype.objectsToZincObjects = function(objects) {
121
+ const zincObjects = [];
122
+ for (let i = 0; i < objects.length; i++) {
123
+ let zincObject = objects[i].userData;
124
+ if (zincObject) {
125
+ if (zincObject.isGlyph || zincObject.isGlyphset) {
126
+ let glyphset = zincObject;
127
+ if (zincObject.isGlyph)
128
+ glyphset = zincObject.getGlyphset();
129
+ zincObjects. push(glyphset);
130
+ } else {
131
+ zincObjects. push(zincObject);
132
+ }
133
+ }
134
+ }
135
+ return zincObjects;
136
+ }
137
+
138
+
139
+ RendererModule.prototype.setSelectedByObjects = function(
140
+ objects, propagateChanges) {
141
+ const changed = this.graphicsHighlight.setSelected(objects);
142
+ if (changed) {
143
+ const zincObjects = this.objectsToZincObjects(objects);
144
+ this.setupLiveCoordinates(zincObjects);
145
+ if (propagateChanges) {
146
+ const eventType = require("./eventNotifier").EVENT_TYPE.SELECTED;
147
+ const annotations = this.getAnnotationsFromObjects(objects);
148
+ this.publishChanges(annotations, eventType);
149
+ }
150
+ }
151
+ return changed;
152
+ }
153
+
154
+ RendererModule.prototype.setSelectedByZincObject = function(
155
+ zincObject, propagateChanges) {
156
+ return this.setSelectedByObjects([zincObject ? zincObject.morph : undefined], propagateChanges);
157
+ }
158
+
159
+ const addGlyphToArray = function(objects) {
160
+ return function(glyph) {
161
+ objects.push(glyph.getMesh());
162
+ }
163
+ }
164
+
165
+ RendererModule.prototype.findObjectsByGroupName = function(groupName) {
166
+ const geometries = this.scene.findGeometriesWithGroupName(groupName);
167
+ const objects = [];
168
+ for (let i = 0; i < geometries.length; i ++ ) {
169
+ objects.push(geometries[i].morph);
170
+ }
171
+ const glyphsets = this.scene.findGlyphsetsWithGroupName(groupName);
172
+ for (let i = 0; i < glyphsets.length; i ++ ) {
173
+ glyphsets[i].forEachGlyph(addGlyphToArray(objects));
174
+ }
175
+
176
+ return objects;
177
+ }
178
+
179
+ RendererModule.prototype.setHighlightedByGroupName = function(groupName, propagateChanges) {
180
+ const objects = this.findObjectsByGroupName(groupName);
181
+ return this.setHighlightedByObjects(objects, propagateChanges);
182
+ }
183
+
184
+ RendererModule.prototype.setSelectedByGroupName = function(groupName, propagateChanges) {
185
+ const objects = this.findObjectsByGroupName(groupName);
186
+ return this.setSelectedByObjects(objects, propagateChanges);
187
+ }
188
+
189
+ RendererModule.prototype.changeBackgroundColour = function(backgroundColourString) {
190
+ const colour = new THREE.Color(backgroundColourString);
191
+ if (this.zincRenderer) {
192
+ let internalRenderer = this.zincRenderer.getThreeJSRenderer();
193
+ internalRenderer.setClearColor( colour, 1 );
194
+ }
195
+ }
196
+
197
+ RendererModule.prototype.resetView = function() {
198
+ if (this.zincRenderer)
199
+ this.zincRenderer.resetView();
200
+ }
201
+
202
+ RendererModule.prototype.viewAll = function() {
203
+ if (this.zincRenderer)
204
+ this.zincRenderer.viewAll();
205
+ }
206
+
207
+ /**
208
+ * Start the animation and let the renderer to processs with
209
+ * time progression
210
+ */
211
+ RendererModule.prototype.playAnimation = function(flag) {
212
+ if (this.zincRenderer)
213
+ this.zincRenderer.playAnimation = flag;
214
+ }
215
+
216
+ /**
217
+ * Set the speed of playback
218
+ */
219
+ RendererModule.prototype.setPlayRate = function(value) {
220
+ if (this.zincRenderer)
221
+ this.zincRenderer.setPlayRate(value);
222
+ }
223
+
224
+ /**
225
+ * Get the speed of playback
226
+ */
227
+ RendererModule.prototype.getPlayRate = function(value) {
228
+ if (this.zincRenderer)
229
+ return this.zincRenderer.getPlayRate();
230
+ else
231
+ return 0.0;
232
+ }
233
+
234
+ /** Initialise everything in the renderer, including the 3D renderer,
235
+ * and picker for the 3D renderer.
236
+ *
237
+ */
238
+ RendererModule.prototype.initialiseRenderer = function(displayAreaIn) {
239
+ if (this.zincRenderer === undefined || this.rendererContainer === undefined) {
240
+ let returnedValue = createRenderer();
241
+ this.zincRenderer = returnedValue["renderer"];
242
+ this.rendererContainer = returnedValue["container"];
243
+ }
244
+ if (displayAreaIn) {
245
+ this.displayArea = displayAreaIn;
246
+ this.displayArea.appendChild( this.rendererContainer );
247
+ if (this.zincRenderer)
248
+ this.zincRenderer.animate();
249
+ }
250
+ }
251
+
252
+ RendererModule.prototype.destroy = function() {
253
+ if (this.zincRenderer) {
254
+ this.zincRenderer.dispose();
255
+ this.zincRenderer.getThreeJSRenderer().dispose();
256
+ this.zincRenderer = undefined;
257
+ }
258
+ (require('./BaseModule').BaseModule).prototype.destroy.call( this );
259
+ }
260
+
261
+ exports.RendererModule = RendererModule;
@@ -0,0 +1,94 @@
1
+ /**
2
+ * @author alteredq / http://alteredqualia.com/
3
+ * @author mr.doob / http://mrdoob.com/
4
+ */
5
+
6
+ exports.WEBGL = {
7
+
8
+ isWebGLAvailable: function () {
9
+
10
+ try {
11
+
12
+ var canvas = document.createElement( 'canvas' );
13
+ return !! ( window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ) );
14
+
15
+ } catch ( e ) {
16
+
17
+ return false;
18
+
19
+ }
20
+
21
+ },
22
+
23
+ isWebGL2Available: function () {
24
+
25
+ try {
26
+
27
+ var canvas = document.createElement( 'canvas' );
28
+ return !! ( window.WebGL2RenderingContext && canvas.getContext( 'webgl2' ) );
29
+
30
+ } catch ( e ) {
31
+
32
+ return false;
33
+
34
+ }
35
+
36
+ },
37
+
38
+ getWebGLErrorMessage: function () {
39
+
40
+ return this.getErrorMessage( 1 );
41
+
42
+ },
43
+
44
+ getWebGL2ErrorMessage: function () {
45
+
46
+ return this.getErrorMessage( 2 );
47
+
48
+ },
49
+
50
+ getErrorMessage: function ( version ) {
51
+
52
+ var names = {
53
+ 1: 'WebGL',
54
+ 2: 'WebGL 2'
55
+ };
56
+
57
+ var contexts = {
58
+ 1: window.WebGLRenderingContext,
59
+ 2: window.WebGL2RenderingContext
60
+ };
61
+
62
+ var message = 'This module requires <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#008">$1</a> support but your $0 does not seem to support it.';
63
+
64
+ var element = document.createElement( 'div' );
65
+ element.id = 'webglmessage';
66
+ element.style.fontFamily = 'monospace';
67
+ element.style.fontSize = '20px';
68
+ element.style.fontWeight = 'normal';
69
+ element.style.textAlign = 'center';
70
+ element.style.background = '#fff';
71
+ element.style.color = '#000';
72
+ element.style.padding = '1.5em';
73
+ element.style.width = '400px';
74
+ element.style.margin = '5em auto 0';
75
+
76
+ if ( contexts[ version ] ) {
77
+
78
+ message = message.replace( '$0', 'graphics card' );
79
+
80
+ } else {
81
+
82
+ message = message.replace( '$0', 'browser' );
83
+
84
+ }
85
+
86
+ message = message.replace( '$1', names[ version ] );
87
+
88
+ element.innerHTML = message;
89
+
90
+ return element;
91
+
92
+ }
93
+
94
+ };
@@ -0,0 +1,5 @@
1
+ exports.annotation = function() {
2
+ this.type = "anatomical";
3
+ this.data = undefined;
4
+ this.isAnnotation = true;
5
+ }
@@ -0,0 +1,65 @@
1
+ const EVENT_TYPE = { ALL: 0, SELECTED: 1, HIGHLIGHTED: 2 };
2
+
3
+ const SelectionEvent = function(eventTypeIn, identifiersIn) {
4
+ this.eventType = eventTypeIn;
5
+ this.identifiers = identifiersIn;
6
+ }
7
+
8
+ const returnFullID = function(sourceId) {
9
+ //return full annotations with all different name
10
+ }
11
+
12
+ const Subscription = function(subscriberIn, callbackIn, eventType) {
13
+ this.targetedID = [];
14
+ const subscriber = subscriberIn;
15
+ const callback = callbackIn;
16
+ this.targetEventType = eventType;
17
+ const _this = this;
18
+
19
+ if (eventType === undefined)
20
+ this.targetEventType = EVENT_TYPE.ALL;
21
+
22
+ this.getEventType = function() {
23
+ return eventType;
24
+ }
25
+
26
+ this.notify = function(source, eventType, ids) {
27
+ if (source !== subscriber && (_this.targetEventType === EVENT_TYPE.ALL ||
28
+ _this.targetEventType === eventType)) {
29
+ //should support different type of id e.g lyph, name, fmas...
30
+ //need a function that finds all relavant ids
31
+ const event = new SelectionEvent(eventType, ids);
32
+ callback(event);
33
+ }
34
+ }
35
+ }
36
+
37
+ exports.EventNotifier = function() {
38
+ const subscriptions = [];
39
+
40
+ this.publish = function(source, eventType, id) {
41
+ for (let i = 0; i < subscriptions.length;i++) {
42
+ subscriptions[i].notify(source, eventType, id);
43
+ }
44
+ }
45
+
46
+ this.subscribe = function(subscriber, callbackFunction, eventType) {
47
+ if (typeof callbackFunction === "function") {
48
+ const subscription = new Subscription(subscriber, callbackFunction, eventType);
49
+ subscriptions.push(subscription);
50
+ return subscription;
51
+ }
52
+ return undefined;
53
+ }
54
+
55
+ this.unsubscribe = function(subscription) {
56
+ for (let i = 0; i < subscriptions.length;i++) {
57
+ if (subscription === subscriptions[i]) {
58
+ subscriptions.splice(i, 1);
59
+ return;
60
+ }
61
+ }
62
+ }
63
+ }
64
+
65
+ exports.EVENT_TYPE = EVENT_TYPE;
@@ -0,0 +1,132 @@
1
+ var THREE = require('zincjs').THREE;
2
+
3
+ /**
4
+ * This module manages highlighted and selected objects in 3D modules.
5
+ *
6
+ * @class
7
+ * @returns {exports.GraphicsHighlight}
8
+ */
9
+ exports.GraphicsHighlight = function() {
10
+ let currentHighlightedObjects = [];
11
+ let currentSelectedObjects = [];
12
+ this.highlightColour = 0x0000FF;
13
+ this.selectColour = 0x00FF00;
14
+ this.originalColour = 0x000000;
15
+ const _this = this;
16
+
17
+ const isDifferent = function(array1, array2) {
18
+ if ((array1.length == 0) && (array2.length == 0))
19
+ return false;
20
+ for (let i = 0; i < array1.length; i++) {
21
+ let matched = false;
22
+ for (let j = 0; j < array2.length; j++) {
23
+ if (array1[i] === array2[j]) {
24
+ matched = true;
25
+ }
26
+ }
27
+ if (!matched)
28
+ return true;
29
+ }
30
+ for (let i = 0; i < array2.length; i++) {
31
+ let matched = false;
32
+ for (let j = 0; j < array1.length; j++) {
33
+ if (array2[i] === array1[j]) {
34
+ matched = true;
35
+ }
36
+ }
37
+ if (!matched)
38
+ return true;
39
+ }
40
+ return false;
41
+ }
42
+
43
+ const getUnmatchingObjects = function(objectsArray1, objectsArray2) {
44
+ const unmatchingObjects = [];
45
+ if (objectsArray2.length == 0)
46
+ return objectsArray1;
47
+ for (let i = 0; i < objectsArray1.length; i++) {
48
+ let matched = false;
49
+ for (let j = 0; j < objectsArray2.length; j++) {
50
+ if (objectsArray1[i] === objectsArray2[j]) {
51
+ matched = true;
52
+ }
53
+ }
54
+ if (!matched)
55
+ unmatchingObjects.push(objectsArray1[i]);
56
+ }
57
+ return unmatchingObjects;
58
+ }
59
+
60
+ this.setHighlighted = function(objects) {
61
+ const previousHighlightedObjects = currentHighlightedObjects;
62
+ _this.resetHighlighted();
63
+ // Selected object cannot be highlighted
64
+ const array = getUnmatchingObjects(objects, currentSelectedObjects);
65
+ const fullList = getFullListOfObjects(array);
66
+ for (let i = 0; i < fullList.length; i++) {
67
+ if (fullList[i] && fullList[i].material && fullList[i].material.emissive)
68
+ fullList[i].material.emissive.setHex(_this.highlightColour);
69
+ }
70
+ currentHighlightedObjects = array;
71
+ return isDifferent(currentHighlightedObjects, previousHighlightedObjects);
72
+ }
73
+
74
+ this.setSelected = function(objects) {
75
+ // first find highlighted object that are not selected
76
+ const previousHSelectedObjects = currentSelectedObjects;
77
+ const array = getUnmatchingObjects(currentHighlightedObjects, objects);
78
+ currentHighlightedObjects = array;
79
+ _this.resetSelected();
80
+ const fullList = getFullListOfObjects(objects);
81
+ for (let i = 0; i < fullList.length; i++) {
82
+ if (fullList[i] && fullList[i].material && fullList[i].material.emissive)
83
+ fullList[i].material.emissive.setHex(_this.selectColour);
84
+ }
85
+ currentSelectedObjects = objects;
86
+ return isDifferent(currentSelectedObjects, previousHSelectedObjects);
87
+ }
88
+
89
+ const getFullListOfObjects = function(objects) {
90
+ let fullList = [];
91
+ for (let i = 0; i < objects.length; i++) {
92
+ if (objects[i].material)
93
+ fullList.push(objects[i]);
94
+ }
95
+ return fullList;
96
+ }
97
+
98
+ this.resetHighlighted = function() {
99
+ const fullList = getFullListOfObjects(currentHighlightedObjects);
100
+ for (let i = 0; i < fullList.length; i++) {
101
+ if (fullList[i] && fullList[i].material) {
102
+ if (fullList[i].material.emissive)
103
+ fullList[i].material.emissive.setHex(_this.originalColour);
104
+ if (fullList[i].material.depthFunc)
105
+ fullList[i].material.depthFunc = THREE.LessEqualDepth;
106
+ }
107
+ }
108
+ currentHighlightedObjects = [];
109
+ }
110
+
111
+ this.resetSelected = function() {
112
+ const fullList = getFullListOfObjects(currentSelectedObjects);
113
+ for (let i = 0; i < fullList.length; i++) {
114
+ if (fullList[i] && fullList[i].material) {
115
+ if (fullList[i].material.emissive)
116
+ fullList[i].material.emissive.setHex(_this.originalColour);
117
+ if (fullList[i].material.depthFunc)
118
+ fullList[i].material.depthFunc = THREE.LessEqualDepth;
119
+ }
120
+ }
121
+ currentSelectedObjects = [];
122
+ }
123
+
124
+ this.getSelected = function() {
125
+ return currentSelectedObjects;
126
+ }
127
+
128
+ this.reset = function() {
129
+ _this.resetSelected();
130
+ _this.resetHighlighted();
131
+ }
132
+ }