mirror of
https://github.com/molstar/molstar.git
synced 2026-06-04 13:30:24 +08:00
Instance granularity improvements
- Add `instanceGranularity: 'auto'` as a memory guard - Honor `instanceGranularity` in `Visual.getLoci`
This commit is contained in:
@@ -5,6 +5,8 @@ Note that since we don't clearly distinguish between a public and private interf
|
||||
|
||||
## [Unreleased]
|
||||
- Fix empty transforms default in `ShapeFromPly`
|
||||
- Add `instanceGranularity: 'auto'` as a memory guard
|
||||
- Honor `instanceGranularity` in `Visual.getLoci`
|
||||
|
||||
## [v5.9.0] - 2026-05-03
|
||||
- Fix edge case when `PluginSpec.animations` is empty
|
||||
|
||||
@@ -72,6 +72,25 @@ export function getColorSmoothingProps(smoothColors: PD.Values<ColorSmoothingPar
|
||||
|
||||
//
|
||||
|
||||
export type InstanceGranularityValue = true | false | 'auto'
|
||||
export const InstanceGranularityOptions: [InstanceGranularityValue, string][] = [[true, 'On'], [false, 'Off'], ['auto', 'Auto']];
|
||||
|
||||
/**
|
||||
* Threshold (in `groupCount * instanceCount`, e.g. number of marker-texture
|
||||
* slots) above which `instanceGranularity: 'auto'` resolves to `true`.
|
||||
*/
|
||||
export const AutoInstanceGranularityThreshold = 50_000_000;
|
||||
|
||||
/**
|
||||
* Resolves the `instanceGranularity` param value to a boolean.
|
||||
*/
|
||||
export function resolveInstanceGranularity(value: InstanceGranularityValue, groupCount: number, instanceCount: number): boolean {
|
||||
if (value === 'auto') return groupCount * instanceCount > AutoInstanceGranularityThreshold;
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
export namespace BaseGeometry {
|
||||
export const MaterialCategory: PD.Info = { category: 'Material' };
|
||||
export const ShadingCategory: PD.Info = { category: 'Shading' };
|
||||
@@ -88,7 +107,7 @@ export namespace BaseGeometry {
|
||||
clip: PD.Group(Clip.Params),
|
||||
emissive: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }),
|
||||
density: PD.Numeric(0.2, { min: 0, max: 1, step: 0.01 }, { description: 'Density value to estimate object thickness.' }),
|
||||
instanceGranularity: PD.Boolean(false, { description: 'Use instance granularity for marker, transparency, clipping, overpaint, substance data to save memory.' }),
|
||||
instanceGranularity: PD.Select<InstanceGranularityValue>('auto', InstanceGranularityOptions, { description: 'Use instance granularity for marker, transparency, clipping, overpaint, substance data to save memory. When set to `auto`, granularity is enabled if `groupCount * instanceCount` exceeds `AutoInstanceGranularityThreshold`.' }),
|
||||
lod: PD.Vec3(Vec3(), undefined, { ...CullingLodCategory, description: 'Level of detail.', fieldLabels: { x: 'Min Distance', y: 'Max Distance', z: 'Overlap (Shader)' } }),
|
||||
cellSize: PD.Numeric(200, { min: 0, max: 5000, step: 100 }, { ...CullingLodCategory, description: 'Instance grid cell size.' }),
|
||||
batchSize: PD.Numeric(2000, { min: 0, max: 50000, step: 500 }, { ...CullingLodCategory, description: 'Instance grid batch size.' }),
|
||||
@@ -130,7 +149,7 @@ export namespace BaseGeometry {
|
||||
uClipObjectScale: ValueCell.create(clip.objects.scale),
|
||||
uClipObjectTransform: ValueCell.create(clip.objects.transform),
|
||||
|
||||
instanceGranularity: ValueCell.create(props.instanceGranularity),
|
||||
instanceGranularity: ValueCell.create(resolveInstanceGranularity(props.instanceGranularity, counts.groupCount, counts.instanceCount)),
|
||||
uLod: ValueCell.create(Vec4.create(props.lod[0], props.lod[1], props.lod[2], 0)),
|
||||
};
|
||||
}
|
||||
@@ -153,7 +172,7 @@ export namespace BaseGeometry {
|
||||
ValueCell.update(values.uClipObjectScale, clip.objects.scale);
|
||||
ValueCell.update(values.uClipObjectTransform, clip.objects.transform);
|
||||
|
||||
ValueCell.updateIfChanged(values.instanceGranularity, props.instanceGranularity);
|
||||
ValueCell.updateIfChanged(values.instanceGranularity, resolveInstanceGranularity(props.instanceGranularity, values.uGroupCount.ref.value, values.instanceCount.ref.value));
|
||||
ValueCell.update(values.uLod, Vec4.set(values.uLod.ref.value, props.lod[0], props.lod[1], props.lod[2], 0));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { calculateInvariantBoundingSphere, calculateTransformBoundingSphere } fr
|
||||
import { Sphere3D } from '../../../mol-math/geometry';
|
||||
import { Theme } from '../../../mol-theme/theme';
|
||||
import { Color } from '../../../mol-util/color';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createEmptyOverpaint } from '../overpaint-data';
|
||||
import { createEmptyTransparency } from '../transparency-data';
|
||||
import { hashFnv32a } from '../../../mol-data/util';
|
||||
@@ -225,7 +225,7 @@ export namespace Cylinders {
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const size = createSizes(locationIt, positionIt, theme.size);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -17,7 +17,7 @@ import { ValueCell } from '../../../mol-util';
|
||||
import { Color } from '../../../mol-util/color';
|
||||
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
|
||||
import { Box } from '../../primitive/box';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createColors } from '../color-data';
|
||||
import { GeometryUtils } from '../geometry';
|
||||
import { createMarkers } from '../marker-data';
|
||||
@@ -228,7 +228,7 @@ export namespace DirectVolume {
|
||||
const positionIt = createPositionIterator(directVolume, transform);
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -14,7 +14,7 @@ import { Theme } from '../../../mol-theme/theme';
|
||||
import { ValueCell } from '../../../mol-util';
|
||||
import { Color } from '../../../mol-util/color';
|
||||
import { ParamDefinition as PD } from '../../../mol-util/param-definition';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createColors } from '../color-data';
|
||||
import { GeometryUtils } from '../geometry';
|
||||
import { createMarkers } from '../marker-data';
|
||||
@@ -201,7 +201,7 @@ namespace Image {
|
||||
const positionIt = createPositionIterator(image, transform);
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -21,7 +21,7 @@ import { calculateInvariantBoundingSphere, calculateTransformBoundingSphere } fr
|
||||
import { Sphere3D } from '../../../mol-math/geometry';
|
||||
import { Theme } from '../../../mol-theme/theme';
|
||||
import { Color } from '../../../mol-util/color';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createEmptyOverpaint } from '../overpaint-data';
|
||||
import { createEmptyTransparency } from '../transparency-data';
|
||||
import { hashFnv32a } from '../../../mol-data/util';
|
||||
@@ -232,7 +232,7 @@ export namespace Lines {
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const size = createSizes(locationIt, positionIt, theme.size);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -20,7 +20,7 @@ import { calculateInvariantBoundingSphere, calculateTransformBoundingSphere } fr
|
||||
import { Theme } from '../../../mol-theme/theme';
|
||||
import { MeshValues } from '../../../mol-gl/renderable/mesh';
|
||||
import { Color } from '../../../mol-util/color';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createEmptyOverpaint } from '../overpaint-data';
|
||||
import { createEmptyTransparency } from '../transparency-data';
|
||||
import { createEmptyClipping } from '../clipping-data';
|
||||
@@ -684,7 +684,7 @@ export namespace Mesh {
|
||||
const positionIt = createPositionIterator(mesh, transform);
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -20,7 +20,7 @@ import { Theme } from '../../../mol-theme/theme';
|
||||
import { PointsValues } from '../../../mol-gl/renderable/points';
|
||||
import { RenderableState } from '../../../mol-gl/renderable';
|
||||
import { Color } from '../../../mol-util/color';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createEmptyOverpaint } from '../overpaint-data';
|
||||
import { createEmptyTransparency } from '../transparency-data';
|
||||
import { hashFnv32a } from '../../../mol-data/util';
|
||||
@@ -178,7 +178,7 @@ export namespace Points {
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const size = createSizes(locationIt, positionIt, theme.size);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -17,7 +17,7 @@ import { TextureImage, calculateInvariantBoundingSphere, calculateTransformBound
|
||||
import { Sphere3D } from '../../../mol-math/geometry';
|
||||
import { createSizes, getMaxSize } from '../size-data';
|
||||
import { Color } from '../../../mol-util/color';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createEmptyOverpaint } from '../overpaint-data';
|
||||
import { createEmptyTransparency } from '../transparency-data';
|
||||
import { hashFnv32a } from '../../../mol-data/util';
|
||||
@@ -314,7 +314,7 @@ export namespace Spheres {
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const size = createSizes(locationIt, positionIt, theme.size);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -25,7 +25,7 @@ import { FontAtlasParams } from './font-atlas';
|
||||
import { RenderableState } from '../../../mol-gl/renderable';
|
||||
import { clamp } from '../../../mol-math/interpolate';
|
||||
import { createRenderObject as _createRenderObject } from '../../../mol-gl/render-object';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createEmptyOverpaint } from '../overpaint-data';
|
||||
import { createEmptyTransparency } from '../transparency-data';
|
||||
import { hashFnv32a } from '../../../mol-data/util';
|
||||
@@ -219,7 +219,7 @@ export namespace Text {
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const size = createSizes(locationIt, positionIt, theme.size);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -15,7 +15,7 @@ import { createMarkers } from '../marker-data';
|
||||
import { GeometryUtils } from '../geometry';
|
||||
import { Theme } from '../../../mol-theme/theme';
|
||||
import { Color } from '../../../mol-util/color';
|
||||
import { BaseGeometry } from '../base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../base';
|
||||
import { createEmptyOverpaint } from '../overpaint-data';
|
||||
import { createEmptyTransparency } from '../transparency-data';
|
||||
import { TextureMeshValues } from '../../../mol-gl/renderable/texture-mesh';
|
||||
@@ -203,7 +203,7 @@ export namespace TextureMesh {
|
||||
const positionIt = Utils.createPositionIterator(textureMesh, transform);
|
||||
|
||||
const color = createColors(locationIt, positionIt, theme.color);
|
||||
const marker = props.instanceGranularity
|
||||
const marker = resolveInstanceGranularity(props.instanceGranularity, groupCount, instanceCount)
|
||||
? createMarkers(instanceCount, 'instance')
|
||||
: createMarkers(instanceCount * groupCount, 'groupInstance');
|
||||
const overpaint = createEmptyOverpaint();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import { Geometry, GeometryUtils } from '../../mol-geo/geometry/geometry';
|
||||
import { resolveInstanceGranularity } from '../../mol-geo/geometry/base';
|
||||
import { Representation } from '../representation';
|
||||
import { Shape, ShapeGroup } from '../../mol-model/shape';
|
||||
import { Subject } from 'rxjs';
|
||||
@@ -129,7 +130,7 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
|
||||
// console.log('update transform')
|
||||
locationIt = Shape.groupIterator(_shape);
|
||||
const { instanceCount, groupCount } = locationIt;
|
||||
if (props.instanceGranularity) {
|
||||
if (resolveInstanceGranularity(newProps.instanceGranularity, groupCount, instanceCount)) {
|
||||
createMarkers(instanceCount, 'instance', _renderObject.values);
|
||||
} else {
|
||||
createMarkers(instanceCount * groupCount, 'groupInstance', _renderObject.values);
|
||||
@@ -197,14 +198,15 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
|
||||
}
|
||||
|
||||
function lociApply(loci: Loci, apply: (interval: Interval) => boolean) {
|
||||
const instanceGranularity = resolveInstanceGranularity(currentProps.instanceGranularity, _shape.groupCount, _shape.transforms.length);
|
||||
if (isEveryLoci(loci) || (Shape.isLoci(loci) && loci.shape === _shape)) {
|
||||
if (currentProps.instanceGranularity) {
|
||||
if (instanceGranularity) {
|
||||
return apply(Interval.ofBounds(0, _shape.transforms.length));
|
||||
} else {
|
||||
return apply(Interval.ofBounds(0, _shape.groupCount * _shape.transforms.length));
|
||||
}
|
||||
} else {
|
||||
if (currentProps.instanceGranularity) {
|
||||
if (instanceGranularity) {
|
||||
return eachInstance(loci, _shape, apply);
|
||||
} else {
|
||||
return eachShapeGroup(loci, _shape, apply);
|
||||
@@ -226,7 +228,8 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
|
||||
getLoci(pickingId: PickingId) {
|
||||
const { objectId, groupId, instanceId } = pickingId;
|
||||
if (_renderObject && _renderObject.id === objectId) {
|
||||
if (groupId === PickingId.Null) {
|
||||
const instanceGranularity = resolveInstanceGranularity(currentProps.instanceGranularity, _shape.groupCount, _shape.transforms.length);
|
||||
if (groupId === PickingId.Null || instanceGranularity) {
|
||||
return Shape.Loci(_shape);
|
||||
} else {
|
||||
return ShapeGroup.Loci(_shape, [{ ids: OrderedSet.ofSingleton(groupId), instance: instanceId }]);
|
||||
|
||||
@@ -32,6 +32,7 @@ import { Text } from '../../mol-geo/geometry/text/text';
|
||||
import { SizeTheme } from '../../mol-theme/size';
|
||||
import { DirectVolume } from '../../mol-geo/geometry/direct-volume/direct-volume';
|
||||
import { createMarkers } from '../../mol-geo/geometry/marker-data';
|
||||
import { resolveInstanceGranularity } from '../../mol-geo/geometry/base';
|
||||
import { StructureParams, StructureMeshParams, StructureTextParams, StructureDirectVolumeParams, StructureLinesParams, StructureCylindersParams, StructureTextureMeshParams, StructureSpheresParams, StructurePointsParams, StructureImageParams } from './params';
|
||||
import { Clipping } from '../../mol-theme/clipping';
|
||||
import { TextureMesh } from '../../mol-geo/geometry/texture-mesh/texture-mesh';
|
||||
@@ -173,7 +174,7 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
|
||||
if (updateState.updateTransform) {
|
||||
// console.log('update transform')
|
||||
const { instanceCount, groupCount } = locationIt;
|
||||
if (newProps.instanceGranularity) {
|
||||
if (resolveInstanceGranularity(newProps.instanceGranularity, groupCount, instanceCount)) {
|
||||
createMarkers(instanceCount, 'instance', renderObject.values);
|
||||
} else {
|
||||
createMarkers(instanceCount * groupCount, 'groupInstance', renderObject.values);
|
||||
@@ -237,14 +238,15 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
|
||||
}
|
||||
|
||||
function lociApply(loci: Loci, apply: (interval: Interval) => boolean, isMarking: boolean) {
|
||||
const instanceGranularity = resolveInstanceGranularity(currentProps.instanceGranularity, locationIt.groupCount, locationIt.instanceCount);
|
||||
if (lociIsSuperset(loci)) {
|
||||
if (currentProps.instanceGranularity) {
|
||||
if (instanceGranularity) {
|
||||
return apply(Interval.ofBounds(0, locationIt.instanceCount));
|
||||
} else {
|
||||
return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount));
|
||||
}
|
||||
} else {
|
||||
if (currentProps.instanceGranularity) {
|
||||
if (instanceGranularity) {
|
||||
return eachInstance(loci, currentStructure, apply);
|
||||
} else {
|
||||
return eachLocation(loci, currentStructure, apply, isMarking);
|
||||
@@ -279,7 +281,11 @@ export function ComplexVisual<G extends Geometry, P extends StructureParams & Ge
|
||||
finalize(ctx);
|
||||
},
|
||||
getLoci(pickingId: PickingId) {
|
||||
return renderObject ? getLoci(pickingId, currentStructure, renderObject.id) : EmptyLoci;
|
||||
if (!renderObject) return EmptyLoci;
|
||||
if (resolveInstanceGranularity(currentProps.instanceGranularity, locationIt.groupCount, locationIt.instanceCount)) {
|
||||
pickingId = { ...pickingId, groupId: PickingId.Null };
|
||||
}
|
||||
return getLoci(pickingId, currentStructure, renderObject.id);
|
||||
},
|
||||
eachLocation(cb: LocationCallback) {
|
||||
locationIt.reset();
|
||||
|
||||
@@ -20,6 +20,7 @@ import { Interval } from '../../mol-data/int';
|
||||
import { LocationCallback, VisualUpdateState } from '../util';
|
||||
import { ColorTheme } from '../../mol-theme/color';
|
||||
import { createMarkers } from '../../mol-geo/geometry/marker-data';
|
||||
import { resolveInstanceGranularity } from '../../mol-geo/geometry/base';
|
||||
import { MarkerAction } from '../../mol-util/marker-action';
|
||||
import { ValueCell, deepEqual } from '../../mol-util';
|
||||
import { createSizes } from '../../mol-geo/geometry/size-data';
|
||||
@@ -214,7 +215,7 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
|
||||
if (updateState.updateTransform) {
|
||||
// console.log('update transform');
|
||||
const { instanceCount, groupCount } = locationIt;
|
||||
if (newProps.instanceGranularity) {
|
||||
if (resolveInstanceGranularity(newProps.instanceGranularity, groupCount, instanceCount)) {
|
||||
createMarkers(instanceCount, 'instance', renderObject.values);
|
||||
} else {
|
||||
createMarkers(instanceCount * groupCount, 'groupInstance', renderObject.values);
|
||||
@@ -313,14 +314,15 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
|
||||
}
|
||||
|
||||
function lociApply(loci: Loci, apply: (interval: Interval) => boolean, isMarking: boolean) {
|
||||
const instanceGranularity = resolveInstanceGranularity(currentProps.instanceGranularity, locationIt.groupCount, locationIt.instanceCount);
|
||||
if (lociIsSuperset(loci)) {
|
||||
if (currentProps.instanceGranularity) {
|
||||
if (instanceGranularity) {
|
||||
return apply(Interval.ofBounds(0, locationIt.instanceCount));
|
||||
} else {
|
||||
return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount));
|
||||
}
|
||||
} else {
|
||||
if (currentProps.instanceGranularity) {
|
||||
if (instanceGranularity) {
|
||||
return eachInstance(loci, currentStructureGroup, apply);
|
||||
} else {
|
||||
return eachLocation(loci, currentStructureGroup, apply, isMarking);
|
||||
@@ -355,7 +357,11 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
|
||||
finalize(ctx);
|
||||
},
|
||||
getLoci(pickingId: PickingId) {
|
||||
return renderObject ? getLoci(pickingId, currentStructureGroup, renderObject.id) : EmptyLoci;
|
||||
if (!renderObject) return EmptyLoci;
|
||||
if (resolveInstanceGranularity(currentProps.instanceGranularity, locationIt.groupCount, locationIt.instanceCount)) {
|
||||
pickingId = { ...pickingId, groupId: PickingId.Null };
|
||||
}
|
||||
return getLoci(pickingId, currentStructureGroup, renderObject.id);
|
||||
},
|
||||
eachLocation(cb: LocationCallback) {
|
||||
locationIt.reset();
|
||||
|
||||
@@ -33,7 +33,7 @@ import { Emissive } from '../../mol-theme/emissive';
|
||||
import { Wiggle } from '../../mol-theme/wiggle';
|
||||
import { SizeTheme } from '../../mol-theme/size';
|
||||
import { Sphere3D } from '../../mol-math/geometry/primitives/sphere3d';
|
||||
import { BaseGeometry } from '../../mol-geo/geometry/base';
|
||||
import { BaseGeometry, resolveInstanceGranularity } from '../../mol-geo/geometry/base';
|
||||
|
||||
export const VolumeParams = {
|
||||
...BaseGeometry.Params,
|
||||
@@ -182,7 +182,7 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
|
||||
if (updateState.updateTransform || updateState.updateLocation) {
|
||||
// console.log('update transform');
|
||||
const { instanceCount, groupCount } = locationIt;
|
||||
if (newProps.instanceGranularity) {
|
||||
if (resolveInstanceGranularity(newProps.instanceGranularity, groupCount, instanceCount)) {
|
||||
createMarkers(instanceCount, 'instance', renderObject.values);
|
||||
} else {
|
||||
createMarkers(instanceCount * groupCount, 'groupInstance', renderObject.values);
|
||||
@@ -279,14 +279,15 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
|
||||
}
|
||||
|
||||
function lociApply(loci: Loci, apply: (interval: Interval) => boolean) {
|
||||
const instanceGranularity = resolveInstanceGranularity(currentProps.instanceGranularity, locationIt.groupCount, locationIt.instanceCount);
|
||||
if (isEveryLoci(loci)) {
|
||||
if (currentProps.instanceGranularity) {
|
||||
if (instanceGranularity) {
|
||||
return apply(Interval.ofBounds(0, locationIt.instanceCount));
|
||||
} else {
|
||||
return apply(Interval.ofBounds(0, locationIt.groupCount * locationIt.instanceCount));
|
||||
}
|
||||
} else {
|
||||
if (currentProps.instanceGranularity) {
|
||||
if (instanceGranularity) {
|
||||
return eachInstance(loci, currentVolume, currentKey, apply);
|
||||
} else {
|
||||
return eachLocation(loci, currentVolume, currentKey, currentProps, apply, geometry);
|
||||
@@ -308,7 +309,11 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
|
||||
}
|
||||
},
|
||||
getLoci(pickingId: PickingId) {
|
||||
return renderObject ? getLoci(pickingId, currentVolume, currentKey, currentProps, renderObject.id, geometry) : EmptyLoci;
|
||||
if (!renderObject) return EmptyLoci;
|
||||
if (resolveInstanceGranularity(currentProps.instanceGranularity, locationIt.groupCount, locationIt.instanceCount)) {
|
||||
pickingId = { ...pickingId, groupId: PickingId.Null };
|
||||
}
|
||||
return getLoci(pickingId, currentVolume, currentKey, currentProps, renderObject.id, geometry);
|
||||
},
|
||||
eachLocation(cb: LocationCallback) {
|
||||
locationIt.reset();
|
||||
|
||||
Reference in New Issue
Block a user