summaryrefslogtreecommitdiff
path: root/CSXCAD/matlab/export_excellon.m
diff options
context:
space:
mode:
Diffstat (limited to 'CSXCAD/matlab/export_excellon.m')
-rw-r--r--CSXCAD/matlab/export_excellon.m144
1 files changed, 144 insertions, 0 deletions
diff --git a/CSXCAD/matlab/export_excellon.m b/CSXCAD/matlab/export_excellon.m
new file mode 100644
index 0000000..8877fcd
--- /dev/null
+++ b/CSXCAD/matlab/export_excellon.m
@@ -0,0 +1,144 @@
+function export_excellon( CSX, filename, options )
+% export_excellon( CSX, filename, options )
+%
+% Exports the geometry defined in CSX to filename as an excellon drill file.
+% Only cylinders will be considered for export.
+% The xy-plane is exported.
+%
+% CSX: CSX-object created by InitCSX()
+% filename: export filename (e.g. '/tmp/export.gbr')
+% options (optional): struct
+% .header: (string) add this to the header of the file
+% comment line must have ';' as the very first character
+% .exclude: (cell array) ignore these CSX-properties
+% .include: (cell array) include only these CSX-properties
+% if neither .exclude or .include is specified, process all properties
+%
+% See also InitCSX
+% CSXCAD matlab interface
+% -----------------------
+% author: Sebastian Held <sebastian.held@gmx.de>
+% 26. Aug 2010: initial version
+
+
+if nargin < 3
+ options = [];
+end
+
+fid = fopen( filename, 'w' );
+
+% create header
+header = [];
+header = [header 'M48\n'];
+header = [header '; EXCELLON file written by CSXCAD\n' ];
+header = [header '; ' datestr(now) '\n' ];
+header = [header 'METRIC,LZ\n'];
+header = [header 'VER,1\n'];
+header = [header 'FMAT,1\n'];
+
+if isfield(options,'header')
+ header = [header options.header];
+end
+
+% determine the drawing unit
+options.drawingunit = CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit;
+
+if isfield(CSX.Properties,'Material')
+ % process material
+ Material = CSX.Properties.Material;
+ options.Property = 'Material';
+ [tools,drill] = process_primitives( Material, options );
+end
+if isfield(CSX.Properties,'Metal')
+ % process PEC
+ Metal = CSX.Properties.Metal;
+ options.Property = 'Metal';
+ [tools_,drill_] = process_primitives( Metal, options );
+ tools = unique( [tools tools_] );
+ drill = [drill drill_];
+end
+
+% check the generated tools
+[~,m] = unique( cellfun( @(x) x(1:3), tools, 'UniformOutput', 0 ) );
+if length(m) ~= numel(tools)
+ disp( 'the tool list is not unique:' );
+ disp( tools );
+ error( 'the tool list is not unique!' );
+end
+a = unique( cellfun( @(x) x(4), tools, 'UniformOutput', 0 ) );
+if (length(a) > 1) || (a ~= 'C')
+ disp( 'the tool list has errors:' );
+ disp( tools );
+ error( 'the tool list has errors!' );
+end
+
+% convert cell array of strings to string
+tools = char(cellfun( @(x)[x '\n'], tools ));
+drill = char(cellfun( @(x)[x '\n'], drill ));
+
+% save the file
+fprintf( fid, header );
+fprintf( fid, tools );
+fprintf( fid, '%s\n', 'M95' ); % end of program header
+fprintf( fid, drill );
+fprintf( fid, '%s\n', 'M00' ); % end
+fclose( fid );
+
+
+% -----------------------------------------------------------------------------
+function str = coord(v)
+% str = coord(v)
+% 2D-vector v takes coordinates in unit m
+x = sprintf( '%.3f', v(1)*1e3 ); % mm
+y = sprintf( '%.3f', v(2)*1e3 ); % mm
+str = ['X' x 'Y' y];
+
+% -----------------------------------------------------------------------------
+function [tool,drill] = primitive_cylinder( CSX_cylinder, drawingunit )
+start = [CSX_cylinder.P1.ATTRIBUTE.X CSX_cylinder.P1.ATTRIBUTE.Y] * drawingunit;
+stop = [CSX_cylinder.P2.ATTRIBUTE.X CSX_cylinder.P2.ATTRIBUTE.Y] * drawingunit;
+radius = CSX_cylinder.ATTRIBUTE.Radius * drawingunit;
+if start(1:2) == stop(1:2)
+ % via in z-plane
+ dia_mm = radius * 2 * 1e3; % mm
+ tool = sprintf( 'T%02iC1.3f', round(dia_mm*10), dia_mm );
+ drill = sprintf( 'T%02i\n%s', round(dia_mm*10), coord(start(1:2)) );
+else
+ disp( 'omitting primitive cylinder, because the projection onto the z-plane is not a circle' );
+end
+
+
+% -----------------------------------------------------------------------------
+function [tools,drill] = process_primitives( prop, options )
+exclude = {};
+if isfield(options,'exclude'), exclude = options.exclude; end
+for num=1:numel(prop)
+ Name = prop{num}.ATTRIBUTE.Name;
+ if any( strcmp(Name,exclude) )
+ disp( ['omitting ' Name '...'] );
+ continue
+ end
+ if isfield(options,'include')
+ include = options.include;
+ if ~any( strcmp(Name,include) )
+ disp( ['omitting ' Name '...'] );
+ continue
+ end
+ end
+
+ tools = {};
+ drill = {};
+
+ disp( ['processing ' prop{num}.ATTRIBUTE.Name '...'] );
+ fprintf( fid, '%s\n', ['%LN' Name '*%'] );
+ if isfield(prop{num}.Primitives,'Cylinder')
+ for a=1:numel(prop{num}.Primitives.Cylinder)
+ % iterate over all cylinders
+ Cylinder = prop{num}.Primitives.Cylinder{a};
+ [tool,drill_] = primitive_cylinder( fid, Cylinder );
+ tools = [tools tool];
+ drill = [drill drill_];
+ end
+ end
+end
+