Skip to content
Snippets Groups Projects
Commit 1125c490 authored by Alexander Rose's avatar Alexander Rose
Browse files

fixed shape loci handling

was alwas marking the whole shape
parent a06169b8
No related branches found
No related tags found
No related merge requests found
/** /**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { StructureElement } from './structure' import { StructureElement } from './structure'
import { Link } from './structure/structure/unit/links' import { Link } from './structure/structure/unit/links'
import { Shape } from './shape/shape'; import { ShapeGroup } from './shape/shape';
/** A null value Location */ /** A null value Location */
export const NullLocation = { kind: 'null-location' as 'null-location' } export const NullLocation = { kind: 'null-location' as 'null-location' }
...@@ -15,4 +15,4 @@ export function isNullLocation(x: any): x is NullLocation { ...@@ -15,4 +15,4 @@ export function isNullLocation(x: any): x is NullLocation {
return !!x && x.kind === 'null-location'; return !!x && x.kind === 'null-location';
} }
export type Location = StructureElement | Link.Location | Shape.Location | NullLocation export type Location = StructureElement | Link.Location | ShapeGroup.Location | NullLocation
\ No newline at end of file \ No newline at end of file
/** /**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { StructureElement } from './structure' import { StructureElement } from './structure'
import { Link } from './structure/structure/unit/links' import { Link } from './structure/structure/unit/links'
import { Shape } from './shape'; import { Shape, ShapeGroup } from './shape';
import { Sphere3D } from 'mol-math/geometry'; import { Sphere3D } from 'mol-math/geometry';
import { CentroidHelper } from 'mol-math/geometry/centroid-helper'; import { CentroidHelper } from 'mol-math/geometry/centroid-helper';
import { Vec3 } from 'mol-math/linear-algebra'; import { Vec3 } from 'mol-math/linear-algebra';
...@@ -46,7 +46,7 @@ export function createDataLoci(data: any, tag: string, indices: OrderedSet<numbe ...@@ -46,7 +46,7 @@ export function createDataLoci(data: any, tag: string, indices: OrderedSet<numbe
export { Loci } export { Loci }
type Loci = StructureElement.Loci | Structure.Loci | Link.Loci | EveryLoci | EmptyLoci | DataLoci | Shape.Loci type Loci = StructureElement.Loci | Structure.Loci | Link.Loci | EveryLoci | EmptyLoci | DataLoci | Shape.Loci | ShapeGroup.Loci
namespace Loci { namespace Loci {
export function areEqual(lociA: Loci, lociB: Loci) { export function areEqual(lociA: Loci, lociB: Loci) {
...@@ -67,6 +67,9 @@ namespace Loci { ...@@ -67,6 +67,9 @@ namespace Loci {
if (Shape.isLoci(lociA) && Shape.isLoci(lociB)) { if (Shape.isLoci(lociA) && Shape.isLoci(lociB)) {
return Shape.areLociEqual(lociA, lociB) return Shape.areLociEqual(lociA, lociB)
} }
if (ShapeGroup.isLoci(lociA) && ShapeGroup.isLoci(lociB)) {
return ShapeGroup.areLociEqual(lociA, lociB)
}
return false return false
} }
...@@ -96,6 +99,9 @@ namespace Loci { ...@@ -96,6 +99,9 @@ namespace Loci {
e.aUnit.conformation.position(e.bUnit.elements[e.bIndex], tempPos); e.aUnit.conformation.position(e.bUnit.elements[e.bIndex], tempPos);
sphereHelper.radiusStep(tempPos); sphereHelper.radiusStep(tempPos);
} }
} else if (loci.kind === 'shape-loci') {
// TODO
return void 0;
} else if (loci.kind === 'group-loci') { } else if (loci.kind === 'group-loci') {
// TODO // TODO
return void 0; return void 0;
......
/** /**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
...@@ -43,6 +43,13 @@ export namespace Shape { ...@@ -43,6 +43,13 @@ export namespace Shape {
} }
} }
export interface Loci { readonly kind: 'shape-loci', readonly shape: Shape }
export function Loci(shape: Shape): Loci { return { kind: 'shape-loci', shape } }
export function isLoci(x: any): x is Loci { return !!x && x.kind === 'shape-loci' }
export function areLociEqual(a: Loci, b: Loci) { return a.shape === b.shape }
}
export namespace ShapeGroup {
export interface Location { export interface Location {
readonly kind: 'group-location' readonly kind: 'group-location'
shape: Shape shape: Shape
......
...@@ -9,7 +9,7 @@ import { createRenderObject, GraphicsRenderObject } from 'mol-gl/render-object'; ...@@ -9,7 +9,7 @@ import { createRenderObject, GraphicsRenderObject } from 'mol-gl/render-object';
import { Representation } from '../representation'; import { Representation } from '../representation';
import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci'; import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci';
import { ValueCell } from 'mol-util'; import { ValueCell } from 'mol-util';
import { Shape } from 'mol-model/shape'; import { Shape, ShapeGroup } from 'mol-model/shape';
import { OrderedSet, Interval } from 'mol-data/int'; import { OrderedSet, Interval } from 'mol-data/int';
import { ParamDefinition as PD } from 'mol-util/param-definition'; import { ParamDefinition as PD } from 'mol-util/param-definition';
import { createTransform, TransformData } from 'mol-geo/geometry/transform-data'; import { createTransform, TransformData } from 'mol-geo/geometry/transform-data';
...@@ -170,7 +170,7 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa ...@@ -170,7 +170,7 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
getLoci(pickingId: PickingId) { getLoci(pickingId: PickingId) {
const { objectId, groupId, instanceId } = pickingId const { objectId, groupId, instanceId } = pickingId
if (_renderObject && _renderObject.id === objectId) { if (_renderObject && _renderObject.id === objectId) {
return Shape.Loci(_shape, [{ ids: OrderedSet.ofSingleton(groupId) }], instanceId) return ShapeGroup.Loci(_shape, [{ ids: OrderedSet.ofSingleton(groupId) }], instanceId)
} }
return EmptyLoci return EmptyLoci
}, },
...@@ -210,7 +210,7 @@ function createShapeTransform(transforms: Mat4[], transformData?: TransformData) ...@@ -210,7 +210,7 @@ function createShapeTransform(transforms: Mat4[], transformData?: TransformData)
} }
function eachShapeGroup(loci: Loci, shape: Shape, apply: (interval: Interval) => boolean) { function eachShapeGroup(loci: Loci, shape: Shape, apply: (interval: Interval) => boolean) {
if (!Shape.isLoci(loci)) return false if (!ShapeGroup.isLoci(loci)) return false
if (loci.shape !== shape) return false if (loci.shape !== shape) return false
let changed = false let changed = false
const { groupCount } = shape const { groupCount } = shape
...@@ -233,7 +233,7 @@ function eachShapeGroup(loci: Loci, shape: Shape, apply: (interval: Interval) => ...@@ -233,7 +233,7 @@ function eachShapeGroup(loci: Loci, shape: Shape, apply: (interval: Interval) =>
export namespace ShapeGroupIterator { export namespace ShapeGroupIterator {
export function fromShape(shape: Shape): LocationIterator { export function fromShape(shape: Shape): LocationIterator {
const instanceCount = shape.transforms.length const instanceCount = shape.transforms.length
const location = Shape.Location(shape) const location = ShapeGroup.Location(shape)
const getLocation = (groupIndex: number, instanceIndex: number) => { const getLocation = (groupIndex: number, instanceIndex: number) => {
location.group = groupIndex location.group = groupIndex
location.instance = instanceIndex location.instance = instanceIndex
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import { ColorTheme } from '../color'; import { ColorTheme } from '../color';
import { Color } from 'mol-util/color'; import { Color } from 'mol-util/color';
import { Location } from 'mol-model/location'; import { Location } from 'mol-model/location';
import { Shape } from 'mol-model/shape'; import { ShapeGroup } from 'mol-model/shape';
import { ParamDefinition as PD } from 'mol-util/param-definition' import { ParamDefinition as PD } from 'mol-util/param-definition'
import { ThemeDataContext } from 'mol-theme/theme'; import { ThemeDataContext } from 'mol-theme/theme';
...@@ -25,7 +25,7 @@ export function ShapeGroupColorTheme(ctx: ThemeDataContext, props: PD.Values<Sha ...@@ -25,7 +25,7 @@ export function ShapeGroupColorTheme(ctx: ThemeDataContext, props: PD.Values<Sha
factory: ShapeGroupColorTheme, factory: ShapeGroupColorTheme,
granularity: 'groupInstance', granularity: 'groupInstance',
color: (location: Location): Color => { color: (location: Location): Color => {
if (Shape.isLocation(location)) { if (ShapeGroup.isLocation(location)) {
return location.shape.getColor(location.group, location.instance) return location.shape.getColor(location.group, location.instance)
} }
return DefaultColor return DefaultColor
......
...@@ -33,6 +33,8 @@ export function labelFirst(loci: Loci): string { ...@@ -33,6 +33,8 @@ export function labelFirst(loci: Loci): string {
case 'link-loci': case 'link-loci':
const link = loci.links[0] const link = loci.links[0]
return link ? linkLabel(link) : 'Unknown' return link ? linkLabel(link) : 'Unknown'
case 'shape-loci':
return loci.shape.name
case 'group-loci': case 'group-loci':
const g = loci.groups[0] const g = loci.groups[0]
if (g) { if (g) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
import { Location } from 'mol-model/location'; import { Location } from 'mol-model/location';
import { Shape } from 'mol-model/shape'; import { ShapeGroup } from 'mol-model/shape';
import { ParamDefinition as PD } from 'mol-util/param-definition' import { ParamDefinition as PD } from 'mol-util/param-definition'
import { ThemeDataContext } from 'mol-theme/theme'; import { ThemeDataContext } from 'mol-theme/theme';
import { SizeTheme } from 'mol-theme/size'; import { SizeTheme } from 'mol-theme/size';
...@@ -24,7 +24,7 @@ export function ShapeGroupSizeTheme(ctx: ThemeDataContext, props: PD.Values<Shap ...@@ -24,7 +24,7 @@ export function ShapeGroupSizeTheme(ctx: ThemeDataContext, props: PD.Values<Shap
factory: ShapeGroupSizeTheme, factory: ShapeGroupSizeTheme,
granularity: 'groupInstance', granularity: 'groupInstance',
size: (location: Location): number => { size: (location: Location): number => {
if (Shape.isLocation(location)) { if (ShapeGroup.isLocation(location)) {
return location.shape.getSize(location.group, location.instance) return location.shape.getSize(location.group, location.instance)
} }
return DefaultSize return DefaultSize
......
...@@ -15,6 +15,9 @@ import { ColorNames } from 'mol-util/color/tables'; ...@@ -15,6 +15,9 @@ import { ColorNames } from 'mol-util/color/tables';
import { Mesh } from 'mol-geo/geometry/mesh/mesh'; import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { labelFirst } from 'mol-theme/label'; import { labelFirst } from 'mol-theme/label';
import { RuntimeContext, Progress } from 'mol-task'; import { RuntimeContext, Progress } from 'mol-task';
import { Representation } from 'mol-repr/representation';
import { MarkerAction } from 'mol-geo/geometry/marker-data';
import { EveryLoci } from 'mol-model/loci';
const parent = document.getElementById('app')! const parent = document.getElementById('app')!
parent.style.width = '100%' parent.style.width = '100%'
...@@ -34,14 +37,23 @@ info.style.right = '20px' ...@@ -34,14 +37,23 @@ info.style.right = '20px'
info.style.color = 'white' info.style.color = 'white'
parent.appendChild(info) parent.appendChild(info)
let prevReprLoci = Representation.Loci.Empty
const canvas3d = Canvas3D.create(canvas, parent) const canvas3d = Canvas3D.create(canvas, parent)
canvas3d.animate() canvas3d.animate()
canvas3d.input.move.subscribe(async ({x, y}) => { canvas3d.input.move.subscribe(async ({x, y}) => {
const pickingId = await canvas3d.identify(x, y) const pickingId = await canvas3d.identify(x, y)
let label = '' let label = ''
if (pickingId) { if (pickingId) {
const { loci } = canvas3d.getLoci(pickingId) const reprLoci = canvas3d.getLoci(pickingId)
label = labelFirst(loci) label = labelFirst(reprLoci.loci)
if (!Representation.Loci.areEqual(prevReprLoci, reprLoci)) {
canvas3d.mark(prevReprLoci, MarkerAction.RemoveHighlight)
canvas3d.mark(reprLoci, MarkerAction.Highlight)
prevReprLoci = reprLoci
}
} else {
canvas3d.mark({ loci: EveryLoci }, MarkerAction.RemoveHighlight)
prevReprLoci = Representation.Loci.Empty
} }
info.innerText = label info.innerText = label
}) })
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment