大致上还是沿用了loop细分中寻找边界的思路,将其中的一部分代码截出来形成了新的算法,如果一条边只被索引了一次就是边界,而空洞一定是由这些边界组成的。所以目标就是找到边界,主要的函数如下find_holes_in_triangle_mesh.m,输入点和面的信息,输出的是一个n*n的数组(n表示点的个数),如果i行j列上的元素是1,表示ij连线是边界
function edge = find_holes_in_triangle_mesh(vertices, faces)
% find_holes_in_triangle_mesh
%
% Dimensions:
% vertices: 3xnVertices
% faces: 3xnFaces
%
% Author: zhenyu
global edgeVertice;
nVertices = size(vertices,2);
nFaces = size(faces,2);
edgeVertice = zeros(nVertices, nVertices, 3);
edge=zeros(nVertices,nVertices);
for i=1:nFaces
[vaIndex, vbIndex, vcIndex] = deal(faces(1,i), faces(2,i), faces(3,i));
addEdgeVertice(vaIndex, vbIndex);
addEdgeVertice(vbIndex, vcIndex);
addEdgeVertice(vaIndex, vcIndex);
end;
for i=1:nVertices
for j=1:nVertices
if (edgeVertice(i, j, 1) ~= 0)&&(edgeVertice(i, j, 3)==0)
edge(i, j)=1;
end
end
end
end
% ---------------------------------------------------------------------------- %
function addEdgeVertice(v1Index, v2Index)
global edgeVertice;
if (v1Index>v2Index) % setting: v1 <= v2
vTmp = v1Index;
v1Index = v2Index;
v2Index = vTmp;
end;
if (edgeVertice(v1Index, v2Index, 1)==0) % new vertex
edgeVertice(v1Index, v2Index, 1) = 1;
edgeVertice(v1Index, v2Index, 2) = 1;
else
edgeVertice(v1Index, v2Index, 3) = 1;
end;
return;
end
之后利用trans_matrix_to_arrow函数将edge里的边界找出,形成edges矩阵,是一个2*m,第i列表示第i条边的两个点的索引值
function edges = trans_matrix_to_arrow( edge)
%TRANS_MATRIX_TO_ARROW Summary of this function goes here
% Detailed explanation goes here
n=size(edge,1);
x=[];
y=[];
for i=1:n
for j=1:n
if (edge(i,j)~=0)
x(end+1)=i;
y(end+1)=j;
end
end
end
n=size(x,2);
edges=zeros(2,n);
edges(1,:)=x;
edges(2,:)=y;
end
最后是一段测试代码,我们先将正方体挖去两个面,再找出其边界
[V,F]=obj__read('cube.obj');
edge = find_holes_in_triangle_mesh(V, F);
F=F';V=V';
edges=trans_matrix_to_arrow(edge);
trep=triangulation(F,V);
n=size(edges,2);
for i=1:n
plot3(V(edges(:,i),1),V(edges(:,i),2),V(edges(:,i),3),'Color','blue','linewidth',2);hold on;
end
trisurf(trep,'edgecolor','k','facecolor','w');
最后是演示效果,用蓝色显示出空洞
好像有点简单吼[奸笑]