MODULE PZComputeCurvature EXPORTS Main;

(* Compute chain invariants *)
(* Last edited on 1999-11-08 05:39:57 by hcgl *)

IMPORT ParseParams, Process, FileRd, Wr, FileWr;
IMPORT OSError, Thread, Stdio, Fmt, TextWr;
IMPORT LR3;
IMPORT PZLR3Chain, PZLRChain;

FROM LR3 IMPORT Norm;
FROM LR3Extras IMPORT Cross;
FROM Stdio IMPORT stderr;
FROM PZTypes IMPORT LONG, NAT;

<* FATAL Wr.Failure, Thread.Alerted, OSError.E *>

TYPE
  Options = RECORD
      input: TEXT;      (* Input float chain file (without ".flv") *)
      output: TEXT;     (* Output curvature chain file name (without ".flc") *)
      lambda: LONG;     (* Filtering scale *)
    END;

PROCEDURE Main() =
  BEGIN
    WITH
      o = GetOptions(),
      rp = PZLR3Chain.Read(FileRd.Open(o.input & ".flc"), headerOnly := FALSE),
      p = rp.c^,
      rv = PZLR3Chain.Read(FileRd.Open(o.input & ".flv"), headerOnly := FALSE),
      v = rv.c^,
      ra = PZLR3Chain.Read(FileRd.Open(o.input & ".fla"), headerOnly := FALSE),
      a = ra.c^,
      cmt = rp.cmt & "\n" & PZComputeCurvatureComments(o, NUMBER(p)),
      cv = InvariantChainFromLR3Chain(p, v, a)^
    DO
      WITH
        cvUnit = ra.unit,
        cvCmt = cmt & "\n" & "Curvature - computed at filtered curve points"
      DO
        PZLRChain.Write(FileWr.Open(o.output & ".fcv"), cvCmt, cv, 0.0d0, cvUnit)
      END;
    END
  END Main;

PROCEDURE InvariantChainFromLR3Chain(
    READONLY  p: PZLR3Chain.T;
    READONLY  v: PZLR3Chain.T;
    READONLY  a: PZLR3Chain.T;
  ): REF PZLRChain.T =
  (*
    Given n equally spaced points along a curve computes the corresponding
    invariant (curvature) chain.
  *)
  VAR cmax : LONG;
  BEGIN
    WITH
      NP = NUMBER(p),
      c = NEW(REF PZLRChain.T, NP)
    DO
      <* ASSERT NUMBER(v) = NP *>
      <* ASSERT NUMBER(a) = NP *>
      cmax := 0.0d0;
      FOR i:= 0 TO NP-1 DO
        WITH
          vel = Norm(v[i]),
          cv = Cross(v[i],a[i])
        DO
          c[i] := cv[2] / (vel * vel * vel);
        END;
      END;
      RETURN c
    END
  END InvariantChainFromLR3Chain;

PROCEDURE GetOptions(): Options =
  VAR o: Options;
  BEGIN
    WITH
      pp = NEW(ParseParams.T).init(stderr)
    DO
      TRY
        pp.getKeyword("-input");
        o.input := pp.getNext();

        pp.getKeyword("-output");
        o.output := pp.getNext();

        pp.getKeyword("-lambda");
        o.lambda := pp.getNextLongReal();

        pp.finish();
      EXCEPT
      | ParseParams.Error =>
          Wr.PutText(stderr, "Usage: PZComputeCurvature \\\n");
          Wr.PutText(stderr, "  -input FILE \\\n");
          Wr.PutText(stderr, "  -output FILE \\\n");
          Wr.PutText(stderr, "  -lambda NUMBER \n");
        Process.Exit(1);
      END;
    END;
    RETURN o

  END GetOptions;

PROCEDURE PZComputeCurvatureComments(READONLY o: Options; nSamples: NAT):TEXT=
  BEGIN
    WITH
      wr = NEW(TextWr.T).init()
    DO
      Wr.PutText( wr, "PZComputeCurvature:\n");
      Wr.PutText( wr, "  input: " & o.input & "\n");
      Wr.PutText( wr, "  output: " & o.output & "\n");
      Wr.PutText( wr, "  lambda: " & Fmt.LongReal(o.lambda) & "\n");
      Wr.PutText( wr, "  nSamples: " & Fmt.Int(nSamples));
      RETURN(TextWr.ToText(wr))
    END (* DO *);
  END PZComputeCurvatureComments;

BEGIN
  Main()
END PZComputeCurvature.
(*
  Copyright © 2001 Universidade Estadual de Campinas (UNICAMP).
  Authors: Helena C. G. Leitão and Jorge Stolfi.
  
  This file can be freely distributed, used, and modified, provided
  that this copyright and authorship notice is preserved, and that any
  modified versions are clearly marked as such.
  
  This software has NO WARRANTY of correctness or applicability for
  any purpose. Neither the authors nor their employers chall be held
  responsible for any losses or damages that may result from its use.
*)