1 #include <stdlib.h>
2 #include <string.h>
3 #include "global.h"
4
5 static void write_pnts(struct Map_info *, char *, char *, int, int, int);
6
add_polyline(struct dxf_file * dxf,struct Map_info * Map)7 void add_polyline(struct dxf_file *dxf, struct Map_info *Map)
8 {
9 int code;
10 char handle[DXF_BUF_SIZE]; /* entity handle, 16 hexadecimal digits */
11 char layer[DXF_BUF_SIZE]; /* layer name */
12 int layer_flag = 0; /* indicates if a layer name has been found */
13 int polyline_flag = 0; /* indicates the type of polyline */
14 int warn_flag66 = 1; /* indicates if error message printed once */
15 int vert_flag; /* indicates that vertices are following */
16 int xflag = 0; /* indicates if a x value has been found */
17 int yflag = 0; /* indicates if a y value has been found */
18 int zflag = 0; /* indicates if a z value has been found */
19 int arr_size = 0;
20
21 /* variables to create arcs */
22 double bulge = 0.0; /* for arc curves */
23 double prev_bulge = 0.0; /* for arc curves */
24
25 /* variables for polyface mesh */
26 int vertex_flag = 0;
27 int vertex_idx = 0;
28 int polyface_mesh_started = 0;
29 int mesh_pnts = 0;
30 double *mesh_xpnts = NULL;
31 double *mesh_ypnts = NULL;
32 double *mesh_zpnts = NULL;
33
34 handle[0] = 0;
35 strcpy(layer, UNIDENTIFIED_LAYER);
36
37 /* read in lines and process information until a 0 is read in */
38 while ((code = dxf_get_code(dxf)) != 0) {
39 if (code == -2)
40 return;
41
42 switch (code) {
43 case 66: /* vertices follow flag */
44 vert_flag = atoi(dxf_buf);
45 if (vert_flag != 1) /* flag must be always 1 */
46 if (warn_flag66) {
47 G_warning(_("vertices following flag missing"));
48 warn_flag66 = 0;
49 }
50 break;
51 case 70: /* polyline flag */
52 polyline_flag = atoi(dxf_buf);
53
54 /*******************************************************************
55 Polyline flag (bit-coded); default is 0:
56 1 = This is a closed polyline (or a polygon mesh closed in
57 the M direction).
58 2 = Curve-fit vertices have been added.
59 4 = Spline-fit vertices have been added.
60 8 = This is a 3D polyline.
61 16 = This is a 3D polygon mesh.
62 32 = The polygon mesh is closed in the N direction.
63 64 = The polyline is a polyface mesh.
64 128 = The linetype pattern is generated continuously around
65 the vertices of this polyline.
66 ******************************************************************/
67 break;
68 }
69 }
70
71 zpnts[0] = 0.0;
72 /* loop until SEQEND in the dxf file */
73 while (strcmp(dxf_buf, "SEQEND") != 0) {
74 if (feof(dxf->fp)) /* EOF */
75 return;
76
77 if (strcmp(dxf_buf, "VERTEX") == 0) {
78 vertex_idx++;
79 xflag = 0;
80 yflag = 0;
81 zflag = 0;
82 while ((code = dxf_get_code(dxf)) != 0) {
83 if (code == -2) /* EOF */
84 return;
85
86 switch (code) {
87 case 5: /* entity handle */
88 strcpy(handle, dxf_buf);
89 break;
90 case 8: /* layer name */
91 /* if no layer previously assigned */
92 if (!layer_flag && *dxf_buf) {
93 if (flag_list) {
94 if (!is_layer_in_list(dxf_buf))
95 add_layer_to_list(dxf_buf, 1);
96 return;
97 }
98 /* skip if (opt_layers != NULL && (
99 * (flag_invert == 0 && is_layer_in_list == 0) ||
100 * (flag_invert == 1 && is_layer_in_list == 1)
101 * )
102 */
103 if (opt_layers &&
104 flag_invert == is_layer_in_list(dxf_buf))
105 return;
106 strcpy(layer, dxf_buf);
107 layer_flag = 1;
108 }
109 break;
110 case 10: /* x coordinate */
111 xpnts[arr_size] = atof(dxf_buf);
112 xflag = 1;
113 break;
114 case 20: /* y coordinate */
115 ypnts[arr_size] = atof(dxf_buf);
116 yflag = 1;
117 break;
118 case 30: /* Z coordinate */
119 zpnts[arr_size] = atof(dxf_buf);
120 zflag = 1;
121 break;
122 case 40: /* starting width */
123 case 41: /* ending width */
124 break;
125 case 42: /* bulge */
126 bulge = atof(dxf_buf);
127 break;
128 case 50: /* curve fit tangent direction */
129 break;
130 case 70: /* vertex flag */
131 vertex_flag = atoi(dxf_buf);
132
133 /*******************************************************************
134 Vertex flags:
135 1 = Extra vertex created by curve-fitting
136 2 = Curve-fit tangent defined for this vertex. A curve-fit tangent
137 direction of 0 may be omitted from DXF output but is
138 significant if this bit is set.
139 4 = Not used
140 8 = Spline vertex created by spline-fitting
141 16 = Spline frame control point
142 32 = 3D polyline vertex
143 64 = 3D polygon mesh vertex
144 128 = Polyface mesh vertex
145 ******************************************************************/
146 if (vertex_flag == 16) {
147 /* spline frame control point: don't draw it! */
148 xflag = 0;
149 yflag = 0;
150 zflag = 0;
151 }
152 break;
153 /* NOTE: there are more cases possible */
154 case 71:
155 case 72:
156 case 73:
157 case 74:
158 if (!((vertex_flag & 128) && !(vertex_flag & 64)))
159 break;
160
161 if (!polyface_mesh_started) {
162 /* save vertex coordinates to mesh_?pnts */
163 mesh_xpnts =
164 (double *)G_malloc(arr_size * sizeof(double));
165 mesh_ypnts =
166 (double *)G_malloc(arr_size * sizeof(double));
167 mesh_zpnts =
168 (double *)G_malloc(arr_size * sizeof(double));
169 memcpy(mesh_xpnts, xpnts, arr_size * sizeof(double));
170 memcpy(mesh_ypnts, ypnts, arr_size * sizeof(double));
171 memcpy(mesh_zpnts, zpnts, arr_size * sizeof(double));
172
173 polyface_mesh_started = 1;
174 arr_size = 0;
175 mesh_pnts = 0;
176 }
177 vertex_idx = atoi(dxf_buf);
178 if (vertex_idx > 0) {
179 xpnts[arr_size] = mesh_xpnts[vertex_idx - 1];
180 ypnts[arr_size] = mesh_ypnts[vertex_idx - 1];
181 zpnts[arr_size] = mesh_zpnts[vertex_idx - 1];
182 arr_size++;
183 mesh_pnts++;
184 }
185 break;
186 }
187 }
188
189 if (polyface_mesh_started) {
190 if (mesh_pnts > 0) {
191 /* close a mesh */
192 xpnts[arr_size] = xpnts[0];
193 ypnts[arr_size] = ypnts[0];
194 zpnts[arr_size] = zpnts[0];
195 arr_size++;
196 if (flag_frame)
197 write_vect(Map, layer, "POLYFACE FRAME", handle, "",
198 arr_size, GV_LINE);
199 else
200 write_vect(Map, layer, "POLYFACE", handle, "",
201 arr_size, GV_FACE);
202 arr_size = 0;
203 mesh_pnts = 0;
204 }
205 continue;
206 }
207
208 if (xflag && yflag) {
209 arr_size =
210 make_arc_from_polyline(arr_size, bulge, prev_bulge);
211 prev_bulge = bulge;
212 bulge = 0.0;
213 } /* processing polyline vertex */
214 }
215 } /* vertex loop */
216
217 if (polyface_mesh_started) {
218 G_free(mesh_xpnts);
219 G_free(mesh_ypnts);
220 G_free(mesh_zpnts);
221 }
222 else
223 write_pnts(Map, layer, handle, polyline_flag, zflag, arr_size);
224
225 return;
226 }
227
write_pnts(struct Map_info * Map,char * layer,char * handle,int polyline_flag,int zflag,int arr_size)228 static void write_pnts(struct Map_info *Map, char *layer, char *handle,
229 int polyline_flag, int zflag, int arr_size)
230 {
231 /* done reading vertices */
232 if (polyline_flag & 1) { /* only dealing with polyline_flag = 1 */
233 /* check to make sure vertex points describe a closed polyline */
234 if (xpnts[0] != xpnts[arr_size - 1] ||
235 ypnts[0] != ypnts[arr_size - 1]) {
236 /* add on the vertex point to complete closed polyline */
237 xpnts[arr_size] = xpnts[0];
238 ypnts[arr_size] = ypnts[0];
239 zpnts[arr_size] = zpnts[0];
240 arr_size++;
241
242 /* arr_size incremented to be consistent with polyline_flag != 1 */
243 if (arr_size == arr_max) {
244 arr_max += ARR_INCR;
245 xpnts = (double *)G_realloc(xpnts, arr_max * sizeof(double));
246 ypnts = (double *)G_realloc(ypnts, arr_max * sizeof(double));
247 zpnts = (double *)G_realloc(zpnts, arr_max * sizeof(double));
248 }
249 }
250 }
251
252 if (!zflag) {
253 int i;
254
255 for (i = 0; i < arr_size; i++)
256 zpnts[i] = 0.0;
257 }
258
259 write_vect(Map, layer, "POLYLINE", handle, "", arr_size, GV_LINE);
260
261 return;
262 }
263