Revision 2ce396a76821d352b608cbcadbb6c57de59620c3 authored by Alec Jacobson on 08 January 2020, 05:26:22 UTC, committed by Alec Jacobson on 08 January 2020, 05:26:22 UTC
1 parent 9d0a7c0
emboss.m
function [VV,FF,J,P,M,AO,TV,TF,r,i,ni,R] = emboss(V,F,str,varargin)
% EMBOSS Find a spot on a mesh to emboss with given text
%
% [VV,FF] = emboss(V,F,str)
% [VV,FF,J] = emboss(V,F,str,'ParameterName',ParameterValue, ...)
%
% Inputs:
% V #V by 3 list of mesh vertex positions
% F #F by 3 list of triangle indices into V
% str string to emboss
% Outputs:
% VV #VV by 3 list of mesh vertex positions
% FF #FF by 3 list of triangle indices into VV
% J #FF list of indices into 1:size(F,1)+size(EF,1) where EF are the faces
% of the embossed letters: J<=size(F,1) indicates an original birth face
%
th = normrow(max(V)-min(V))/(100/3);
fontname = [];
engrave = false;
max_r = inf;
% Map of parameter names to variable names
params_to_variables = containers.Map( ...
{'Engrave','Height','FontName','MaxRadius'}, ...
{'engrave','th','fontname','max_r'});
v = 1;
while v <= numel(varargin)
param_name = varargin{v};
if isKey(params_to_variables,param_name)
assert(v+1<=numel(varargin));
v = v+1;
% Trick: use feval on anonymous function to use assignin to this workspace
feval(@()assignin('caller',params_to_variables(param_name),varargin{v}));
else
error('Unsupported parameter: %s',varargin{v});
end
v=v+1;
end
% Generate 10000 uniformly random samples
[P,I] = random_points_on_mesh(V,F,10000,'Color','blue');
% Compute the normals per-face
N = normalizerow(normals(V,F));
% Find the 160 closest points
[K,D] = knnsearch(P,P,'K',160);
% Compute normals at each point
NIK = reshape(N(I(K),:),[size(K) 3]);
% Compute a weighted fall-off per point
W = exp(-(4*D./max(D,[],2)).^2);
% Compute the ambient occlusion per point
AO = ambient_occlusion(V,F,P,N(I,:),1000);
M = sum(W.*acos(min(max(sum(NIK.*permute(N(I,:),[1 3 2]),3),-1),1)).^2,2)+AO;
[r,i] = max(D(:,end).*(M==min(M)));
r = min(r,max_r);
ni = N(I(i),:);
[w,a] = axisanglebetween(ni,[0 0 1],[1 0 0]);
R = axisangle2matrix(w,a);
[TV,TF] = text_to_mesh(str,'FontName',fontname,'TriangleFlags',' ');
TV = TV-0.5*(max(TV)-min(TV));
TV = TV/max(normrow(TV));
TV(:,3) = TV(:,3)/max(TV(:,3));
TV = TV*diag([r r th])*R+P(i,:);
%clf;
%hold on;
%tsurf(F,V,fsoft,'FaceColor',orange,'EdgeColor','none','FaceAlpha',0.5);
%tsurf(TF,TV,fsoft,'FaceColor',blue,'EdgeColor','none','FaceAlpha',0.5);
%quiver3(P(i,1),P(i,2),P(i,3),N(I(i),1),N(I(i),2),N(I(i),3));
%hold off;
%camlight;
%axis equal;
if engrave
[VV,FF,J] = mesh_boolean(V,F,TV,TF,'minus');
else
[VV,FF,J] = mesh_boolean(V,F,TV,TF,'union');
end
end
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...