###################################################################
UPDATE:  28 Jun 2020
###################################################################

----------------------------------------------
MacOS 10.10+ interface slowdown fix
----------------------------------------------

On recent MacOS's (e.g., 10.15), the catastrophic
tk interface slowdown that began with MacOS 10.10
can be fixed simply by the following sequence:

  boot
  login, start X11
  logout
  login, start X11

The speedup will stick until the next reboot
(start csurf with 'csurf -nohack' to skip the
xterm cover/uncover hack).

----------------------------------------------
FreeSurfer.zsh
----------------------------------------------

FreeSurfer.sh has been fixed to be zsh-compatible
for MacOS 10.15.  I added a link so both 'source
FreeSurfer.sh' and 'source FreeSurfer.zsh' will
work in zsh.

----------------------------------------------
new tcl script - searchlightarea.tcl
----------------------------------------------

This script estimates local area differences by
resampling individual subject vertexwise area data
to fsaverage, and then running a surface-based
searchlight operation on the resampled data using
fsaverage sphere.

First, create a Cross-Subject Session (for display
subject, fsaverage) with:

  csurf -> File -> New SphereAvg
  (pseudo-subject "XS" for "cross-session")

Then, open the just-created empty session and
select searchlightarea.tcl from the "tcl:"
dropdown in at the top left of the tksurfer
interface.  This generates a pop-up to select a
subject and adjust parameters.

Clicking "RUN SCRIPT" on the pop-up resamples the
area data, and then runs the searchlight
operation:

  4 -> sum of data in searchlight

writing the result of the operation as a
vertexwise curvature-format file.  The
multithreaded operation takes about 10
min/hemisphere on an Intel i7.

The size, ${num,sqmm,mm}, of the approximately
geodesic surface searchlight circles can be
specified by vertex count, area, radius, or by
neighbor order (1=immediate neighbors, 2=also
include neighbors of neighbors, etc):

  Searchlight size ($fillneartype):

    0 -> num vertices
    1 -> area (in mm^2)
    2 -> radius (in mm)
    3 -> neighbor order (1-6)

The first three searchlight size specifications
($fillneartype) use the C/tcl function,
searchlightop_val2stat (multi-threaded), while the
fourth specification uses the C/tcl function,
neighop_val2stat (similar result for similar
vertex count, goes up to 6th-order neighbors,
which is 127 vertices).

Adjustable parameters can be hard-coded in this
script (see commented-out example inside) in order
to run it non-interactively from the command line
as a tksurfer tcl script, for example:

#! /bin/sh
sublist="marty sean jill sue"
hemlist="rh lh"
cd $SUBJECTS_DIR/fsaverage/scripts
cp $CSURF_DIR/lib/tcl/searchlightarea.tcl .
for sub in $sublist; do
  for hem in $hemlist; do
    export sampsubj=$sub    # tcl script reads env
    tksurfer fsaverage $hem sphere -tcl searchlightarea.tcl
  done
done

TODO: Gaussian instead of boxcar

----------------------------------------------
tksurfer reads/writes Wavefront *.obj surface files
----------------------------------------------

Surfaces in Wavefront/Alias *.obj (ASCII) format
can now be autodetected and read by tksurfer.
Any optional color appended to vertices is
currently ignored and normals are recalculated
(rather than read out of the *.obj file).

Surfaces can be exported in Wavefront/Alias
format using the "OBJ" button on the "outsurf:"
line at the top right of the large F3 interface
(C/tcl function: write_obj_surface).  Output
formats are:

  basic surface
  include vertexwise colors
  include normals
  include colors + normals

----------------------------------------------
tksurfer reads colors from Wavefront *.obj surface files
----------------------------------------------

If a Wavefront *.obj (ASCII) format surface
contains vertexwise colors, these can now be read
as if they were an annotation (a set of
patches-of-interest).  That is, the vertices in
each unique color will be assigned to different
brain region, and can then be used to extract
surface data.

Any *.obj file in the surf directory will be
loaded in the "label:" line dropdown and can be
read with the "D" button (which uses the C/tcl
function, read_obj_to_annot).


