Bläddra i källkod

improved sheet caps

Alexander Rose 6 år sedan
förälder
incheckning
532d26e0a5

+ 46 - 57
src/mol-geo/geometry/mesh/builder/sheet.ts

@@ -15,6 +15,8 @@ const tV = Vec3.zero()
 
 const horizontalVector = Vec3.zero()
 const verticalVector = Vec3.zero()
+const verticalRightVector = Vec3.zero()
+const verticalLeftVector = Vec3.zero()
 const normalOffset = Vec3.zero()
 const positionVector = Vec3.zero()
 const normalVector = Vec3.zero()
@@ -25,6 +27,41 @@ const p2 = Vec3.zero()
 const p3 = Vec3.zero()
 const p4 = Vec3.zero()
 
+function addCap(offset: number, builder: MeshBuilder, controlPoints: ArrayLike<number>, normalVectors: ArrayLike<number>, binormalVectors: ArrayLike<number>, width: number, leftHeight: number, rightHeight: number) {
+    const { vertices, normals, indices } = builder.state
+    const vertexCount = vertices.elementCount
+
+    Vec3.fromArray(verticalLeftVector, normalVectors, offset)
+    Vec3.scale(verticalLeftVector, verticalLeftVector, leftHeight)
+
+    Vec3.fromArray(verticalRightVector, normalVectors, offset)
+    Vec3.scale(verticalRightVector, verticalRightVector, rightHeight)
+
+    Vec3.fromArray(horizontalVector, binormalVectors, offset)
+    Vec3.scale(horizontalVector, horizontalVector, width)
+
+    Vec3.fromArray(positionVector, controlPoints, offset)
+
+    Vec3.add(p1, Vec3.add(p1, positionVector, horizontalVector), verticalRightVector)
+    Vec3.sub(p2, Vec3.add(p2, positionVector, horizontalVector), verticalLeftVector)
+    Vec3.sub(p3, Vec3.sub(p3, positionVector, horizontalVector), verticalLeftVector)
+    Vec3.add(p4, Vec3.sub(p4, positionVector, horizontalVector), verticalRightVector)
+
+    ChunkedArray.add3(vertices, p1[0], p1[1], p1[2])
+    ChunkedArray.add3(vertices, p2[0], p2[1], p2[2])
+    ChunkedArray.add3(vertices, p3[0], p3[1], p3[2])
+    ChunkedArray.add3(vertices, p4[0], p4[1], p4[2])
+
+    Vec3.cross(normalVector, horizontalVector, verticalLeftVector)
+
+    for (let i = 0; i < 4; ++i) {
+        ChunkedArray.add3(normals, normalVector[0], normalVector[1], normalVector[2])
+    }
+    ChunkedArray.add3(indices, vertexCount + 2, vertexCount + 1, vertexCount)
+    ChunkedArray.add3(indices, vertexCount, vertexCount + 3, vertexCount + 2)
+}
+
+/** set arrowHeight = 0 for no arrow */
 export function addSheet(builder: MeshBuilder, controlPoints: ArrayLike<number>, normalVectors: ArrayLike<number>, binormalVectors: ArrayLike<number>, linearSegments: number, width: number, height: number, arrowHeight: number, startCap: boolean, endCap: boolean) {
     const { currentGroup, vertices, normals, indices, groups } = builder.state
 
@@ -112,67 +149,19 @@ export function addSheet(builder: MeshBuilder, controlPoints: ArrayLike<number>,
     }
 
     if (startCap) {
-        const offset = 0
-        vertexCount = vertices.elementCount
-
-        Vec3.fromArray(verticalVector, normalVectors, offset)
-        Vec3.scale(verticalVector, verticalVector, arrowHeight === 0 ? height : arrowHeight);
-
-        Vec3.fromArray(horizontalVector, binormalVectors, offset)
-        Vec3.scale(horizontalVector, horizontalVector, width);
-
-        Vec3.fromArray(positionVector, controlPoints, offset)
-
-        Vec3.add(p1, Vec3.add(p1, positionVector, horizontalVector), verticalVector)
-        Vec3.sub(p2, Vec3.add(p2, positionVector, horizontalVector), verticalVector)
-        Vec3.sub(p3, Vec3.sub(p3, positionVector, horizontalVector), verticalVector)
-        Vec3.add(p4, Vec3.sub(p4, positionVector, horizontalVector), verticalVector)
-
-        ChunkedArray.add3(vertices, p1[0], p1[1], p1[2])
-        ChunkedArray.add3(vertices, p2[0], p2[1], p2[2])
-        ChunkedArray.add3(vertices, p3[0], p3[1], p3[2])
-        ChunkedArray.add3(vertices, p4[0], p4[1], p4[2])
-
-        Vec3.cross(normalVector, horizontalVector, verticalVector)
-
-        for (let i = 0; i < 4; ++i) {
-            ChunkedArray.add3(normals, normalVector[0], normalVector[1], normalVector[2])
-        }
-        ChunkedArray.add3(indices, vertexCount + 2, vertexCount + 1, vertexCount);
-        ChunkedArray.add3(indices, vertexCount, vertexCount + 3, vertexCount + 2);
+        const h = arrowHeight === 0 ? height : arrowHeight
+        addCap(0, builder, controlPoints, normalVectors, binormalVectors, width, h, h)
+    } else if (arrowHeight > 0) {
+        addCap(0, builder, controlPoints, normalVectors, binormalVectors, width, -arrowHeight, height)
+        addCap(0, builder, controlPoints, normalVectors, binormalVectors, width, arrowHeight, -height)
     }
 
     if (endCap && arrowHeight === 0) {
-        const offset = linearSegments * 3
-        vertexCount = vertices.elementCount
-
-        Vec3.fromArray(verticalVector, normalVectors, offset)
-        Vec3.scale(verticalVector, verticalVector, height);
-
-        Vec3.fromArray(horizontalVector, binormalVectors, offset)
-        Vec3.scale(horizontalVector, horizontalVector, width);
-
-        Vec3.fromArray(positionVector, controlPoints, offset)
-
-        Vec3.add(p1, Vec3.add(p1, positionVector, horizontalVector), verticalVector)
-        Vec3.sub(p2, Vec3.add(p2, positionVector, horizontalVector), verticalVector)
-        Vec3.sub(p3, Vec3.sub(p3, positionVector, horizontalVector), verticalVector)
-        Vec3.add(p4, Vec3.sub(p4, positionVector, horizontalVector), verticalVector)
-
-        ChunkedArray.add3(vertices, p1[0], p1[1], p1[2])
-        ChunkedArray.add3(vertices, p2[0], p2[1], p2[2])
-        ChunkedArray.add3(vertices, p3[0], p3[1], p3[2])
-        ChunkedArray.add3(vertices, p4[0], p4[1], p4[2])
-
-        Vec3.cross(normalVector, horizontalVector, verticalVector)
-
-        for (let i = 0; i < 4; ++i) {
-            ChunkedArray.add3(normals, normalVector[0], normalVector[1], normalVector[2])
-        }
-        ChunkedArray.add3(indices, vertexCount + 2, vertexCount + 1, vertexCount);
-        ChunkedArray.add3(indices, vertexCount, vertexCount + 3, vertexCount + 2);
+        addCap(linearSegments * 3, builder, controlPoints, normalVectors, binormalVectors, width, height, height)
     }
 
-    const addedVertexCount = (linearSegments + 1) * 8 + (startCap ? 4 : 0) + (endCap && arrowHeight === 0 ? 4 : 0)
+    const addedVertexCount = (linearSegments + 1) * 8 + 
+        (startCap ? 4 : (arrowHeight > 0 ? 8 : 0)) + 
+        (endCap && arrowHeight === 0 ? 4 : 0)
     for (let i = 0, il = addedVertexCount; i < il; ++i) ChunkedArray.add(groups, currentGroup)
 }

