## 1ST STAGE: draw sweep along the knot.
## All knot points except those at the crossings lie on x-y plane. The z coordinate of the knot points can change from 0 to 1,
## 2ND STAGE: draw spanning surface in mode 1
################################################################################


#################################
## SUBDIVISION INTERFACE

tclinit {
  package require slideui
}


tclinit { 
  toplevel .slfWindow.ui
  CreateSLIDESubdivisionObject oSubdivision
  set widget [CreateSLIDESubdivisionUI .slfWindow.ui oSubdivision]
  pack $widget
}


###################################
## KNOT SWEEP INTERFACE 

tclinit {

  package require slideui
  

  proc CreateParamObject { name } {
    set this $name
    global $this

    # surfMode
    set ${this}(surfMode) 0
    set ${this}(surfMode_min) 0
    set ${this}(surfMode_max) 1
    set ${this}(surfMode_resolution) 1

    # drawSurface
    set ${this}(drawSurface) 1
    set ${this}(drawSurface_min) 0
    set ${this}(drawSurface_max) 1
    set ${this}(drawSurface_resolution) 1

    # minTorsion
    set ${this}(minTorsion) 1
    set ${this}(minTorsion_min) 0
    set ${this}(minTorsion_max) 1
    set ${this}(minTorsion_resolution) 1

    # slices
    set ${this}(slices) 8
    set ${this}(slices_min) 3
    set ${this}(slices_max) 20
    set ${this}(slices_resolution) 1

    # sweeprad
    set ${this}(sweepRad) 0.03
    set ${this}(sweepRad_min) 0.01
    set ${this}(sweepRad_max) 0.1
    set ${this}(sweepRad_resolution) 0.01
    
    # drawSweep
    set ${this}(drawSweep) 1
    set ${this}(drawSweep_min) 0
    set ${this}(drawSweep_max) 1
    set ${this}(drawSweep_resolution) 1

    # drawKnot
    set ${this}(drawKnot) 1
    set ${this}(drawKnot_min) 0
    set ${this}(drawKnot_max) 1
    set ${this}(drawKnot_resolution) 1

    # zscale
    set ${this}(zScale) 0.2
    set ${this}(zScale_min) 0.1
    set ${this}(zScale_max) 1.0
    set ${this}(zScale_resolution) 0.1
    
  }

   proc CreateParamUI { parent name } {
    set root $parent.f$name
    set this $name

    global $this
    frame $root

    ## SLIDER Frame
    frame $root.fScales
    
    # surfMode
    set widget [CreateScale $root.fScales scalesurfMode \
	    ${this}(surfMode) "Surface Mode" \
	    [subst $${this}(surfMode_min)] \
	    [subst $${this}(surfMode_max)] \
	    [subst $${this}(surfMode_resolution)]]
    pack $widget -side top -fill x

    # drawSurface
    set widget [CreateScale $root.fScales scaleDrawSurface \
	    ${this}(drawSurface) "Draw Surface" \
	    [subst $${this}(drawSurface_min)] \
	    [subst $${this}(drawSurface_max)] \
	    [subst $${this}(drawSurface_resolution)]]
    pack $widget -side top -fill x

    # minTorsion
    set widget [CreateScale $root.fScales scaleMinTorsion \
	    ${this}(minTorsion) "Minimize Torsion" \
	    [subst $${this}(minTorsion_min)] \
	    [subst $${this}(minTorsion_max)] \
	    [subst $${this}(minTorsion_resolution)]]
    pack $widget -side top -fill x

    # slices
    set widget [CreateScale $root.fScales scaleSlices \
	    ${this}(slices) "Slices" \
	    [subst $${this}(slices_min)] \
	    [subst $${this}(slices_max)] \
	    [subst $${this}(slices_resolution)]]
    pack $widget -side top -fill x

    # sweeprad
    set widget [CreateScale $root.fScales scaleSweepRad \
	    ${this}(sweepRad) "Sweep Radius" \
	    [subst $${this}(sweepRad_min)] \
	    [subst $${this}(sweepRad_max)] \
	    [subst $${this}(sweepRad_resolution)]]
    pack $widget -side top -fill x

    # drawSweep
    set widget [CreateScale $root.fScales scaleDrawSweep \
	    ${this}(drawSweep) "Draw Sweep" \
	    [subst $${this}(drawSweep_min)] \
	    [subst $${this}(drawSweep_max)] \
	    [subst $${this}(drawSweep_resolution)]]
    pack $widget -side top -fill x

    # drawKnot
    set widget [CreateScale $root.fScales scaleDrawKnot \
	    ${this}(drawKnot) "Draw Knot" \
	    [subst $${this}(drawKnot_min)] \
	    [subst $${this}(drawKnot_max)] \
	    [subst $${this}(drawKnot_resolution)]]
    pack $widget -side top -fill x

    # zscale
    set widget [CreateScale $root.fScales scaleZScale \
	    ${this}(zScale) "Z-scale" \
	    [subst $${this}(zScale_min)] \
	    [subst $${this}(zScale_max)] \
	    [subst $${this}(zScale_resolution)]]
    pack $widget -side top -fill x

    pack $root.fScales -side top -fill x

    return $root
  }

  toplevel .slfWindow.param
  CreateParamObject param
  set widget [CreateParamUI .slfWindow.param param]
  pack $widget

  puts "created paramUI"
}

