Skip to content
Snippets Groups Projects
Select Git revision
  • 1b904ee2c999c9349159835585e1b72fe07f5888
  • master default protected
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

single-async-queue.ts

Blame
  • structure-overpaint.ts 3.99 KiB
    /**
     * Copyright (c) 2019-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
     *
     * @author Alexander Rose <alexander.rose@weirdbyte.de>
     * @author David Sehnal <david.sehnal@gmail.com>
     */
    
    import { Structure, StructureElement } from '../../mol-model/structure';
    import { PluginStateObject } from '../../mol-plugin-state/objects';
    import { StateTransforms } from '../../mol-plugin-state/transforms';
    import { PluginContext } from '../../mol-plugin/context';
    import { StateBuilder, StateObjectCell, StateSelection, StateTransform } from '../../mol-state';
    import { Overpaint } from '../../mol-theme/overpaint';
    import { Color } from '../../mol-util/color';
    import { StructureComponentRef } from '../manager/structure/hierarchy-state';
    import { EmptyLoci, isEmptyLoci, Loci } from '../../mol-model/loci';
    
    type OverpaintEachReprCallback = (update: StateBuilder.Root, repr: StateObjectCell<PluginStateObject.Molecule.Structure.Representation3D, StateTransform<typeof StateTransforms.Representation.StructureRepresentation3D>>, overpaint?: StateObjectCell<any, StateTransform<typeof StateTransforms.Representation.OverpaintStructureRepresentation3DFromBundle>>) => Promise<void>
    const OverpaintManagerTag = 'overpaint-controls';
    
    export async function setStructureOverpaint(plugin: PluginContext, components: StructureComponentRef[], color: Color | -1, lociGetter: (structure: Structure) => Promise<StructureElement.Loci | EmptyLoci>, types?: string[]) {
        await eachRepr(plugin, components, async (update, repr, overpaintCell) => {
            if (types && types.length > 0 && !types.includes(repr.params!.values.type.name)) return;
    
            const structure = repr.obj!.data.sourceData;
            // always use the root structure to get the loci so the overpaint
            // stays applicable as long as the root structure does not change
            const loci = await lociGetter(structure.root);
            if (Loci.isEmpty(loci) || isEmptyLoci(loci)) return;
    
            const layer = {
                bundle: StructureElement.Bundle.fromLoci(loci),
                color: color === -1 ? Color(0) : color,
                clear: color === -1
            };
    
            if (overpaintCell) {
                const bundleLayers = [...overpaintCell.params!.values.layers, layer];
                const filtered = getFilteredBundle(bundleLayers, structure);
                update.to(overpaintCell).update(Overpaint.toBundle(filtered));
            } else {
                const filtered = getFilteredBundle([layer], structure);
                update.to(repr.transform.ref)
                    .apply(StateTransforms.Representation.OverpaintStructureRepresentation3DFromBundle, Overpaint.toBundle(filtered), { tags: OverpaintManagerTag });
            }
        });
    }
    
    export async function clearStructureOverpaint(plugin: PluginContext, components: StructureComponentRef[], types?: string[]) {
        await eachRepr(plugin, components, async (update, repr, overpaintCell) => {
            if (types && types.length > 0 && !types.includes(repr.params!.values.type.name)) return;
            if (overpaintCell) {
                update.delete(overpaintCell.transform.ref);
            }
        });
    }
    
    async function eachRepr(plugin: PluginContext, components: StructureComponentRef[], callback: OverpaintEachReprCallback) {
        const state = plugin.state.data;
        const update = state.build();
        for (const c of components) {
            for (const r of c.representations) {
                const overpaint = state.select(StateSelection.Generators.ofTransformer(StateTransforms.Representation.OverpaintStructureRepresentation3DFromBundle, r.cell.transform.ref).withTag(OverpaintManagerTag));
                await callback(update, r.cell, overpaint[0]);
            }
        }
    
        return update.commit({ doNotUpdateCurrent: true });
    }
    
    /** filter overpaint layers for given structure */
    function getFilteredBundle(layers: Overpaint.BundleLayer[], structure: Structure) {
        const overpaint = Overpaint.ofBundle(layers, structure.root);
        const merged = Overpaint.merge(overpaint);
        return Overpaint.filter(merged, structure) as Overpaint<StructureElement.Loci>;
    }