source: trunk/gui/scripts/moleculeViewer.tcl @ 7

Last change on this file since 7 was 7, checked in by mmc, 16 years ago

Created an initial EnergyLevels? viewer and MoleculeViewer?. The
MoleculeViewer? is integrated into the driver, but the EnergyLevels?
is not. The material library file contains some new properties
for the appearance of atoms, and the MoleculeViewer? uses this.
Both energyLevels.tcl and moleculeViewer.tcl still have some
driver code at the bottom of the files, so you can run them as
a single file, by themselves, for testing. This code should be
removed when we get further along.

File size: 8.7 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: MoleculeViewer - view a molecule in 3D
3#
4#  This widget brings up a 3D representation of a molecule, which you
5#  can rotate.  It extracts atoms and bonds from the Rappture XML
6#  representation for a <molecule>.
7# ======================================================================
8#  AUTHOR:  Michael McLennan, Purdue University
9#  Copyright (c) 2004  Purdue Research Foundation, West Lafayette, IN
10# ======================================================================
11package require Itk
12package require vtk
13package require vtkinteraction
14
15option add *MoleculeViewer.width 4i widgetDefault
16option add *MoleculeViewer.height 4i widgetDefault
17option add *MoleculeViewer.backdrop black widgetDefault
18
19itcl::class Rappture::MoleculeViewer {
20    inherit itk::Widget
21
22    itk_option define -backdrop backdrop Backdrop "black"
23    itk_option define -device device Device ""
24    itk_option define -library library Library ""
25
26    constructor {args} { # defined below }
27    destructor { # defined below }
28
29    protected method _render {}
30    protected method _color2rgb {color}
31
32    private variable _actors ""  ;# list of actors in renderer
33}
34                                                                               
35itk::usual MoleculeViewer {
36}
37
38# ----------------------------------------------------------------------
39# CONSTRUCTOR
40# ----------------------------------------------------------------------
41itcl::body Rappture::MoleculeViewer::constructor {args} {
42    itk_option add hull.width hull.height
43    pack propagate $itk_component(hull) no
44
45    vtkRenderWindow $this-renWin
46    vtkRenderer $this-ren
47    $this-renWin AddRenderer $this-ren
48
49    vtkRenderWindowInteractor $this-int
50    $this-int SetRenderWindow $this-renWin
51
52    vtkSphereSource $this-sphere
53    $this-sphere SetRadius 1.0
54    $this-sphere SetThetaResolution 18
55    $this-sphere SetPhiResolution 18
56
57    vtkPolyDataMapper $this-map
58    $this-map SetInput [$this-sphere GetOutput]
59
60    itk_component add renderer {
61        vtkTkRenderWidget $itk_interior.ren -rw $this-renWin
62    } {
63    }
64    pack $itk_component(renderer) -expand yes -fill both
65
66    eval itk_initialize $args
67}
68
69# ----------------------------------------------------------------------
70# DESTRUCTOR
71# ----------------------------------------------------------------------
72itcl::body Rappture::MoleculeViewer::destructor {} {
73    rename $this-renWin ""
74    rename $this-ren ""
75    rename $this-int ""
76    rename $this-sphere ""
77    rename $this-map ""
78}
79
80# ----------------------------------------------------------------------
81# USAGE: _render
82#
83# Used internally to rebuild the scene whenever options within this
84# widget change.  Destroys all actors and rebuilds them from scratch.
85# ----------------------------------------------------------------------
86itcl::body Rappture::MoleculeViewer::_render {} {
87    foreach a $_actors {
88        $this-ren RemoveActor $a
89        rename $a ""
90    }
91    set _actors ""
92
93    if {$itk_option(-device) != ""} {
94        set dev $itk_option(-device)
95        set counter 0
96        foreach atom [$dev children -type atom components.molecule] {
97            set symbol [$dev get components.molecule.$atom.symbol]
98            set xyz [$dev get components.molecule.$atom.xyz]
99            regsub {,} $xyz {} xyz
100
101            set aname "::actor[incr counter]"
102            vtkActor $aname
103            $aname SetMapper $this-map
104            eval $aname SetPosition $xyz
105            $this-ren AddActor $aname
106
107            if {$itk_option(-library) != ""} {
108                set sfac 0.7
109                set scale [$itk_option(-library) get elements.($symbol).scale]
110                if {$scale != ""} {
111                    $aname SetScale [expr {$sfac*$scale}]
112                }
113                set color [$itk_option(-library) get elements.($symbol).color]
114                if {$color != ""} {
115                    eval [$aname GetProperty] SetColor [_color2rgb $color]
116                }
117            }
118
119            lappend _actors $aname
120        }
121    }
122    $this-ren ResetCamera
123    $this-renWin Render
124}
125
126# ----------------------------------------------------------------------
127# USAGE: _color2rgb color
128#
129# Used internally to convert a Tk color name into the r,g,b values
130# used in Vtk (scaled 0-1).
131# ----------------------------------------------------------------------
132itcl::body Rappture::MoleculeViewer::_color2rgb {color} {
133    foreach {r g b} [winfo rgb $itk_component(hull) $color] {}
134    set r [expr {$r/65535.0}]
135    set g [expr {$g/65535.0}]
136    set b [expr {$b/65535.0}]
137    return [list $r $g $b]
138}
139
140# ----------------------------------------------------------------------
141# OPTION: -backdrop
142# ----------------------------------------------------------------------
143itcl::configbody Rappture::MoleculeViewer::backdrop {
144    eval $this-ren SetBackground [_color2rgb $itk_option(-backdrop)]
145    $this-renWin Render
146}
147
148# ----------------------------------------------------------------------
149# OPTION: -device
150# ----------------------------------------------------------------------
151itcl::configbody Rappture::MoleculeViewer::device {
152    if {$itk_option(-device) != ""
153          && ![Rappture::library isvalid $itk_option(-device)]} {
154        error "bad value \"$itk_option(-device)\": should be Rappture::library object"
155    }
156    after idle [itcl::code $this _render]
157}
158
159# ----------------------------------------------------------------------
160# OPTION: -library
161# ----------------------------------------------------------------------
162itcl::configbody Rappture::MoleculeViewer::library {
163    _render
164}
165
166package require Rappture
167Rappture::MoleculeViewer .e -library [Rappture::library -std library.xml]
168pack .e -expand yes -fill both
169
170set dev [Rappture::library {<?xml version="1.0"?>
171<structure>
172<components>
173<molecule id="Aspirin">
174  <formula>???</formula>
175  <info>Aspirin molecule</info>
176  <atom id="1">
177    <symbol>C</symbol>
178    <xyz>-1.892  -0.992  -1.578</xyz>
179  </atom>
180  <atom id="2">
181    <symbol>C</symbol>
182    <xyz>-1.370  -2.149  -0.990</xyz>
183  </atom>
184  <atom id="3">
185    <symbol>C</symbol>
186    <xyz>-0.079  -2.146  -0.464</xyz>
187  </atom>
188  <atom id="4">
189    <symbol>C</symbol>
190    <xyz>0.708  -0.986  -0.521</xyz>
191  </atom>
192  <atom id="5">
193    <symbol>C</symbol>
194    <xyz>0.203   0.156  -1.196</xyz>
195  </atom>
196  <atom id="6">
197    <symbol>C</symbol>
198    <xyz>-1.108   0.161  -1.654</xyz>
199  </atom>
200  <atom id="7">
201    <symbol>C</symbol>
202    <xyz>2.085  -1.030   0.104</xyz>
203  </atom>
204  <atom id="8">
205    <symbol>O</symbol>
206    <xyz>2.533  -2.034   0.636</xyz>
207  </atom>
208  <atom id="9">
209    <symbol>O</symbol>
210    <xyz>2.879   0.025   0.112</xyz>
211  </atom>
212  <atom id="10">
213    <symbol>O</symbol>
214    <xyz>0.753   1.334  -1.084</xyz>
215  </atom>
216  <atom id="11">
217    <symbol>C</symbol>
218    <xyz>0.668   2.025   0.034</xyz>
219  </atom>
220  <atom id="12">
221    <symbol>O</symbol>
222    <xyz>1.300   3.063   0.152</xyz>
223  </atom>
224  <atom id="13">
225    <symbol>C</symbol>
226    <xyz>-0.243   1.577   1.144</xyz>
227  </atom>
228  <atom id="14">
229    <symbol>H</symbol>
230    <xyz>-2.879  -0.962  -1.985</xyz>
231  </atom>
232  <atom id="15">
233    <symbol>H</symbol>
234    <xyz>-1.988  -3.037  -0.955</xyz>
235  </atom>
236  <atom id="16">
237    <symbol>H</symbol>
238    <xyz>0.300  -3.063  -0.005</xyz>
239  </atom>
240  <atom id="17">
241    <symbol>H</symbol>
242    <xyz>-1.489   1.084  -2.059</xyz>
243  </atom>
244  <atom id="18">
245    <symbol>H</symbol>
246    <xyz>2.566   0.782  -0.326</xyz>
247  </atom>
248  <atom id="19">
249    <symbol>H</symbol>
250    <xyz>-0.761   0.636   0.933</xyz>
251  </atom>
252  <atom id="20">
253    <symbol>H</symbol>
254    <xyz>-1.009   2.349   1.290</xyz>
255  </atom>
256  <atom id="21">
257    <symbol>H</symbol>
258    <xyz>0.346   1.435   2.059</xyz>
259  </atom>
260</molecule>
261</components>
262</structure>}]
263# add connectivity at some point...
264#CONECT    1    2    6   14                   
265#CONECT    2    1    3   15                   
266#CONECT    3    2    4   16                   
267#CONECT    4    3    5    7                   
268#CONECT    5    4    6   10                   
269#CONECT    6    1    5   17                   
270#CONECT    7    4    8    9                   
271#CONECT    8    7                             
272#CONECT    9    7   18                       
273#CONECT   10    5   11                       
274#CONECT   11   10   12   13                   
275#CONECT   12   11                             
276#CONECT   13   11   19   20   21             
277#CONECT   14    1                             
278#CONECT   15    2                             
279#CONECT   16    3                             
280#CONECT   17    6                             
281#CONECT   18    9                             
282#CONECT   19   13                             
283#CONECT   20   13                             
284#CONECT   21   13               
285
286.e configure -device $dev
Note: See TracBrowser for help on using the repository browser.