本文共 6861 字,大约阅读时间需要 22 分钟。
function [V,F,UV,TF,N,NF] = readOBJ(filename,varargin) % READOBJ reads an OBJ file with vertex/face information % % [V,F,UV,TF,N,NF] = readOBJ(filename) % [V,F,UV,TF,N,NF] = readOBJ(filename,'ParameterName',ParameterValue,...) % % Input: % filename path to .obj file % Optional: % 'Quads' whether to output face information in X by 4 matrices (faces % with degree larger than 4 are still triangulated). A trailing zero % will mean a triangle was read. % Outputs: % V #V by 3 list of vertices % F #F by 3 list of triangle indices % UV #V by 2 list of texture coordinates % TF #F by 3 list of triangle texture coordinates % N #V by 3 list of normals % NF #F by 3 list of triangle corner normal indices into N % % Examples: % % read a quad/triangle mesh and display it % [V,F] = readOBJ('quads.obj','Quads',true); % % Turn triangles into degenerate quads % DF = (F==0).*F(:,[4 1 2 3])+(F~=0).*F; % trisurf(DF,V(:,1),V(:,2),V(:,3)); % % % See also: load_mesh, readOBJfast, readOFF % default values quads = false; % Map of parameter names to variable names params_to_variables = containers.Map( ... {'Quads'}, ... {'quads'}); 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 numv = 0; numf = 0; numuv = 0; numtf = 0; numn = 0; numnf = 0; % simplex size if quads ss = 4; else ss = 3; end % Amortized array allocation V = zeros(10000,3); F = zeros(10000,ss); UV = zeros(10000,3); TF = zeros(10000,ss); N = zeros(10000,3); NF = zeros(10000,ss); triangulated = false; all_ss = true; fp = fopen( filename, 'r' ); type = fscanf( fp, '%s', 1 ); count = 0; while strcmp( type, '' ) == 0 line = fgets(fp); if strcmp( type, 'v' ) == 1 v = sscanf( line, '%lf %lf %lf' ); numv = numv+1; if(numv>size(V,1)) V = cat(1,V,zeros(10000,3)); end V(numv,:) = [v(1:3)']; elseif strcmp( type, 'vt') v = sscanf( line, '%f %f %f' ); numuv = numuv+1; if size(UV,2)>2 && length(v) == 2 UV = UV(:,1:2); end if(numuv>size(UV,1)) UV = cat(1,UV,zeros(10000,length(v))); end UV(numuv,:) = [v']; elseif strcmp( type, 'vn') n = sscanf( line, '%f %f %f' ); numn = numn+1; if(numn>size(N,1)) N = cat(1,N,zeros(10000,3)); end N(numn,:) = [n']; elseif strcmp( type, 'f' ) == 1 [t, count] = sscanf(line,'%d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d'); if (count>2) tf = t(2:3:end); nf = t(3:3:end); t = t(1:3:end); else [t, count] = sscanf(line, '%d/%d %d/%d %d/%d %d/%d %d/%d'); if (count>2) tf = t(2:2:end); t = t(1:2:end); nf = -ones(numel(t),1); else [t, count] = sscanf(line, '%d//%d %d//%d %d//%d %d//%d %d//%d'); if (count>2) nf = t(2:2:end); t = t(1:2:end); tf = -ones(numel(t),1); else [t, count] = sscanf( line, '%d %d %d %d %d %d %d %d %d %d %d\n' ); if (count>2) tf = -ones(numel(t),1); nf = -ones(numel(t),1); else [t, count] = sscanf( line, '%d// %d// %d// %d// %d// %d// %d// %d// %d// %d// %d//\n' ); tf = -ones(numel(t),1); nf = -ones(numel(t),1); end end end end t = t + (t<0).* (numv+1); tf = tf + (tf<0).*(numuv+1); nf = nf + (nf<0).*(numn+1); assert(numel(t) == numel(tf)); assert(numel(t) == numel(nf)); if numel(t) > ss if ~triangulated warning('Trivially triangulating high degree facets'); end triangulated = true; end j = 2; i = 1; %Vt = V(t,:); %[~,A] = affine_fit(Vt); %VtA = Vt*A; %VtA0 = Vt*A; %[~,alpha] = curvature(VtA); %flip = -sign(sum(alpha)); %E = [1:size(VtA,1);2:size(VtA,1) 1]'; %[dV,dF] = triangle(VtA,E,[]); %if size(dF,1)>2 % tsurf(dF,dV); % hold on; % plot(VtA0([1:end 1],1),VtA0([1:end 1],2),'LineWidth',3); % hold off % pause %end while true if numel(t) > ss corners = [1 2 3]; %plot(VtA0([1:end 1],1),VtA0([1:end 1],2)); %hold on; %plot(VtA([1:3],1),VtA([1:3],2),'LineWidth',3); %hold off; %expand_axis(2); %pause; %[~,alpha] = curvature(VtA,[1 2;2 3]); %alpha = flip * alpha(2); %others = VtA(setdiff(1:end,corners),:); %these = VtA(corners,:); %w = inpolygon(others(:,1),others(:,2),these(:,1),these(:,2)); %alpha %if alpha>=0 && ~any(w) % % lazy % t = t([2:end 1]); % VtA = VtA([2:end 1],:); % continue; %end else if all_ss && numel(t)注意, maya, meshlab中索引是以0为基础的, 而matlab 里面是以1为基础的, 所以要想选择同一个点, 当maya里面索引为17的时候, matlab相应的应该为18size(F,1)) F = cat(1,F,zeros(10000,ss)); end F(numf,1:numel(corners)) = [t(corners)']; numtf = numtf+1; if(numtf>size(TF,1)) TF = cat(1,TF,zeros(10000,ss)); end TF(numtf,1:numel(corners)) = [tf(corners)']; numnf = numnf+1; if(numnf>size(NF,1)) NF = cat(1,NF,zeros(10000,ss)); end NF(numnf,1:numel(corners)) = [nf(corners)']; if numel(t) <= ss break; end t = t([1 3:end]); %VtA = VtA([1 3:end],:); if numel(t) < 3 break; end end elseif strcmp( type, '#' ) == 1 %fscanf( fp, '%s\n', 1 ); % ignore line end type = fscanf( fp, '%s', 1 ); end fclose( fp ); %try % F = cell2mat(F); %end V = V(1:numv,:); F = F(1:numf,:); UV = UV(1:numuv,:); TF = TF(1:numtf,:); N = N(1:numn,:); NF = NF(1:numnf,:); %% transform into array if all faces have the same number of vertices if (size(UV,1)>0) UV = UV; endend
转载地址:http://opxdi.baihongyu.com/