Browse Source

support for smoothing control points and direction vectors

Alexander Rose 6 years ago
parent
commit
5c0fd3df3d

+ 10 - 4
src/mol-geo/representation/structure/visual/polymer-trace-mesh.ts

@@ -160,7 +160,7 @@ async function createPolymerTraceMesh(ctx: RuntimeContext, unit: Unit, mesh?: Me
         //     Vec3.fromArray(normalVec, normalVectors, j * 3)
         //     Vec3.fromArray(binormalVec, binormalVectors, j * 3)
         //     Vec3.fromArray(tangentVec, tangentVectors, j * 3)
-        //     builder.addIcosahedron(controlPoint, 0.1, 1)
+        //     builder.addIcosahedron(controlPoint, 0.25, 1)
         //     builder.addCylinder(
         //         controlPoint,
         //         Vec3.add(tmp, controlPoint, normalVec),
@@ -181,18 +181,24 @@ async function createPolymerTraceMesh(ctx: RuntimeContext, unit: Unit, mesh?: Me
         //     )
         // }
 
+        // builder.addIcosahedron(v.t0, 0.25, 1)
+        // builder.addIcosahedron(v.t1, 0.25, 1)
+        // builder.addIcosahedron(v.t2, 0.25, 1)
+        // builder.addIcosahedron(v.t3, 0.25, 1)
+        // builder.addIcosahedron(v.t4, 0.25, 1)
+
         let width = 0.2
         let height = 0.2
         if (
             SecondaryStructureType.is(v.secStrucType, SecondaryStructureType.Flag.Beta) ||
             SecondaryStructureType.is(v.secStrucType, SecondaryStructureType.Flag.Helix)
         ) {
-            width = 0.2
-            height = 0.6
+            width = 0.1
+            height = 0.8
         }
 
         // TODO size theme
-        builder.addTube(controlPoints, normalVectors, binormalVectors, linearSegments, radialSegments, width, height)
+        builder.addTube(controlPoints, normalVectors, binormalVectors, linearSegments, radialSegments, width, height, 1)
 
         if (i % 10000 === 0 && ctx.shouldUpdate) {
             await ctx.update({ message: 'Polymer trace mesh', current: i, max: polymerElementCount });

+ 51 - 7
src/mol-geo/representation/structure/visual/util/polymer.ts

@@ -265,6 +265,19 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
     private state: AtomicPolymerTraceIteratorState = AtomicPolymerTraceIteratorState.nextPolymer
     private residueAtomSegments: Segmentation<ElementIndex, ResidueIndex>
 
+    private p0 = Vec3.zero();
+    private p1 = Vec3.zero();
+    private p2 = Vec3.zero();
+    private p3 = Vec3.zero();
+    private p4 = Vec3.zero();
+    private p5 = Vec3.zero();
+    private p6 = Vec3.zero();
+
+    private v01 = Vec3.zero();
+    private v12 = Vec3.zero();
+    private v23 = Vec3.zero();
+    private v34 = Vec3.zero();
+
     hasNext: boolean = false;
 
     private pos(target: Vec3, index: number) {
@@ -294,6 +307,24 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
         return elementIndex === -1 ? 0 as ElementIndex : elementIndex
     }
 
+    setControlPoint(out: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, residueIndex: number) {
+        const ss = this.unit.model.properties.secondaryStructure.type[residueIndex]
+        if (SecondaryStructureType.is(ss, SecondaryStructureType.Flag.Beta)) {
+            Vec3.scale(out, Vec3.add(out, p1, Vec3.add(out, p3, Vec3.add(out, p2, p2))), 1/4)
+        } else {
+            Vec3.copy(out, p2)
+        }
+    }
+
+    setDirectionVector(out: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, residueIndex: number) {
+        const ss = this.unit.model.properties.secondaryStructure.type[residueIndex]
+        if (SecondaryStructureType.is(ss, SecondaryStructureType.Flag.Beta)) {
+            Vec3.scale(out, Vec3.add(out, p1, Vec3.add(out, p2, p3)), 1/3)
+        } else {
+            Vec3.copy(out, p2)
+        }
+    }
+
     move() {
         const { residueIt, polymerIt, value } = this
 
@@ -313,17 +344,30 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
             const { index: residueIndex } = residueIt.move();
             value.center.element = this.getElementIndex(residueIndex, 'trace')
 
-            this.pos(value.t0, this.getAtomIndex(residueIndex - 2, 'trace'))
-            this.pos(value.t1, this.getAtomIndex(residueIndex - 1, 'trace'))
-            this.pos(value.t2, this.getAtomIndex(residueIndex, 'trace'))
-            this.pos(value.t3, this.getAtomIndex(residueIndex + 1, 'trace'))
-            this.pos(value.t4, this.getAtomIndex(residueIndex + 2, 'trace'))
+            this.pos(this.p0, this.getAtomIndex(residueIndex - 3, 'trace'))
+            this.pos(this.p1, this.getAtomIndex(residueIndex - 2, 'trace'))
+            this.pos(this.p2, this.getAtomIndex(residueIndex - 1, 'trace'))
+            this.pos(this.p3, this.getAtomIndex(residueIndex, 'trace'))
+            this.pos(this.p4, this.getAtomIndex(residueIndex + 1, 'trace'))
+            this.pos(this.p5, this.getAtomIndex(residueIndex + 2, 'trace'))
+            this.pos(this.p6, this.getAtomIndex(residueIndex + 3, 'trace'))
 
-            this.pos(value.d12, this.getAtomIndex(residueIndex - 1, 'direction'))
-            this.pos(value.d23, this.getAtomIndex(residueIndex, 'direction'))
+            this.pos(this.v01, this.getAtomIndex(residueIndex - 2, 'direction'))
+            this.pos(this.v12, this.getAtomIndex(residueIndex - 1, 'direction'))
+            this.pos(this.v23, this.getAtomIndex(residueIndex, 'direction'))
+            this.pos(this.v34, this.getAtomIndex(residueIndex + 1, 'direction'))
 
             this.value.secStrucType = this.unit.model.properties.secondaryStructure.type[residueIndex]
 
+            this.setControlPoint(value.t0, this.p0, this.p1, this.p2, residueIndex - 2)
+            this.setControlPoint(value.t1, this.p1, this.p2, this.p3, residueIndex - 1)
+            this.setControlPoint(value.t2, this.p2, this.p3, this.p4, residueIndex)
+            this.setControlPoint(value.t3, this.p3, this.p4, this.p5, residueIndex + 1)
+            this.setControlPoint(value.t4, this.p4, this.p5, this.p6, residueIndex + 2)
+
+            this.setDirectionVector(value.d12, this.v01, this.v12, this.v23, residueIndex)
+            this.setDirectionVector(value.d23, this.v12, this.v23, this.v34, residueIndex + 1)
+
             value.first = residueIndex === this.polymerSegment.start
             value.last = residueIndex === this.polymerSegment.end - 1
 

+ 2 - 11
src/mol-geo/shape/mesh-builder.ts

@@ -27,7 +27,7 @@ export interface MeshBuilder {
     addDoubleCylinder(start: Vec3, end: Vec3, lengthScale: number, shift: Vec3, props: CylinderProps): void
     addFixedCountDashedCylinder(start: Vec3, end: Vec3, lengthScale: number, segmentCount: number, props: CylinderProps): void
     addIcosahedron(center: Vec3, radius: number, detail: number): void
-    addTube(controlPoints: Helpers.NumberArray, torsionVectors: Helpers.NumberArray, normalVectors: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number): void
+    addTube(controlPoints: Helpers.NumberArray, torsionVectors: Helpers.NumberArray, normalVectors: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number): void
     setId(id: number): void
     getMesh(): Mesh
 }
@@ -176,11 +176,7 @@ export namespace MeshBuilder {
                 setIcosahedronMat(tmpIcosahedronMat, center)
                 add(tmpIcosahedronMat, vertices, normals, indices)
             },
-            addTube: (controlPoints: Helpers.NumberArray, normalVectors: Helpers.NumberArray, binormalVectors: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number) => {
-                // console.log(controlPoints, normalVectors, binormalVectors, linearSegments, radialSegments)
-
-                // const ico = getIcosahedron({ radius: 0.1, detail: 1 })
-
+            addTube: (controlPoints: Helpers.NumberArray, normalVectors: Helpers.NumberArray, binormalVectors: Helpers.NumberArray, linearSegments: number, radialSegments: number, width: number, height: number, waveFactor: number) => {
                 const normalVector = Vec3.zero()
                 const binormalVector = Vec3.zero()
                 const tempPos = Vec3.zero()
@@ -189,8 +185,6 @@ export namespace MeshBuilder {
                 const u = Vec3.zero()
                 const v = Vec3.zero()
 
-                const waveFactor = 1
-
                 const vertexCount = vertices.elementCount
                 const di = 1 / linearSegments
 
@@ -229,9 +223,6 @@ export namespace MeshBuilder {
                         ChunkedArray.add3(vertices, tempPos[0], tempPos[1], tempPos[2]);
                         ChunkedArray.add3(normals, normalVector[0], normalVector[1], normalVector[2]);
                         ChunkedArray.add(ids, currentId);
-
-                        // setIcosahedronMat(tmpIcosahedronMat, tempPos)
-                        // add(tmpIcosahedronMat, ico.vertices, ico.normals, ico.indices)
                     }
                 }