Ignore:
Timestamp:
Jul 16, 2005, 2:31:32 PM (19 years ago)
Author:
mmc
Message:

Lots of changes to support Huckel-IV:

  • Support for embedded <tool> declarations
  • New <integer> entry
  • Support for numbers and structures as output elements
  • Atom numbers/symbols in MoleculeViewer?
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/scripts/moleculeViewer.tcl

    r11 r22  
    1313package require vtk
    1414package require vtkinteraction
     15package require BLT
    1516
    1617option add *MoleculeViewer.width 4i widgetDefault
     
    1819option add *MoleculeViewer.backdrop black widgetDefault
    1920
     21blt::bitmap define MoleculeViewer-reset {
     22#define reset_width 12
     23#define reset_height 12
     24static unsigned char reset_bits[] = {
     25   0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02,
     26   0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00};
     27}
     28
     29blt::bitmap define MoleculeViewer-zoomin {
     30#define zoomin_width 12
     31#define zoomin_height 12
     32static unsigned char zoomin_bits[] = {
     33   0x7c, 0x00, 0x82, 0x00, 0x11, 0x01, 0x11, 0x01, 0x7d, 0x01, 0x11, 0x01,
     34   0x11, 0x01, 0x82, 0x03, 0xfc, 0x07, 0x80, 0x0f, 0x00, 0x0f, 0x00, 0x06};
     35}
     36
     37blt::bitmap define MoleculeViewer-zoomout {
     38#define zoomout_width 12
     39#define zoomout_height 12
     40static unsigned char zoomout_bits[] = {
     41   0x7c, 0x00, 0x82, 0x00, 0x01, 0x01, 0x01, 0x01, 0x7d, 0x01, 0x01, 0x01,
     42   0x01, 0x01, 0x82, 0x03, 0xfc, 0x07, 0x80, 0x0f, 0x00, 0x0f, 0x00, 0x06};
     43}
     44
     45blt::bitmap define MoleculeViewer-atoms {
     46#define atoms_width 12
     47#define atoms_height 12
     48static unsigned char atoms_bits[] = {
     49   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x02, 0x4c, 0x02, 0xc8, 0x03,
     50   0x48, 0x02, 0x48, 0x02, 0x5c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
     51}
     52
    2053itcl::class Rappture::MoleculeViewer {
    2154    inherit itk::Widget
     
    2861
    2962    protected method _render {}
     63    protected method _zoom {option}
     64    protected method _move {option x y}
     65    protected method _3dView {theta phi}
     66    protected method _fixLabels {{option position}}
    3067    protected method _color2rgb {color}
    3168
    3269    private variable _tool ""    ;# tool containing this viewer
    3370    private variable _actors ""  ;# list of actors in renderer
     71    private variable _label2atom ;# maps 2D text actor => underlying atom
     72    private variable _view       ;# view params for 3D view
     73    private variable _limits     ;# limits of x/y/z axes
     74    private variable _click      ;# info used for _move operations
    3475}
    3576                                                                               
     
    61102    $this-map SetInput [$this-sphere GetOutput]
    62103
     104    vtkCoordinate $this-xyzconv
     105    $this-xyzconv SetCoordinateSystemToWorld
     106
     107    set _view(theta) 0
     108    set _view(phi) 0
     109
     110    itk_component add controls {
     111        frame $itk_interior.cntls
     112    } {
     113        usual
     114        rename -background -controlbackground controlBackground Background
     115    }
     116    pack $itk_component(controls) -side right -fill y
     117
     118    itk_component add reset {
     119        button $itk_component(controls).reset \
     120            -borderwidth 1 -padx 1 -pady 1 \
     121            -bitmap MoleculeViewer-reset \
     122            -command [itcl::code $this _zoom reset]
     123    } {
     124        usual
     125        ignore -borderwidth
     126        rename -highlightbackground -controlbackground controlBackground Background
     127    }
     128    pack $itk_component(reset) -padx 4 -pady 4
     129    Rappture::Tooltip::for $itk_component(reset) "Reset the view to the default zoom level"
     130
     131    itk_component add zoomin {
     132        button $itk_component(controls).zin \
     133            -borderwidth 1 -padx 1 -pady 1 \
     134            -bitmap MoleculeViewer-zoomin \
     135            -command [itcl::code $this _zoom in]
     136    } {
     137        usual
     138        ignore -borderwidth
     139        rename -highlightbackground -controlbackground controlBackground Background
     140    }
     141    pack $itk_component(zoomin) -padx 4 -pady 4
     142    Rappture::Tooltip::for $itk_component(zoomin) "Zoom in"
     143
     144    itk_component add zoomout {
     145        button $itk_component(controls).zout \
     146            -borderwidth 1 -padx 1 -pady 1 \
     147            -bitmap MoleculeViewer-zoomout \
     148            -command [itcl::code $this _zoom out]
     149    } {
     150        usual
     151        ignore -borderwidth
     152        rename -highlightbackground -controlbackground controlBackground Background
     153    }
     154    pack $itk_component(zoomout) -padx 4 -pady 4
     155    Rappture::Tooltip::for $itk_component(zoomout) "Zoom out"
     156
     157    itk_component add labels {
     158        label $itk_component(controls).labels \
     159            -borderwidth 1 -padx 1 -pady 1 \
     160            -bitmap MoleculeViewer-atoms
     161    } {
     162        usual
     163        ignore -borderwidth
     164        rename -highlightbackground -controlbackground controlBackground Background
     165    }
     166    pack $itk_component(labels) -padx 4 -pady 8 -ipadx 1 -ipady 1
     167    Rappture::Tooltip::for $itk_component(labels) "Show/hide the labels on atoms"
     168    bind $itk_component(labels) <ButtonPress> \
     169        [itcl::code $this _fixLabels toggle]
     170
     171    #
     172    # RENDERING AREA
     173    #
     174    itk_component add area {
     175        frame $itk_interior.area
     176    }
     177    pack $itk_component(area) -expand yes -fill both
     178    bind $itk_component(area) <Configure> \
     179        [itcl::code $this _fixLabels]
     180
    63181    itk_component add renderer {
    64         vtkTkRenderWidget $itk_interior.ren -rw $this-renWin
     182        vtkTkRenderWidget $itk_component(area).ren -rw $this-renWin
    65183    } {
    66184    }
     
    68186
    69187    eval itk_initialize $args
     188
     189    # prevent interactions -- use our own
     190    blt::busy hold $itk_component(area) -cursor left_ptr
     191    bind $itk_component(area)_Busy <ButtonPress> \
     192        [itcl::code $this _move click %x %y]
     193    bind $itk_component(area)_Busy <B1-Motion> \
     194        [itcl::code $this _move drag %x %y]
     195    bind $itk_component(area)_Busy <ButtonRelease> \
     196        [itcl::code $this _move release %x %y]
     197
     198    _fixLabels on
    70199}
    71200
     
    79208    rename $this-sphere ""
    80209    rename $this-map ""
     210    rename $this-xyzconv ""
    81211}
    82212
     
    93223    }
    94224    set _actors ""
     225    catch {unset _label2atom}
     226
     227    foreach lim {xmin xmax ymin ymax zmin zmax} {
     228        set _limits($lim) ""
     229    }
    95230
    96231    if {$itk_option(-device) != ""} {
     
    104239            regsub {,} $xyz {} xyz
    105240
    106             set aname "::actor[incr counter]"
     241            # update overall limits for molecules along all axes
     242            foreach axis {x y z} val $xyz {
     243                if {"" == $_limits(${axis}min)} {
     244                    set _limits(${axis}min) $val
     245                    set _limits(${axis}max) $val
     246                } else {
     247                    if {$val < $_limits(${axis}min)} {
     248                        set _limits(${axis}min) $val
     249                    }
     250                    if {$val > $_limits(${axis}max)} {
     251                        set _limits(${axis}max) $val
     252                    }
     253                }
     254            }
     255
     256            # create an actor for each atom
     257            set aname $this-actor[incr counter]
    107258            vtkActor $aname
    108259            $aname SetMapper $this-map
     
    121272
    122273            lappend _actors $aname
    123         }
     274
     275            # create a label for each atom
     276            set lname $this-label$counter
     277            vtkTextActor $lname
     278            $lname SetInput "$counter $symbol"
     279            $lname ScaledTextOff
     280
     281            set tprop [$lname GetTextProperty]
     282            $tprop SetJustificationToCentered
     283            $tprop SetVerticalJustificationToCentered
     284            $tprop ShadowOn
     285            $tprop SetColor 1 1 1
     286
     287            set _label2atom($lname) $aname
     288            lappend _actors $lname
     289        }
     290        if {[$itk_component(labels) cget -relief] == "sunken"} {
     291            _fixLabels on
     292        }
     293        after cancel [list catch [itcl::code $this _zoom reset]]
     294        after 200 [list catch [itcl::code $this _zoom reset]]
    124295    }
    125296    $this-ren ResetCamera
     297    $this-renWin Render
     298}
     299
     300# ----------------------------------------------------------------------
     301# USAGE: _zoom in
     302# USAGE: _zoom out
     303# USAGE: _zoom reset
     304#
     305# Called automatically when the user clicks on one of the zoom
     306# controls for this widget.  Changes the zoom for the current view.
     307# ----------------------------------------------------------------------
     308itcl::body Rappture::MoleculeViewer::_zoom {option} {
     309    switch -- $option {
     310        in {
     311            [$this-ren GetActiveCamera] Zoom 1.25
     312            _fixLabels
     313            $this-renWin Render
     314        }
     315        out {
     316            [$this-ren GetActiveCamera] Zoom 0.8
     317            _fixLabels
     318            $this-renWin Render
     319        }
     320        reset {
     321            [$this-ren GetActiveCamera] SetViewAngle 30
     322            $this-ren ResetCamera
     323            [$this-ren GetActiveCamera] Zoom 1.25
     324            _3dView 45 45
     325            $this-renWin Render
     326
     327            after cancel [list catch [itcl::code $this _fixLabels]]
     328            after 2000 [list catch [itcl::code $this _fixLabels]]
     329        }
     330    }
     331}
     332
     333# ----------------------------------------------------------------------
     334# USAGE: _move click <x> <y>
     335# USAGE: _move drag <x> <y>
     336# USAGE: _move release <x> <y>
     337#
     338# Called automatically when the user clicks/drags/releases in the
     339# plot area.  Moves the plot according to the user's actions.
     340# ----------------------------------------------------------------------
     341itcl::body Rappture::MoleculeViewer::_move {option x y} {
     342    switch -- $option {
     343        click {
     344            blt::busy configure $itk_component(area) -cursor fleur
     345            set _click(x) $x
     346            set _click(y) $y
     347            set _click(theta) $_view(theta)
     348            set _click(phi) $_view(phi)
     349        }
     350        drag {
     351            if {[array size _click] == 0} {
     352                _move click $x $y
     353            } else {
     354                set w [winfo width $itk_component(renderer)]
     355                set h [winfo height $itk_component(renderer)]
     356                set dx [expr {double($x-$_click(x))/$w}]
     357                set dy [expr {double($y-$_click(y))/$h}]
     358
     359                #
     360                # Rotate the camera in 3D
     361                #
     362                set theta [expr {$_view(theta) - $dy*180}]
     363                if {$theta < 2} { set theta 2 }
     364                if {$theta > 178} { set theta 178 }
     365                set phi [expr {$_view(phi) - $dx*360}]
     366
     367                _3dView $theta $phi
     368                _fixLabels
     369                $this-renWin Render
     370
     371                set _click(x) $x
     372                set _click(y) $y
     373            }
     374        }
     375        release {
     376            _move drag $x $y
     377            blt::busy configure $itk_component(area) -cursor left_ptr
     378            catch {unset _click}
     379        }
     380        default {
     381            error "bad option \"$option\": should be click, drag, release"
     382        }
     383    }
     384}
     385
     386# ----------------------------------------------------------------------
     387# USAGE: _3dView <theta> <phi>
     388#
     389# Used internally to change the position of the camera for 3D data
     390# sets.  Sets the camera according to the angles <theta> (angle from
     391# the z-axis) and <phi> (angle from the x-axis in the x-y plane).
     392# Both angles are in degrees.
     393# ----------------------------------------------------------------------
     394itcl::body Rappture::MoleculeViewer::_3dView {theta phi} {
     395    set deg2rad 0.0174532927778
     396    set xn [expr {sin($theta*$deg2rad)*cos($phi*$deg2rad)}]
     397    set yn [expr {sin($theta*$deg2rad)*sin($phi*$deg2rad)}]
     398    set zn [expr {cos($theta*$deg2rad)}]
     399
     400    set xm [expr {0.5*($_limits(xmax)+$_limits(xmin))}]
     401    set ym [expr {0.5*($_limits(ymax)+$_limits(ymin))}]
     402    set zm [expr {0.5*($_limits(zmax)+$_limits(zmin))}]
     403
     404    set cam [$this-ren GetActiveCamera]
     405    set zoom [$cam GetViewAngle]
     406    $cam SetViewAngle 30
     407
     408    $cam SetFocalPoint $xm $ym $zm
     409    $cam SetPosition [expr {$xm-$xn}] [expr {$ym-$yn}] [expr {$zm+$zn}]
     410    $cam ComputeViewPlaneNormal
     411    $cam SetViewUp 0 0 1  ;# z-dir is up
     412    $cam OrthogonalizeViewUp
     413    $this-ren ResetCamera
     414    $cam SetViewAngle $zoom
     415
     416    # fix up the labels so they sit over the new atom positions
     417    _fixLabels
     418
     419    set _view(theta) $theta
     420    set _view(phi) $phi
     421}
     422
     423# ----------------------------------------------------------------------
     424# USAGE: _fixLabels on
     425# USAGE: _fixLabels off
     426# USAGE: _fixLabels toggle
     427# USAGE: _fixLabels position
     428#
     429# Used internally to turn labels associated with atoms on/off, and to
     430# update the positions of the labels so they sit on top of each atom.
     431# ----------------------------------------------------------------------
     432itcl::body Rappture::MoleculeViewer::_fixLabels {{option position}} {
     433    switch -- $option {
     434        on {
     435            set state 1
     436        }
     437        off {
     438            set state 0
     439        }
     440        toggle {
     441            if {[$itk_component(labels) cget -relief] == "sunken"} {
     442                set state 0
     443            } else {
     444                set state 1
     445            }
     446        }
     447        position {
     448            foreach lname [array names _label2atom] {
     449                set aname $_label2atom($lname)
     450                set xyz [$aname GetPosition]
     451                eval $this-xyzconv SetValue $xyz
     452                set xy [$this-xyzconv GetComputedViewportValue $this-ren]
     453                eval $lname SetDisplayPosition $xy
     454            }
     455            return
     456        }
     457        default {
     458            error "bad option \"$option\": should be on, off, toggle, position"
     459        }
     460    }
     461
     462    if {$state} {
     463        $itk_component(labels) configure -relief sunken
     464        foreach lname [array names _label2atom] {
     465            catch {$this-ren AddActor2D $lname}
     466        }
     467        _fixLabels position
     468    } else {
     469        $itk_component(labels) configure -relief raised
     470        foreach lname [array names _label2atom] {
     471            catch {$this-ren RemoveActor $lname}
     472        }
     473    }
    126474    $this-renWin Render
    127475}
     
    159507    after idle [itcl::code $this _render]
    160508}
    161 
    162 #package require Rappture
    163 #Rappture::MoleculeViewer .e
    164 #pack .e -expand yes -fill both
    165 #
    166 #set dev [Rappture::library {<?xml version="1.0"?>
    167 #<structure>
    168 #<components>
    169 #<molecule id="Aspirin">
    170 #  <formula>???</formula>
    171 #  <info>Aspirin molecule</info>
    172 #  <atom id="1">
    173 #    <symbol>C</symbol>
    174 #    <xyz>-1.892  -0.992  -1.578</xyz>
    175 #  </atom>
    176 #  <atom id="2">
    177 #    <symbol>C</symbol>
    178 #    <xyz>-1.370  -2.149  -0.990</xyz>
    179 #  </atom>
    180 #  <atom id="3">
    181 #    <symbol>C</symbol>
    182 #    <xyz>-0.079  -2.146  -0.464</xyz>
    183 #  </atom>
    184 #  <atom id="4">
    185 #    <symbol>C</symbol>
    186 #    <xyz>0.708  -0.986  -0.521</xyz>
    187 #  </atom>
    188 #  <atom id="5">
    189 #    <symbol>C</symbol>
    190 #    <xyz>0.203   0.156  -1.196</xyz>
    191 #  </atom>
    192 #  <atom id="6">
    193 #    <symbol>C</symbol>
    194 #    <xyz>-1.108   0.161  -1.654</xyz>
    195 #  </atom>
    196 #  <atom id="7">
    197 #    <symbol>C</symbol>
    198 #    <xyz>2.085  -1.030   0.104</xyz>
    199 #  </atom>
    200 #  <atom id="8">
    201 #    <symbol>O</symbol>
    202 #    <xyz>2.533  -2.034   0.636</xyz>
    203 #  </atom>
    204 #  <atom id="9">
    205 #    <symbol>O</symbol>
    206 #    <xyz>2.879   0.025   0.112</xyz>
    207 #  </atom>
    208 #  <atom id="10">
    209 #    <symbol>O</symbol>
    210 #    <xyz>0.753   1.334  -1.084</xyz>
    211 #  </atom>
    212 #  <atom id="11">
    213 #    <symbol>C</symbol>
    214 #    <xyz>0.668   2.025   0.034</xyz>
    215 #  </atom>
    216 #  <atom id="12">
    217 #    <symbol>O</symbol>
    218 #    <xyz>1.300   3.063   0.152</xyz>
    219 #  </atom>
    220 #  <atom id="13">
    221 #    <symbol>C</symbol>
    222 #    <xyz>-0.243   1.577   1.144</xyz>
    223 #  </atom>
    224 #  <atom id="14">
    225 #    <symbol>H</symbol>
    226 #    <xyz>-2.879  -0.962  -1.985</xyz>
    227 #  </atom>
    228 #  <atom id="15">
    229 #    <symbol>H</symbol>
    230 #    <xyz>-1.988  -3.037  -0.955</xyz>
    231 #  </atom>
    232 #  <atom id="16">
    233 #    <symbol>H</symbol>
    234 #    <xyz>0.300  -3.063  -0.005</xyz>
    235 #  </atom>
    236 #  <atom id="17">
    237 #    <symbol>H</symbol>
    238 #    <xyz>-1.489   1.084  -2.059</xyz>
    239 #  </atom>
    240 #  <atom id="18">
    241 #    <symbol>H</symbol>
    242 #    <xyz>2.566   0.782  -0.326</xyz>
    243 #  </atom>
    244 #  <atom id="19">
    245 #    <symbol>H</symbol>
    246 #    <xyz>-0.761   0.636   0.933</xyz>
    247 #  </atom>
    248 #  <atom id="20">
    249 #    <symbol>H</symbol>
    250 #    <xyz>-1.009   2.349   1.290</xyz>
    251 #  </atom>
    252 #  <atom id="21">
    253 #    <symbol>H</symbol>
    254 #    <xyz>0.346   1.435   2.059</xyz>
    255 #  </atom>
    256 #</molecule>
    257 #</components>
    258 #</structure>}]
    259 # add connectivity at some point...
    260 #CONECT    1    2    6   14                   
    261 #CONECT    2    1    3   15                   
    262 #CONECT    3    2    4   16                   
    263 #CONECT    4    3    5    7                   
    264 #CONECT    5    4    6   10                   
    265 #CONECT    6    1    5   17                   
    266 #CONECT    7    4    8    9                   
    267 #CONECT    8    7                             
    268 #CONECT    9    7   18                       
    269 #CONECT   10    5   11                       
    270 #CONECT   11   10   12   13                   
    271 #CONECT   12   11                             
    272 #CONECT   13   11   19   20   21             
    273 #CONECT   14    1                             
    274 #CONECT   15    2                             
    275 #CONECT   16    3                             
    276 #CONECT   17    6                             
    277 #CONECT   18    9                             
    278 #CONECT   19   13                             
    279 #CONECT   20   13                             
    280 #CONECT   21   13               
    281 
    282 #.e configure -device $dev
Note: See TracChangeset for help on using the changeset viewer.