Skip to content

Commit

Permalink
more robust half space
Browse files Browse the repository at this point in the history
  • Loading branch information
alecjacobson committed Jan 26, 2016
1 parent 0ad46f8 commit 05f8127
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 50 deletions.
92 changes: 46 additions & 46 deletions mesh/half_space_intersect.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function [VV,FF,birth] = half_space_intersect(V,F,p,n,varargin)
function [VV,FF,birth,UT,E] = half_space_intersect(V,F,p,n,varargin)
% HALF_SPACE_INTERSECT Intersect a closed mesh (V,F) with a half space
% defined by a point on a plane the plane's normal.
%
Expand Down Expand Up @@ -70,44 +70,34 @@
switch method
case 'exact'
bbd = sqrt(sum((max(V)-min(V)).^2,2));
% row vectors
n = reshape(n,1,[]);
p = reshape(p,1,[]);
N = null(n)';
CV = bsxfun(@plus,p,bbd*[1 1;1 -1;-1 -1;-1 1]*N);
CF = [1 2 3;1 3 4];

VCV = [V;CV];
FCF = [F;size(V,1)+CF];
[VV,FF,~,J,IM] = selfintersect(VCV,FCF);

if cap
CF = FF(J>size(F,1),:);
BC = barycenter(VV,CF);
w = winding_number(V,F,BC);
CF = CF(w>0.5,:);
else
CF = [];
end

F = FF(J<=size(F,1),:);
birth = J(J<=size(F,1));
BC = barycenter(VV,F);
above = sum(bsxfun(@times,bsxfun(@minus,BC,p),n),2)>=0;
F = F(above,:);
birth = birth(above);
FF = [F;CF];
birth = [birth;zeros(size(CF,1),1)];
[VV,~,J] = remove_duplicate_vertices(VV,1e-10);
FF = J(FF);
[VV,J] = remove_unreferenced(VV,FF);
FF = J(FF);
if remesh_cap && cap
[VV,FF] = remesh_planar_patches(VV,FF,'MinSize',4,'Force',true, ...
'Except',1:size(F,1));
% better have only remeshed on cap.
birth = [birth(1:size(F,1));zeros(size(FF,1)-size(F,1),1)];
[CV,CF] = cube(2,2,2);
R = vrrotvec2mat(vrrotvec(n,[0 0 1]));
% project vertex mean onto plane
pp = mean(V) - ((mean(V)-p)*n')*n;
% rotate box around projected mean
CV = bsxfun(@plus,bsxfun(@minus,CV,[0.5 0.5 0])*diag([2 2 1])*bbd*R,pp);

[VV,FF,J] = mesh_boolean(V,F,CV,CF,'intersect');
if ~cap
FF = FF(J<=size(F,1),:);
[VV,IM] = remove_unreferenced(VV,FF);
FF = IM(FF);
elseif remesh_cap
VA = VV;
FA = FF(J<=size(F,1),:);
JA = J(J<=size(F,1));
VB = VV;
FB = FF(J>size(F,1),:);
[VB,FB] = remesh_planar_patches( ...
VB,FB,'MinSize',4,'Force',true,'TriangleFlags','-q32Y');
VV = [VA;VB];
FF = [FA;size(VA,1)+FB];
J = [JA;size(FA,1)+ones(size(FB,1),1)];
[VV,~,IM] = remove_duplicate_vertices(VV,0);
FF = IM(FF);
end
birth = J;
birth(birth>size(F,1)) = 0;
case 'fast'
plane = [n(:)' -dot(p,n)];

Expand All @@ -123,7 +113,7 @@
[U,E31,F31below,F31above,BC31] = one_below(U,F(I31,:),-IF(I31,:));

VV = U;
above = all(IF>0,2);
above = all(IF>=0,2);
FF = [F(above,:);F13above;F31below];
birth = [find(above);repmat(find(I13),2,1);find(I31)];
E = [E13;E31];
Expand All @@ -145,13 +135,23 @@
% mesh of cap
% compute transformation taking plane to (XY)-plane
un = plane(1:3)/norm(plane(1:3));
v = cross(un,[0 0 1]);
c = dot(un,[0 0 1]);
s = norm(v);
cp = @(v) [0 -v(3) v(2);v(3) 0 -v(1);-v(2) v(1) 0];
R = eye(3) + cp(v) + cp(v)*cp(v)*(1-c)/s^2;
T = [R [0;0;R(3,:)*(un'/norm(plane(1:3))*plane(4))]];
[~,SF] = triangle(U*T(1:2,1:3)',E,[],'Flags','-Y');
z = [0 0 1];
c = dot(un,z);
if abs(1-c)>eps
v = cross(un,z);
s = norm(v);
cp = @(v) [0 -v(3) v(2);v(3) 0 -v(1);-v(2) v(1) 0];
R = eye(3) + cp(v) + cp(v)*cp(v)*(1-c)/s^2;
T = [R [0;0;R(3,:)*(un'/norm(plane(1:3))*plane(4))]];
UT = U*T(1:2,1:3)';
else
UT = U(:,1:2);
end

if any(sum(adjacency_matrix(E),2) < 2)
warning('Open boundary... cap will be wrong...');
end
[~,SF] = triangle(UT,E,[],'Flags','-Yc');
RIM = full(sparse(IM,1,1:numel(IM)));
% Index back onto U
SF = RIM(SF);
Expand Down
8 changes: 5 additions & 3 deletions mesh/statistics.m
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@
% could feasibly be oriented (a meshed self-intersection).
S.num_conflictingly_oriented_edges = nnz(OA);

S.num_nonmanifold_vertices = sum(is_vertex_nonmanifold(F));
S.num_nonmanifold_vertices = sum(is_vertex_nonmanifold(F)) - ...
S.num_unreferenced_vertices;

[~,BC] = conncomp( (DA==1)+(DA==1)' );
S.num_boundary_loops = sum(sparse(BC,1,1)>1);
Expand All @@ -139,9 +140,10 @@
% g = (2-b-X)/2
% http://sketchesoftopology.wordpress.com/2008/02/04/genus-euler-characteristic-boundary-components/
S.num_handles = ...
(2*S.num_connected_components - ...
(2* ...
(S.num_connected_components-S.num_unreferenced_vertices) - ...
S.num_boundary_loops - ...
S.euler_characteristic)/2;
(S.euler_characteristic-S.num_unreferenced_vertices))/2 ;

dblA = doublearea(V,F);
S.num_geometrically_degenerate_faces = sum(dblA==0);
Expand Down
8 changes: 7 additions & 1 deletion wrappers/triangle.m
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,13 @@
while(ii <= nargin)
switch varargin{ii}
case 'Quiet'
quiet = true;
if( (ii+1)<=nargin && ~ischar(varargin{ii+1}))
ii = ii + 1;
assert(ii <= nargin);
quiet = varargin{ii};
else
quiet = true;
end
case 'Quality'
if( (ii+1)<=nargin && ~ischar(varargin{ii+1}))
ii = ii + 1;
Expand Down

0 comments on commit 05f8127

Please sign in to comment.