----------------------------------------------
tksurfer reads Brain Voyager *.poi files
----------------------------------------------

Any *.poi file, a Brain Voyager "Patches of
Interest" annotation file (ASCII, vers=2), in the
current subject's label directory will be loaded
into the "label:" line dropdown and can be read
with the "D" button (which uses the C/tcl
function, read_obj_to_annot).

The expected file format looks like this:

  -------------------------------------------
   FileVersion:      2
   FromMeshFile:     "<none>"
   NrOfMeshVertices: 163842
   NrOfPOIs:         8

   NameOfPOI:        "Te10"
   InfoTextFile:     "<none>"
   ColorOfPOI:       227 26 28
   LabelVertex:      0
   NrOfVertices:     468
   52656
   52657
   ... [vtxnums for every vtx in this patch]

   NameOfPOI:        "Te11"
   InfoTextFile:     "<none>"
   ColorOfPOI:       253 191 111
   LabelVertex:      0
   NrOfVertices:     855
   43
   166
   ... [vtxnums for every vtx in this patch]

   ... [additional patches]
  -------------------------------------------

The result of reading a *.poi file is the same as
when reading an MGH annotation file, and the
displayed labels/patches can be used in the same
way to extract surface data.


----------------------------------------------
tksurfer reads Brain Voyager *.srf surface files
----------------------------------------------

Brain Voyager *.srf binary surface files can now
be read into tksurfer.

Vertexwise color data is currently ignored, and
surface normals and neighbor lists are
recalculated.

N.B.: when the left-handed PIL coordinates of
native Brain Voyager surfaces are read into the
right-handed RAS coordinate system of freesurfer,
the surface will appear mirror-imaged (a right
hemisphere will look like a left hemisphere and
vice versa).

The surface can be mirror-imaged (see next) and
then written out as a native freesurfer surface.


----------------------------------------------
tksurfer can mirror-image a surface
----------------------------------------------

The new "FlipHemi" button at the upper far right
of the larger F3 interface mirror-images the
currently displayed surface.

N.B.: this will misalign the surface with any 3D
image data that it was derived from.

N.B.: there is no permanent effect until the
surface is saved (see below).

This operation is occasionally needed for
surfaces read in from other software packages.
The C/tcl functions used are:

  really_flip_brain_x
  compute_normals_areas
  redraw

After the x-coordinate has been flipped, the
order of the vertices in the entry for each face
is flipped so that lighting calculations work
correctly.

The resulting flipped surface can be saved by
entering a name in the upper-left "outsurf:"
entry in the F3 interface and clicking "W".  To
perform the same action with a tcl script, do
something like:

  setfile outsurf ~/surf/lh.my_flipped_RH
  write_binary_surface

----------------------------------------------
tkmedit FILL can append, get volume, fill 3D annotation
----------------------------------------------

The FILL button now allows appending to an
existing filled ROI, measuring the total volume of
current ROIs, and filling 3D annotation regions
(e.g., from rh.aparc.a2009s.annot).  In order of
precedence, the criteria for a connected FILL
volume can be:

 1) current clicked 3D annotation segid
 2) stat mask above current $sfthresh
 3) overlay data amplitude above curr $fthresh
 4) struct between $white_lolim and $white_hilim

Whichever of these four are in force can be
logically AND'ed with a max radius as well as any
temporary edits-to-black of the struct underlay
image (to constrain the FILL).


##########################################################################
UPDATE: 28 Jun 2020
##########################################################################

