Matlab读取显示STL\OBJ文件

news/2025/2/13 22:17:11/

综述

最近在做图形学的一些任务,其中有一部分是使用MATLAB读取OBJ、STL、OFF文件。
其实OFF和OBJ很相似,所以这里只给出OBJ的文件和STL文件的读取。
最近抽空整理一下。

说明

我的环境时Macos+matlab r2014b
对于matlab而言,与您的环境没有任何关系。请您放心使用

代码

追求优秀是一种习惯

stl读取以及显示

STL读取代码:
创建m文件 stlread.m

function [x, y, z, varargout] = stlread(filename)%转发\作者信息:山东大学计算机基地Frankdura
%时间:2018\5\1
% This function reads an STL file in binary format into matrixes X, Y and
% Z, and C.  C is optional and contains color rgb data in 5 bits.  
%
% USAGE: [x, y, z, c] = stlread(filename);
%
% To plot use patch(x,y,z,c), or patch(x,y,z)
%
% Written by Doron Harlevif nargout>4error('Too many output arguments')
end
use_color=(nargout==4);fid=fopen(filename, 'r'); %Open the file, assumes STL Binary format.
if fid == -1 error('File could not be opened, check name or path.')
endftitle=fread(fid,80,'uchar=>schar'); % Read file title
num_facet=fread(fid,1,'int32'); % Read number of Facetsfprintf('\nTitle: %s\n', char(ftitle'));
fprintf('Num Facets: %d\n', num_facet);% Preallocate memory to save running time
x=zeros(3,num_facet); y=zeros(3,num_facet); z=zeros(3,num_facet);
if use_colorc=uint8(zeros(3,num_facet));
endh = waitbar(0,'Please wait...');
for i=1:num_facet,norm=fread(fid,3,'float32'); % normal coordinates, ignored for nowver1=fread(fid,3,'float32'); % vertex 1ver2=fread(fid,3,'float32'); % vertex 2ver3=fread(fid,3,'float32'); % vertex 3col=fread(fid,1,'uint16'); % color bytesif (bitget(col,16)==1 & use_color)r=bitshift(bitand(2^16-1, col),-10);g=bitshift(bitand(2^11-1, col),-5);b=bitand(2^6-1, col);c(:,i)=[r; g; b];endx(:,i)=[ver1(1); ver2(1); ver3(1)]; % convert to matlab "patch" compatible formaty(:,i)=[ver1(2); ver2(2); ver3(2)];z(:,i)=[ver1(3); ver2(3); ver3(3)];if mod(i,floor(num_facet/10))==0waitbar(i/num_facet,h);end
end
if use_colorvarargout(1)={c};
end
fclose(fid);
close(h);

STL文件显示:
注意我们的是使用 patch(x,y,z)命令,这个命令可以绘制多边形

patch(x,y,z)

调用,即可:

[x,y,z]=stlread('b.stl')
patch(x,y,z)

效果图:
这里写图片描述

obj读取以及显示

obj读取代码:
创建m文件 objread.m

function [node_xyz, face_node ]= objread( input_file_name )%*****************************************************************************80
%
%% OBJ_DISPLAY displays the faces of a shape defined by an OBJ file.
%
%  Usage:
%
%    obj_display ( 'file.obj' )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Get sizes.
%[ node_num, face_num, normal_num, order_max ] = obj_size ( input_file_name );
%
%  Get the data.
%[ node_xyz, face_order, face_node ] = ...obj_read ( input_file_name, node_num, face_num, normal_num, order_max );
%
%  FACE_NODE may contain polygons of different orders.
%  To make the call to PATCH, we will assume all the polygons are the same order.
%  To do so, we'll simply "stutter" the first node in each face list.
%for face = 1 : face_numface_node(face_order(face)+1:order_max,face) = face_node(1,face);end
%
%  If any node index is still less than 1, set the whole face to 1's.
%  We're giving up on this presumably meaningless face, but we need to
%  do it in a way that keeps MATLAB happy!
%for face = 1 : face_numfor i = 1 : order_maxface_node(i,face) = max ( face_node(i,face), 1 );endend
%
%  Display the shape.
%  The TITLE function will interpret underscores in the title.
%  We need to unescape such escape sequences!return
end
function c = ch_cap ( c )%*****************************************************************************80
%
%% CH_CAP capitalizes a single character.
%
%  Parameters:
%
%    Input, character C, the character to capitalize.
%    Output, character C, the capitalized character.
%if ( 'a' <= c && c <= 'z' )c = c + 'A' - 'a';endreturn
end
function truefalse = ch_eqi ( c1, c2 )%*****************************************************************************80
%
%% CH_EQI is a case insensitive comparison of two characters for equality.
%
%  Example:
%
%    CH_EQI ( 'A', 'a' ) is TRUE.
%
%
%  Parameters:
%
%    Input, character C1, C2, the characters to compare.
%
%    Output, logical TRUEFALSE, is TRUE (1) if the characters are equal.
%FALSE = 0;TRUE = 1;if ( ch_cap ( c1 ) == ch_cap ( c2 ) )truefalse = TRUE;elsetruefalse = FALSE;endreturn
end
function value = ch_index ( s, c )%*****************************************************************************80
%
%% CH_INDEX is the first occurrence of a character in a string.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string to be searched.
%
%    Input, character C, the character to be searched for.
%
%    Output, integer VALUE, the location of the first occurrence of C 
%    in the string, or 0 if C does not occur.
%value = 0;for i = 1 : length ( s )if ( s(i:i) == c )value = i;returnendendreturn
end
function value = ch_is_control ( ch )%*****************************************************************************80
%
%% CH_IS_CONTROL is TRUE if a character is a control character.
%
%  Discussion:
%
%    A "control character" has ASCII code <= 31 or 127 <= ASCII code.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character CH, the character to be tested.
%
%    Output, integer CH_IS_CONTROL, TRUE if the character is a control
%    character, and FALSE otherwise.
%if ( ch <= 31 || 127 <= ch )value = 1;elsevalue = 0;endreturn
end
function truefalse = ch_is_digit ( c )%*****************************************************************************80
%
% CH_IS_DIGIT returns TRUE if the character C is a digit.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Parameters:
%
%    Input, character C, a character.
%
%    Output, integer TRUEFALSE, is TRUE (1) if C is a digit, FALSE (0) otherwise.
%TRUE = 1;FALSE = 0;if ( '0' <= c && c <= '9' )truefalse = TRUE;elsetruefalse = FALSE;endreturn
end
function digit = ch_to_digit ( c )%*****************************************************************************80
%
%% CH_TO_DIGIT returns the integer value of a base 10 digit.
%
%  Example:
%
%     C   DIGIT
%    ---  -----
%    '0'    0
%    '1'    1
%    ...  ...
%    '9'    9
%    ' '    0
%    'X'   -1
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 November 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character C, the decimal digit, '0' through '9' or blank
%    are legal.
%
%    Output, integer DIGIT, the corresponding integer value.  If C was
%    'illegal', then DIGIT is -1.
%if ( '0' <= c && c <= '9' )digit = c - '0';elseif ( c == ' ' )digit = 0;elsedigit = -1;endreturn
end
function [ node_xyz, face_order, face_node, normal_vector, vertex_normal ] = ...obj_read ( input_file_name, node_num, face_num, normal_num, order_max )%*****************************************************************************80
%
%% OBJ_READ reads graphics information from a Wavefront OBJ file.
%
%  Discussion:
%
%    It is intended that the information read from the file can
%    either start a whole new graphics object, or simply be added
%    to a current graphics object via the '<<' command.
%
%    This is controlled by whether the input values have been zeroed
%    out or not.  This routine simply tacks on the information it
%    finds to the current graphics object.
%
%  Example:
%
%    #  magnolia.obj
%
%    v -3.269770 -39.572201 0.876128
%    v -3.263720 -39.507999 2.160890
%    ...
%    v 0.000000 -9.988540 0.000000
%    vn 1.0 0.0 0.0
%    ...
%    vn 0.0 1.0 0.0
%
%    f 8 9 11 10
%    f 12 13 15 14
%    ...
%    f 788 806 774
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%
%  Parameters:
%
%    Input, string INPUT_FILE_NAME, the name of the input file.
%    Input, integer NODE_NUM, the number of points.
%    Input, integer FACE_NUM, the number of faces.
%    Input, integer NORMAL_NUM, the number of normal vectors.
%    Input, integer ORDER_MAX, the maximum number of vertices per face.
%    Output, real NODE_XYZ(3,NODE_NUM), the coordinates of points.
%    Output, integer FACE_ORDER(FACE_NUM), the number of vertices per face.
%    Output, integer FACE_NODE(ORDER_MAX,FACE_NUM), the nodes making faces.
%    Output, real NORMAL_VECTOR(3,NORMAL_NUM), normal vectors.
%    Output, integer VERTEX_NORMAL(ORDER_MAX,FACE_NUM), the indices of normal
%    vectors per vertex.
%face = 0;node = 0;normal = 0;text_num = 0;face_node = zeros ( order_max, face_num );face_order = zeros ( face_num, 1 );node_xyz = zeros ( 3, node_num );normal_vector = zeros ( 3, normal_num );vertex_normal = zeros ( order_max, face_num );
%
%  If no file input, try to get one from the user.
%if ( nargin < 1 )input_file_name = input ( 'Enter the name of the ASCII OBJ file.' );if ( isempty ( input_file_name ) )returnendend
%
%  Open the file.
%input_file_unit = fopen ( input_file_name, 'r' );if ( input_file_unit < 0 )fprintf ( 1, '\n' );fprintf ( 1, 'OBJ_READ - Fatal error!\n' );fprintf ( 1, '  Could not open the file "%s".\n', input_file_name );error ( 'OBJ_READ - Fatal error!' );end
%
%  Read a line of text from the file.
%while ( 1 )text = fgetl ( input_file_unit );if ( text == -1 )breakendtext_num = text_num + 1;
%
%  Replace any control characters (in particular, TAB's) by blanks.
%s_control_blank ( text );done = 1;word_index = 0;
%
%  Read a word from the line.
%[ word, done ] = word_next_read ( text, done );
%
%  If no more words in this line, read a new line.
%if ( done )continueend
%
%  If this word begins with '#' or '$', then it's a comment.  Read a new line.
%if ( word(1) == '#' || word(1) == '$' )continueendword_index = word_index + 1;if ( word_index == 1 )word_one = word;end
%
%  BEVEL
%  Bevel interpolation.
%if ( s_eqi ( word_one, 'BEVEL' ) )
%
%  BMAT
%  Basis matrix.
%elseif ( s_eqi ( word_one, 'BMAT' ) )
%
%  C_INTERP
%  Color interpolation.
%elseif ( s_eqi ( word_one, 'C_INTERP' ) )
%
%  CON
%  Connectivity between free form surfaces.
%elseif ( s_eqi ( word_one, 'CON' ) )
%
%  CSTYPE
%  Curve or surface type.
%elseif ( s_eqi ( word_one, 'CSTYPE' ) )
%
%  CTECH
%  Curve approximation technique.
%elseif ( s_eqi ( word_one, 'CTECH' ) )
%
%  CURV
%  Curve.
%elseif ( s_eqi ( word_one, 'CURV' ) )
%
%  CURV2
%  2D curve.
%elseif ( s_eqi ( word_one, 'CURV2' ) )
%
%  D_INTERP
%  Dissolve interpolation.
%elseif ( s_eqi ( word_one, 'D_INTERP' ) )
%
%  DEG
%  Degree.
%elseif ( s_eqi ( word_one, 'DEG' ) )
%
%  END
%  End statement.
%elseif ( s_eqi ( word_one, 'END' ) )
%
%  F V1 V2 V3 ...
%    or
%  F V1/VT1/VN1 V2/VT2/VN2 ...
%    or
%  F V1//VN1 V2//VN2 ...
%
%  Face.
%  A face is defined by the vertices.
%  Optionally, slashes may be used to include the texture vertex
%  and vertex normal indices.
%elseif ( s_eqi ( word_one, 'F' ) )face = face + 1;vertex = 0;while ( 1 )[ word, done ] = word_next_read ( text, done );if ( done )breakendvertex = vertex + 1;order_max = max ( order_max, vertex );
%
%  Locate the slash characters in the word, if any.
%i1 = ch_index ( word, '/' );if ( 0 < i1 )i2 = ch_index ( word(i1+1), '/' ) + i1;elsei2 = 0;end
%
%  Read the vertex index.
%itemp = s_to_i4 ( word );face_node(vertex,face) = itemp;face_order(face) = face_order(face) + 1;
%
%  If there are two slashes, then read the data following the second one.
%if ( 0 < i2 )itemp = s_to_i4 ( word(i2+1) );vertex_normal(vertex,face) = itemp;endend
%
%  G
%  Group name.
%elseif ( s_eqi ( word_one, 'G' ) )
%
%  HOLE
%  Inner trimming loop.
%elseif ( s_eqi ( word_one, 'HOLE' ) )
%
%  L
%  A line, described by a sequence of vertex indices.
%  Are the vertex indices 0 based or 1 based?
%elseif ( s_eqi ( word_one, 'L' ) )
%
%  LOD
%  Level of detail.
%elseif ( s_eqi ( word_one, 'LOD' ) )
%
%  MG
%  Merging group.
%elseif ( s_eqi ( word_one, 'MG' ) )
%
%  MTLLIB
%  Material library.
%elseif ( s_eqi ( word_one, 'MTLLIB' ) )
%
%  O
%  Object name.
%elseif ( s_eqi ( word_one, 'O' ) )
%
%  P
%  Point.
%elseif ( s_eqi ( word_one, 'P' ) )
%
%  PARM
%  Parameter values.
%elseif ( s_eqi ( word_one, 'PARM' ) )
%
%  S
%  Smoothing group.
%elseif ( s_eqi ( word_one, 'S' ) )
%
%  SCRV
%  Special curve.
%elseif ( s_eqi ( word_one, 'SCRV' ) )
%
%  SHADOW_OBJ
%  Shadow casting.
%elseif ( s_eqi ( word_one, 'SHADOW_OBJ' ) )
%
%  SP
%  Special point.
%elseif ( s_eqi ( word_one, 'SP' ) )
%
%  STECH
%  Surface approximation technique.
%elseif ( s_eqi ( word_one, 'STECH' ) )
%
%  STEP
%  Stepsize.
%elseif ( s_eqi ( word_one, 'STEP' ) )
%
%  SURF
%  Surface.
%elseif ( s_eqi ( word_one, 'SURF' ) )
%
%  TRACE_OBJ
%  Ray tracing.
%elseif ( s_eqi ( word_one, 'TRACE_OBJ' ) )
%
%  TRIM
%  Outer trimming loop.
%elseif ( s_eqi ( word_one, 'TRIM' ) )
%
%  USEMTL
%  Material name.
%elseif ( s_eqi ( word_one, 'USEMTL' ) )
%
%  V X Y Z
%  Geometric vertex.
%elseif ( s_eqi ( word_one, 'V' ) )node = node + 1;for i = 1 : 3[ word, done ] = word_next_read ( text, done );temp = s_to_r8 ( word );node_xyz(i,node) = temp;end
%
%  VN
%  Vertex normals.
%elseif ( s_eqi ( word_one, 'VN' ) )normal = normal + 1;for i = 1 : 3[ word, done ] = word_next_read ( text, done );temp = s_to_r8 ( word );normal_vector(i,normal) = temp;end
%
%  VT
%  Vertex texture.
%elseif ( s_eqi ( word_one, 'VT' ) )
%
%  VP
%  Parameter space vertices.
%elseif ( s_eqi ( word_one, 'VP' ) )
%
%  Unrecognized keyword.
%elseendendfclose ( input_file_unit );return
end
function [ node_num, face_num, normal_num, order_max ] = obj_size ( ...input_file_name )%*****************************************************************************80
%
%% OBJ_SIZE determines sizes of graphics objects in an Alias OBJ file.
%
%  Discussion:
%
%    The only items of interest to this routine are vertices,
%    faces, and normal vectors.
%
%  Example:
%
%    #  magnolia.obj
%
%    v -3.269770 -39.572201 0.876128
%    v -3.263720 -39.507999 2.160890
%    ...
%    v 0.000000 -9.988540 0.000000
%
%    vn 1.0 0.0 0.0
%    ...
%    vn 0.0 1.0 0.0
%
%    f 8 9 11 10
%    f 12 13 15 14
%    ...
%    f 788 806 774
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string INPUT_FILE_NAME, the input file name.
%
%    Output, integer NODE_NUM, the number of points.
%
%    Output, integer FACE_NUM, the number of faces.
%
%    Output, integer NORMAL_NUM, the number of normal vectors.
%
%    Output, integer ORDER_MAX, the maximum face order.
%face_num = 0;node_num = 0;normal_num = 0;order_max = 0;text_num = 0;
%
%  If no file input, try to get one from the user.
%if ( nargin < 1 )input_file_name = input ( 'Enter the name of the ASCII OBJ file.' );if ( isempty ( input_file_name ) )returnendend
%
%  Open the file.
%input_file_unit = fopen ( input_file_name, 'r' );if ( input_file_unit < 0 )fprintf ( 1, '\n' );fprintf ( 1, 'OBJ_SIZE - Fatal error!\n' );fprintf ( 1, '  Could not open the file "%s".\n', input_file_name );error ( 'OBJ_SIZE - Fatal error!' );end
%
%  Read a line of text from the file.
%while ( 1 )text = fgetl ( input_file_unit );if ( text == -1 )breakendtext_num = text_num + 1;
%
%  Replace any control characters (in particular, TABs) by blanks.
%s_control_blank ( text );done = 1;word_index = 0;
%
%  Read a word from the line.
%[ word, done ] = word_next_read ( text, done );
%
%  If no more words in this line, read a new line.
%if ( done )continueend
%
%  If this word begins with '#' or '$', then it is a comment.  Read a new line.
%if ( word(1) == '#' || word(1) == '$' )continueendword_index = word_index + 1;if ( word_index == 1 )word_one = word;end
%
%  F V1 V2 V3 ...
%    or
%  F V1/VT1/VN1 V2/VT2/VN2 ...
%    or
%  F V1//VN1 V2//VN2 ...
%
%  Face.
%  A face is defined by the vertices.
%  Optionally, slashes may be used to include the texture vertex
%  and vertex normal indices.
%if ( s_eqi ( word_one, 'F' ) )face_num = face_num + 1;vertex = 0;while ( 1 )[ word, done ] = word_next_read ( text, done );if ( done )breakendvertex = vertex + 1;order_max = max ( order_max, vertex );
%
%  Locate the slash characters in the word, if any.
%i1 = ch_index ( word, '/' );if ( 0 < i1 )i2 = ch_index ( word(i1+1), '/' ) + i1;elsei2 = 0;end
%
%  Read the vertex index.
%s_to_i4 ( word );
%
%  If there are two slashes, then read the data following the second one.
%if ( 0 < i2 )s_to_i4 ( word(i2+1) );endend
%
%  V X Y Z W
%  Geometric vertex.
%elseif ( s_eqi ( word_one, 'V' ) )node_num = node_num + 1;continue
%
%  VN
%  Vertex normals.
%elseif ( s_eqi ( word_one, 'VN' ) )normal_num = normal_num + 1;continueendendfclose ( input_file_unit );return
end
function s = s_control_blank ( s )%*****************************************************************************80
%
%% S_CONTROL_BLANK replaces control characters with blanks.
%
%  Discussion:
%
%    A "control character" has ASCII code <= 31 or 127 <= ASCII code.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input/output, string S, the string to be transformed.
%s_length = s_len_trim ( s );for i = 1 : s_lengthif ( ch_is_control ( s(i) ) )s(i) = ' ';endendreturn
end
function value = s_eqi ( s1, s2 )%*****************************************************************************80
%
%% S_EQI is a case insensitive comparison of two strings for equality.
%
%  Example:
%
%    S_EQI ( 'Anjana', 'ANJANA' ) is TRUE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 April 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S1, S2, the strings to compare.
%
%    Output, logical VALUE, is TRUE if the strings are equal.
%FALSE = 0;TRUE = 1;len1 = length ( s1 );len2 = length ( s2 );lenc = min ( len1, len2 );for i = 1 : lencc1 = ch_cap ( s1(i) );c2 = ch_cap ( s2(i) );if ( c1 ~= c2 )value = FALSE;returnendendfor i = lenc + 1 : len1if ( s1(i) ~= ' ' )value = FALSE;returnendendfor i = lenc + 1 : len2if ( s2(i) ~= ' ' )value = FALSE;returnendendvalue = TRUE;return
end
function len = s_len_trim ( s )%*****************************************************************************80
%
%% S_LEN_TRIM returns the length of a character string to the last nonblank.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string to be measured.
%
%    Output, integer LEN, the length of the string up to the last nonblank.
%len = length ( s );while ( 0 < len )if ( s(len) ~= ' ' )returnendlen = len - 1;endreturn
end
function ival = s_to_i4 ( s )%*****************************************************************************80
%
%% S_TO_I4 reads an integer value from a string.
%
%  Parameters:
%
%    Input, string S, a string to be examined.
%
%    Output, integer IVAL, the integer value read from the string.
%sgn = 1;state = 0;ival = 0;i = 0;while ( i < s_len_trim ( s ) )i = i + 1;c = s(i);if ( state == 0 )if ( c == ' ' )elseif ( c == '-' )state = 1;sgn = -1;elseif ( c == '+' )state = 1;sgn = +1;elseif ( '0' <= c && c <= '9' )state = 2;ival = c - '0';elsefprintf ( '\n' );fprintf ( 'S_TO_I4 - Fatal error!\n' );fprintf ( '  Illegal character %c while in state %d.\n', c, state );return;end
%
%  Have read the sign, now expecting the first digit.
%elseif ( state == 1 )if ( c == ' ' )elseif ( '0' <= c && c <= '9' )state = 2;ival = c - '0';elsefprintf ( '\n' );fprintf ( 'S_TO_I4 - Fatal error!\n' );fprintf ( '  Illegal character %c while in state %d.\n', c, state );returnend
%
%  Have read at least one digit, expecting more.
%elseif ( state == 2 )if ( '0' <= c && c <= '9' )ival = 10 * ival + c - '0';elseival = sgn * ival;return;endendend
%
%  If we read all the characters in the string, see if we're OK.
%if ( state ~= 2 )fprintf ( '\n' );fprintf ( 'S_TO_I4 - Fatal error!\n' );fprintf ( '  Did not read enough information to define an integer!\n' );return;endival = sgn * ival;return
end
function [ r, lchar, ierror ] = s_to_r8 ( s )%*****************************************************************************80
%
%% S_TO_R8 reads an R8 from a string.
%
%  Discussion:
%
%    This routine will read as many characters as possible until it reaches
%    the end of the string, or encounters a character which cannot be
%    part of the real number.
%
%    Legal input is:
%
%       1 blanks,
%       2 '+' or '-' sign,
%       2.5 spaces
%       3 integer part,
%       4 decimal point,
%       5 fraction part,
%       6 'E' or 'e' or 'D' or 'd', exponent marker,
%       7 exponent sign,
%       8 exponent integer part,
%       9 exponent decimal point,
%      10 exponent fraction part,
%      11 blanks,
%      12 final comma or semicolon.
%
%    with most quantities optional.
%
%  Example:
%
%    S                 R
%
%    '1'               1.0
%    '     1   '       1.0
%    '1A'              1.0
%    '12,34,56'        12.0
%    '  34 7'          34.0
%    '-1E2ABCD'        -100.0
%    '-1X2ABCD'        -1.0
%    ' 2E-1'           0.2
%    '23.45'           23.45
%    '-4.2E+2'         -420.0
%    '17d2'            1700.0
%    '-14e-2'         -0.14
%    'e2'              100.0
%    '-12.73e-9.23'   -12.73 * 10.0**(-9.23)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 November 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string containing the
%    data to be read.  Reading will begin at position 1 and
%    terminate at the end of the string, or when no more
%    characters can be read to form a legal real.  Blanks,
%    commas, or other nonnumeric data will, in particular,
%    cause the conversion to halt.
%
%    Output, real R, the value that was read from the string.
%
%    Output, integer LCHAR, the number of characters of S that were used to form R.
%
%    Output, integer IERROR, is 0 if no error occurred.
%s_length = s_len_trim ( s );ierror = 0;lchar = -1;isgn = 1;rtop = 0.0;rbot = 1.0;jsgn = 1;jtop = 0;jbot = 1;ihave = 1;iterm = 0;while ( 1 )lchar = lchar + 1;c = s(lchar+1);
%
%  Blank character.
%if ( c == ' ' )if ( ihave == 2 )elseif ( ihave == 6 || ihave == 7 )iterm = 1;elseif ( 1 < ihave )ihave = 11;end
%
%  Comma.
%elseif ( c == ',' || c == ';' )if ( ihave ~= 1 )iterm = 1;ihave = 12;lchar = lchar + 1;end
%
%  Minus sign.
%elseif ( c == '-' )if ( ihave == 1 );ihave = 2;isgn = -1;elseif ( ihave == 6 )ihave = 7;jsgn = -1;elseiterm = 1;end
%
%  Plus sign.
%elseif ( c == '+' )if ( ihave == 1 )ihave = 2;elseif ( ihave == 6 )ihave = 7;elseiterm = 1;end
%
%  Decimal point.
%elseif ( c == '.' )if ( ihave < 4 )ihave = 4;elseif ( 6 <= ihave && ihave <= 8 )ihave = 9;elseiterm = 1;end
%
%  Exponent marker.
%elseif ( ch_eqi ( c, 'E' ) || ch_eqi ( c, 'D' ) )if ( ihave < 6 )ihave = 6;elseiterm = 1;end
%
%  Digit.
%elseif ( ihave < 11 && ch_is_digit ( c ) )if ( ihave <= 2 )ihave = 3;elseif ( ihave == 4 )ihave = 5;elseif ( ihave == 6 || ihave == 7 )ihave = 8;elseif ( ihave == 9 )ihave = 10;endd = ch_to_digit ( c );if ( ihave == 3 )rtop = 10.0 * rtop + d;elseif ( ihave == 5 )rtop = 10.0 * rtop + d;rbot = 10.0 * rbot;elseif ( ihave == 8 )jtop = 10 * jtop + d;elseif ( ihave == 10 )jtop = 10 * jtop + d;jbot = 10 * jbot;end
%
%  Anything else is regarded as a terminator.
%elseiterm = 1;end
%
%  If we haven't seen a terminator, and we haven't examined the
%  entire string, go get the next character.
%if ( iterm == 1 || s_length <= lchar + 1 )break;endend
%
%  If we haven't seen a terminator, and we have examined the
%  entire string, then we're done, and LCHAR is equal to S_LENGTH.
%if ( iterm ~= 1 && lchar + 1 == s_length )lchar = s_length;end
%
%  Number seems to have terminated.  Have we got a legal number?
%  Not if we terminated in states 1, 2, 6 or 7!
%if ( ihave == 1 || ihave == 2 || ihave == 6 || ihave == 7 )fprintf ( 1, '\n' );fprintf ( 1, 'S_TO_R8 - Fatal error!\n' );fprintf ( 1, '  IHAVE = %d\n', ihave );error ( 'S_TO_R8 - Fatal error!' );end
%
%  Number seems OK.  Form it.
%if ( jtop == 0 )rexp = 1.0;elseif ( jbot == 1 )rexp = 10.0^( jsgn * jtop );elserexp = jsgn * jtop;rexp = rexp / jbot;rexp = 10.0^rexp;endendr = isgn * rexp * rtop / rbot;return
end
function [ word, done ] = word_next_read ( s, done )%*****************************************************************************80
%
%% WORD_NEXT_READ "reads" words from a string, one at a time.
%
%  Special cases:
%
%    The following characters are considered to be a single word,
%    whether surrounded by spaces or not:
%
%      " ( ) { } [ ]
%
%    Also, if there is a trailing comma on the word, it is stripped off.
%    This is to facilitate the reading of lists.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Parameters:
%
%    Input, string S, a string, presumably containing words
%    separated by spaces.
%
%    Input, logical DONE.
%    TRUE, if we are beginning a new string;
%    FALSE, if we are continuing to process the current string.
%
%    Output, string WORD.
%    If DONE is FALSE, then WORD contains the "next" word read.
%    If DONE is TRUE, then WORD is blank, because there was no more to read.
%
%    Output, logical DONE.
%      FALSE if another word was read,
%      TRUE if no more words could be read.
%persistent lenc;persistent next;tab = char ( 9 );
%
%  We "remember" LENC and NEXT from the previous call.
%
%  An input value of DONE = TRUE signals a new line of text to examine.
%if ( done )next = 1;done = 0;lenc = s_len_trim ( s );if ( lenc <= 0 )done = 1;word = ' ';returnendend
%
%  Beginning at index NEXT, search the string for the next nonblank,
%  which signals the beginning of a word.
%ilo = next;
%
%  ...S(NEXT:) is blank.  Return with WORD = ' ' and DONE = TRUE.
%while ( 1 )if ( lenc < ilo )word = ' ';done = 1;next = lenc + 1;returnend
%
%  If the current character is blank, skip to the next one.
%if ( s(ilo) ~= ' ' && s(ilo) ~= tab )breakendilo = ilo + 1;end
%
%  ILO is the index of the next nonblank character in the string.
%
%  If this initial nonblank is a special character,
%  then that's the whole word as far as we're concerned,
%  so return immediately.
%if ( s(ilo) == '"' || ...s(ilo) == '(' || ...s(ilo) == ')' || ...s(ilo) == '{' || ...s(ilo) == '}' || ...s(ilo) == '[' || ...s(ilo) == ']' )word = s(ilo);next = ilo + 1;returnend
%
%  Now search for the last contiguous character that is not a
%  blank, TAB, or special character.
%next = ilo + 1;while ( next <= lenc )if ( s(next) == ' ' )break;elseif ( s(next) == tab )break;elseif ( s(next) == '"' )break;elseif ( s(next) == '(' )break;elseif ( s(next) == ')' )break;elseif ( s(next) == '{' )break;elseif ( s(next) == '}' )break;elseif ( s(next) == '[' )break;elseif ( s(next) == ']' )break;endnext = next + 1;endif ( s(next-1) == ',' ) word = s(ilo:next-2);elseword = s(ilo:next-1);endreturn
end

obj显示代码:

function objPlot(v, f, name)
%STLPLOT is an easy way to plot an STL object
%V is the Nx3 array of vertices
%F is the Mx3 array of faces
%NAME is the name of the object, that will be displayed as a titlefigure;
object.vertices = v;
size(object.vertices)
object.faces = f;
size(object.faces)patch(object,'FaceColor',       [0.8 0.8 1.0], ...'EdgeColor',       'none',        ...'FaceLighting',    'gouraud',     ...'AmbientStrength', 0.15);% Add a camera light, and tone down the specular highlighting
camlight('headlight');
material('dull');% Fix the axes scaling, and set a nice view angle
axis('image');
view([-135 35]);
grid on;
title(name);

调用

[n,f] = objread('d.obj');
%记得需要转置
n = n';
f = f';
objPlot(n,f,'mymodel');

作者信息

SDU 计算机 基地 Frankdura
感谢代码提供者的付出。侵删。


http://www.ppmy.cn/news/646576.html

相关文章

RED FRACTION (BLACK LAGOON黑礁片头曲)歌词 + 高保真翻译

RED FRACTION &#xff08;BLACK LAGOON黑礁片头曲&#xff09;歌词 演唱 MELL 作词 MELL 作曲 高濑一矢 &#xff08;翻译修订一&#xff09; ------------------------------------------------------ I have a big gun 我有一把火爆的枪 I took it from my lord …

ipfs pubsub代码解读

Pubsub: Publish-subscribe发布订阅模式 运行环境 版本&#xff1a;go-ipfsv0.4.23 go-libp2p-pubsubv0.0.3 本文运行两个节点&#xff0c;一个在ubuntu&#xff0c;另外一个在windows&#xff0c;下文用ipfs1代表ubuntu端的ipfs&#xff0c;用ipfs2代表windows端的ipfs。两…

嵌入式linux之go语言开发(四)go语言8583协议报文解析

原来的pos用c语言开发的&#xff0c;与银联后台通信走的是8583协议。那么用go来做&#xff0c;得实现个go语言8583协议报文解析 且若想在电脑上跑交易&#xff0c;做个工具。用c语音处理起来不方便。用go还可以在电脑上跑交易。 于是用go语言做一个8583解析&#xff0c;方便使…

Go语言银联8583报文解析库,支持联小额免密付和银商聚合支付

很早之前就整过一个Go语言版的银联8583报文解析库&#xff0c;当时仅是8583报文的解析。 最近整合了进了银联小额双免交易和银商的聚合支付交易通道&#xff0c;这可以是网上最简单的8583报文解析库了。 银联双免支付通道支持银行卡免密和云闪付二维码交易&#xff0c;而银商…

华为oj: 图片整理

<pre name"code" class"cpp">/* Lily上课时使用字母数字图片教小朋友们学习英语单词&#xff0c; 每次都需要把这些图片按照大小&#xff08;ASCII码值从小到大&#xff09;排列收好。请大家给Lily帮忙&#xff0c;通过C语言解决。 eg:输入&#xff…

BACnet协议简要说明及组网简介

主题概要BACnet协议BACnet协议简要说明&#xff0c;组网简介编辑时间新建20160217序号参考资料1BACnet协议正文1995版2http://www.bacnet.org/Tutorial/BACnetIP/ 1 协议说明 BACnet协议(A Data Communication Protocol for Building Automation and Control Networks)&#…

linux 软盘启动程序,Linux 引导过程及原理-从软盘启动GRUB

制作启动盘后&#xff0c;可以用软盘启动引导硬盘上的操作系统。插入制作好的启动软盘&#xff0c;进入BIOS并设置用软盘启动。软盘启动成功后就会进入GRUB的命令行模式&#xff1a; grub> 要启动一个操作系统&#xff0c;首先指定引导哪个分区上的系统&#xff0c;例如要引…

英语口语练习十四之It's the most...that I have ever...(这个……是我最……)的用法

It’s the most…that I have ever… 这个……是我最……的 用法透视 这个句型用来表达某事物是你在同类事物经历中的之最。 支持范例 It’s the best movie I have ever seen. 这是我看过的最好的电影。You’re one of the nicest persons that I’ve ever met. 你是我见…