#############################
## DEFINE SURFACE COLOR

surface RED color ( 1 0 0 ) endsurface
surface YEL color ( 1 1 0 ) endsurface
surface GRN color ( 0 1 0 ) endsurface
surface CYN color ( 0 0 1 ) endsurface
surface BLU color ( 0 0 1 ) endsurface
surface MAG color ( 1 0 1 ) endsurface
surface WHT color ( 1 1 1 ) endsurface


include "data.slf"

###################################
## DEFINE KNOT SWEEP

crosssection swCircle
  type circle
  radius {expr $param(sweepRad)}
  slices {expr $param(slices)}
endcrosssection

sweep knot
  path backbone
    minimizetorsion {expr $param(minTorsion)}
  endpath

  crosssection swCircle
    surface BLU
    orientation 0
    endcap 0
    begincap 0

  endcrosssection

  drawpath {expr $param(drawKnot)}
  drawsweep {expr $param(drawSweep)}
endsweep


###################################
## DEFINE MESH SUBDIVISION

group gWholeMeshCCW
  instance OddWindingCCW
  endinstance
endgroup
(*
group gWholeMeshCW
  instance OddWindingCW
  endinstance
endgroup
*)
subdivision oSubdivSurf

  lod {expr $oSubdivision(lod)}
  shading {expr $oSubdivision(shading)}
  #solid SLF_HOLLOW

  type {expr $oSubdivision(type)}

  subdivisions {expr $oSubdivision(subdivisions) }
  errormetric {expr $oSubdivision(errormetric)}
  drawcontrols {expr $oSubdivision(drawcontrols)}
  drawcurrent {expr $oSubdivision(drawcurrent)}
  drawvertices {expr $oSubdivision(drawvertices)}

  # Hack to get non-uniform knot spacing on some of the edges
  uknots {expr $oSubdivision(weightededges)}
  uorder {expr $oSubdivision(weight)}
  vknots {expr $oSubdivision(a)}
  vorder {expr $oSubdivision(b)}

  # Hack to assign a tolerance value for the selective subdivision
  tolerance {expr $oSubdivision(tolerance)}
  facetsmax {expr $oSubdivision(facetsmax)}

  instance gWholeMeshCCW
    surface RED
  endinstance
(*
  instance gWholeMeshCW
    surface YEL
  endinstance
  *)

endsubdivision

##########################################
## scene

group assembly
  instance oSubdivSurf
    surface RED
  endinstance 
endgroup

light amb
  type SLF_AMBIENT
  color (0.2 0.2 0.2)
endlight

light sun
  type SLF_DIRECTIONAL
  color (0.8 0.8 0.8)
endlight

light anti_sun
  type SLF_DIRECTIONAL
  color (0.4 0.4 0.4)
endlight

group world
    instance assembly 
      lod { if { $param(drawSurface) == 1 } {expr $oSubdivision(lod)} else {expr $SLF_OFF} }
    endinstance
  instance knot
  endinstance

  instance amb
    id main_amb
  endinstance
  instance sun
    id front_sun
    rotate (0 1 0) (-30)
    rotate (0 0 1) (-45)
  endinstance
  instance anti_sun
    id back_sun
    rotate (1 0 0) (180)
    rotate (0 1 0) (-30)
    rotate (0 0 1) (-45)
  endinstance
endgroup

camera cam
   projection SLF_PARALLEL
  #frustum ( -0.1 -0.1 -2.0 ) ( 0.1 0.1 -0.01)
endcamera

group gCam
  instance cam
    id iCam
    translate ( 0.0 0.0 1 )
  endinstance
endgroup

window Window
  background (0.3 0.6 0.3)
endwindow

viewport vp Window
endviewport

render vp gCam.iCam.cam world 
  light world.front_sun.sun
  light world.back_sun.anti_sun
  light world.main_amb.amb
endrender