File: remeshsurf.m

package info (click to toggle)
octave-iso2mesh 1.9.8%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 11,128 kB
  • sloc: cpp: 11,982; ansic: 10,158; sh: 365; makefile: 59
file content (75 lines) | stat: -rw-r--r-- 2,408 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
function [newno, newfc] = remeshsurf(node, face, opt)
%
% [newno,newfc]=remeshsurf(node,face,opt)
%
% remesh a triangular surface and the output is guaranteed to be
% free of self-intersecting element. This function is similar to
% meshresample, but it can both downsample or upsample a mesh
%
% author: Qianqian Fang (q.fang at neu.edu)
%
% input:
%    node: list of nodes on the input suface mesh, 3 columns for x,y,z
%    face: list of trianglular elements on the surface, [n1,n2,n3,region_id]
%    opt: function parameters
%      opt.gridsize:  resolution for the voxelization of the mesh
%      opt.closesize: if there are openings, set the closing diameter
%      opt.elemsize:  the size of the element of the output surface
%      if opt is a scalar, it defines the elemsize and gridsize=opt/4
%
% output:
%    newno:  list of nodes on the resulting suface mesh, 3 columns for x,y,z
%    newfc:  list of trianglular elements on the surface, [n1,n2,n3,region_id]
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%

p0 = min(node);
p1 = max(node);

if (isstruct(opt))
    if (isfield(opt, 'gridsize'))
        dx = opt.gridsize;
    end
else
    dx = opt / 4;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% step 1: convert the old surface to a volumetric image
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
img = surf2vol(node, face, p0(1) - dx:dx:p1(1) + dx, p0(2) - dx:dx:p1(2) + dx, p0(3) - dx:dx:p1(3) + dx);

eg = surfedge(face);
closesize = 0;

if (~isempty(eg) && isstruct(opt))
    if (isfield(opt, 'closesize'))
        closesize = opt.closesize;
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% step 2: fill holes in the volumetric binary image
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

img = fillholes3d(img, closesize);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% step 3: convert the filled volume to a new surface
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if (isstruct(opt))
    if (isfield(opt, 'elemsize'))
        opt.radbound = opt.elemsize / dx;
        [newno, newfc] = v2s(img, 0.5, opt, 'cgalsurf');
    end
else
    opt = struct('radbound', opt / dx);
    [newno, newfc] = v2s(img, 0.5, opt, 'cgalsurf');
end

newno(:, 1:3) = newno(:, 1:3) * dx;
newno(:, 1) = newno(:, 1) + p0(1);
newno(:, 2) = newno(:, 2) + p0(2);
newno(:, 3) = newno(:, 3) + p0(3);