https://wiki.pymol.org/api.php?action=feedcontributions&user=Sunhwan&feedformat=atom
PyMOL Wiki - User contributions [en]
2024-03-28T17:51:58Z
User contributions
MediaWiki 1.35.1
https://wiki.pymol.org/index.php?title=Plane_Wizard&diff=12935
Plane Wizard
2010-10-04T18:16:32Z
<p>Sunhwan: </p>
<hr />
<div>This wizard has a simple purpose - to draw a cgo plane that passes through three points picked by the user. Most of the wizard itself was copied from the measure wizard.<br />
<br />
To use, put it in the same directory as the other wizards. This is not quality code, and there may be bugs, but it seems to work okay.<br />
<br />
<source lang="python"><br />
import pymol<br />
from pymol import cmd<br />
from pymol.wizard import Wizard<br />
from chempy import cpv<br />
from pymol.cgo import *<br />
<br />
def makePrimitive(cgo, name):<br />
cmd.set('auto_zoom', 0, quiet=1)<br />
cmd.load_cgo(cgo, name)<br />
cmd.set('auto_zoom', 1, quiet=1)<br />
<br />
def point(p):<br />
x, y, z = p<br />
return [COLOR, 1, 1, 1, SPHERE, float(x), float(y), float(z), 0.5]<br />
<br />
def line(p1, p2):<br />
x1, y1, z1 = p1<br />
x2, y2, z2 = p2<br />
return [CYLINDER, float(x1), float(y1), float(z1), float(x2), float(y2), float(z2), 0.25, 1, 1, 1, 1, 1, 1]<br />
<br />
def plane(corner1, corner2, corner3, corner4, normal):<br />
planeObj = []<br />
planeObj.extend(point(corner1))<br />
planeObj.extend(point(corner2))<br />
planeObj.extend(point(corner3))<br />
planeObj.extend(point(corner4))<br />
planeObj.extend(line(corner1, corner2))<br />
planeObj.extend(line(corner2, corner3))<br />
planeObj.extend(line(corner3, corner4))<br />
planeObj.extend(line(corner4, corner1))<br />
<br />
planeObj.extend([COLOR, 0.8, 0.8, 0.8])<br />
planeObj.extend([BEGIN, TRIANGLE_STRIP])<br />
planeObj.append(NORMAL)<br />
planeObj.extend(normal)<br />
for corner in [corner1, corner2, corner3, corner4, corner1]:<br />
planeObj.append(VERTEX)<br />
planeObj.extend(corner)<br />
planeObj.append(END)<br />
return planeObj<br />
<br />
def planeFromPoints(point1, point2, point3, facetSize):<br />
v1 = cpv.normalize(cpv.sub(point2, point1))<br />
v2 = cpv.normalize(cpv.sub(point3, point1))<br />
normal = cpv.cross_product(v1, v2)<br />
v2 = cpv.cross_product(normal, v1)<br />
x = cpv.scale(v1, facetSize)<br />
y = cpv.scale(v2, facetSize)<br />
center = point2<br />
corner1 = cpv.add(cpv.add(center, x), y)<br />
corner2 = cpv.sub(cpv.add(center, x), y)<br />
corner3 = cpv.sub(cpv.sub(center, x), y)<br />
corner4 = cpv.add(cpv.sub(center, x), y)<br />
return plane(corner1, corner2, corner3, corner4, normal)<br />
<br />
<br />
class PlaneWizard(Wizard):<br />
<br />
def __init__(self):<br />
Wizard.__init__(self)<br />
<br />
# some attributes to do with picking<br />
self.pick_count = 0<br />
self.object_count = 0<br />
self.object_prefix = "pw"<br />
<br />
# the plane facet size (the 'radius' of the section of plane we show)<br />
self.facetSize = 5<br />
<br />
self.selection_mode = cmd.get_setting_legacy("mouse_selection_mode")<br />
cmd.set("mouse_selection_mode",0) # set selection mode to atomic<br />
cmd.deselect()<br />
<br />
def reset(self):<br />
cmd.delete(self.object_prefix + "*")<br />
cmd.delete("sele*")<br />
cmd.delete("_indicate*")<br />
cmd.unpick()<br />
cmd.refresh_wizard()<br />
<br />
def delete_all(self):<br />
cmd.delete("plane*")<br />
<br />
def cleanup(self):<br />
cmd.set("mouse_selection_mode",self.selection_mode) # restore selection mode<br />
self.reset()<br />
self.delete_all()<br />
<br />
def get_prompt(self):<br />
self.prompt = None<br />
if self.pick_count == 0:<br />
self.prompt = [ 'Please click on the first atom...']<br />
elif self.pick_count == 1:<br />
self.prompt = [ 'Please click on the second atom...' ]<br />
elif self.pick_count == 2:<br />
self.prompt = [ 'Please click on the third atom...' ]<br />
return self.prompt<br />
<br />
def do_select(self, name):<br />
# "edit" only this atom, and not others with the object prefix<br />
try:<br />
cmd.edit("%s and not %s*" % (name, self.object_prefix))<br />
self.do_pick(0)<br />
except pymol.CmdException, pmce:<br />
print pmce<br />
<br />
def pickNextAtom(self, atom_name):<br />
# transfer the click selection to a named selection<br />
cmd.select(atom_name, "(pk1)")<br />
<br />
# delete the click selection<br />
cmd.unpick()<br />
<br />
# using the magic of indicate, highlight stuff<br />
indicate_selection = "_indicate" + self.object_prefix<br />
cmd.select(indicate_selection, atom_name)<br />
cmd.enable(indicate_selection)<br />
<br />
self.pick_count += 1<br />
self.error = None<br />
<br />
# necessary to force update of the prompt<br />
cmd.refresh_wizard()<br />
<br />
def do_pick(self, picked_bond):<br />
<br />
# this shouldn't actually happen if going through the "do_select"<br />
if picked_bond:<br />
self.error = "Error: please select bonds, not atoms"<br />
print self.error<br />
return<br />
<br />
atom_name = self.object_prefix + str(self.pick_count)<br />
if self.pick_count < 2:<br />
self.pickNextAtom(atom_name)<br />
else:<br />
self.pickNextAtom(atom_name)<br />
<br />
point1 = cmd.get_atom_coords("(%s%s)" % (self.object_prefix, "0"))<br />
point2 = cmd.get_atom_coords("(%s%s)" % (self.object_prefix, "1"))<br />
point3 = cmd.get_atom_coords("(%s%s)" % (self.object_prefix, "2"))<br />
plane = planeFromPoints(point1, point2, point3, self.facetSize)<br />
<br />
planeName = "plane-%02d" % self.object_count<br />
self.object_count += 1<br />
makePrimitive(plane, planeName)<br />
cmd.show("cgo", "plane*")<br />
<br />
self.pick_count = 0<br />
self.reset()<br />
<br />
def get_panel(self):<br />
return [<br />
[ 1, 'Plane Wizard',''],<br />
[ 2, 'Reset','cmd.get_wizard().reset()'],<br />
[ 2, 'Delete All Planes' , 'cmd.get_wizard().delete_all()'],<br />
[ 2, 'Done','cmd.set_wizard()'],<br />
]<br />
<br />
# create an instance<br />
<br />
wiz = PlaneWizard()<br />
<br />
# make this the active wizard<br />
<br />
cmd.set_wizard(wiz)<br />
</source><br />
[[Category:Script_Library|Plane Wizard]]<br />
[[Category:Math_Scripts]]</div>
Sunhwan