+ 1 - 1
src/mol-repr/structure/visual/polymer-direction-wedge.ts

@@ -62,7 +62,7 @@ async function createPolymerDirectionWedgeMesh(ctx: VisualContext, unit: Unit, s
 
         interpolateCurveSegment(state, v, tension, shift)
 
-        if ((isSheet && !v.secStrucChange) || !isSheet) {
+        if ((isSheet && !v.secStrucLast) || !isSheet) {
             const size = theme.size.size(v.center) * sizeFactor
             const depth = depthFactor * size
             const width = widthFactor * size

+ 13 - 14
src/mol-repr/structure/visual/util/polymer/trace-iterator.ts

@@ -119,8 +119,7 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
     }
 
     private setControlPoint(out: Vec3, p1: Vec3, p2: Vec3, p3: Vec3, residueIndex: ResidueIndex) {
-        const ss = this.unit.model.properties.secondaryStructure.type[residueIndex]
-        if (SecondaryStructureType.is(ss, SecondaryStructureType.Flag.Beta)) {
+        if (SecondaryStructureType.is(this.currSecStrucType, 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)
@@ -137,6 +136,8 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
                 this.updateResidueSegmentRange(this.polymerSegment)
                 if (residueIt.hasNext) {
                     this.state = AtomicPolymerTraceIteratorState.nextResidue
+                    this.currSecStrucType = SecStrucTypeNA
+                    this.nextSecStrucType = this.secondaryStructureType[this.residueSegmentMin]
                     break
                 }
             }
@@ -144,7 +145,17 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
 
         if (this.state === AtomicPolymerTraceIteratorState.nextResidue) {
             const { index: residueIndex } = residueIt.move();
+            this.prevSecStrucType = this.currSecStrucType
+            this.currSecStrucType = this.nextSecStrucType
+            this.nextSecStrucType = residueIt.hasNext ? this.secondaryStructureType[residueIndex + 1] : SecStrucTypeNA
+
+            value.secStrucType = this.currSecStrucType
             value.center.element = this.getElementIndex(residueIndex, 'trace')
+            value.first = residueIndex === this.residueSegmentMin
+            value.last = residueIndex === this.residueSegmentMax
+            value.secStrucFirst = this.prevSecStrucType !== this.currSecStrucType
+            value.secStrucLast = this.currSecStrucType !== this.nextSecStrucType
+            value.moleculeType = getAtomicMoleculeType(this.unit.model, residueIndex)
 
             this.pos(this.p0, this.getElementIndex(residueIndex - 3 as ResidueIndex, 'trace'))
             this.pos(this.p1, this.getElementIndex(residueIndex - 2 as ResidueIndex, 'trace'))
@@ -159,12 +170,6 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
             this.pos(this.v23, this.getElementIndex(residueIndex, 'direction'))
             // this.pos(this.v34, this.getAtomIndex(residueIndex + 1 as ResidueIndex, 'direction'))
 
-            this.prevSecStrucType = this.currSecStrucType
-            this.currSecStrucType = this.nextSecStrucType
-            this.nextSecStrucType = residueIt.hasNext ? this.secondaryStructureType[residueIndex + 1] : SecStrucTypeNA
-
-            this.value.secStrucType = this.currSecStrucType
-
             this.setControlPoint(value.p0, this.p0, this.p1, this.p2, residueIndex - 2 as ResidueIndex)
             this.setControlPoint(value.p1, this.p1, this.p2, this.p3, residueIndex - 1 as ResidueIndex)
             this.setControlPoint(value.p2, this.p2, this.p3, this.p4, residueIndex)
@@ -174,12 +179,6 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
             Vec3.copy(value.d12, this.v12)
             Vec3.copy(value.d23, this.v23)
 
-            value.first = residueIndex === this.residueSegmentMin
-            value.last = residueIndex === this.residueSegmentMax
-            value.secStrucFirst = this.prevSecStrucType !== this.currSecStrucType
-            value.secStrucLast = this.currSecStrucType !== this.nextSecStrucType
-            value.moleculeType = getAtomicMoleculeType(this.unit.model, residueIndex)
-
             if (!residueIt.hasNext) {
                 this.state = AtomicPolymerTraceIteratorState.nextPolymer
             }