## Copyright (C) 2016-2020 Philip Nienhuis ## ## 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 . ## -*- texinfo -*- ## @deftypefn {} [@var{h}] = dxfdraw (@var{dxf}) ## @deftypefnx {} [@var{h}] = dxfdraw (@var{dxf}, @var{clr}) ## @deftypefnx {} [@var{h}] = dxfdraw (@dots{}, @var{name}, @var{value}, @dots{}) ## Draw a map of a DXF file based on a DXF cell array or DXF drawing struct. ## ## Input argument @var{dxf} is the name of a DXF cell array (see ## dxfread.m), or the name of a DXF file, or a DXF drawing struct made ## by dxfparse. ## ## @var{clr} is the color used to draw the DXF contents. All lines and ## arcs are drawn in the same color; similar for all filled surfaces. ## For points, lines and polylines this can be a 3x1 RGB vector or a color ## code. For polygons it can be a 2x1 vector of color codes or a 2x3 double ## array of RGB entries. The default is [0.7 0.7 0.7; 0.8 0.9 0.99]. ## ## In addition several graphics properties can be specified, e.g., linestyle ## and linewidth. No checks are performed whether these are valid for the ## entities present in the DXF cell array or file. ## ## Currently the following entities are supported: POINT, LINE, POLYLINE, ## LWPOLYLINE, CIRCLE, ARC and 3DFACE. For drawing CIRCLE and ARC entities ## functions from the geometry packge are required. ## ## Optional output argument @var{h} is the graphics handle of the resulting ## map. ## ## @seealso{dxfread, dxfparse} ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2016-01-25 function [h] = dxfdraw (dxf, clr=[0.7 0.7 0.7; 0.8 0.9 0.99], varargin) if (isstruct (dxf)) ## Cursory validation fldnm = fieldnames (dxf); if (! all (ismember({"i3d", "ic", "ia", "j3", "jr", "il", "ip"}, fldnm))) error ("dxfdraw: invalid struct input for arg #1"); endif else if (isempty (dxf)) return elseif (iscell (dxf)) ## Cursory Q-checks: minumum 3 columns, col 1 & 3 numeric, col #2 character if (size (dxf, 2) < 3 || ! all (all (cellfun (@isnumeric, dxf(:, [1, 3])))) ... || ! all (cellfun (@ischar, dxf(:, 2)))) error ("dxfdraw: input arg #1 does not look like a valid dxf cell array"); endif elseif (ischar (dxf)) ## Maybe a DXF file? [~, ~, ext] = fileparts (dxf); if (isempty (ext) || ! strcmpi (ext, ".dxf")) ## Just add a .dxf suffix dxf = [dxf ".dxf"]; endif fid = fopen (dxf); if (fid < 0) error ("File '%s' not found", dxf); else fclose (fid); endif ## Read DXF file into DXF cell array dxf = dxfread (dxf); else error ("dxfdraw: DXF cell array, DXF file name, or DXF drawing struct \ expected for arg #1 "); endif ## parse DXF cell array into a DXF drawing struct dxf = dxfparse (dxf, 0); endif ## We should have a valid struct now. Extract data i3d = dxf.i3d; is = dxf.is; ir = dxf.ir; ic = dxf.ic; ia = dxf.ia; j3 = dxf.j3; jr = dxf.jr; il = dxf.il; ip = dxf.ip; jf = dxf.jf; jw = dxf.jw; jl = dxf.jl; XYZ = dxf.XYZ; XYZp = dxf.XYZp; XY = dxf.XY; CIRCLES = dxf.CIRCLES; ARCS = dxf.ARCS; VRT3 = dxf.VRT3; FAC3 = dxf.FAC3; LWP = dxf.LWP; LWV = dxf.LWV; VRTS = dxf.VRTS; FACP = dxf.FACP; ## dxf not needed from here, clear it as it may hold lots of RAM needed for plot clear dxf; h = figure (); hold on; axis equal; if (i3d) if (is > 0) plot3 (XYZp(:, 1), XYZp(:, 2), XYZp(:, 3), "color", clr(1, :), varargin{:}); endif if (ir > 0) plot3 (XYZ(:, 1), XYZ(:, 2), XYZ(:, 3), "color", clr(1, :), varargin{:}); endif if (ic > 0) drawCircle3d (CIRCLES, "color", clr(1, :), varargin{:}); endif if (ia > 0) drawCircleArc3d (ARCS, "color", clr(1, :), varargin{:}); endif if (j3 > 0) patch ("vertices", VRT3, "faces", FAC3, "edgecolor", clr(1, :), ... "facecolor", clr(2, :), varargin{:}); endif else if (is > 0) plot (XYZp(:, 1), XYZp(:, 2), "color", clr(1, :), varargin{:}); endif if (ir > 0) plot (XYZ(:, 1), XYZ(:, 2), "color", clr(1, :), varargin{:}); endif if (ic > 0) drawCircle (CIRCLES, "color", clr(1, :), varargin{:}); endif if (ia > 0) drawCircleArc (ARCS, "color", clr(1, :), varargin{:}); endif if (jr > 0) plot (XY(:, 1), XY(:, 2), "color", clr(1, :), varargin{:}); endif if (il > 0) LWV(jw+1:end, :) = []; LWV(LWV == 0) = NaN; patch ("vertices", LWP, "faces", LWV, "edgecolor", clr(1, :), ... "facecolor", clr(2, :), varargin{:}); endif endif if (ip > 0) FACP(jf+1:end, :) = []; FACP(FACP == 0) = NaN; if (! i3d) VRTS(:, 3) = []; endif patch ("vertices", VRTS, "faces", FACP, "edgecolor", clr(1, :), ... "facecolor", clr(2, :), varargin{:}); endif endfunction