| 1 | # -----------------------------------------------------------------------------
|
|---|
| 2 | # Report surface coloring volume data value in the status line when mouse
|
|---|
| 3 | # is over surface.
|
|---|
| 4 | #
|
|---|
| 5 | # Opening this script starts the reporting and there is no way to turn it off.
|
|---|
| 6 | #
|
|---|
| 7 | def show_surface_value(event):
|
|---|
| 8 |
|
|---|
| 9 | # Find surfaces being colored by volume data.
|
|---|
| 10 | import SurfaceColor as sc
|
|---|
| 11 | surface_models = [s for s in sc.colorable_surface_models()
|
|---|
| 12 | if isinstance(sc.surface_coloring(s)[0], sc.Volume_Color)]
|
|---|
| 13 | if len(surface_models) == 0:
|
|---|
| 14 | return # No surfaces colored with volume data
|
|---|
| 15 |
|
|---|
| 16 | # Find surface intercept under mouse
|
|---|
| 17 | from VolumeViewer import slice
|
|---|
| 18 | xyz_in, xyz_out = slice.clip_plane_points(event.x, event.y)
|
|---|
| 19 | import PickBlobs as pb
|
|---|
| 20 | f, p, t = pb.closest_surface_intercept(surface_models, xyz_in, xyz_out)
|
|---|
| 21 | if f is None:
|
|---|
| 22 | return # No surface intercept
|
|---|
| 23 |
|
|---|
| 24 | # Look-up surface coloring volume value including surface offset.
|
|---|
| 25 | from Matrix import linear_combination, apply_matrix, xform_matrix
|
|---|
| 26 | xyz = linear_combination((1.0-f), xyz_in, f, xyz_out)
|
|---|
| 27 | sxyz = apply_matrix(xform_matrix(p.model.openState.xform.inverse()), xyz)
|
|---|
| 28 | cs = sc.surface_coloring(p.model)[0]
|
|---|
| 29 | vol = cs.volume
|
|---|
| 30 | va, ta = p.maskedGeometry(p.Solid)
|
|---|
| 31 | tri = ta[t]
|
|---|
| 32 | w = triangle_vertex_weights(sxyz, [va[vi] for vi in tri])
|
|---|
| 33 | values, outside = cs.volume_values(p)
|
|---|
| 34 | v = sum([w[i]*values[vi] for i,vi in enumerate(tri)])
|
|---|
| 35 |
|
|---|
| 36 | # Report value on status line.
|
|---|
| 37 | from chimera import replyobj
|
|---|
| 38 | replyobj.status('%s value at surface point = %.5g' % (vol.name, v))
|
|---|
| 39 |
|
|---|
| 40 | # -----------------------------------------------------------------------------
|
|---|
| 41 | # Linear interpolate normal vector within surface triangle.
|
|---|
| 42 | #
|
|---|
| 43 | def triangle_vertex_weights(xyz, triangle_corners):
|
|---|
| 44 | c0, c1, c2 = triangle_corners
|
|---|
| 45 | p = xyz - c0
|
|---|
| 46 | from Matrix import distance, cross_product as cp
|
|---|
| 47 | from numpy import dot as ip
|
|---|
| 48 | n = cp(c1-c0, c2-c0)
|
|---|
| 49 | n1 = cp(n,c1-c0)
|
|---|
| 50 | n2 = cp(n,c2-c0)
|
|---|
| 51 | i1 = ip(n1,c2-c0)
|
|---|
| 52 | a2 = ip(n1,p)/i1 if i1 != 0 else 0
|
|---|
| 53 | i2 = ip(n2,c1-c0)
|
|---|
| 54 | a1 = ip(n2,p)/i2 if i2 != 0 else 0
|
|---|
| 55 | w = ((1-a1-a2),a1,a2)
|
|---|
| 56 | return w
|
|---|
| 57 |
|
|---|
| 58 | # -----------------------------------------------------------------------------
|
|---|
| 59 | #
|
|---|
| 60 | def register_motion_handler():
|
|---|
| 61 |
|
|---|
| 62 | import SurfaceColor
|
|---|
| 63 | if not hasattr(SurfaceColor, 'svmhandler'):
|
|---|
| 64 | from chimera import tkgui
|
|---|
| 65 | h = tkgui.app.graphics.bind('<Any-Motion>', show_surface_value, add=1)
|
|---|
| 66 | SurfaceColor.svmhandler = h
|
|---|
| 67 | from chimera import replyobj
|
|---|
| 68 | replyobj.status('Started reporting surface value under mouse')
|
|---|
| 69 |
|
|---|
| 70 |
|
|---|