Home > matGeom > meshes3d > cutMeshByPlane.m

cutMeshByPlane

PURPOSE ^

CUTMESHBYPLANE Cut a mesh by a plane.

SYNOPSIS ^

function varargout = cutMeshByPlane(v, f, plane, varargin)

DESCRIPTION ^

CUTMESHBYPLANE Cut a mesh by a plane.

   [ABOVE, IN, BELOW] = cutMeshByPlane(MESH, PLANE)
   where MESH, ABOVE, IN, BELOW are structs with the fields vertices and
   faces, and PLANE is given as a row containing initial point and 2
   direction vectors. ABOVE, IN, BELOW contain the corresponding parts of
   the input mesh.

   [ABOVE_V, ABOVE_F, IN_V, IN_F, BELOW_V,BELOW_F] = ...
       cutMeshByPlane(V, F, PLANE) where V is a [NVx3] array containing
   coordinates and F is a [NFx3] array containing indices of vertices of
   the triangular faces.

   BELOW = cutMeshByPlane(V, F, PLANE, 'part', 'below') BELOW is a struct
   with the fields vertices and faces. Other options are:
       'part'  -   'above': Faces above the plane
               -   'in'   : Faces in the plane
               -   'below': Faces below the plane

   [BELOW_V, BELOW_F] = cutMeshByPlane(MESH, PLANE, 'part', 'below') is
   possible, too.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function varargout = cutMeshByPlane(v, f, plane, varargin)
0002 %CUTMESHBYPLANE Cut a mesh by a plane.
0003 %
0004 %   [ABOVE, IN, BELOW] = cutMeshByPlane(MESH, PLANE)
0005 %   where MESH, ABOVE, IN, BELOW are structs with the fields vertices and
0006 %   faces, and PLANE is given as a row containing initial point and 2
0007 %   direction vectors. ABOVE, IN, BELOW contain the corresponding parts of
0008 %   the input mesh.
0009 %
0010 %   [ABOVE_V, ABOVE_F, IN_V, IN_F, BELOW_V,BELOW_F] = ...
0011 %       cutMeshByPlane(V, F, PLANE) where V is a [NVx3] array containing
0012 %   coordinates and F is a [NFx3] array containing indices of vertices of
0013 %   the triangular faces.
0014 %
0015 %   BELOW = cutMeshByPlane(V, F, PLANE, 'part', 'below') BELOW is a struct
0016 %   with the fields vertices and faces. Other options are:
0017 %       'part'  -   'above': Faces above the plane
0018 %               -   'in'   : Faces in the plane
0019 %               -   'below': Faces below the plane
0020 %
0021 %   [BELOW_V, BELOW_F] = cutMeshByPlane(MESH, PLANE, 'part', 'below') is
0022 %   possible, too.
0023 %
0024 
0025 % ---------
0026 % Authors: oqilipo, David Legland
0027 % Created: 2017-07-09
0028 % Copyright 2017
0029 
0030 narginchk(2,5)
0031 nargoutchk(1,6)
0032 
0033 
0034 %% Parse inputs
0035 % If first argument is a struct
0036 if nargin == 2 || nargin == 4
0037     if ~isempty(varargin)
0038         varargin = [{plane}, varargin(:)'];
0039     end
0040     plane = f;
0041     [v, f] = parseMeshData(v);
0042 end
0043 
0044 p = inputParser;
0045 addRequired(p,'plane',@isPlane)
0046 validStrings = {'above','in','below'};
0047 addParameter(p,'part','above',@(x) any(validatestring(x, validStrings)))
0048 parse(p, plane, varargin{:});
0049 part=p.Results.part;
0050 
0051 
0052 %% Algorithm
0053 % Logical index to the vertices below the plane
0054 VBPl_LI = isBelowPlane(v, plane);
0055 
0056 % Logical index to three vertices of each face
0057 FBP_LI = VBPl_LI(f);
0058 switch nargout
0059     case {1, 2}
0060         switch part
0061             case 'above'
0062                 % Faces above the plane, all three vertices == 0 -> sum has to be 0
0063                 above = removeMeshFaces(v, f, ~(sum(FBP_LI, 2) == 0) );
0064             case 'in'
0065                 % Faces in the plane, 1 or 2 vertices == 0 -> sum can be 1 or 2
0066                 inside = removeMeshFaces(v, f, ~((sum(FBP_LI, 2) > 0 & sum(FBP_LI, 2) < 3)));
0067             case 'below'
0068                 % Faces below the plane, all three vertices == 1 -> sum has to be 3
0069                 below = removeMeshFaces(v, f, ~(sum(FBP_LI, 2) == 3) );
0070         end
0071     case {3, 6}
0072         % Faces above the plane, all three vertices == 0 -> sum has to be 0
0073         above = removeMeshFaces(v, f, ~(sum(FBP_LI, 2) == 0) );
0074         % Faces in the plane, 1 or 2 vertices == 0 -> sum can be 1 or 2
0075         inside = removeMeshFaces(v, f, ~((sum(FBP_LI, 2) > 0 & sum(FBP_LI, 2) < 3)));
0076         % Faces below the plane, all three vertices == 1 -> sum has to be 3
0077         below = removeMeshFaces(v, f, ~(sum(FBP_LI, 2) == 3) );
0078     otherwise
0079         error('Invalid number of output arguments')
0080 end
0081 
0082 
0083 %% Parse outputs
0084 switch nargout
0085     case 1
0086         switch part
0087             case 'above'
0088                 varargout{1}=above;
0089             case 'in'
0090                 varargout{1}=inside;
0091             case 'below'
0092                 varargout{1}=below;
0093         end
0094     case 2
0095         switch part
0096             case 'above'
0097                 varargout{1}=above.vertices;
0098                 varargout{2}=above.faces;
0099             case 'in'
0100                 varargout{1}=inside.vertices;
0101                 varargout{2}=inside.faces;
0102             case 'below'
0103                 varargout{1}=below.vertices;
0104                 varargout{2}=below.faces;
0105         end
0106     case 3
0107         varargout{1}=above;
0108         varargout{2}=inside;
0109         varargout{3}=below;
0110     case 6
0111         varargout{1}=above.vertices;
0112         varargout{2}=above.faces;
0113         varargout{3}=inside.vertices;
0114         varargout{4}=inside.faces;
0115         varargout{5}=below.vertices;
0116         varargout{6}=below.faces;
0117     otherwise
0118         error('Invalid number of output arguments')
0119 end
0120 
0121 end

Generated on Wed 16-Feb-2022 15:10:47 by m2html © 2003-2019