nglviewer / ngl

WebGL protein viewer
http://nglviewer.org/ngl/
MIT License
665 stars 169 forks source link

Sparse surface meshes #198

Closed fredludlow closed 7 years ago

fredludlow commented 8 years ago

Related to #180 but different enough to warrant its own issue:

I had a bit of a play with making sparser meshes using quads and triangles. Here's a demo! (In the example menu called "contour")

Original (no smoothing, wireframe): screenshot 1

Sparser: screenshot

Basic idea is rendering triangle edges from marching cubes but only those edges that fall on a cube face (I think this is actually equivalent to the 2D contouring mentioned before).

The way it's coded at the moment (in my contour-surface branch) is very much a big hack (I abused the various existing classes to connect the UI and end up returning a LineBuffer rather than a SurfaceBuffer) but the changes in marching-cubes.js outline the meat of it. The current implementation is also quite inefficient (most lines are drawn twice) so plenty of room for optimization.

By itself this isn't particularly appealing to the eye - I haven't got a way of smoothing these surfaces - but in combination with a better method for generating a continuously valued grid (rather than the binary 1/0 you get with EDT) it could make some prettier (and more accurate) wire-mesh surfaces.

If you like the look of this I can have a go at turning it from ugly hack to actual feature (though need some thought/discussion on how to restructure the various classes to do it cleanly).

arose commented 8 years ago

I like it! Will think about how this could be cleanly implemented. Maybe instead of from and to arrays use the index array and in the SurfaceBuffer set an option to render as Line (this.line = true;). That way everything else should work.

fredludlow commented 8 years ago

So in marching-cubes.js positionArray stores triangle vertices, and indexArray specifies which ones to use to make the triangles (length of indexArray is 3x number of triangles). Do you mean that in line mode indexArray would now be 2x number of lines (from and to)? (And then appropriate handling depending on value of SurfaceBuffer.line flag)?

Another thing I'd just ignored was the atomIndex array, though I guess that's quite important (to get the filterSele functionality)

arose commented 8 years ago

in line mode indexArray would now be 2x number of lines (from and to)?

Exactly

Another thing I'd just ignored was the atomIndex array, though I guess that's quite important (to get the filterSele functionality)

Yes, that should be available (btw I am working on just calculating the surface around a ligand)

fredludlow commented 8 years ago

in line mode indexArray would now be 2x number of lines (from and to)?

Exactly

Cool, will have a look

Yes, that should be available (btw I am working on just calculating the surface around a ligand)

Yay!

I've also mostly ported Mike Hartshorn's AstexViewer surface code - I'll push it up to my fork today hopefully.

fredludlow commented 7 years ago

I was just about to have another look at this. The first thing is to get the marching-cubes output as discussed above, i.e. an object with

The other thing you mentioned was changing SurfaceBuffer to take an option to render in line mode. At the moment SurfaceBuffer inherits from MeshBuffer so I'm not sure what to do there (should MeshSurface reference different shaders conditionally on line/triangles mode, or have MeshSurfaceBuffer and LineSurfaceBuffer classes, or something else...)

For now I'll work on making a neater version of my previous hacks on marching-cubes.js

arose commented 7 years ago

normal: no longer needed?

not for now but in the future wireframe lighting could be nice

LineBuffer also inherits from Buffer but sets this.line = true

Might as simple as (untested):

var contourBuffer = new Buffer( position, color, index );
contourBuffer.line = true;
fredludlow commented 7 years ago

Okay, think I've got something working :)

Code: https://github.com/fredludlow/ngl/tree/contour-surfaces2 Demo: http://fredludlow.com/ngldev/examples/webapp.html (avSurface example)

Before: screenshot 14 After: screenshot 15

Changes are:

If you're happy with it I'll create a PR, if not, let me know what needs doing!

Cheers, Fred

arose commented 7 years ago

Hi Fred, sorry for the wait. Looks very nice, thank you! Please do a PR, just some very minor things.

remove the dysfunct edgeFilter code?

reuse some code in https://github.com/fredludlow/ngl/blob/contour-surfaces2/src/representation/molecularsurface-representation.js#L202-L234

var position = info.surface.getPosition();
var color = info.surface.getColor( this.getColorParams() );
var index = info.surface.getFilteredIndex( this.filterSele, sview );

(turning this contour and wireframe on together is interesting, might be good to prevent this somehow?)

add to setParameters

        // forbid setting wireframe to true when contour is true
        if( params && params.wireframe && (
                params.contour || ( params.contour === undefined && this.contour )
            )
        ){
            params.wireframe = false;
        }

and call this.getBufferParams( { wireframe: false } ) with wireframe set to false when getting the params for the ContourBuffer