################################################################################
#    Copyright (C) 1998  Dennis Roddeman
#    email: dennis.roddeman@uibk.ac.at
#
# The initial version of this vtnvtk.tcl file is for the largest part taken from
# an early version of the Melati program 
# of Jos M. Runarko e-mail:runarko@fzs05.ms.tu-berlin.de
# with kind permission.
#
# The Melati program itself was based on the Decimate.tcl program of Will Schroeder.
#
# Changes with respect to the early version of Melati and
# the Decimate.tcl program are made by Dennis Roddeman e-mail:Dennis.Roddeman@uibk.ac.at,
# for inclusion in the Visual Tochnog layer of the Tochnog program.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
################################################################################

# Initialise VTK

proc vtnvtk {} {

  global tnpath
  source $tnpath/vtn/global.tcl

  global RenWin
  
  catch {load vtktcl}
  
  ################################################################################
  # Instances of vtk objects
  ################################################################################
  
  set view Left

  set LineSurface Surface
  
  catch {vtkUnstructuredGrid UnstructuredGridData }
  
      UnstructuredGridData GlobalWarningDisplayOff
  
  catch {vtkUnstructuredGrid PreviousUnstructuredGridData}
  
  catch {vtkUnstructuredGrid TempUnstructuredGridData}
  
  catch {vtkUnstructuredGridReader reader}
  
  catch {vtkCellTypes CellTypes}
  
  ################################################################################
  # Create top-level GUI
  ################################################################################
  
  set w_vtnvtk .vtnvtk
  catch {destroy $w_vtnvtk}
  toplevel $w_vtnvtk
  wm title $w_vtnvtk "Visual Tochnog - Visual Toolkit graphics "
  wm geometry $w_vtnvtk 500x500
  wm geometry $w_vtnvtk $window_offset
  focus $w_vtnvtk
  
  frame $w_vtnvtk.mbar -relief raised -bd 2
  
  pack $w_vtnvtk.mbar -side top -fill x
  
  wm withdraw $w_vtnvtk
  
  # create the menu bar
  
  menubutton $w_vtnvtk.mbar.select -text Select -menu $w_vtnvtk.mbar.select.menu
  
  menubutton $w_vtnvtk.mbar.view -text View -menu $w_vtnvtk.mbar.view.menu
  
  menubutton $w_vtnvtk.mbar.options -text Options -menu $w_vtnvtk.mbar.options.menu
  
  menubutton $w_vtnvtk.mbar.save -text Save -menu $w_vtnvtk.mbar.save.menu

  menubutton $w_vtnvtk.mbar.help -text Help -menu $w_vtnvtk.mbar.help.menu
  
  pack $w_vtnvtk.mbar.select $w_vtnvtk.mbar.view $w_vtnvtk.mbar.options \
    $w_vtnvtk.mbar.save -side left

  pack $w_vtnvtk.mbar.help -side right

  # create the submenu for select
  
  menu $w_vtnvtk.mbar.select.menu

  $w_vtnvtk.mbar.select.menu add command -label "Select" -command SelectUnknown

  # create the submenu for viewing control
  
  menu $w_vtnvtk.mbar.view.menu
  
      $w_vtnvtk.mbar.view.menu add radiobutton -label Front -variable view -value Front\
              -command {UpdateView 1 0 0 0 1 0}
  
      $w_vtnvtk.mbar.view.menu add radiobutton -label Back -variable view -value Back\
              -command {UpdateView -1 0 0 0 1 0}
  
      $w_vtnvtk.mbar.view.menu add radiobutton -label Left -variable view -value Left\
              -command {UpdateView 0 0 1 0 1 0}
  
      $w_vtnvtk.mbar.view.menu add radiobutton -label Right -variable view -value Right\
              -command {UpdateView 0 0 -1 0 1 0}
  
      $w_vtnvtk.mbar.view.menu add radiobutton -label Top -variable view -value Top\
              -command {UpdateView 0 1 0 0 0 1}
  
      $w_vtnvtk.mbar.view.menu add radiobutton -label Bottom -variable view -value Bottom\
              -command {UpdateView 0 -1 0 0 0 1}
      $w_vtnvtk.mbar.view.menu add radiobutton -label Isometric -variable view \
          -value Isometric -command {UpdateView 1 1 1 0 1 0}
  
  
  # create the submenu for options
  
  menu $w_vtnvtk.mbar.options.menu
  
      $w_vtnvtk.mbar.options.menu add command -label "Background Color..." \
  	    -command BackgroundColor
      $w_vtnvtk.mbar.options.menu add command -label "Switch Line/Surface" \
  	    -command SwitchLineSurface

  # create the submenu for save
  
  menu $w_vtnvtk.mbar.save.menu
  
      $w_vtnvtk.mbar.save.menu add command -label "Save" -command SaveImage
  
  # create the submenu for help

  menu $w_vtnvtk.mbar.help.menu

  $w_vtnvtk.mbar.help.menu add command -label {About} -command {
    help "The first version of vtnvtk is heavily based on the Melati Program of Jos Runarko. It is adjusted for Visual Tochnog by Dennis Roddeman"
  }
  
  ################################################################################
  # The rendering widget
  ################################################################################
  
  update idletasks
  vtkTkRenderWidget $w_vtnvtk.window -width 500 -height 500 
  BindTkRenderWidget $w_vtnvtk.window
  
  pack $w_vtnvtk.window -side top -anchor nw -padx 3 -pady 3 -fill both -expand 1
  wm withdraw $w_vtnvtk
  
  # Graphics objects
  
  catch {vtkCamera camera}
  catch {vtkLight light}
  catch {vtkRenderer Renderer}
      Renderer SetActiveCamera camera
      Renderer AddLight light

  vtkRenderer CompareRenderer
    CompareRenderer SetViewport 0.0 0.0 0.5 1.0
    CompareRenderer SetActiveCamera camera
    CompareRenderer AddLight light
  
  set RenWin [$w_vtnvtk.window GetRenderWindow]
  $RenWin AddRenderer Renderer
  
  ################################################################################
  # the widgets
  ################################################################################
  
  toplevel $w_vtnvtk.back
  wm withdraw $w_vtnvtk.back
  wm geometry $w_vtnvtk.back +575+0
  wm title $w_vtnvtk.back "Select Background Color"
  wm protocol $w_vtnvtk.back WM_DELETE_WINDOW {wm withdraw $w_vtnvtk.back}
  
  frame $w_vtnvtk.back.f1
  
  
  frame $w_vtnvtk.back.f1.l  -relief raised -borderwidth 3
  
  scale $w_vtnvtk.back.f1.l.r -from 255 -to 0 -orient vertical -background #f00 \
  	-command SetColor
  
  scale $w_vtnvtk.back.f1.l.g -from 255 -to 0 -orient vertical -background #0f0 \
  	-command SetColor
  
  scale $w_vtnvtk.back.f1.l.b -from 255 -to 0 -orient vertical -background #00f \
  	-command SetColor
  
  pack $w_vtnvtk.back.f1.l.r $w_vtnvtk.back.f1.l.g $w_vtnvtk.back.f1.l.b -side left -fill both
  
  
  
  frame $w_vtnvtk.back.f1.m -relief raised -borderwidth 3
  
  label $w_vtnvtk.back.f1.m.sample -highlightthickness 0 -text "  Background Color  "
  
  pack $w_vtnvtk.back.f1.m.sample -fill both -expand 1
  
  
  
  frame $w_vtnvtk.back.f1.r -relief raised -borderwidth 3
  
  image create photo ColorWheel -file $tnpath/vtn/ColorWheel.ppm
  
  label $w_vtnvtk.back.f1.r.wheel -image ColorWheel -highlightthickness 0
  
  bind $w_vtnvtk.back.f1.r.wheel <Button-1> {
  
      scan [ColorWheel get %x %y] "%%f %%f %%f" r g b
  
      $w_vtnvtk.back.f1.l.r set $r
  
      $w_vtnvtk.back.f1.l.g set $g
  
      $w_vtnvtk.back.f1.l.b set $b
  
  }
  
  pack $w_vtnvtk.back.f1.r.wheel -fill both
  
  pack $w_vtnvtk.back.f1.l $w_vtnvtk.back.f1.m $w_vtnvtk.back.f1.r -side left -expand 1 -fill both
  
  
  
  frame $w_vtnvtk.back.fb
  
  button $w_vtnvtk.back.fb.apply -text Apply -command ApplyBackground
  
  button $w_vtnvtk.back.fb.cancel -text Cancel -command CloseBackground
  
  pack $w_vtnvtk.back.fb.apply $w_vtnvtk.back.fb.cancel -side left -expand 1 -fill x
  
  pack $w_vtnvtk.back.f1 $w_vtnvtk.back.fb -side top -fill both -expand 1
  
  
  ################################################################################
  #
  # the Pipeline
  #
  ################################################################################             
  
                set Select ""
                reader SetScalarsName "$Select"             
  
          catch {vtkConnectivityFilter connect1}
  
                connect1 SetInput UnstructuredGridData
  
          catch {vtkGeometryFilter femobject}
  
                femobject SetInput [connect1 GetOutput]
  
          catch {vtkPolyDataNormals normals1}
  
                normals1 SetInput [femobject GetOutput]
  
                normals1 SetFeatureAngle 60
  
          catch {vtkLookupTable lut}
  
                lut SetHueRange 0.0 0.66667
  
          catch {vtkPolyDataMapper femobjectMapper}
  
                femobjectMapper SetInput [normals1 GetOutput]
  
                femobjectMapper SetLookupTable lut
  
          #     eval femobjectMapper SetScalarRange $Range
  
          catch {vtkActor femobjectActor1}
  
                femobjectActor1 SetMapper femobjectMapper
  
          Renderer AddActor femobjectActor1
  
          Renderer ResetCamera
  
  
  # Window
  
  wm withdraw $w_vtnvtk
  
  update idletasks
  after 2500 {catch {wm deiconify $w_vtnvtk}}
  focus $w_vtnvtk
  
}

