dsehnal 3 роки тому
батько
коміт
9f953ef51c
1 змінених файлів з 47 додано та 36 видалено
  1. 47 36
      src/extensions/model-export/export.ts

+ 47 - 36
src/extensions/model-export/export.ts

@@ -14,52 +14,63 @@ import { zip } from '../../mol-util/zip/zip';
 
 export async function exportHierarchy(plugin: PluginContext, options?: { format?: 'cif' | 'bcif' }) {
     try {
-        await _exportHierarchy(plugin, options);
+        await plugin.runTask(_exportHierarchy(plugin, options), { useOverlay: true });
     } catch (e) {
         console.error(e);
         plugin.log.error(`Model export failed. See console for details.`);
     }
 }
 
-async function _exportHierarchy(plugin: PluginContext, options?: { format?: 'cif' | 'bcif' }) {
-    const format = options?.format ?? 'cif';
-    const { structures } = plugin.managers.structure.hierarchy.current;
+function _exportHierarchy(plugin: PluginContext, options?: { format?: 'cif' | 'bcif' }) {
+    return Task.create('Export', async ctx => {
+        await ctx.update({ message: 'Exporting...', isIndeterminate: true, canAbort: false });
 
-    const files: [name: string, data: string | Uint8Array][] = [];
-    const entryMap = new Map<string, number>();
+        const format = options?.format ?? 'cif';
+        const { structures } = plugin.managers.structure.hierarchy.current;
 
-    for (const _s of structures) {
-        const s = _s.transform?.cell.obj?.data ?? _s.cell.obj?.data;
-        if (!s) continue;
-        if (s.models.length > 1) {
-            plugin.log.warn(`[Export] Skipping ${_s.cell.obj?.label}: Multimodel exports not supported.`);
-            continue;
-        }
+        const files: [name: string, data: string | Uint8Array][] = [];
+        const entryMap = new Map<string, number>();
 
-        const name = entryMap.has(s.model.entryId)
-            ? `${s.model.entryId}_${entryMap.get(s.model.entryId)! + 1}.${format}`
-            : `${s.model.entryId}.${format}`;
-        entryMap.set(s.model.entryId, (entryMap.get(s.model.entryId) ?? 0) + 1);
-        files.push([name, to_mmCIF(s.model.entryId, s, format === 'bcif', { copyAllCategories: true })]);
-    }
+        for (const _s of structures) {
+            const s = _s.transform?.cell.obj?.data ?? _s.cell.obj?.data;
+            if (!s) continue;
+            if (s.models.length > 1) {
+                plugin.log.warn(`[Export] Skipping ${_s.cell.obj?.label}: Multimodel exports not supported.`);
+                continue;
+            }
+
+            const name = entryMap.has(s.model.entryId)
+                ? `${s.model.entryId}_${entryMap.get(s.model.entryId)! + 1}.${format}`
+                : `${s.model.entryId}.${format}`;
+            entryMap.set(s.model.entryId, (entryMap.get(s.model.entryId) ?? 0) + 1);
+
+            await ctx.update({ message: `Exporting ${s.model.entryId}...`, isIndeterminate: true, canAbort: false });
+            if (s.elementCount > 100000) {
+                // Give UI chance to update, only needed for larger structures.
+                await new Promise(res => setTimeout(res, 50));
+            }
+
+            files.push([name, to_mmCIF(s.model.entryId, s, format === 'bcif', { copyAllCategories: true })]);
+        }
 
-    if (files.length === 1) {
-        download(new Blob([files[0][1]]), files[0][0]);
-    } else if (files.length > 1) {
-        const zipData: Record<string, Uint8Array> = {};
-        for (const [fn, data] of files) {
-            if (data instanceof Uint8Array) {
-                zipData[fn] = data;
-            } else {
-                const bytes = new Uint8Array(utf8ByteCount(data));
-                utf8Write(bytes, 0, data);
-                zipData[fn] = bytes;
+        if (files.length === 1) {
+            download(new Blob([files[0][1]]), files[0][0]);
+        } else if (files.length > 1) {
+            const zipData: Record<string, Uint8Array> = {};
+            for (const [fn, data] of files) {
+                if (data instanceof Uint8Array) {
+                    zipData[fn] = data;
+                } else {
+                    const bytes = new Uint8Array(utf8ByteCount(data));
+                    utf8Write(bytes, 0, data);
+                    zipData[fn] = bytes;
+                }
             }
+            await ctx.update({ message: `Compressing Data...`, isIndeterminate: true, canAbort: false });
+            const buffer = await zip(ctx, zipData);
+            download(new Blob([new Uint8Array(buffer, 0, buffer.byteLength)]), `structures_${getFormattedTime()}.zip`);
         }
-        const task = Task.create('Export Models', async ctx => {
-            return zip(ctx, zipData);
-        });
-        const buffer = await plugin.runTask(task);
-        download(new Blob([new Uint8Array(buffer, 0, buffer.byteLength)]), `structures_${getFormattedTime()}.zip`);
-    }
+
+        plugin.log.info(`[Export] Done.`);
+    });
 }