/* voxm_splat_tube.h --- voxel-based modeling of tubes and ropes */
/* Last edited on 2016-04-03 20:24:29 by stolfilocal */

#ifndef voxm_splat_tube_H
#define voxm_splat_tube_H

#define _GNU_SOURCE
#include <stdint.h>

#include <bool.h>
#include <r3.h>
#include <r3_path.h>
#include <ppv_array.h>

#include <voxm_path.h>
#include <voxm_bezier.h>

/* SPLATTING TUBES, ROPES, ETC 

  Each procedure in this section splats into the tomogram {a} a "fuzzy
  worm", an object obtained by sweeping a "fuzzy brush" along a path.
  
  The path is densely sampled so that no part of the brush moves more
  than a fraction of a voxel between samples. A copy of the brush is
  positioned at each sample point, and turned so that a fixed axis of it
  is tangent to the direction of travel. These copies of the brush are
  then united (by taking the max of their occupancy functions) to
  generate the worm object.
  
  If {sub} is false, the brush is a fuzzy torus with outer radius {otR} and
  hole radius {inR}, so that the worm is a tube with outer radius {otR}
  and inner radius {inR}. The tube is united (splatted with
  {max}) with the objects already in {a}.
  
  If {sub} is true, the brush is a fuzzy sphere with radius {inR}, so that the 
  worm is a fuzzy wire with radius {inR}.  The wire is subtracted (complemented
  and splatted with {min}) from the objects already in {a}.  This is useful to ensure that the bore of a 
  tube is clear even if it crosses other objects. 
  
  Either way, the worm has a fuzzy layer that
  extends {fuzzR} on both sides of the outer and inner surface.
 
 */
 
void voxm_splat_tube_round_helix
  ( ppv_array_t *a, 
    double t0,
    double t1,
    r3_path_state_t *S, 
    double L, 
    double A,
    double H, 
    double inR, 
    double otR, 
    double fuzzR, 
    bool_t sub,
    r3_path_state_t *S0,
    r3_path_state_t *S1
  );
  /* The midline is an arc of helix,  generated by {r3_path_helix(t,L,A,H)} 
    where {t} ranges from {t0} to {t1}. 
    
    When {t} is zero, the path goes through the point {S.p}. The
    spiral's axis will be parallel to {S.w}, and the axis is
    located {L/A} units from {S.p} in the direction of {S.v}.
    The vector {S.u} will not be tangent to the tube's midline (unless {H} is
    zero), but is orthogonal to the spiral axis and tangent to the
    enclosing cylinder at {S.p}.
    
    Also returns in {*S0} and {*S1} (if they are not NULL) the
    first and last tangent states of the tube, with row 0 
    of the pose matrix tangent to the helix, row 1 pointing
    straight towards the helix axis, and row 2 perpendicular to both 
    (not parallel to the helix axis). */

void voxm_splat_tube_round_segment
  ( ppv_array_t *a, 
    voxm_path_state_t *S, 
    voxm_path_state_t *T, 
    double inR, 
    double otR, 
    double fuzzR, 
    bool_t sub
  );
  /* The midline starts with the path state {S} and
    ends with path state {T}. The velocity vector is interpreted as if
    the path was traversed in approximately unit time. */

void voxm_splat_tube_round_bezier
  ( ppv_array_t *a, 
    r3_t *p0, 
    r3_t *p1, 
    r3_t *p2, 
    r3_t *p3, 
    double inR, 
    double otR, 
    double fuzzR, 
    bool_t sub
  );
  /* The midline is a Bezier arc that starts at point {p0} moving towards
    {p1}, and ends at point {p3} as if coming straight from {p2}. */

#endif

