Bläddra i källkod

fixed shape loci handling

was alwas marking the whole shape
Alexander Rose 6 år sedan
förälder
incheckning
1125c4905d

+ 3 - 3
src/mol-model/location.ts

@@ -1,12 +1,12 @@
 /**
- * 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>
  */
 
 import { StructureElement } from './structure'
 import { Link } from './structure/structure/unit/links'
-import { Shape } from './shape/shape';
+import { ShapeGroup } from './shape/shape';
 
 /** A null value Location */
 export const NullLocation = { kind: 'null-location' as 'null-location' }
@@ -15,4 +15,4 @@ export function isNullLocation(x: any): x is NullLocation {
     return !!x && x.kind === 'null-location';
 }
 
-export type Location = StructureElement | Link.Location | Shape.Location | NullLocation
+export type Location = StructureElement | Link.Location | ShapeGroup.Location | NullLocation

+ 9 - 3
src/mol-model/loci.ts

@@ -1,12 +1,12 @@
 /**
- * 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>
  */
 
 import { StructureElement } from './structure'
 import { Link } from './structure/structure/unit/links'
-import { Shape } from './shape';
+import { Shape, ShapeGroup } from './shape';
 import { Sphere3D } from 'mol-math/geometry';
 import { CentroidHelper } from 'mol-math/geometry/centroid-helper';
 import { Vec3 } from 'mol-math/linear-algebra';
@@ -46,7 +46,7 @@ export function createDataLoci(data: any, tag: string, indices: OrderedSet<numbe
 
 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 {
     export function areEqual(lociA: Loci, lociB: Loci) {
@@ -67,6 +67,9 @@ namespace Loci {
         if (Shape.isLoci(lociA) && Shape.isLoci(lociB)) {
             return Shape.areLociEqual(lociA, lociB)
         }
+        if (ShapeGroup.isLoci(lociA) && ShapeGroup.isLoci(lociB)) {
+            return ShapeGroup.areLociEqual(lociA, lociB)
+        }
         return false
     }
 
@@ -96,6 +99,9 @@ namespace Loci {
                 e.aUnit.conformation.position(e.bUnit.elements[e.bIndex], tempPos);
                 sphereHelper.radiusStep(tempPos);
             }
+        } else if (loci.kind === 'shape-loci') {
+            // TODO
+            return void 0;
         } else if (loci.kind === 'group-loci') {
             // TODO
             return void 0;

+ 8 - 1
src/mol-model/shape/shape.ts

@@ -1,5 +1,5 @@
 /**
- * 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>
  */
@@ -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 {
         readonly kind: 'group-location'
         shape: Shape

+ 4 - 4
src/mol-repr/shape/representation.ts

@@ -9,7 +9,7 @@ import { createRenderObject, GraphicsRenderObject } from 'mol-gl/render-object';
 import { Representation } from '../representation';
 import { Loci, EmptyLoci, isEveryLoci } from 'mol-model/loci';
 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 { ParamDefinition as PD } from 'mol-util/param-definition';
 import { createTransform, TransformData } from 'mol-geo/geometry/transform-data';
@@ -170,7 +170,7 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
         getLoci(pickingId: PickingId) {
             const { objectId, groupId, instanceId } = pickingId
             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
         },
@@ -210,7 +210,7 @@ function createShapeTransform(transforms: Mat4[], transformData?: TransformData)
 }
 
 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
     let changed = false
     const { groupCount } = shape
@@ -233,7 +233,7 @@ function eachShapeGroup(loci: Loci, shape: Shape, apply: (interval: Interval) =>
 export namespace ShapeGroupIterator {
     export function fromShape(shape: Shape): LocationIterator {
         const instanceCount = shape.transforms.length
-        const location = Shape.Location(shape)
+        const location = ShapeGroup.Location(shape)
         const getLocation = (groupIndex: number, instanceIndex: number) => {
             location.group = groupIndex
             location.instance = instanceIndex

+ 2 - 2
src/mol-theme/color/shape-group.ts

@@ -7,7 +7,7 @@
 import { ColorTheme } from '../color';
 import { Color } from 'mol-util/color';
 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 { ThemeDataContext } from 'mol-theme/theme';
 
@@ -25,7 +25,7 @@ export function ShapeGroupColorTheme(ctx: ThemeDataContext, props: PD.Values<Sha
         factory: ShapeGroupColorTheme,
         granularity: 'groupInstance',
         color: (location: Location): Color => {
-            if (Shape.isLocation(location)) {
+            if (ShapeGroup.isLocation(location)) {
                 return location.shape.getColor(location.group, location.instance)
             }
             return DefaultColor

+ 2 - 0
src/mol-theme/label.ts

@@ -33,6 +33,8 @@ export function labelFirst(loci: Loci): string {
         case 'link-loci':
             const link = loci.links[0]
             return link ? linkLabel(link) : 'Unknown'
+        case 'shape-loci':
+            return loci.shape.name
         case 'group-loci':
             const g = loci.groups[0]
             if (g) {

+ 2 - 2
src/mol-theme/size/shape-group.ts

@@ -5,7 +5,7 @@
  */
 
 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 { ThemeDataContext } from 'mol-theme/theme';
 import { SizeTheme } from 'mol-theme/size';
@@ -24,7 +24,7 @@ export function ShapeGroupSizeTheme(ctx: ThemeDataContext, props: PD.Values<Shap
         factory: ShapeGroupSizeTheme,
         granularity: 'groupInstance',
         size: (location: Location): number => {
-            if (Shape.isLocation(location)) {
+            if (ShapeGroup.isLocation(location)) {
                 return location.shape.getSize(location.group, location.instance)
             }
             return DefaultSize

+ 14 - 2
src/tests/browser/render-shape.ts

@@ -15,6 +15,9 @@ import { ColorNames } from 'mol-util/color/tables';
 import { Mesh } from 'mol-geo/geometry/mesh/mesh';
 import { labelFirst } from 'mol-theme/label';
 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')!
 parent.style.width = '100%'
@@ -34,14 +37,23 @@ info.style.right = '20px'
 info.style.color = 'white'
 parent.appendChild(info)
 
+let prevReprLoci = Representation.Loci.Empty
 const canvas3d = Canvas3D.create(canvas, parent)
 canvas3d.animate()
 canvas3d.input.move.subscribe(async ({x, y}) => {
     const pickingId = await canvas3d.identify(x, y)
     let label = ''
     if (pickingId) {
-        const { loci } = canvas3d.getLoci(pickingId)
-        label = labelFirst(loci)
+        const reprLoci = canvas3d.getLoci(pickingId)
+        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
 })