controls.ts 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /**
  2. * Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Sukolsak Sakshuwong <sukolsak@stanford.edu>
  5. */
  6. import { getStyle } from '../../mol-gl/renderer';
  7. import { PluginComponent } from '../../mol-plugin-state/component';
  8. import { PluginContext } from '../../mol-plugin/context';
  9. import { Task } from '../../mol-task';
  10. import { PluginStateObject } from '../../mol-plugin-state/objects';
  11. import { StateSelection } from '../../mol-state';
  12. import { ParamDefinition as PD } from '../../mol-util/param-definition';
  13. import { SetUtils } from '../../mol-util/set';
  14. import { ObjExporter } from './obj-exporter';
  15. import { GlbExporter } from './glb-exporter';
  16. import { StlExporter } from './stl-exporter';
  17. export const GeometryParams = {
  18. format: PD.Select('glb', [
  19. ['glb', 'glTF 2.0 Binary (.glb)'],
  20. ['stl', 'Stl (.stl)'],
  21. ['obj', 'Wavefront (.obj)']
  22. ])
  23. };
  24. export class GeometryControls extends PluginComponent {
  25. readonly behaviors = {
  26. params: this.ev.behavior<PD.Values<typeof GeometryParams>>(PD.getDefaultValues(GeometryParams))
  27. }
  28. private getFilename() {
  29. const models = this.plugin.state.data.select(StateSelection.Generators.rootsOfType(PluginStateObject.Molecule.Model)).map(s => s.obj!.data);
  30. const uniqueIds = new Set<string>();
  31. models.forEach(m => uniqueIds.add(m.entryId.toUpperCase()));
  32. const idString = SetUtils.toArray(uniqueIds).join('-');
  33. return `${idString || 'molstar-model'}`;
  34. }
  35. exportGeometry() {
  36. const task = Task.create('Export Geometry', async ctx => {
  37. try {
  38. const renderObjects = this.plugin.canvas3d?.getRenderObjects()!;
  39. const filename = this.getFilename();
  40. let renderObjectExporter: ObjExporter | GlbExporter | StlExporter;
  41. switch (this.behaviors.params.value.format) {
  42. case 'obj':
  43. renderObjectExporter = new ObjExporter(filename);
  44. break;
  45. case 'glb':
  46. const style = getStyle(this.plugin.canvas3d?.props.renderer.style!);
  47. renderObjectExporter = new GlbExporter(style);
  48. break;
  49. case 'stl':
  50. renderObjectExporter = new StlExporter();
  51. break;
  52. default: throw new Error('Unsupported format.');
  53. }
  54. for (let i = 0, il = renderObjects.length; i < il; ++i) {
  55. await ctx.update({ message: `Exporting object ${i}/${il}` });
  56. await renderObjectExporter.add(renderObjects[i], this.plugin.canvas3d?.webgl!, ctx);
  57. }
  58. const blob = await renderObjectExporter.getBlob(ctx);
  59. return {
  60. blob,
  61. filename: filename + '.' + renderObjectExporter.fileExtension
  62. };
  63. } catch (e) {
  64. this.plugin.log.error('' + e);
  65. throw e;
  66. }
  67. });
  68. return this.plugin.runTask(task, { useOverlay: true });
  69. }
  70. constructor(private plugin: PluginContext) {
  71. super();
  72. }
  73. }