changeset 12525:29a3da21f6df octave-forge

Added new function
author rafavzqz
date Tue, 30 Sep 2014 12:13:38 +0000
parents 3d8947eadc0e
children 7dea50dc947c
files extra/nurbs/INDEX extra/nurbs/inst/nrb2iges.m
diffstat 2 files changed, 309 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/extra/nurbs/INDEX	Tue Sep 23 00:39:17 2014 +0000
+++ b/extra/nurbs/INDEX	Tue Sep 30 12:13:38 2014 +0000
@@ -22,14 +22,16 @@
  nrbrevolve
  nrbruled
  nrbcoons
+ nrbtestcrv
+ nrbtestsrf
+ nrbunclamp
+ nrbmultipatch
+Plot and export
  nrbplot
  nrbctrlplot
  nrbkntplot
  nrbexport
- nrbtestcrv
- nrbtestsrf
- nrbunclamp
- nrbmultipatch
+ nrb2iges
 B-Spline functions
  bspeval
  bspderiv
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extra/nurbs/inst/nrb2iges.m	Tue Sep 30 12:13:38 2014 +0000
@@ -0,0 +1,303 @@
+function nrb2iges (nurbs, filename)
+% NRB2IGES : Write a NURBS curve or surface to an IGES file.
+%
+% Calling Sequence:
+% 
+%   nrb2iges (nurbs, filename);
+% 
+% INPUT:
+% 
+%   nurbs    : NURBS curve or surface, see nrbmak.
+%   filename : name of the output file.
+%  
+% Description:
+% 
+%   The data of the nurbs structure is written in a file following the IGES
+%   format. For a more in-depth explanation see, for example:
+%   <http://engineeronadisk.com/V2/notes_design/engineeronadisk-76.html>.
+%
+%    Copyright (C) 2014 Jacopo Corno
+%
+%    This program is free software: you can redistribute it and/or modify
+%    it under the terms of the GNU General Public License as published by
+%    the Free Software Foundation, either version 3 of the License, or
+%    (at your option) any later version.
+
+%    This program is distributed in the hope that it will be useful,
+%    but WITHOUT ANY WARRANTY; without even the implied warranty of
+%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%    GNU General Public License for more details.
+%
+%    You should have received a copy of the GNU General Public License
+%    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+%
+%    This file is based on nurbs2iges.m, (C) 2006 Fu Qiang, originally 
+%    released under the MIT license.
+
+  dt = datestr (now, 'yyyy.mm.dd');
+  
+  dim = numel (nurbs(1).order);
+  
+  % START SECTION
+  S{1} = '';
+  S{2} = 'IGES obtained from Nurbs toolbox.';
+  S{3} = 'See <http://octave.sourceforge.net/nurbs/>.';
+  S{4} = '';
+    
+  % GLOBAL SECTION
+  G{1} = '1H,';                           % Parameter Deliminator Character
+  G{2} = '1H;';                           % Record Delimiter Character
+  G{3} = HString ('Nurbs toolbox');       % Product ID from Sender
+  G{4} = HString (filename);              % File Name
+  G{5} = HString ('Octave Nurbs');        % System ID
+  G{6} = HString ('nrb2iges');            % Pre-processor Version
+  G{7} = '32';                            % Number of Bits for Integers (No. of bits present in the integer representation of the sending system)
+  G{8} = '75';                            % Single Precision Magnitude (Maximum power of 10 which may be represented as a single precision floating point number from the sending system)
+  G{9} = '6';                             % Single Precision Significance (No. of significant digits of a single precision floating point number on the sending system)
+  G{10}= '75';                            % Double Precision Magnitude (Maximum power of 10 which may be represented as a double precision floating point number from the sending system)
+  G{11}= '15';                            % Double Precision Significance (No. of significant digits of a double precision floating point number on the sending system)
+  G{12}= HString('Nurbs from Octave');    % Product ID for Receiver
+  G{13}= '1.0';                           % Model Space Scale
+  G{14}= '6';                             % Unit Flag (6 = metres)
+  G{15}= HString('M');                    % Units  (metres = "M")
+  G{16}= '1000';                          % Maximum Number of Line Weights
+  G{17}= '1.0';                           % Size of Maximum Line Width
+  G{18}= HString(dt);                     % Date and Time of file generation
+  G{19}= '0.000001';                      % Minimum User-intended Resolution
+  G{20}= '10000.0';                       % Approximate Maximum Coordinate
+  G{21}= HString('Jacopo Corno');         % Name of Author
+  G{22}= HString('GSCE - TU Darmstadt');  % Author's Organization
+  G{23}= '3';                             % IGES Version Number (3 = IGES version 2.0)
+  G{24}= '0';                             % Drafting Standard Code (0 = no standard)
+  
+  % Convert section array to lines (maximum lenght 72)
+  SectionG = make_section (G, 72);
+  
+  % DIRECTORY ENTRY SECTION
+  % Each directory entry consists of two, 80 character, fixed formatted lines
+  D = [];
+  for ii = 1:length (nurbs)
+    switch (dim)
+      case 1 % NURBS curve
+        D(ii).type = 126;
+      case 2 % NURBS surface
+        D(ii).type = 128;
+      otherwise
+        error ('Only curves and surfaces can be saved in IGES format.')
+    end
+    D(ii).id = 2*ii - 1; % odd counter (see Parameter data section)
+    D(ii).p_start = 0;
+    D(ii).p_count = 0;
+  end
+  
+  % PARAMETER DATA SECTION
+  % The structure is a free formatted data entry from columns 1 to 64.
+  % Each line of free formatted data consists of the entity type number
+  % followed by the parameter data describing the entity.
+  % Columns 65 to 72 are reserved for a parameter data index which is an
+  % odd number counter, right justified in the field, which begins at the
+  % number 1 and progresses in odd increments for each entity entered.
+  % Column 73 is reserved for the letter ‘P’ to indicate the data element
+  % belongs to the parameter data section. 
+  % Columns 74 to 80 are reserved for the sequence number. Each line of 
+  % data corresponds to the entity type as specified in the global section.
+  SectionP = {};
+  for ii = 1:length (nurbs)
+    P = make_section_array (nurbs(ii)); % finish one entity
+    % Convert section array to lines
+    SP = make_section (P, 64);
+    D(ii).p_count = length (SP);
+    if (ii == 1)
+        D(ii).p_start = 1;
+    else
+        D(ii).p_start = D(ii-1).p_start + D(ii-1).p_count;
+    end
+    SectionP{ii} = SP;
+  end
+
+  % SAVE
+  fid = fopen (filename, 'w');
+  
+  % Save Start Section
+  for ii = 1:length (S)
+    fprintf (fid, '%-72sS%7d\n', S{ii}, ii);
+  end
+  
+  % Save Global Section
+  for ii = 1:length (SectionG)
+    fprintf (fid, '%-72sG%7d\n', SectionG{ii}, ii);
+  end
+  
+  % Save Directory Entry Section
+  for i = 1:length (D)
+    fprintf (fid, '%8d%8d%8d%8d%8d%8d%8d%8d%8dD%7d\n', ...
+             D(i).type, D(i).p_start, 0, 0 ,0, 0, 0, 0, 0, i*2-1);
+    fprintf (fid, '%8d%8d%8d%8d%8d%8s%8s%8s%8dD%7d\n', ...
+             D(i).type, 0, 0, D(i).p_count, 0, ' ', ' ', ' ', 0, i*2);
+  end
+  
+  % Save Parameter Data Section
+  lines_p = 0;
+  for jj = 1:length (D)
+    sec = SectionP{jj};
+    for ii = 1:length (sec)
+      lines_p = lines_p + 1;
+      fprintf (fid, '%-64s %7dP%7d\n', sec{ii}, D(jj).id, lines_p);
+    end
+  end
+  
+  % Save Terminate Section
+  sec_t = sprintf ('%7dS%7dG%7dD%7dP%7d', length (S), length(SectionG), 2*length(D), lines_p);
+  fprintf (fid, '%-72sT%7d\n', sec_t, 1);
+  
+  fclose(fid);
+  
+end
+
+function P = make_section_array (nurbs)
+  dim = numel (nurbs.order);
+  
+  % in IGES the control points are stored in the format [x, y, z, w]
+  % instead of [w*x, w*y, w*z, w]
+  for idim = 1:3
+    nurbs.coefs(idim,:) = nurbs.coefs(idim,:) ./ nurbs.coefs(4,:);
+  end
+  
+  P = {};
+  switch dim
+    case 1
+      % Rational B-Spline Curve Entity
+      cp = nurbs.coefs;
+      deg = nurbs.order - 1;
+      knots = nurbs.knots;
+      uspan = [0 1];
+      isplanar = ~any(cp(3,:));
+      P{1} = '126';                       % NURBS curve
+      P{2} = int2str (size (cp, 2) - 1);  % Number of control points
+      P{3} = int2str (deg);               % Degree
+      P{4} = int2str (isplanar);          % Curve on xy plane
+      P{5} = '0';
+      P{6} = '0';
+      P{7} = '0';
+      index = 8;
+      for ii = 1:length (knots)
+        P{index} = sprintf ('%f', knots(ii));
+        index = index + 1;
+      end
+      for ii = 1:size (cp, 2)
+        P{index} = sprintf ('%f', cp(4,ii));
+        index = index + 1;
+      end
+      for ii = 1:size (cp, 2)
+        P{index} = sprintf ('%f', cp(1,ii));
+        index = index + 1;
+        P{index} = sprintf ('%f', cp(2,ii));
+        index = index + 1;
+        P{index} = sprintf ('%f', cp(3,ii));
+        index = index + 1;
+      end
+      P{index} = sprintf ('%f', uspan(1));
+      index = index +1;
+      P{index} = sprintf ('%f', uspan(2));
+      index = index +1;
+      P{index} = '0.0';
+      index = index +1;
+      P{index} = '0.0';
+      index = index +1;
+      if isplanar
+        P{index} = '1.0';
+      else
+        P{index} = '0.0';
+      end
+      index = index + 1;
+      P{index} = '0';
+      index = index + 1;
+      P{index} = '0';
+    case 2
+      % Rational B-Spline Surface Entity
+      cp = nurbs.coefs;
+      degU = nurbs.order(1) - 1;
+      degV = nurbs.order(2) - 1;
+      knotsU = nurbs.knots{1};
+      knotsV = nurbs.knots{2};
+      uspan = [0 1];
+      vspan = [0 1];
+      P{1} = '128';                       % NURBS surface
+      P{2} = int2str (size (cp, 2) - 1);  % Number of control points in U
+      P{3} = int2str (size (cp, 3) - 1);  % Number of control points in V
+      P{4} = int2str (degU);              % Degree in U
+      P{5} = int2str (degV);              % Degree in V
+      P{6} = '0';
+      P{7} = '0';
+      P{8} = '0';
+      P{9} = '0';
+      P{10} = '0';
+      index = 11;
+      for ii = 1:length (knotsU)
+        P{index} = sprintf ('%f', knotsU(ii));
+        index = index + 1;
+      end
+      for ii = 1:length (knotsV)
+        P{index} = sprintf ('%f', knotsV(ii));
+        index = index + 1;
+      end
+      for jj = 1:size (cp, 3)
+        for ii = 1:size (cp, 2)
+          P{index} = sprintf ('%f', cp(4,ii,jj));
+          index = index + 1;
+        end
+      end
+      for jj = 1:size (cp, 3)
+        for ii = 1:size (cp, 2)
+          P{index} = sprintf ('%f',cp(1,ii,jj));
+          index = index + 1;
+          P{index} = sprintf ('%f',cp(2,ii,jj));
+          index = index + 1;
+          P{index} = sprintf ('%f',cp(3,ii,jj));
+          index = index + 1;
+        end
+      end
+      P{index} = sprintf('%f',uspan(1));
+      index = index +1;
+      P{index} = sprintf('%f',uspan(2));
+      index = index +1;
+      P{index} = sprintf('%f',vspan(1));
+      index = index +1;
+      P{index} = sprintf('%f',vspan(2));
+      index = index +1;
+      P{index} = '0';
+      index = index + 1;
+      P{index} = '0';
+    otherwise
+      
+  end
+end
+
+function hs = HString (str)
+% HString : Convert the string STR to the Hollerith format.
+
+  hs = sprintf ('%dH%s', length(str), str);
+end
+
+function sec = make_section (fields, linewidth)
+  sec = {};
+  index = 1;
+  line = '';
+  num = length (fields);
+  for i = 1:num
+    if (i < num)
+      newitem = [fields{i} ','];
+    else
+      newitem = [fields{i} ';'];
+    end
+    len = length (line) + length (newitem);
+    if ( len > linewidth )
+      % new line
+      sec{index} = line;
+      index = index + 1;
+      line = '';
+    end
+    line = [line newitem];
+  end
+  sec{index} = line;
+end