/* CMD: Julienne
 *
 * Finely slice an object along an axis.  This is a useful precursor
 * to bend.
 */
syscode = "Julienne"
sysnam = "Julienne"
statfil = 'T:julienne.state'
version = 'Julienne v1.0'

	/* Boilerplate.
	 */
	mxx="LWModelerARexx.port"
	signal on error
	signal on syntax
	mxx_add = addlib(mxx,0)
  call addlib "rexxsupport.library", 0, -30, 0
	call main
	if (mxx_add) then call remlib(mxx)
	exit

	syntax:
	error:
	t=Notify(1,'!Rexx Script Error','@'ErrorText(rc),'Line 'SIGL)
	if (mxx_add) then call remlib(mxx)
	exit



MAIN:

fg = curlayer()
emp = emptylayers()
if (words(emp) = 0) then do
    call notify(1,"!Need a background layer for scratch work.")
    return
end
temp = word(emp,1)

if (setup() = 0) then return


/* Compute transpositions for selected axis.  Vectors are transposed
 * with xr when coming from Modeler, and transposed with xf when going
 * out to Modeler.  Internally, we think of X as the slice axis, and
 * Z as the drill axis.
 */
select
    when (axis = 1) then do
	xf = 1 2 3
	xr = 1 2 3
	end
    when (axis = 2) then do
	xf = 2 1 3
	xr = 2 1 3
	end
    otherwise do
	xf = 2 3 1
	xr = 3 1 2
	end
    end

/* Get bounding box for fg data transposed into local space.
 */
parse value boundingbox() with n x1 x2 y1 y2 z1 z2 .
if (n = 0) then return
lo = xpose(x1 y1 z1, xr)
hi = xpose(x2 y2 z2, xr)

/* Compute ranges for x and y.  Add small offsets to make our values
 * overlap the actual bounds.
 */
x1 = word(lo,1)
x2 = word(hi,1)
d = (x2 - x1) / 101
x1 = x1 - d
x2 = x2 + d
xw = (x2 - x1) / divs

y1 = word(lo,2)
y2 = word(hi,2)
d = (y2 - y1) / 3
y1 = y1 - d
y2 = y2 + d

/* Goto background layer and build our slicing blades.
 */
call setlayer(temp)
call add_begin()
x0 = x1 + xw
do i=1 to divs/2
    i1 = add_point(xpose(x0 y1 0, xf))
    i2 = add_point(xpose(x0 y2 0, xf))
    x0 = x0 + xw
    i3 = add_point(xpose(x0 y2 0, xf))
    i4 = add_point(xpose(x0 y1 0, xf))
    x0 = x0 + xw

    call add_polygon(i1 i2 i3 i4)
end i
call add_end()

/* Perform the slice and remove the blades.
 */
call setlayer(fg)
call setblayer(temp)
call axisdrill('slice', word('x y z', word(xr, 3)))
call setlayer(temp)
call cut()
call setlayer(fg)

return



SETUP:

/* Setup state variables, reading stored ones, if any.
 */
axis = 1
divs = 20
if (exists(statfil)) then do
    if (~open(state, statfil, 'R')) then break
    if (readln(state) ~= version) then break
    parse value readln(state) with axis divs .
    call close state
end

/* Query user for their function and area to evaluate.
 */
call req_begin sysnam

id_axis = req_addcontrol("Axis", 'c', 'X Y Z')
id_divs = req_addcontrol("Divisions", 'n')

call req_setval id_axis, axis
call req_setval id_divs, divs, 20

if (~req_post()) then do
    call req_end
    return 0
end

axis = req_getval(id_axis)
divs = req_getval(id_divs) % 1

call req_end

/* Save state now, in case something fails.
 */
if (open(state, statfil, 'W')) then do
    call writeln state, version
    call writeln state, axis divs
    call close state
end

return 1


/* Transpose the positions in a vector by the indices in x.
 * If the vector is X Y Z and the transposition is 2 3 1, then
 * the resultant vector is Y Z X.
 */
Xpose: procedure
    arg v, x
    vv = ''
    do i=1 to 3
	vv = vv word(v,word(x,i))
    end i
    return vv