--csurf: fix bug in -nohack option
--tksurfer.tcl: SAVE/GOTO add-suffix-to-viewmatrix popups show avail suffixes
--csurf: add lights,blufact to all-help
--mk0: combine lib/help/tksurfer/light{1,2,3,4} -> lights
--tksurfer.tcl: better help for the lights
--tksurfer.tcl: bold the "View" butt (curr saved matrix popup), report saved dir
--lib/help/tksurfer/script_searchligharea: update
--FreeSurfer.sh: fix zsh path parsing
--tksurfer.tcl: force load example-res mgz file before FILL3d, write_fill_images
--tksurfer.tcl: also load subjectdir *.mgh files into "val:" dropdown (areas)
--tksurfer.tcl: 6th overload S/V with swap_origarea_val
--tksurfer.c: add swap_origarea_val() -> .origarea loaded at start w/areafile
--tksurfer.c: add copy_area_curv() (fix so-far-unused copy_area_val() bug)
--tksurfer.c: export threadcnt (def=8), incl opt/env
--tksurfer.tcl: blk reabbrev callbacks curv/area in sessdir (was just subjdir)
--searchlightarea.tcl/mk0: new script
--calcvert.c: 1D MGH outp opt for area (rename vars: vnum*->vcnt*, fnum*->fcnt*)
--tksurfer.tcl: fix mid-clk SMOOTH logic (searchlightop_val2stat does neighfill)
--tksurfer.c: searchlightop_val2stat calls neighop_val2stat if filltype=NEIFILL
--tksurfer.c: add SLOPSUM searchlight operation to neighop_val2stat
--tksurfer.c: add copy_area_val()
--tkmedit.c: fill_roi, vol_rois put return in $genstrret_1k for tcl scripts
--tkmedit.c: print 3D brainregion2 name to log (was only double-mid-click)
--tkmedit.c: shift-middle-TRUNC voxel count now pops-up result
--lib/help/tkmedit/roi_fill: update
--tkmedit.tcl: shift-left-click overload FILL button: vol_rois
--tkmedit.tcl: middle-click overload FILL button: clear_rois
--tkmedit.c: vol_rois() to measure current total ROI volume (vox=64)
--tkmedit.c: fill_roi() has option to append to existing region
--tkmedit.c: fill_roi() now has option to fill annotation region
--tkmedit.c: add clear_rois() (was roi_fill auto-cleared each time)
--lib/help/csurf/rc-surfaces,lib/help/tksurfer/surf: FlipHemi update
--csurf/tksurfer.tcl: chklefthandedsurf: change subj re-arms chk left-handed
--csurf: warn read *.srf (but not *.obj), kill popup after 8sec, twice only
--tksurfer.tcl: warn read *.srf possibly left-handed (but not *.obj)
--tksurfer.c: back to not-flipping BV coords (force use F3 interface FlipHemi)
--tksurfer.tcl: rm "surf:" dropdown dups (rh.surftmp match, strip, *.obj re-add)
--tksurfer.c: bail on read BV cols (color indices + RGB, req's POI file anyway!)
--tksurfer.c: make_filenames: *obj,*srf leave hemi on fpref for stdfmt curv etc
--tksurfer.tcl: select_surf try pre-append *.obj/*.srf if non-preappend missing
--csurf: tksurfercmd: special case for non-freesurfer-style *.obj,*.srf names
--csurf: =>w/no surfext prefix, can't tell if intended file is ?h.*.obj, *.obj
--csurf: =>parallel to tksurfer:make_filenames() -> not found, try no preappend
--csurf: fixsurfaces: only strip hemi from globbed surf tail if present!
--csurf: fixsurfaces (fix "surface:" dropdown if newsubj): load all *.obj,*.srf
--tksurfer.c: make_filenames: *.obj/*.srf, also chk surffile no hemi preappend
--lib/help/tksurfer/outsurfobj_write: new helpfile, add to mk0
--tksurfer.tcl: add OBJ to F3 panel for write_obj_surface
--tksurfer.c: write_obj_surface(): basic, colors, normals, colors+normals
--tksurfer.c: order_all_faces(): arr faces around vtxs: unordered->same winding
--tksurfer.tcl: load all *.srf regardless of hemi to "surf:" dropdown
--csurf: load all *.srf regardless of hemi to "surface:" dropdown, fixsurfaces
--tksurfer.c: make_filenames accepts no-hemi-prefix *.srf
--tksurfer.c: read_binary_surface(): tri BrainVoyager .srf surf fmt (flip x!)
--tksurfer.c: fish out find_annot_borders()
--csurf: add Flip (FlipHemi) to all help panel
--lib/help/tksurfer/fliphemi: new help file, add to mk0{.csh}
--tksurfer.tcl: add "FlipHemi" button to REDRAW row on F3 interface
--tksurfer.c: flip_faces(): used by really_flip_brain functions
--tksurfer.c: fix read_binary_surface reading of *.off surfaces (export was OK)
--tksurfer.tcl: "D" button uses read_obj_to_annot if *.obj suffix
--tksurfer.tcl: also load $subject/surf/*.obj file to "label:" dropdown
--tksurfer.c: read_obj_to_annot(): read just colors out of *.obj surf to annot
--tksurfer.tcl: "D" button uses read_poi_annot if *.poi suffix
--tksurfer.tcl: also load $subject/label/*.poi file to "label:" dropdown
--tksurfer.c: read_poi_annot(): load poi file into mghannot/brainregion
--lib/help/csurf/csurf, lib/help/tksurfer/surf, add .obj format
--tksurfer.c: flip_normals()
--csurf: load all *.obj regardless of hemi to "surface:" dropdown, fixsurfaces
--tksurfer.tcl: load all *LH/RH*.obj to "surf:" dropdown
--tksurfer.c: make_filenames accept any *.obj surf, detect maybe fixes hemi
--tksurfer.c: read_binary_surface() accepts tri Wavefront .obj surface format
--tksurfer.c: rename vertex struct members: vnum->vcnt, num->fcnt
--tksurfer.c: really_flip_brain
--tksurfer.tcl: also look-for/dropdown-load oldstyle valfiles in $subject/surf
--mkrandlut(.tcl): new lib/tcl script (add to mk0)
--tksurfer.c: add SLOPPAT=3 to neighop_val2stat->color patches w/stat int id's
--tksurfer.c: neighop_val2stat SLOPPAT=3: non-overlap colpatches w/stat intid's
--tksurfer.tcl: jam unlabeled $insidesurffact entry next to offset on F3 panel
--csurf: add insidesurffact to all help
--lib/help/tksurfer/insidesurffact: new helpfile, add to mk0
--tksurfer.c: insidesurffact to control relative brightness inside surface
--csurf: also load surface dropdown with $inflatedext? $pialext?
--csurf: accepts subject or session dir as arg
--csurf: change default startup volume to orig (was T1)

##########################################################################
PREVIOUS UPDATE: 16 Dec 2019
##########################################################################

--mk0{.csh}: add -viewerlin,-viewermac to make self-contained quickstart inst
--tksurfer.c: rm redundant diploadedflag
--tksurfer.c: add/export read_mgh_dipoles(): from $val (must be 3-frame .mgh)
--tksurfer.tcl: lib/help/tksurfer/arrownorm: update
--tksurfer.tcl: shift-right-clk on unlabeled arrowstick toggles dipolesflag
--tksurfer.tcl: read .mgh val: check embedded *.rh/lh.* (vs. *-rh/lh.w), warn
--tksurfer.tcl: wider "RD" dropdown list for rawdata BRIKs
--{wrappers,tksurfer}.tcl: -selectforeground black for linux dti,regraw popups
--tksurfer.c: paint_surface: if stat dims=0, subst rawdata dims, fail if both=0
--tksurfer.c: init xx0=xx1=yy0=yy1=zz0=zz1=0.0 (enable test unset, not yet done)
--tksurfer.c: rename: push_val_dip() to copy_val_dip() [no history yet]
--lib/tcl/zz-examples/renderoffscreen.tcl: respect previous rename
--lib/tcl/{borders,eccen-,fs-make,phasemovie,polar-,twocond-*}.tcl: respect prev
--tksurfer.c: rename: push_val_val2() to copy_val_val2(), push_ another synonym
--tksurfer.c: if diploadedflag, printvtx reports it
--tksurfer.c: calc avg len dip (for scale)
--tksurfer.tcl: do_dtivec: force sample single cortical depth, update NormSamp
--tksurfer.tcl: dtivecctrls: add parms for sampling surface, cortical depth
...

