MESHSILHOUETTE Compute the 2D outline of a 3D mesh on an arbitrary plane. ATTENTION: Very slow brute force approach! Keep the number of faces as low as possible. SILHOUETTE = meshSilhouette(MESH, PLANE) Calculates the silhouette (2D outline) of the MESH projected on the PLANE. SILHOUETTE = meshSilhouette(MESH) uses the x-y plane. SILHOUETTE = meshSilhouette(V, F, ...) SILHOUETTE = meshSilhouette(..., 'visu', 1) visualizes the results. By default the results are not visualized. Example: v = [5, 2, 6, 0, 3; 0, 2, 4, 2, 1; -5, -6, -6, -7, -9]'; f = [1, 2, 4; 1, 5, 4; 1, 2, 5; 2, 3, 5; 2, 4, 3; 3, 4, 5]; sil = meshSilhouette(v, f, rand(1,9),'visu',1); See also: projPointOnPlane Source: Sean de Wolski - https://www.mathworks.com/matlabcentral/answers/68004
0001 function silhouette = meshSilhouette(v, f, varargin) 0002 %MESHSILHOUETTE Compute the 2D outline of a 3D mesh on an arbitrary plane. 0003 % 0004 % ATTENTION: Very slow brute force approach! Keep the number of faces as 0005 % low as possible. 0006 % 0007 % SILHOUETTE = meshSilhouette(MESH, PLANE) 0008 % Calculates the silhouette (2D outline) of the MESH projected on the 0009 % PLANE. 0010 % 0011 % SILHOUETTE = meshSilhouette(MESH) uses the x-y plane. 0012 % 0013 % SILHOUETTE = meshSilhouette(V, F, ...) 0014 % 0015 % SILHOUETTE = meshSilhouette(..., 'visu', 1) visualizes the results. 0016 % By default the results are not visualized. 0017 % 0018 % Example: 0019 % v = [5, 2, 6, 0, 3; 0, 2, 4, 2, 1; -5, -6, -6, -7, -9]'; 0020 % f = [1, 2, 4; 1, 5, 4; 1, 2, 5; 2, 3, 5; 2, 4, 3; 3, 4, 5]; 0021 % sil = meshSilhouette(v, f, rand(1,9),'visu',1); 0022 % 0023 % See also: 0024 % projPointOnPlane 0025 % 0026 % Source: 0027 % Sean de Wolski - https://www.mathworks.com/matlabcentral/answers/68004 0028 0029 % --------- 0030 % Authors: oqilipo 0031 % Created: 2020-07-29 0032 % Copyright 2020 0033 0034 narginchk(1,5) 0035 nargoutchk(0,1) 0036 0037 %% Parse inputs 0038 % If first argument is a struct 0039 if isstruct(v) 0040 if nargin > 1 0041 varargin=[{f} varargin{:}]; 0042 end 0043 mesh = v; 0044 [v, f] = parseMeshData(v); 0045 else 0046 mesh.vertices = v; 0047 mesh.faces = f; 0048 end 0049 0050 p = inputParser; 0051 logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); 0052 addOptional(p,'plane',[0 0 0 1 0 0 0 1 0],@isPlane) 0053 addParameter(p,'visualization',false,logParValidFunc); 0054 parse(p, varargin{:}); 0055 plane = p.Results.plane; 0056 0057 % Transform into the x-y plane 0058 TFM = createBasisTransform3d('g', plane); 0059 v = transformPoint3d(v,TFM); 0060 0061 % Initialize final polygon vectors 0062 [px, py] = boundary(polyshape(v(f(1,:),1) ,v(f(1,:),2), 'Simplify',false)); 0063 for i = 2:size(f,1) 0064 A = polyshape(v(f(i,:),1), v(f(i,:),2), 'Simplify',false); 0065 B = polyshape(px, py, 'Simplify',false); 0066 [px, py] = boundary(union(A,B)); 0067 end 0068 0069 % Transform back into the plane 0070 silhouette = transformPoint3d([px,py,zeros(size(px))], inv(TFM)); 0071 0072 if p.Results.visualization 0073 figure('Color','w'); axH = axes(); axis(axH, 'equal', 'tight') 0074 drawPolyline3d(axH, silhouette,'Color','r','LineWidth',3) 0075 drawPlane3d(axH, plane,'FaceAlpha',0.5) 0076 drawMesh(mesh,'FaceAlpha',0.5,'FaceColor','none') 0077 axis(axH, 'equal') 0078 camTar = nanmean(silhouette); 0079 axH.CameraTarget = camTar; 0080 axH.CameraPosition = camTar + ... 0081 planeNormal(plane)*vectorNorm3d(axH.CameraPosition-axH.CameraTarget); 0082 axH.CameraUpVector = plane(4:6); 0083 xlabel(axH, 'x'); ylabel(axH, 'y'); zlabel(axH, 'z'); 0084 end 0085 0086 end