Browse Source

BoxShape3D transform

dsehnal 4 years ago
parent
commit
00cb783d4c
2 changed files with 68 additions and 1 deletions
  1. 3 1
      src/mol-plugin-state/transforms.ts
  2. 65 0
      src/mol-plugin-state/transforms/shape.ts

+ 3 - 1
src/mol-plugin-state/transforms.ts

@@ -9,13 +9,15 @@ import * as Misc from './transforms/misc';
 import * as Model from './transforms/model';
 import * as Volume from './transforms/volume';
 import * as Representation from './transforms/representation';
+import * as Shape from './transforms/shape';
 
 export const StateTransforms = {
     Data,
     Misc,
     Model,
     Volume,
-    Representation
+    Representation,
+    Shape
 };
 
 export type StateTransforms = typeof StateTransforms

+ 65 - 0
src/mol-plugin-state/transforms/shape.ts

@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
+import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder';
+import { BoxCage } from '../../mol-geo/primitive/box';
+import { Sphere3D } from '../../mol-math/geometry';
+import { Mat4, Vec3 } from '../../mol-math/linear-algebra';
+import { Shape } from '../../mol-model/shape';
+import { Task } from '../../mol-task';
+import { ColorNames } from '../../mol-util/color/names';
+import { ParamDefinition as PD } from '../../mol-util/param-definition';
+import { PluginStateObject as SO, PluginStateTransform } from '../objects';
+
+export { BoxShape3D };
+type BoxShape3D = typeof BoxShape3D
+const BoxShape3D = PluginStateTransform.BuiltIn({
+    name: 'box-shape-3d',
+    display: 'Box Shape',
+    from: SO.Root,
+    to: SO.Shape.Provider,
+    params: {
+        bottomLeft: PD.Vec3(Vec3()),
+        topRight: PD.Vec3(Vec3.create(1, 1, 1)),
+        radius: PD.Numeric(0.15, { min: 0.01, max: 4, step: 0.01 }),
+        color: PD.Color(ColorNames.red)
+    }
+})({
+    canAutoUpdate() {
+        return true;
+    },
+    apply({ params }) {
+        return Task.create('Shape Representation', async ctx => {
+            return new SO.Shape.Provider({
+                label: 'Box',
+                data: params,
+                params: Mesh.Params,
+                getShape: (_, data: typeof params) => {
+
+                    const diag = Vec3.sub(Vec3(), data.topRight, data.bottomLeft);
+                    const translateUnit = Mat4.fromTranslation(Mat4(), Vec3.create(0.5, 0.5, 0.5));
+                    const scale = Mat4.fromScaling(Mat4(), diag);
+                    const translate = Mat4.fromTranslation(Mat4(), data.bottomLeft);
+                    const transform = Mat4.mul3(Mat4(), translate, scale, translateUnit);
+
+                    // TODO: optimize
+                    const state = MeshBuilder.createState(256, 128);
+                    state.currentGroup = 1;
+                    MeshBuilder.addCage(state, transform, BoxCage(), data.radius, 2, 20);
+                    const mesh = MeshBuilder.getMesh(state);
+
+                    const center = Vec3.scaleAndAdd(Vec3(), data.bottomLeft, diag, 0.5);
+                    const radius = Vec3.distance(data.bottomLeft, center);
+                    mesh.setBoundingSphere(Sphere3D.create(center, radius));
+
+                    return Shape.create('Box', data, mesh, () => data.color, () => 1, () => 'Box');
+                },
+                geometryUtils: Mesh.Utils
+            }, { label: 'Box' });
+        });
+    }
+});