Dear Octave forge developers,
I am relatively new to octave (had a first look at it last year) and noticed
that in the field of 3d graphical data processing there are some missing
functions like isosurface and other related functions.
I made preliminary substitutes for some of them for my own use which I would
like to share if there is interest.
The isosurface function is based on a vectorized form of the marching cube
algorithm. The original marching cube algorithm was patented in the past, but
the patent expired a few years ago, so I can see no legal problem using it in
the open source community.
If someone sees a problem problem with that, I implement at the moment the
marching tetrahedron algorithm which can then be used instead.
For the next time I plan to implement isocaps too.
Code documentation and error handling needs to be improved, no plan when I
will find time, but I will do it.
Since it seems to be that jhandles is the only graphical backend which has all
necessary features for visualization of the corresponding 3d patches including
facelighting and gouraud shading, the first tests I made are exclusively done
with it (jhandles 0.3.4 and octave 3.0.3).
I also made some preliminary tests with fltk and octave 3.1.53+ built from the
mercurial repository that shows a noticable performance enhacement for the
algorithm (the subscripting with the development sources are much faster) and
the basic visualization features are working well without lighting (the light
function is missing).
Attached you can find the implementations to have a look at it. You can tell
me if they are appropriate or not. There is also a simple octave package which
is available on my private homepage. (I am not familiar with the packaging
system but it worked for me).
http://www.mhelm.de/octave/pkg/visualize3d-0.1.2.tar.gz
With some simple examples
http://www.mhelm.de/octave/index.html
Kind regards
Martin Helm
## Copyright (C) 2009 Martin Helm
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
##
## Author: Martin Helm <[email protected]>
## usage: [Vxyz, idx, frac] = interp_cube(x, y, z, val, v)
##
function [Vxyz, idx, frac] = interp_cube(x, y, z, val, v, req = "values" )
if ( ismatrix(x) && ndims(x) == 3 && ismatrix(y) && ndims(y) == 3 ...
&& ismatrix(z) && ndims(z) == 3 && size(x) == size(y) ...
&& size(y) == size(z) )
x = squeeze(x(1,:,1))(:);
y = squeeze(y(:,1,1))(:);
z = squeeze(z(1,1,:))(:);
elseif (isvector(x) && isvector(y) && isvector(z) )
x = x(:);
y = y(:);
z = z(:);
else
error("x, y, z have wrong dimensions");
endif
if (size(val) != [length(x), length(y), length(z) ] )
error("val has wrong dimensions");
endif
if (size(v, 2) != 3 )
error( "v has to be N*3 matrix");
endif
if ( !ischar(req) )
error ("Invalid request parameter use 'values' or 'normals'");
endif
switch req
case "values"
[Vxyz, idx, frac] = interp_cube_trilin(x, y, z, val, v);
case "normals"
[idx, frac] = cube_idx(x, y, z, v);
dx = x(2:end) - x(1:end-1);
dy = y(2:end) - y(1:end-1);
dz = z(2:end) - z(1:end-1);
dx = 0.5 .* [dx;dx(end)](idx(:,2));
dy = 0.5 .* [dy;dy(end)](idx(:,1));
dz = 0.5 .* [dz;dz(end)](idx(:,3));
p000 = [v(:, 1) - dx, v(:, 2) - dy, v(:, 3) - dz];
p100 = [v(:, 1) + dx, v(:, 2) - dy, v(:, 3) - dz];
p010 = [v(:, 1) - dx, v(:, 2) + dy, v(:, 3) - dz];
p001 = [v(:, 1) - dx, v(:, 2) - dy, v(:, 3) + dz];
p011 = [v(:, 1) - dx, v(:, 2) + dy, v(:, 3) + dz];
p101 = [v(:, 1) + dx, v(:, 2) - dy, v(:, 3) + dz];
p110 = [v(:, 1) + dx, v(:, 2) + dy, v(:, 3) - dz];
p111 = [v(:, 1) + dx, v(:, 2) + dy, v(:, 3) + dz];
v000 = interp_cube_trilin(x, y, z, val, p000);
v100 = interp_cube_trilin(x, y, z, val, p100);
v010 = interp_cube_trilin(x, y, z, val, p010);
v001 = interp_cube_trilin(x, y, z, val, p001);
v011 = interp_cube_trilin(x, y, z, val, p011);
v101 = interp_cube_trilin(x, y, z, val, p101);
v110 = interp_cube_trilin(x, y, z, val, p110);
v111 = interp_cube_trilin(x, y, z, val, p111);
Bx = By = Bz = 0.5;
Dx = ...
v000 .* -1 .* (1 .- By) .* (1 .- Bz) .+ ...
v100 .* (1 .- By) .* (1 .- Bz) .+ ...
v010 .* -1 .* By .* (1 .- Bz) .+ ...
v001 .* -1 .* (1 .- By) .* Bz .+ ...
v011 .* -1 .* By .* Bz .+ ...
v101 .* (1 .- By) .* Bz .+ ...
v110 .* By .* (1 .- Bz) .+ ...
v111 .* By .* Bz;
Dy = ...
v000 .* (1 .- Bx) .* -1 .* (1 .- Bz) .+ ...
v100 .* Bx .* -1 .* (1 .- Bz) .+ ...
v010 .* (1 .- Bx) .* (1 .- Bz) .+ ...
v001 .* (1 .- Bx) .* -1 .* Bz .+ ...
v011 .* (1 .- Bx) .* Bz .+ ...
v101 .* Bx .* -1 .* Bz .+ ...
v110 .* Bx .* (1 .- Bz) .+ ...
v111 .* Bx .* Bz;
Dz = ...
v000 .* (1 .- Bx) .* (1 .- By) .* -1 .+ ...
v100 .* Bx .* (1 .- By) .* -1 .+ ...
v010 .* (1 .- Bx) .* By .* -1 .+ ...
v001 .* (1 .- Bx) .* (1 .- By) .+ ...
v011 .* (1 .- Bx) .* By + ...
v101 .* Bx .* (1 .- By) .+ ...
v110 .* Bx .* By .* -1 .+ ...
v111 .* Bx .* By;
Vxyz = 2 .* [ Dx./dx, Dy./dy, Dz./dz ];
case "normals8"
[idx, frac] = cube_idx(x, y, z, v);
dx = x(2:end) - x(1:end-1);
dy = y(2:end) - y(1:end-1);
dz = z(2:end) - z(1:end-1);
dx = [dx;dx(end)](idx(:,2));
dy = [dy;dy(end)](idx(:,1));
dz = [dz;dz(end)](idx(:,3));
[Dx, Dy, Dz, idx, frac] = interp_cube_trilin_grad(x, y, z, val, v);
Vxyz = [ Dx./dx, Dy./dy, Dz./dz ];
otherwise
error ("Invalid request type '%s', use 'values' or 'normals'", req);
endswitch
endfunction
function [Vxyz, idx, frac] = interp_cube_trilin(x, y, z, val, v)
[idx, frac] = cube_idx(x(:), y(:), z(:), v);
sval = size(val);
i000 = sub2ind(sval, idx(:, 1), idx(:, 2), idx(:, 3));
i100 = sub2ind(sval, idx(:, 1)+1, idx(:, 2), idx(:, 3));
i010 = sub2ind(sval, idx(:, 1), idx(:, 2)+1, idx(:, 3));
i001 = sub2ind(sval, idx(:, 1), idx(:, 2), idx(:, 3)+1);
i101 = sub2ind(sval, idx(:, 1)+1, idx(:, 2), idx(:, 3)+1);
i011 = sub2ind(sval, idx(:, 1), idx(:, 2)+1, idx(:, 3)+1);
i110 = sub2ind(sval, idx(:, 1)+1, idx(:, 2)+1, idx(:, 3));
i111 = sub2ind(sval, idx(:, 1)+1, idx(:, 2)+1, idx(:, 3)+1 );
Bx = frac(:, 1);
By = frac(:, 2);
Bz = frac(:, 3);
Vxyz = ...
val( i000 ) .* (1 .- Bx) .* (1 .- By) .* (1 .- Bz) .+ ...
val( i100 ) .* Bx .* (1 .- By) .* (1 .- Bz) .+ ...
val( i010 ) .* (1 .- Bx) .* By .* (1 .- Bz) .+ ...
val( i001 ) .* (1 .- Bx) .* (1 .- By) .* Bz .+ ...
val( i011 ) .* (1 .- Bx) .* By .* Bz .+ ...
val( i101 ) .* Bx .* (1 .- By) .* Bz .+ ...
val( i110 ) .* Bx .* By .* (1 .- Bz) .+ ...
val( i111 ) .* Bx .* By .* Bz;
endfunction
function [Dx, Dy, Dz, idx, frac] = interp_cube_trilin_grad(x, y, z, val, v)
[idx, frac] = cube_idx(x(:), y(:), z(:), v);
sval = size(val);
i000 = sub2ind(sval, idx(:, 1), idx(:, 2), idx(:, 3));
i100 = sub2ind(sval, idx(:, 1)+1, idx(:, 2), idx(:, 3));
i010 = sub2ind(sval, idx(:, 1), idx(:, 2)+1, idx(:, 3));
i001 = sub2ind(sval, idx(:, 1), idx(:, 2), idx(:, 3)+1);
i101 = sub2ind(sval, idx(:, 1)+1, idx(:, 2), idx(:, 3)+1);
i011 = sub2ind(sval, idx(:, 1), idx(:, 2)+1, idx(:, 3)+1);
i110 = sub2ind(sval, idx(:, 1)+1, idx(:, 2)+1, idx(:, 3));
i111 = sub2ind(sval, idx(:, 1)+1, idx(:, 2)+1, idx(:, 3)+1 );
Bx = frac(:, 1);
By = frac(:, 2);
Bz = frac(:, 3);
Dx = ...
val( i000 ) .* -1 .* (1 .- By) .* (1 .- Bz) .+ ...
val( i100 ) .* (1 .- By) .* (1 .- Bz) .+ ...
val( i010 ) .* -1 .* By .* (1 .- Bz) .+ ...
val( i001 ) .* -1 .* (1 .- By) .* Bz .+ ...
val( i011 ) .* -1 .* By .* Bz .+ ...
val( i101 ) .* (1 .- By) .* Bz .+ ...
val( i110 ) .* By .* (1 .- Bz) .+ ...
val( i111 ) .* By .* Bz;
Dy = ...
val( i000 ) .* (1 .- Bx) .* -1 .* (1 .- Bz) .+ ...
val( i100 ) .* Bx .* -1 .* (1 .- Bz) .+ ...
val( i010 ) .* (1 .- Bx) .* (1 .- Bz) .+ ...
val( i001 ) .* (1 .- Bx) .* -1 .* Bz .+ ...
val( i011 ) .* (1 .- Bx) .* Bz .+ ...
val( i101 ) .* Bx .* -1 .* Bz .+ ...
val( i110 ) .* Bx .* (1 .- Bz) .+ ...
val( i111 ) .* Bx .* Bz;
Dz = ...
val( i000 ) .* (1 .- Bx) .* (1 .- By) .* -1 .+ ...
val( i100 ) .* Bx .* (1 .- By) .* -1 .+ ...
val( i010 ) .* (1 .- Bx) .* By .* -1 .+ ...
val( i001 ) .* (1 .- Bx) .* (1 .- By) .+ ...
val( i011 ) .* (1 .- Bx) .* By + ...
val( i101 ) .* Bx .* (1 .- By) .+ ...
val( i110 ) .* Bx .* By .* -1 .+ ...
val( i111 ) .* Bx .* By;
endfunction
function [idx, frac] = cube_idx(x, y, z, v)
idx = zeros(size(v));
frac = zeros(size(v));
idx(:, 2) = lookup(x(2:end-1), v(:, 1)) + 1;
frac(:, 2) = (v(:, 1) - x(idx(:, 2)) )...
./ (x(idx(:, 2)+1) - x(idx(:, 2)));
idx(:, 1) = lookup(y(2:end-1), v(:, 2)) + 1;
frac(:, 1) = (v(:, 2) - y(idx(:, 1))) ...
./ (y(idx(:, 1)+1) - y(idx(:, 1)));
idx(:, 3) = lookup(z(2:end-1), v(:, 3)) + 1;
frac(:, 3) = (v(:, 3) - z(idx(:, 3))) ...
./ (z(idx(:, 3)+1) - z(idx(:, 3)));
endfunction## Copyright (C) 2009 Martin Helm
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
##
## Author: Martin Helm <[email protected]>
## usage: NC = isocolors(X,Y,Z,C,VERT)
## usage: NC = isocolors(X,Y,Z,R,G,B,VERT)
## usage: NC = isocolors(C,VERT)
## usage: NC = isocolors(R,G,B,VERT)
## usage: NC = isocolors(...,PatchHandle)
## usage: isocolors(...,PatchHandle)
function varargout = isocolors(varargin)
calc_rgb = false;
switch nargin
case 2
c = varargin{1};
vp = varargin{2};
x = 1:size(c, 2);
y = 1:size(c, 1);
z = 1:size(c, 3);
case 4
calc_rgb = true;
R = varargin{1};
G = varargin{2};
B = varargin{3};
vp = varargin{4};
x = 1:size(R, 1);
y = 1:size(R, 2);
z = 1:size(R, 3);
case 5
x = varargin{1};
y = varargin{2};
z = varargin{3};
c = varargin{4};
vp = varargin{5};
case 7
calc_rgb = true;
x = varargin{1};
y = varargin{2};
z = varargin{3};
R = varargin{4};
G = varargin{5};
B = varargin{6};
vp = varargin{7};
otherwise
print_usage();
endswitch
if (ismatrix(vp) && size(vp,2) == 3)
pa = [];
v = vp;
elseif ( ishandle(vp) )
pa = vp;
v = get(pa, "Vertices");
else
error("Last argument is no vertex list and no patch handle");
endif
if ( calc_rgb )
new_col = zeros(size(v, 1), 3);
new_col(:, 1) = interp_cube(x, y, z, R, v, "values" );
new_col(:, 2) = interp_cube(x, y, z, G, v, "values" );
new_col(:, 3) = interp_cube(x, y, z, B, v, "values" );
else
new_col = interp_cube(x, y, z, c, v, "values" );
endif
switch nargout
case 0
if ( ! isempty(pa) )
set(pa, "FaceVertexCData", new_col);
endif
case 1
varargout = {new_col};
otherwise
print_usage();
endswitch
endfunction## Copyright (C) 2009 Martin Helm
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
##
## Author: Martin Helm <[email protected]>
## usage: NORMALS = isonormals(X,Y,Z,V,VERT)
## usage: NORMALS = isonormals(V,VERT)
## usage: NORMALS = isonormals(V,P)
## usage: NORMALS = isonormals(X,Y,Z,V,P)
## usage: NORMALS = isonormals(...,'negate')
## usage: isonormals(V,P)
## usage: isonormals(X,Y,Z,V,P)
##
function varargout = isonormals(varargin)
na = nargin;
negate = false;
if ( ischar(varargin{nargin}) )
na = nargin-1;
if ( strcmp( lower(varargin{nargin}), "negate") )
negate = true;
else
error("Unknown option '%s'", varargin{nargin} );
endif
endif
switch na
case 2
c = varargin{1};
vp = varargin{2};
x = 1:size(c, 2);
y = 1:size(c, 1);
z = 1:size(c, 3);
case 5
x = varargin{1};
y = varargin{2};
z = varargin{3};
c = varargin{4};
vp = varargin{5};
otherwise
print_usage();
endswitch
if (ismatrix(vp) && size(vp,2) == 3)
pa = [];
v = vp;
elseif ( ishandle(vp) )
pa = vp;
v = get(pa, "Vertices");
else
error("Last argument is no vertex list and no patch handle");
endif
if (negate)
normals = -interp_cube(x, y, z, c, v, "normals" );
else
normals = interp_cube(x, y, z, c, v, "normals" );
endif
switch nargout
case 0
if ( ! isempty(pa) )
set(pa, "VertexNormals", normals);
endif
case 1
varargout = {normals};
otherwise
print_usage();
endswitch
endfunction## Copyright (C) 2009 Martin Helm
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
##
## Author: Martin Helm <[email protected]>
## usage: FV = isosurface(X,Y,Z,V,ISO)
## FV = isosurface(V,ISO)
## FVC = isosurface(...,C)
## FV = isosurface(...,'noshare')
## FV = isosurface(...,'verbose')
## [F,V] = isosurface(...)
## [F,V,C] = isosurface(...)
## isosurface(...)
##
function varargout = isosurface(varargin)
if ( nargin <2 || nargin > 8 || nargout > 3)
print_usage();
endif
calc_colors = false;
f = v = c = [];
verbose = false;
noshare = false;
if (nargin >= 5)
x = varargin{1};
y = varargin{2};
z = varargin{3};
val = varargin{4};
iso = varargin{5};
if ( nargin >= 6 && ismatrix(varargin{6}) )
colors = varargin{6};
calc_colors = true;
endif
else
val = varargin{1};
[n1, n2, n3] = size(val);
[x, y, z] = meshgrid(1:n1, 1:n2, 1:n3);
iso = varargin{2};
if (nargin >= 3 && ismatrix(varargin{3}) )
colors = varargin{3};
calc_colors = true;
endif
endif
if ( calc_colors )
if ( nargout == 2 )
warning ( "Colors will be calculated, but you did not specify an output argument for it!" );
endif
[f, v, c] = marching_cube(x, y, z, val, iso, colors);
else
[f, v] = marching_cube(x, y, z, val, iso);
endif
if ( isempty(f) || isempty(v) )
warning( "The resulting triangulation is empty" );
endif
switch (nargout)
case 0
# plot the calculated surface
if ( calc_colors )
pa = patch('Faces', f,'Vertices',v ,'FaceVertexCData', c);
else
pa = patch('Faces', f,'Vertices', v);
endif
case 1
## this is a little bit special, we can return a struct but patch cannot
## use it, with this workaround a syntax like
## patch(isosurface(...){:}) is possible
if ( calc_colors )
varargout = {{"Faces", f, "Vertices", v, "FaceVertexCData", c }};
else
varargout = {{"Faces", f, "Vertices", v}};
endif
case 2
varargout = {f, v};
case 3
varargout = {f, v, c};
otherwise
print_usage();
endswitch
endfunction
## Copyright (C) 2009 Martin Helm
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see http://www.gnu.org/licenses/gpl.html.
##
## Author: Martin Helm <[email protected]>
## usage: [T, P] = marching_cube( XX, YY, ZZ, C, ISO)
## usage: [T, P, COL] = marching_cube( XX, YY, ZZ, C, ISO, COLOR)
##
## Calculates the triangulation T with points P for the isosurface
## with level ISO. XX, YY, ZZ are meshgrid like values for the
## cube and C holds the scalar values of the field,
## COLOR holds additinal scalar values for coloring the surface.
## The orientation of the triangles is choosen such that the
## normals point from the lower values to the higher values.
##
## edgeTable and triTable are taken from Paul Bourke
## (http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/)
## Based on tables by Cory Gene Bloyd
##
## Example:
##
## x = linspace(0, 2, 20);
## y = linspace(0, 2, 20);
## z = linspace(0, 2, 20);
##
## [ xx, yy, zz ] = meshgrid(x, y, z);
##
## c = (xx-.5).^2 + (yy-.5).^2 + (zz-.5).^2;
## [T, p] = marching_cube(xx, yy, zz, c, 0.5);
## trimesh(T, p(:, 1), p(:, 2), p(:, 3));
##
## with jhandles you can also use the patch function to visualize
##
## clf
## pa = patch('Faces',T,'Vertices',p,'FaceVertexCData',p, ...
## 'FaceColor','interp', 'EdgeColor', 'none');
## set(pa, "VertexNormals", -get(pa, "VertexNormals")) # revert normals
## view(-30, 30)
## set(pa, "FaceLighting", "gouraud")
## light( "Position", [1 1 5])
##
function [T, p, col] = marching_cube( xx, yy, zz, c, iso, colors)
persistent edgeTable=[];
persistent triTable=[];
calc_cols = false;
lindex = 4;
if ( isempty(triTable) || isempty(edgeTable) )
[edgeTable, triTable] = init_mc();
endif
if ( (nargin != 5 && nargin != 6) || (nargout != 2 && nargout != 3) )
print_usage ();
endif
if ( !ismatrix(xx) || !ismatrix(yy) || !ismatrix(zz) || !ismatrix(c) || ...
ndims(xx) != 3 || ndims(yy) != 3 || ndims(zz) != 3 || ndims(c) != 3 )
error("xx, yy, zz, c have to be matrizes of dim 3");
endif
if ( size(xx) != size(yy) || size(yy) != size(zz)|| size(zz) != size(c) )
error("xx, yy, zz, c are not the same size");
endif
if ( any(size(xx) < [2 2 2]) )
error("grid size has to be at least 2x2x2");
endif
if ( !isscalar(iso) )
error("iso needs to be scalar value");
endif
if ( nargin == 6 )
if ( !ismatrix(colors) || ndims(colors) != 3 || size(colors) != size(c) )
error( "color has to be matrix of dim 3 and of same size as c" );
endif
calc_cols = true;
lindex = 5;
endif
n = size(c) - 1;
## phase I: assign information to each voxel which edges are intersected by
## the isosurface
cc = zeros(n(1), n(2), n(3), "uint16");
cedge = zeros(size(cc), "uint16");
vertex_idx = {1:n(1), 1:n(2), 1:n(3); ...
2:n(1)+1, 1:n(2), 1:n(3); ...
2:n(1)+1, 2:n(2)+1, 1:n(3); ...
1:n(1), 2:n(2)+1, 1:n(3); ...
1:n(1), 1:n(2), 2:n(3)+1; ...
2:n(1)+1, 1:n(2), 2:n(3)+1; ...
2:n(1)+1, 2:n(2)+1, 2:n(3)+1; ...
1:n(1), 2:n(2)+1, 2:n(3)+1 };
## calculate which vertices have values less than iso
for ii=1:8
idx = c(vertex_idx{ii, :}) < iso;
cc(idx) = bitset(cc(idx), ii);
endfor
cedge = edgeTable(cc+1); # assign the info about intersected edges
id = find(cedge); # select only voxels which are intersected
## phase II: calculate the list of intersection points
xyz_off = [1, 1, 1; 2, 1, 1; 2, 2, 1; 1, 2, 1; 1, 1, 2; 2, 1, 2; 2, 2, 2; 1, 2, 2];
edges = [1 2; 2 3; 3 4; 4 1; 5 6; 6 7; 7 8; 8 5; 1 5; 2 6; 3 7; 4 8];
offset = sub2ind(size(c), xyz_off(:, 1), xyz_off(:, 2), xyz_off(:, 3)) -1;
pp = zeros(length(id), lindex, 12);
ccedge = [vec(cedge(id)), id];
ix_offset=0;
for jj=1:12
id__ = bitget(ccedge(:, 1), jj);
id_ = ccedge(id__, 2);
[ix iy iz] = ind2sub(size(cc), id_);
id_c = sub2ind(size(c), ix, iy, iz);
id1 = id_c + offset(edges(jj, 1));
id2 = id_c + offset(edges(jj, 2));
if ( calc_cols )
pp(id__, 1:5, jj) = [vertex_interp(iso, xx(id1), yy(id1), zz(id1), ...
xx(id2), yy(id2), zz(id2), c(id1), c(id2), colors(id1), colors(id2)), ...
(1:size(id_, 1))' + ix_offset ];
else
pp(id__, 1:4, jj) = [vertex_interp(iso, xx(id1), yy(id1), zz(id1), ...
xx(id2), yy(id2), zz(id2), c(id1), c(id2)), ...
(1:size(id_, 1))' + ix_offset ];
endif
ix_offset += size(id_, 1);
endfor
## phase III: calculate the triangulation from the point list
T = [];
tri = triTable(cc(id)+1, :);
for jj=1:3:15
id_ = find(tri(:, jj)>0);
p = [id_, lindex*ones(size(id_, 1), 1),tri(id_, jj:jj+2) ];
if ( ! isempty(p) )
p1 = sub2ind(size(pp), p(:,1), p(:,2), p(:,3));
p2 = sub2ind(size(pp), p(:,1), p(:,2), p(:,4));
p3 = sub2ind(size(pp), p(:,1), p(:,2), p(:,5));
T = [T; pp(p1), pp(p2), pp(p3)];
endif
endfor
p = [];
col = [];
for jj = 1:12
idp = pp(:, lindex, jj) > 0;
if ( ! isempty(idp) )
p(pp(idp, lindex, jj), 1:3) = pp(idp, 1:3, jj);
if ( calc_cols )
col(pp(idp, lindex, jj),1) = pp(idp, 4, jj);
endif
endif
endfor
endfunction
function p = vertex_interp(isolevel,p1x, p1y, p1z,...
p2x, p2y, p2z,valp1,valp2, col1, col2)
if (nargin == 9)
p = zeros(length(p1x), 3);
elseif (nargin == 11)
p = zeros(length(p1x), 4);
else
error ("Wrong number of arguments");
endif
mu = zeros(length(p1x), 1);
id = abs(valp1-valp2) < (10*eps) .* (abs(valp1) .+ abs(valp2));
p(id, 1:3) = [ p1x(id), p1y(id), p1z(id) ];
mu(!id) = (isolevel - valp1(!id)) ./ (valp2(!id) - valp1(!id));
p(!id, 1:3) = [p1x(!id) + mu(!id) .* (p2x(!id) - p1x(!id)), ...
p1y(!id) + mu(!id) .* (p2y(!id) - p1y(!id)), ...
p1z(!id) + mu(!id) .* (p2z(!id) - p1z(!id))];
if ( nargin == 11 )
p(!id, 4) = col1(!id) + mu(!id) .* (col2(!id) - col1(!id));
endif
endfunction
function [edgeTable, triTable] = init_mc()
edgeTable = [
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, ...
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, ...
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, ...
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, ...
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, ...
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, ...
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, ...
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, ...
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, ...
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, ...
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, ...
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, ...
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, ...
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, ...
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , ...
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, ...
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, ...
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, ...
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, ...
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, ...
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, ...
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, ...
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, ...
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, ...
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, ...
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, ...
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, ...
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, ...
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, ...
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, ...
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, ...
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 ];
triTable =[
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1;
3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1;
3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1;
3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1;
9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1;
1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1;
9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1;
2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1;
8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1;
9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1;
4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1;
3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1;
1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1;
4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1;
4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1;
9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1;
1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1;
5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1;
2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1;
9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1;
0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1;
2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1;
10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1;
4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1;
5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1;
5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1;
9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1;
0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1;
1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1;
10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1;
8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1;
2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1;
7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1;
9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1;
2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1;
11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1;
9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1;
5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1;
11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1;
11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1;
1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1;
9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1;
5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1;
2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1;
0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1;
5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1;
6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1;
0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1;
3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1;
6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1;
5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1;
1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1;
10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1;
6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1;
1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1;
8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1;
7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1;
3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1;
5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1;
0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1;
9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1;
8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1;
5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1;
0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1;
6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1;
10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1;
10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1;
8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1;
1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1;
3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1;
0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1;
10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1;
0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1;
3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1;
6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1;
9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1;
8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1;
3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1;
6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1;
0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1;
10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1;
10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1;
1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1;
2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1;
7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1;
7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1;
2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1;
1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1;
11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1;
8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1;
0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1;
7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1;
10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1;
2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1;
6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1;
7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1;
2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1;
1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1;
10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1;
10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1;
0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1;
7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1;
6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1;
8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1;
9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1;
6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1;
1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1;
4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1;
10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1;
8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1;
0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1;
1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1;
8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1;
10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1;
4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1;
10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1;
5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1;
11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1;
9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1;
6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1;
7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1;
3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1;
7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1;
9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1;
3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1;
6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1;
9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1;
1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1;
4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1;
7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1;
6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1;
3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1;
0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1;
6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1;
1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1;
0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1;
11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1;
6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1;
5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1;
9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1;
1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1;
1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1;
10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1;
0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1;
5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1;
10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1;
11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1;
0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1;
9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1;
7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1;
2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1;
8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1;
9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1;
9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1;
1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1;
9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1;
9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1;
5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1;
0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1;
10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1;
2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1;
0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1;
0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1;
9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1;
5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1;
3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1;
5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1;
8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1;
0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1;
9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1;
0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1;
1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1;
3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1;
4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1;
9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1;
11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1;
11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1;
2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1;
9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1;
3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1;
1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1;
4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1;
4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1;
0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1;
3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1;
3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1;
0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1;
9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1;
1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ] + 1;
endfunction------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Octave-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/octave-dev