##############################################################################
# Procedure to set particular views
##############################################################################

proc UpdateView {x y z vx vy vz} {

    set camera [Renderer GetActiveCamera]
    $camera SetViewPlaneNormal $x $y $z
    $camera SetViewUp $vx $vy $vz
    Renderer ResetCamera
    Render
}

###############################################################################
# Procedure File IO 
###############################################################################
proc OpenFile {} {

  global tnpath
  source $tnpath/vtn/global.tcl

  global RenWin 
  global reader

  set filename vtn.vtk
  if { [info commands reader] != "" } {reader Delete}
  if { [ file exists $filename ] } {
    vtkUnstructuredGridReader reader
    reader SetFileName $filename
    reader SetScalarsName $Select
  } else {
    puts "Can't read $filename. Run first."
    return
  }             
  reader Update               
  set filename vtnvtk
  UpdateUndo "reader"
  Renderer ResetCamera
  $RenWin Render
}
################################################################################

# Enable the undo procedure after filter execution

 proc UpdateUndo {filter} {
         PreviousUnstructuredGridData CopyStructure UnstructuredGridData
         [PreviousUnstructuredGridData GetPointData] PassData [UnstructuredGridData GetPointData]

         PreviousUnstructuredGridData Modified

         UnstructuredGridData CopyStructure [$filter GetOutput]
         [UnstructuredGridData GetPointData] PassData [[$filter GetOutput] GetPointData]
         UnstructuredGridData Modified  
         ReleaseData
 }

 ################################################################################
