/* Representation and tools of slicing planes. */
/* Last edited on 2015-10-18 02:16:02 by stolfilocal  */

#ifndef salamic_planes_H
#define salamic_planes_H

#define _GNU_SOURCE
#include <stdio.h>

#include <vec.h>
#include <bool.h>
#include <i3.h>

/* THE SLICING PLANES */

/* The slicing planes are required to be horizontal (parallel to the {X}
  and {Y} axes) and their {Z}-coordinates must be odd integer multiples 
  of a given fundamental length unit {eps} (mm), in
  strictly increasing order. Each plane is represented by an odd integer
  {pZ}, and is supposed to be at {Z}-coordinate {pZ*eps}.
  
  In the following procedures, {minZ} and {maxZ} must be even
  integers. The procedures only return planes whose quantized
  {Z}-coordinate {pZ} lies in the range {minZ..maxZ}. */

int_vec_t salamic_planes_get_uniform(float startZ, float deltaZ, float eps, int minZ, int maxZ);
  /* Returns a vector of the quantized {Z} coordinates of uniformly spaced slicing planes.
    
    Roughly speaking, the plane spacing will be {deltaZ}, and one of the planes in principle 
    would go through the {Z}-coordinate {startZ}. Both {startZ} and {deltaZ}
    are quantized to integer multiples of {eps}.  More precisely, 
    the procedure computes {sZ = startZ/eps} rounded to the nearest odd
    integer, and {dZ = deltaZ/eps}, rounded to the nearest even integer. Then it
    returns a vector with all odd integers in the range {minZ..maxZ}
    that are congruent to {sZ} modulo {dZ}.
    
    The rounding of {dZ} may change the spacing of the planes by as much
    as {eps} in either direction. Therefore, {eps} should be
    substantially smaller than {deltaZ} to minimize the relative error
    in the specified plane coordinates. For example, if {deltaZ} is
    0.215 mm, and {eps} is 0.001 mm, then {dZ} will be 214, and the
    spacing of the planes returned by this procedure {dZ*eps}, that is,
    0.214 mm. If the object is {h = 200 mm} tall, there will be {np =
    934} slicing planes instead of 930, and the last one will be off the
    expected position by {np*(dZ*eps - deltaZ) = 0.934 mm}. */

int_vec_t salamic_planes_get_adaptive(char *ZFile, float eps, int minZ, int maxZ);
  /* Returns a vector with the quantized {Z} coordinates of slicing
    planes read from file {ZFile}. Each {Z}-coordinate read from the
    file is divided by the fundamental unit of length {eps} and rounded
    to the nearest odd integer. Discards integers outside the range
    {minZ..maxZ}. The file format is specified by 72
    {salamic_planes_file_format_INFO} below. */
     
#define salamic_planes_file_format_INFO \
  "The file must contain one line with the number of slicing planes {NP}, then" \
  " {NP} lines, each with a single-precision floating-point {Z}-coordinate" \
  " (in millimeters). Blanks are ignored, but there must be no blank" \
  " lines.  The {Z}-coordinates need not be uniformly spaced but must" \
  " be strictly increasing after quantization."

#endif
