ソースを参照

Merge branch 'master' of https://github.com/molstar/molstar into forkdev

ludovic autin 3 年 前
コミット
53a4826274

+ 5 - 0
CHANGELOG.md

@@ -6,11 +6,16 @@ Note that since we don't clearly distinguish between a public and private interf
 
 ## [Unreleased]
 
+
+## [v2.2.3] - 2021-08-25
+
 - Add ``invertCantorPairing`` helper function
 - Add ``Mesh`` processing helper ``.smoothEdges``
 - Smooth border of molecular-surface with ``includeParent`` enabled
 - Hide ``includeParent`` option from gaussian-surface visuals (not particularly useful)
 - Improved ``StructureElement.Loci.size`` performance (for marking large cellpack models)
+- Fix new ``TransformData`` issues (camera/bounding helper not showing up)
+- Improve marking performance (avoid superfluous calls to ``StructureElement.Loci.isWholeStructure``)
 
 ## [v2.2.2] - 2021-08-11
 

+ 2 - 2
package-lock.json

@@ -1,11 +1,11 @@
 {
   "name": "molstar",
-  "version": "2.2.2",
+  "version": "2.2.3",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
-      "version": "2.2.2",
+      "version": "2.2.3",
       "license": "MIT",
       "dependencies": {
         "@types/argparse": "^1.0.38",

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "molstar",
-  "version": "2.2.2",
+  "version": "2.2.3",
   "description": "A comprehensive macromolecular library.",
   "homepage": "https://github.com/molstar/molstar#readme",
   "repository": {

+ 1 - 1
src/extensions/anvil/algorithm.ts

@@ -39,7 +39,7 @@ interface ANVILContext {
 };
 
 export const ANVILParams = {
-    numberOfSpherePoints: PD.Numeric(140, { min: 35, max: 700, step: 1 }, { description: 'Number of spheres/directions to test for membrane placement. Original value is 350.' }),
+    numberOfSpherePoints: PD.Numeric(175, { min: 35, max: 700, step: 1 }, { description: 'Number of spheres/directions to test for membrane placement. Original value is 350.' }),
     stepSize: PD.Numeric(1, { min: 0.25, max: 4, step: 0.25 }, { description: 'Thickness of membrane slices that will be tested' }),
     minThickness: PD.Numeric(20, { min: 10, max: 30, step: 1}, { description: 'Minimum membrane thickness used during refinement' }),
     maxThickness: PD.Numeric(40, { min: 30, max: 50, step: 1}, { description: 'Maximum membrane thickness used during refinement' }),

+ 1 - 1
src/mol-data/int/impl/interval.ts

@@ -16,7 +16,7 @@ export const start = Tuple.fst;
 export const end = Tuple.snd;
 export const min = Tuple.fst;
 export function max(i: Tuple) { return Tuple.snd(i) - 1; }
-export function size(i: Tuple) { return Tuple.snd(i) - Tuple.fst(i); }
+export const size = Tuple.diff;
 export const hashCode = Tuple.hashCode;
 export const toString = Tuple.toString;
 

+ 4 - 4
src/mol-geo/geometry/transform-data.ts

@@ -60,11 +60,8 @@ export function createTransform(transformArray: Float32Array, instanceCount: num
         ValueCell.update(transformData.aInstance, fillSerial(aInstance, instanceCount));
 
         ValueCell.update(transformData.hasReflection, hasReflection);
-
-        updateTransformData(transformData);
-        return transformData;
     } else {
-        return {
+        transformData = {
             aTransform: ValueCell.create(new Float32Array(instanceCount * 16)),
             matrix: ValueCell.create(Mat4.identity()),
             transform: ValueCell.create(new Float32Array(transformArray)),
@@ -75,6 +72,9 @@ export function createTransform(transformArray: Float32Array, instanceCount: num
             hasReflection: ValueCell.create(hasReflection),
         };
     }
+
+    updateTransformData(transformData);
+    return transformData;
 }
 
 const identityTransform = new Float32Array(16);

+ 7 - 4
src/mol-gl/compute/util.ts

@@ -6,11 +6,12 @@
 
 import { WebGLContext } from '../../mol-gl/webgl/context';
 import { Texture } from '../../mol-gl/webgl/texture';
-import { printTextureImage } from '../../mol-gl/renderable/util';
+import { PrintImageOptions, printTextureImage } from '../../mol-gl/renderable/util';
 import { defaults, ValueCell } from '../../mol-util';
 import { ValueSpec, AttributeSpec, UniformSpec, Values } from '../../mol-gl/renderable/schema';
 import { Vec2 } from '../../mol-math/linear-algebra';
 import { GLRenderingContext } from '../../mol-gl/webgl/compat';
+import { PixelData } from '../../mol-util/image';
 
 export const QuadPositions = new Float32Array([
     1.0,  1.0,  -1.0,  1.0,  -1.0, -1.0, // First triangle
@@ -41,7 +42,7 @@ function getArrayForTexture(gl: GLRenderingContext, texture: Texture, size: numb
     throw new Error('unknown/unsupported texture type');
 }
 
-export function readTexture(ctx: WebGLContext, texture: Texture, width?: number, height?: number) {
+export function readTexture(ctx: WebGLContext, texture: Texture, width?: number, height?: number): PixelData {
     const { gl, resources } = ctx;
     width = defaults(width, texture.getWidth());
     height = defaults(height, texture.getHeight());
@@ -55,6 +56,8 @@ export function readTexture(ctx: WebGLContext, texture: Texture, width?: number,
     return { array, width, height };
 }
 
-export function printTexture(ctx: WebGLContext, texture: Texture, scale: number) {
-    printTextureImage(readTexture(ctx, texture), scale);
+export function printTexture(ctx: WebGLContext, texture: Texture, options: Partial<PrintImageOptions> = {}) {
+    const pixelData = readTexture(ctx, texture);
+    PixelData.flipY(pixelData);
+    printTextureImage(pixelData, options);
 }

+ 39 - 13
src/mol-gl/renderable/util.ts

@@ -39,7 +39,15 @@ export function createTextureImage<T extends Uint8Array | Float32Array>(n: numbe
     return { array, width, height };
 }
 
-export function printTextureImage(textureImage: TextureImage<any>, scale = 1) {
+const DefaultPrintImageOptions = {
+    scale: 1,
+    pixelated: false,
+    id: 'molstar.debug.image'
+};
+export type PrintImageOptions = typeof DefaultPrintImageOptions
+
+export function printTextureImage(textureImage: TextureImage<any>, options: Partial<PrintImageOptions> = {}) {
+
     const { array, width, height } = textureImage;
     const itemSize = array.length / (width * height);
     const data = new Uint8ClampedArray(width * height * 4);
@@ -54,32 +62,50 @@ export function printTextureImage(textureImage: TextureImage<any>, scale = 1) {
     } else {
         console.warn(`itemSize '${itemSize}' not supported`);
     }
-    return printImageData(new ImageData(data, width, height), scale);
+    return printImageData(new ImageData(data, width, height), options);
 }
 
-export function printImageData(imageData: ImageData, scale = 1, pixelated = false) {
-    const canvas = document.createElement('canvas');
+let tmpCanvas: HTMLCanvasElement;
+let tmpCanvasCtx: CanvasRenderingContext2D;
+let tmpContainer: HTMLDivElement;
+
+export function printImageData(imageData: ImageData, options: Partial<PrintImageOptions> = {}) {
+    const o = { ...DefaultPrintImageOptions, ...options };
+    const canvas = tmpCanvas || document.createElement('canvas');
+    tmpCanvas = canvas;
     canvas.width = imageData.width;
     canvas.height = imageData.height;
-    const ctx = canvas.getContext('2d');
+    const ctx = tmpCanvasCtx || canvas.getContext('2d');
+    tmpCanvasCtx = ctx;
     if (!ctx) throw new Error('Could not create canvas 2d context');
     ctx.putImageData(imageData, 0, 0);
+
+    if (!tmpContainer) {
+        tmpContainer = document.createElement('div');
+        tmpContainer.style.position = 'absolute';
+        tmpContainer.style.bottom = '0px';
+        tmpContainer.style.right = '0px';
+        tmpContainer.style.border = 'solid orange';
+        tmpContainer.style.pointerEvents = 'none';
+        document.body.appendChild(tmpContainer);
+    }
+
     canvas.toBlob(imgBlob => {
-        const objectURL = window.URL.createObjectURL(imgBlob);
-        const img = document.createElement('img');
+        const objectURL = URL.createObjectURL(imgBlob);
+        const existingImg = document.getElementById(o.id) as HTMLImageElement;
+        const img = existingImg || document.createElement('img');
+        img.id = o.id;
         img.src = objectURL;
-        img.style.width = imageData.width * scale + 'px';
-        img.style.height = imageData.height * scale + 'px';
-        if (pixelated) {
+        img.style.width = imageData.width * o.scale + 'px';
+        img.style.height = imageData.height * o.scale + 'px';
+        if (o.pixelated) {
             // not supported in Firefox and IE
             img.style.imageRendering = 'pixelated';
         }
         img.style.position = 'relative';
-        img.style.top = '0px';
-        img.style.left = '0px';
         img.style.border = 'solid grey';
         img.style.pointerEvents = 'none';
-        document.body.appendChild(img);
+        if (!existingImg) tmpContainer.appendChild(img);
     }, 'image/png');
 }
 

+ 5 - 1
src/mol-repr/structure/complex-representation.ts

@@ -14,7 +14,7 @@ import { getNextMaterialId, GraphicsRenderObject } from '../../mol-gl/render-obj
 import { Theme } from '../../mol-theme/theme';
 import { Task } from '../../mol-task';
 import { PickingId } from '../../mol-geo/geometry/picking';
-import { EmptyLoci, Loci, isEveryLoci, isDataLoci } from '../../mol-model/loci';
+import { EmptyLoci, Loci, isEveryLoci, isDataLoci, EveryLoci } from '../../mol-model/loci';
 import { MarkerAction, MarkerActions } from '../../mol-util/marker-action';
 import { Overpaint } from '../../mol-theme/overpaint';
 import { StructureParams } from './params';
@@ -77,6 +77,10 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
             if (!Structure.areRootsEquivalent(loci.structure, _structure)) return false;
             // Remap `loci` from equivalent structure to the current `_structure`
             loci = Loci.remap(loci, _structure);
+            if (StructureElement.Loci.is(loci) && StructureElement.Loci.isWholeStructure(loci)) {
+                // Change to `EveryLoci` to allow for downstream optimizations
+                loci = EveryLoci;
+            }
         } else if (!isEveryLoci(loci) && !isDataLoci(loci)) {
             return false;
         }

+ 5 - 1
src/mol-repr/structure/units-representation.ts

@@ -15,7 +15,7 @@ import { getNextMaterialId, GraphicsRenderObject } from '../../mol-gl/render-obj
 import { Theme } from '../../mol-theme/theme';
 import { Task } from '../../mol-task';
 import { PickingId } from '../../mol-geo/geometry/picking';
-import { Loci, EmptyLoci, isEmptyLoci, isEveryLoci, isDataLoci } from '../../mol-model/loci';
+import { Loci, EmptyLoci, isEmptyLoci, isEveryLoci, isDataLoci, EveryLoci } from '../../mol-model/loci';
 import { MarkerAction, MarkerActions, applyMarkerAction } from '../../mol-util/marker-action';
 import { Overpaint } from '../../mol-theme/overpaint';
 import { Transparency } from '../../mol-theme/transparency';
@@ -196,6 +196,10 @@ export function UnitsRepresentation<P extends StructureParams>(label: string, ct
             if (!Structure.areRootsEquivalent(loci.structure, _structure)) return false;
             // Remap `loci` from equivalent structure to the current `_structure`
             loci = Loci.remap(loci, _structure);
+            if (StructureElement.Loci.is(loci) && StructureElement.Loci.isWholeStructure(loci)) {
+                // Change to `EveryLoci` to allow for downstream optimizations
+                loci = EveryLoci;
+            }
         } else if (!isEveryLoci(loci) && !isDataLoci(loci)) {
             return false;
         }

+ 4 - 3
src/mol-util/image.ts

@@ -7,13 +7,13 @@
 export { PixelData };
 
 interface PixelData {
-    readonly array: Uint8Array
+    readonly array: Uint8Array | Float32Array
     readonly width: number
     readonly height: number
 }
 
 namespace PixelData {
-    export function create(array: Uint8Array, width: number, height: number): PixelData {
+    export function create(array: Uint8Array | Float32Array, width: number, height: number): PixelData {
         return { array, width, height };
     }
 
@@ -36,8 +36,9 @@ namespace PixelData {
     /** to undo pre-multiplied alpha */
     export function divideByAlpha(pixelData: PixelData): PixelData {
         const { array } = pixelData;
+        const factor = (array instanceof Uint8Array) ? 255 : 1;
         for (let i = 0, il = array.length; i < il; i += 4) {
-            const a = array[i + 3] / 255;
+            const a = array[i + 3] / factor;
             array[i] /= a;
             array[i + 1] /= a;
             array[i + 2] /= a;

+ 1 - 1
src/tests/browser/font-atlas.ts

@@ -33,7 +33,7 @@ function test() {
     fontAtlas.get(String.fromCharCode(0x212B));
     console.timeEnd('Angstrom Sign');
 
-    printTextureImage(fontAtlas.texture, 0.5);
+    printTextureImage(fontAtlas.texture, { scale: 0.5 });
     console.log(`${Object.keys(fontAtlas.mapped).length} chars prepared`);
 }