proc ReleaseData {} {
         [connect1 GetOutput] Initialize
         [femobject GetOutput] Initialize
         [normals1 GetOutput] Initialize
 }

################################################################################

proc Contour {} {
        eval femobjectMapper SetScalarRange [UnstructuredGridData GetScalarRange]
        Render
}

proc Line {} {
        [femobjectActor1 GetProperty] \
	SetRepresentationToWireframe
        Render
}

proc Fill {} {
        [femobjectActor1 GetProperty] \
	SetRepresentationToSurface
        Render
}
proc SaveImage {} {
     global RenWin
        $RenWin SetFileName "save.ppm" ;
        $RenWin SaveImageAsPPM
}


################################################################################
#  Setting background color
################################################################################

proc BackgroundColor {} {


  global tnpath
  source $tnpath/vtn/global.tcl


    set background [Renderer GetBackground]

    $w_vtnvtk.back.f1.l.r set [expr [lindex $background 0] * 255.0]

    $w_vtnvtk.back.f1.l.g set [expr [lindex $background 1] * 255.0]

    $w_vtnvtk.back.f1.l.b set [expr [lindex $background 2] * 255.0]

    wm deiconify $w_vtnvtk.back

}

#########################################################################################

proc CloseBackground {} {

  global tnpath
  source $tnpath/vtn/global.tcl

  wm withdraw $w_vtnvtk.back

}

