Browse Source

ply, support for uniform coloring param

Alexander Rose 6 years ago
parent
commit
c6bf1c67b8
1 changed files with 49 additions and 40 deletions
  1. 49 40
      src/mol-model-formats/shape/ply.ts

+ 49 - 40
src/mol-model-formats/shape/ply.ts

@@ -16,6 +16,7 @@ import { ChunkedArray } from 'mol-data/util';
 import { arrayMax, fillSerial } from 'mol-util/array';
 import { Column } from 'mol-data/db';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
+import { ColorNames } from 'mol-util/color/tables';
 
 // TODO support 'edge' and 'material' elements, see https://www.mathworks.com/help/vision/ug/the-ply-format.html
 
@@ -67,19 +68,30 @@ function getGrouping(count: number, column?: Column<number>) {
 async function getShape(ctx: RuntimeContext, plyFile: PlyFile, props: PD.Values<PlyShapeParams>, shape?: Shape<Mesh>) {
     await ctx.update('async creation of shape from ply file')
 
-    const { vertexProperties: vp } = props
+    const { coloring, grouping } = props
 
     const vertex = plyFile.getElement('vertex') as PlyTable
     if (!vertex) throw new Error('missing vertex element')
 
-    const red = vertex.getProperty(vp.red) || Column.ofConst(127, vertex.rowCount, Column.Schema.int)
-    const green = vertex.getProperty(vp.green) || Column.ofConst(127, vertex.rowCount, Column.Schema.int)
-    const blue = vertex.getProperty(vp.blue) || Column.ofConst(127, vertex.rowCount, Column.Schema.int)
+    const { rowCount } = vertex
+    const int = Column.Schema.int
+
+    let red: Column<number>, green: Column<number>, blue: Column<number>
+    if (coloring.name === 'vertex') {
+        red = vertex.getProperty(coloring.params.red) || Column.ofConst(127, rowCount, int)
+        green = vertex.getProperty(coloring.params.green) || Column.ofConst(127, rowCount, int)
+        blue = vertex.getProperty(coloring.params.blue) || Column.ofConst(127, rowCount, int)
+    } else {
+        const [r, g, b] = Color.toRgb(coloring.params.color)
+        red = Column.ofConst(r, rowCount, int)
+        green = Column.ofConst(g, rowCount, int)
+        blue = Column.ofConst(b, rowCount, int)
+    }
 
     const face = plyFile.getElement('face') as PlyList
     if (!face) throw new Error('missing face element')
 
-    const { ids, map } = getGrouping(vertex.rowCount, vertex.getProperty(vp.group))
+    const { ids, map } = getGrouping(vertex.rowCount, grouping.name === 'vertex' ? vertex.getProperty(grouping.params.group) : undefined)
 
     const mesh = await getPlyMesh(ctx, vertex, face, ids, shape && shape.geometry)
     return Shape.create(
@@ -95,57 +107,54 @@ async function getShape(ctx: RuntimeContext, plyFile: PlyFile, props: PD.Values<
     )
 }
 
-export const PlyShapeParams = {
-    ...Mesh.Params,
-
-    vertexProperties: PD.Group({
-        group: PD.Select('' as string, [['', '']]),
-        red: PD.Select('' as string, [['', '']]),
-        green: PD.Select('' as string, [['', '']]),
-        blue: PD.Select('' as string, [['', '']]),
-    }, { isExpanded: true }),
-}
-export type PlyShapeParams = typeof PlyShapeParams
-
-function setGroupDefault<T>(group: PD.Group<any>, name: string, defaultValue: T) {
-    group.params[name].defaultValue = defaultValue
-    group.defaultValue.group = defaultValue
-}
-function setSelectOptions(select: PD.Select<string>, options: [string, string][]) {
-    select.options = options;
-}
-
-export function getPlyShapeParams(plyFile: PlyFile) {
-    const params = PD.clone(PlyShapeParams)
-    const vertex = plyFile.getElement('vertex') as PlyTable
+function createPlyShapeParams(vertex?: PlyTable) {
+    const options: [string, string][] = [['', '']]
+    const defaultValues = { group: '', red: '', green: '', blue: '' }
     if (vertex) {
-        const options: [string, string][] = [['', '']]
         for (let i = 0, il = vertex.propertyNames.length; i < il; ++i) {
             const name = vertex.propertyNames[i]
             options.push([ name, name ])
         }
-        const vp = params.vertexProperties;
-        setSelectOptions(vp.params.group as PD.Select<string>, options);
-        setSelectOptions(vp.params.red as PD.Select<string>, options);
-        setSelectOptions(vp.params.green as PD.Select<string>, options);
-        setSelectOptions(vp.params.blue as PD.Select<string>, options);
 
         // TODO harcoded as convenience for data provided by MegaMol
-        if (vertex.propertyNames.includes('atomid')) setGroupDefault(vp, 'group', 'atomid')
+        if (vertex.propertyNames.includes('atomid')) defaultValues.group = 'atomid'
+
+        if (vertex.propertyNames.includes('red')) defaultValues.red = 'red'
+        if (vertex.propertyNames.includes('green')) defaultValues.green = 'green'
+        if (vertex.propertyNames.includes('blue')) defaultValues.blue = 'blue'
+    }
 
-        if (vertex.propertyNames.includes('red')) setGroupDefault(vp, 'red', 'red')
-        if (vertex.propertyNames.includes('green')) setGroupDefault(vp, 'green', 'green')
-        if (vertex.propertyNames.includes('blue')) setGroupDefault(vp, 'blue', 'blue')
+    return {
+        ...Mesh.Params,
+
+        coloring: PD.MappedStatic(defaultValues.red && defaultValues.green && defaultValues.blue ? 'vertex' : 'uniform', {
+            vertex: PD.Group({
+                red: PD.Select(defaultValues.red, options, { label: 'Red Property' }),
+                green: PD.Select(defaultValues.green, options, { label: 'Green Property' }),
+                blue: PD.Select(defaultValues.blue, options, { label: 'Blue Property' }),
+            }, { isFlat: true }),
+            uniform: PD.Group({
+                color: PD.Color(ColorNames.grey)
+            }, { isFlat: true })
+        }),
+        grouping: PD.MappedStatic(defaultValues.group ? 'vertex' : 'none', {
+            vertex: PD.Group({
+                group: PD.Select(defaultValues.group, options, { label: 'Group Property' }),
+            }, { isFlat: true }),
+            none: PD.Group({ })
+        }),
     }
-    return params
 }
 
+export const PlyShapeParams = createPlyShapeParams()
+export type PlyShapeParams = typeof PlyShapeParams
+
 export function shapeFromPly(source: PlyFile, params?: {}) {
     return Task.create<ShapeProvider<PlyFile, Mesh, PlyShapeParams>>('Shape Provider', async ctx => {
         return {
             label: 'Mesh',
             data: source,
-            params: getPlyShapeParams(source),
+            params: createPlyShapeParams(source.getElement('vertex') as PlyTable),
             getShape,
             geometryUtils: Mesh.Utils
         }