Skip to content

Commit b5da96a

Browse files
committed
support colorscheme changes on surfaces
Issue #729
1 parent a000a73 commit b5da96a

File tree

4 files changed

+65
-10
lines changed

4 files changed

+65
-10
lines changed

src/GLViewer.ts

+31-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ import { decode, toRGBA8, encode } from 'upng-js'
1717

1818
export const CONTEXTS_PER_VIEWPORT = 16;
1919

20+
interface SurfObj {
21+
geo: Geometry;
22+
mat: Material;
23+
done: Boolean;
24+
finished: Boolean;
25+
lastGL?: any;
26+
symmetries?: any[];
27+
style?: SurfaceStyleSpec;
28+
}
29+
2030
/**
2131
* WebGL-based 3Dmol.js viewer
2232
* Note: The preferred method of instantiating a GLViewer is through {@link createViewer}
@@ -38,7 +48,7 @@ export class GLViewer {
3848
private glDOM: HTMLCanvasElement | null = null;
3949

4050
private models: GLModel[] = []; // atomistic molecular models
41-
private surfaces: any = {};
51+
private surfaces: Record<number,SurfObj[]> = {};
4252
private shapes = []; // Generic shapes
4353
private labels: Label[] = [];
4454
private clickables = []; //things you can click on
@@ -1826,7 +1836,6 @@ export class GLViewer {
18261836
geo.normalsNeedUpdate = true;
18271837
geo.colorsNeedUpdate = true;
18281838
geo.buffersNeedUpdate = true;
1829-
geo.boundingSphere = null;
18301839
surfArr[n].mat.needsUpdate = true;
18311840

18321841
if (surfArr[n].done)
@@ -2512,7 +2521,7 @@ export class GLViewer {
25122521
viewer.render();
25132522
});
25142523
*/
2515-
public addPropertyLabels(prop: string, sel: AtomSelectionSpec, style: AtomStyleSpec) {
2524+
public addPropertyLabels(prop: string, sel: AtomSelectionSpec, style: LabelSpec) {
25162525
this.applyToModels("addPropertyLabels", prop, sel, this, style);
25172526
this.show();
25182527
return this;
@@ -4083,19 +4092,22 @@ export class GLViewer {
40834092

40844093
//set colorArray of there are per-atom colors
40854094
var colorArray = geoGroup.colorArray;
4095+
let atomArray = geoGroup.atomArray;
40864096

40874097
if (mat.voldata && mat.volscheme) {
40884098
//convert volumetric data into colors
40894099
var scheme = mat.volscheme;
40904100
var voldata = mat.voldata;
40914101
var range = scheme.range() || [-1, 1];
40924102
for (let i = 0, il = v.length; i < il; i++) {
4103+
let A = v[i].atomid;
40934104
let val = voldata.getVal(v[i].x, v[i].y, v[i].z);
40944105
let col = CC.color(scheme.valueToHex(val, range));
40954106
let offset = i * 3;
40964107
colorArray[offset] = col.r;
40974108
colorArray[offset + 1] = col.g;
40984109
colorArray[offset + 2] = col.b;
4110+
atomArray[i] = atoms[A];
40994111
}
41004112
}
41014113
else if (colors.length > 0) { //have atom colors
@@ -4106,6 +4118,7 @@ export class GLViewer {
41064118
colorArray[offsetA] = colors[A].r;
41074119
colorArray[offsetA + 1] = colors[A].g;
41084120
colorArray[offsetA + 2] = colors[A].b;
4121+
atomArray[i] = atoms[A];
41094122
}
41104123
}
41114124

@@ -4237,7 +4250,6 @@ export class GLViewer {
42374250
return mat;
42384251
}
42394252

4240-
42414253
/**
42424254
* Adds an explicit mesh as a surface object.
42434255
* @param {Mesh}
@@ -4254,7 +4266,7 @@ export class GLViewer {
42544266
finished: false //the rendered finishes surfaces when they are done
42554267
};
42564268
var surfid = this.nextSurfID();
4257-
this.surfaces[surfid] = surfobj;
4269+
this.surfaces[surfid] = [surfobj];
42584270
return surfid;
42594271
};
42604272

@@ -4597,15 +4609,14 @@ export class GLViewer {
45974609
adjustVolumeStyle(style);
45984610
if (this.surfaces[surf]) {
45994611
var surfArr = this.surfaces[surf];
4600-
surfArr.style = style;
4601-
for (var i = 0; i < surfArr.length; i++) {
4612+
for (let i = 0; i < surfArr.length; i++) {
46024613
var mat = surfArr[i].mat = GLViewer.getMatWithStyle(style);
46034614
surfArr[i].mat.side = FrontSide;
46044615
if (style.color) {
4605-
surfArr[i].mat.color = style.color;
4616+
surfArr[i].mat.color = CC.color(style.color);
46064617
surfArr[i].geo.colorsNeedUpdate = true;
46074618
const c = CC.color(style.color);
4608-
surfArr[i].geo.setColors(function () { return c; });
4619+
surfArr[i].geo.setColor(c);
46094620
}
46104621
else if (mat.voldata && mat.volscheme) {
46114622
//convert volumetric data into colors
@@ -4618,6 +4629,17 @@ export class GLViewer {
46184629
let col = cc.color(scheme.valueToHex(val, range));
46194630
return col;
46204631
});
4632+
} else {
4633+
surfArr[i].geo.colorsNeedUpdate = true;
4634+
for(let geo of surfArr[i].geo.geometryGroups ) {
4635+
for(let j = 0; j < geo.vertices; j++) {
4636+
let c = getColorFromStyle(geo.atomArray[j],style);
4637+
let off = 3*j;
4638+
geo.colorArray[off] = c.r;
4639+
geo.colorArray[off+1] = c.g;
4640+
geo.colorArray[off+2] = c.b;
4641+
}
4642+
}
46214643
}
46224644
surfArr[i].finished = false; // trigger redraw
46234645
}

src/WebGL/core/Geometry.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { LineBasicMaterial } from '../materials/LineBasicMaterial';
33
import { EventDispatcher } from "./EventDispatcher";
44
import { Vector3 } from "../math";
55
import { CC, Color } from "../../colors";
6+
import { AtomSpec } from 'specs';
67
const BUFFERSIZE = 65535; //limited to 16bit indices
78
export class GeometryGroup {
89
id: number;
@@ -12,6 +13,7 @@ export class GeometryGroup {
1213
radiusArray: Float32Array | null = null;
1314
faceArray: Uint16Array | null = null;
1415
lineArray: Uint16Array | null = null;
16+
atomArray: Array<AtomSpec> = Array<AtomSpec>();
1517
vertices: number = 0;
1618
faceidx: number = 0;
1719
lineidx: number = 0;
@@ -22,7 +24,22 @@ export class GeometryGroup {
2224
this.id = id;
2325
}
2426

25-
setColors(setcolor: (r: number, g: number, b: number) => Color | number): void {
27+
public setColor(color: Color | number): void {
28+
//apply constant color
29+
var v = this.vertexArray;
30+
var c = this.colorArray;
31+
if (!v) throw new Error("vertex array not initialized");
32+
if (!c) throw new Error("color array not initialized");
33+
34+
let col = CC.color(color);
35+
for (var i = 0; i < v.length; i += 3) {
36+
c[i] = col.r;
37+
c[i + 1] = col.g;
38+
c[i + 2] = col.b;
39+
}
40+
}
41+
42+
setColors(setcolor: (x: number, y: number, z: number) => Color | number): void {
2643
//apply a function that takes the vertex coordinate and returns a color
2744
var v = this.vertexArray;
2845
var c = this.colorArray;
@@ -448,6 +465,13 @@ export class Geometry extends EventDispatcher {
448465
}
449466
}
450467

468+
setColor(...setcolor: Parameters<GeometryGroup["setColor"]>): void {
469+
var len = this.geometryGroups.length;
470+
for (var g = 0; g < len; g++) {
471+
var geoGroup = this.geometryGroups[g];
472+
geoGroup.setColor(...setcolor);
473+
}
474+
}
451475

452476
setUpWireframe(...lineIndexArgs: Parameters<GeometryGroup["setLineIndices"]>) {
453477
for (var g = 0; g < this.groups; g++) {

tests/auto/tests/surfacechange.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
$3Dmol.download("pdb:4DLN",viewer,{},function(){
3+
viewer.setStyle({'cartoon':{colorscheme: 'ssPyMol'}});
4+
var sb = viewer.addSurface("SAS", {colorscheme: 'ssJmol'} ,{hetflag:false},null,null, function(sb) {
5+
viewer.render( /* no callback */);
6+
viewer.setSurfaceMaterialStyle(sb, {colorscheme: 'ssPyMol',opacity:.7});
7+
viewer.render();
8+
});
9+
});
Loading

0 commit comments

Comments
 (0)