#########################################################################################

proc SetColor {value} {

  global tnpath
  source $tnpath/vtn/global.tcl

    set color [format #%02x%02x%02x [$w_vtnvtk.back.f1.l.r get] [$w_vtnvtk.back.f1.l.g get]\
	    [$w_vtnvtk.back.f1.l.b get]]
    $w_vtnvtk.back.f1.m.sample config -background $color
}

#########################################################################################

proc ApplyBackground {} {

  global tnpath
  source $tnpath/vtn/global.tcl

    Renderer SetBackground [expr [$w_vtnvtk.back.f1.l.r get]/255.0] \
	    [expr [$w_vtnvtk.back.f1.l.g get]/255.0] \
	    [expr [$w_vtnvtk.back.f1.l.b get]/255.0]
    CompareRenderer SetBackground [expr [$w_vtnvtk.back.f1.l.r get]/255.0] \
	    [expr [$w_vtnvtk.back.f1.l.g get]/255.0] \
	    [expr [$w_vtnvtk.back.f1.l.b get]/255.0]
    Render
}

############################################################################################

proc SwitchLineSurface {} {

  global tnpath
  source $tnpath/vtn/global.tcl

  if { $LineSurface == "Surface" } {
        set LineSurface Line
        [femobjectActor1 GetProperty] \
        SetRepresentationToWireframe
        Render
  } else {
        set LineSurface Surface
        [femobjectActor1 GetProperty] \
        SetRepresentationToSurface
        Render
  }

}

############################################################################################

proc SelectUnknown {} {

  global tnpath
  source $tnpath/vtn/global.tcl

  if { [ file exists vtn.ukn ] } {

#     select window
    set w_vtnvtk_select $w_vtnvtk.select
    catch {destroy $w_vtnvtk_select}
    toplevel $w_vtnvtk_select
    wm geometry $w_vtnvtk_select $window_offset
    wm title $w_vtnvtk_select "Select"

#     top frame
    set f $w_vtnvtk_select.frame
    frame $f -relief groove -borderwidth 2
    pack $f -expand 1 -fill both

#     frame list
    catch {destroy $f.framelist}
    frame $f.framelist -relief flat
    pack $f.framelist -fill both -side top -expand 1
    label $f.framelist.lab -text "Select unknown to plot: "
    pack $f.framelist.lab -side top
    listbox $f.framelist.list \
      -relief raised -yscrollcommand "$f.framelist.scroll set"
    scrollbar $f.framelist.scroll -command "$f.framelist.list yview"
    pack $f.framelist.scroll -side right -fill y
    pack $f.framelist.list -side left -fill both -expand 1
    bind $f.framelist.list <Double-1> { 
      set Select [selection get] 
      destroy $w_vtnvtk_select
      OpenFile
      Contour
    }
    set fileid [open vtn.ukn r]
    $f.framelist.list insert end "Mesh"
    while { [gets $fileid line]>=0 } {
      $f.framelist.list insert end $line
    }
    close $fileid

#     help
    frame $f.framespecials -relief flat
    pack $f.framespecials -side bottom -pady 2m -fill x
    button $f.framespecials.ready -text "Ready" -command { 
      destroy $w_vtnvtk_select
    }
    button $f.framespecials.help -text "Help" -command { 
      help "Double click on unknown to plot."
    }
    pack $f.framespecials.ready -side left -anchor w
    pack $f.framespecials.help -side right -anchor e

  } else {

    error_show "No selection possible. Did you run first?"

  }

}

############################################################################################

