1 /*
2 * Code for converting dxf entities to SVG elements
3 * There are multiple ways for converting different items
4 * If possible most DXF enetities will be converted to paths because that is the most flexable object
5 *
6 * Author:
7 * Matt Squires <squiresm@colorado.edu>
8 *
9 * Copyright (C) 2005 Matt Squires
10 *
11 * Released under GNU GPL and LGPL, read the file 'GPL.txt' and 'LGPL.txt' for details
12 */
16 /*
18 Matt Squires
19 SoC 2005
21 */
23 #include "entities2elements.h"
24 #include "tables2svg_info.h"
25 #include <iostream>
26 #include <math.h>
27 #include <string.h>
28 #include <stdlib.h>
29 // The names indicate the DXF entitiy first and the SVG element last
31 // Common elements
32 char* to_arc(double bulge, double r, double start_ang, double end_ang, int precision,char* delim, char * units, double scaling, char *out){
33 // This is used for arcs, polylines, and lwpolylines
34 char temp[50];
36 // Assume that we are adding to the input and not starting over
37 strcat(out," A ");
38 // For arcs there is only one radius
39 strcat(out,gcvt(scaling*r,precision,temp) );
40 strcat(out,",");
41 strcat(out,gcvt(scaling*r,precision,temp) );
43 strcat(out," 0"); // For arc assume no x-axis rotation. That seems to apply to elipse elements only
44 // Determine if it is a large arc
45 if ( (end_ang > start_ang) && ( (end_ang - start_ang) > 180) ){
46 //strcat(out," 1,0 "); // Large arc flag...Always use a zero sweep flag
47 strcat(out," 1, "); // Large arc flag...Always use a zero sweep flag
48 }
49 else{
50 //strcat(out," 0,0 "); // Small arc flag...Always use a zero sweep flag
51 strcat(out," 0,");
52 }
53 // This may be easier if I allow r to be plus and minus, but for now this works
54 if (bulge > 0){
55 strcat(out,"0 ");
56 }
57 else{
58 strcat(out,"1 ");
59 }
60 }
62 // Build Coordinate
63 void coord(entity *ent, int precision,char* delim, char * units, double scaling, char *out); // Pairs of coords with units will be used so often build a function
64 void coord(entity *ent, int precision,char* delim, char * units, double scaling, char *out){
65 // Pairs of coords with units will be used so often build a function build a dedicated function for returning such
67 char temp[20];
68 if (units != NULL) scaling = 1; // If units have been defined then ignore the scaling parameter
69 strcat(out, gcvt(scaling*ent->ret_x(),precision,temp) ); // There must be a better function for double to ascii conversion that is defined in most libraries
70 if (units != NULL) strcat(out, units);
71 strcat(out, delim);
72 strcat(out, gcvt(-scaling*ent->ret_y(),precision,temp) ); // Because SVG has a the Y-axis pointed down multiply by -1
73 if (units != NULL) strcat(out, units);
74 strcat(out, " ");
75 }
77 // DXF Polyline -> SVG
78 void pline2svg(polyline pline, int type, int precision, char * units, double scaling, tables plot_info, char *out); // General function for the conversion of a pline to a SVG element. Very similar functions just make accomidations for parts that may not be supported
79 void pline2svg(polyline pline, int type, int precision, char * units, double scaling, tables plot_info, char *out){
80 // 0 is pline2path
81 // 1 is pline2pline
82 // 2 is pline2polygon
85 char delim[1];
86 double mag_bulge = 0;
87 double prev_mag_bulge = 0;
89 std::vector< vertex >::iterator vver_iter;
90 std::vector< vertex > points = pline.ret_points();
92 if (type < 1){
93 // Put the first Move To at the first, everything else will be a lineto
94 strcpy(delim," ");
95 strcat(out, "M ");
96 coord( &points[0], precision, delim, units, scaling, out );
97 prev_mag_bulge = sqrt(pow(points[0].ret_bulge(),2)); // Because the bulge value can be positive or negative calculate the magnitude
98 if ( prev_mag_bulge > pow(0.1,precision) ){
99 to_arc(pline.bulge(0), pline.bulge_r(0), pline.bulge_start_angle(0), pline.bulge_end_angle(0), precision, delim, units, scaling, out);
100 }
101 for (int i = 1; i < points.size(); i++){
102 if ( prev_mag_bulge < pow(0.1,precision) ){
103 // If the previous point was a bulge then don't use a line to
104 strcat(out, "L ");
105 }
106 coord( &points[i], precision, delim, units, scaling, out );
107 // If bulge > some precsion then add bulge
108 mag_bulge = sqrt(pow(points[i].ret_bulge(),2));
109 if ( (mag_bulge > pow(0.1,precision)) && (i < (points.size() - 1) )){
110 to_arc(pline.bulge(i), pline.bulge_r(i), pline.bulge_start_angle(i), pline.bulge_end_angle(i), precision, delim, units, scaling, out);
111 }
112 prev_mag_bulge = mag_bulge;
113 }
114 if ( pline.is_closed() ){
115 strcat(out,"z");
116 }
117 strcat(out,"\" ");
118 }
119 else{
120 strcpy(delim,",");
121 for (int i = 0; i < points.size(); i++){
122 coord( &points[i], precision, delim, NULL, scaling, out );
123 // If bulge > some precsion then add bulge
124 }
125 // if the element is a SVG::pline and the DXF::pline is closed then simulate by adding an extra point
126 if ( (type == 1) && pline.is_closed() ){
127 coord( &points[0], precision, delim, NULL, scaling, out );
128 }
129 }
131 }
133 char* pline2path(polyline pline, char * units, double scaling, tables plot_info){
134 // Convert a dxf polyline to a SVG path. This is the closest conversion of the DXF polyline to an SVG element
135 char *out_ptr;
136 char out[10000] = "<path d=\"";
137 entity *ent_ptr = &pline;
138 char temp[20];
139 int precision = 6;
141 pline2svg(pline, 0, precision, units, scaling, plot_info, out);
142 // Add some line information
143 strcat(out,"fill=\"none\" stroke=\"black\" stroke-width=\"1\" ");
144 pattern2dasharray(plot_info.ret_ltype( ent_ptr->ret_ltype_name(temp),ent_ptr->ret_layer_name(temp) ), precision, scaling, out); // Add the linetype information
146 strcat(out," />");
147 out_ptr = out;
148 return out_ptr;
149 }
151 char* pline2pline(polyline pline, char * units, double scaling, tables plot_info){
152 // Convert a dxf polyline to a SVG polyline. The conversion is not 1:1 because the SVG pline doesn't support closed objects or curves
153 entity *ent_ptr = &pline;
154 char temp[2000];
155 int precision = 6;
157 char out[10000] = "<polyline fill=\"none\" stroke=\"black\" stroke-width=\"1\" ";
158 ltype linfo = plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
159 pattern2dasharray(linfo, precision, scaling, out); // Add the linetype information
160 //strcpy(temp," ");
162 strcat(out,"points=\"");
164 //strcat(out,"<polyline fill=\"none\" stroke=\"black\" stroke-width=\"1\" points=\"");
165 pline2svg(pline, 1, precision, units, scaling, plot_info, out);
166 // Add some line information
167 // if the DXF pline is closed then add an extra point
169 strcat(out,"\"/>");
170 char *out_ptr = out;
171 return out_ptr;
172 }
173 char* pline2polygon(polyline pline, char * units, double scaling, tables plot_info){
174 // Convert a dxf polyline to a SVG polygon. The conversion is not 1:1 because the SVG polygone assumes a closed path. If the pline is not closed it will be forced closed
175 //return pline2svg(pline, 2, 6, units, double scaling,out);
176 }
179 // DXF LWPolyline -> SVG
182 // This could be a template with polyline and lwpolyline but right now it is not that important
183 void lwpline2svg(lwpolyline pline, int type, int precision, char * units, double scaling, tables plot_info, char *out); // General function for the conversion of a pline to a SVG element. Very similar functions just make accomidations for parts that may not be supported
184 void lwpline2svg(lwpolyline pline, int type, int precision, char * units, double scaling, tables plot_info, char *out){
185 // 0 is pline2path
186 // 1 is pline2pline
187 // 2 is pline2polygon
190 char delim[1];
191 double mag_bulge = 0;
192 double prev_mag_bulge = 0;
194 std::vector< vertex >::iterator vver_iter;
195 std::vector< vertex > points = pline.ret_points();
197 if (type < 1){
198 // Put the first Move To at the first, everything else will be a lineto
199 strcpy(delim," ");
200 strcat(out, "M ");
201 coord( &points[0], precision, delim, NULL, scaling, out );
202 prev_mag_bulge = sqrt(pow(points[0].ret_bulge(),2)); // Because the bulge value can be positive or negative calculate the magnitude
203 if ( prev_mag_bulge > pow(0.1,precision) ){
204 to_arc(pline.bulge(0),pline.bulge_r(0), pline.bulge_start_angle(0), pline.bulge_end_angle(0), precision, delim, NULL, scaling, out);
205 }
207 for (int i = 1; i < points.size(); i++){
208 if ( prev_mag_bulge < pow(0.1,precision) ){
209 // If the previous point was a bulge then don't use a line to
210 strcat(out, "L ");
211 }
212 coord( &points[i], precision, delim, NULL , scaling, out );
213 // If bulge > some precsion then add bulge
214 mag_bulge = sqrt(pow(points[i].ret_bulge(),2));
215 if ( ( mag_bulge > pow(0.1,precision) ) && (i < (points.size() - 1) )){ // Make sure the final point doesn't add a bulge on accident
216 to_arc(pline.bulge(i), pline.bulge_r(i), pline.bulge_start_angle(i), pline.bulge_end_angle(i), precision, delim, units, scaling, out);
217 }
218 prev_mag_bulge = mag_bulge;
219 }
220 if ( pline.is_closed() ){
221 strcat(out,"z");
222 }
223 strcat(out,"\" ");
224 }
225 else{
226 strcpy(delim,",");
227 for (int i = 0; i < points.size(); i++){
228 coord( &points[i], precision, delim, units, scaling, out );
229 // If bulge > some precsion then add bulge
230 }
231 // if the element is a SVG::pline and the DXF::pline is closed then simulate by adding an extra point
232 if ( (type == 1) && pline.is_closed() ){
233 coord( &points[0], precision, delim, units, scaling, out );
234 }
235 }
237 }
239 char* lwpline2path(lwpolyline pline, char * units, double scaling, tables plot_info){
240 // Convert a dxf polyline to a SVG path. This is the closest conversion of the DXF polyline to an SVG element
241 char *out_ptr;
242 char out[10000] = "<path d=\"";
243 entity *ent_ptr = &pline;
244 char temp[20];
245 int precision = 6;
247 lwpline2svg(pline, 0, precision, units, scaling, plot_info, out);
248 // Add some line information
249 strcat(out,"fill=\"none\" stroke=\"black\" stroke-width=\"1\" ");
250 pattern2dasharray(plot_info.ret_ltype( ent_ptr->ret_ltype_name(temp),ent_ptr->ret_layer_name(temp) ), precision, scaling, out); // Add the linetype information
252 strcat(out," />");
253 out_ptr = out;
254 return out_ptr;
255 }
257 // DXF ARC -> SVG
258 char* arc2path(arc a, int precision, char * units, double scaling, tables plot_info, char *out){
259 // So far this appears to be the only way to convert arcs into something recognized by SVG
260 char *out_ptr;
261 char temp[20];
262 entity *ent_ptr = &a;
264 strcpy(out,"<path d=\"M");
265 // Calculate the starting point from the center and the start angle. As far as I can tell the rotation is CCW in the dxf notation and it in degrees
266 strcat(out,gcvt(scaling*(ent_ptr->ret_x()+a.ret_radius()*cos( a.ret_srt_ang()*3.14159/180 )),precision,temp) );
267 strcat(out," ");
268 strcat(out,gcvt(-1*scaling*(ent_ptr->ret_y()+a.ret_radius()*sin( a.ret_srt_ang()*3.14159/180 )),precision,temp) );
269 strcat(out," A ");
270 // For arcs there is only one radius
271 strcat(out,gcvt(scaling*a.ret_radius(),precision,temp) );
272 strcat(out,",");
273 strcat(out,gcvt(scaling*a.ret_radius(),precision,temp) );
275 strcat(out," 0"); // For arc assume no x-axis rotation. That seems to apply to elipse elements only
276 // Determine if it is a large arc
277 if ( (a.ret_end_ang() > a.ret_srt_ang()) && ( (a.ret_end_ang() - a.ret_srt_ang()) > 180) ){
278 strcat(out," 1,0 "); // Large arc flag...Always use a zero sweep flag
279 }
280 else{
281 strcat(out," 0,0 "); // Small arc flag...Always use a zero sweep flag
282 }
284 //The final point
285 strcat(out,gcvt(scaling*(ent_ptr->ret_x()+a.ret_radius()*cos( a.ret_end_ang()*3.14159/180 )),precision,temp) );
286 strcat(out,",");
287 strcat(out,gcvt(-1*scaling*(ent_ptr->ret_y()+a.ret_radius()*sin( a.ret_end_ang()*3.14159/180 )),precision,temp) );
288 strcat(out,"\" fill=\"none\" stroke=\"black\" stroke-width=\"1\" ");
289 ltype linfo = plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
290 pattern2dasharray(linfo, precision, scaling, out); // Add the linetype information
291 strcat(out, " />");
294 out_ptr = out;
295 return out_ptr;
297 }
300 // DXF Circle -> SVG
301 char* circle2circle(circle circ, int precision, char * units, double scaling, tables plot_info, char *out){
302 // Direct conversion of DXF circle to SVG circle
303 char *out_ptr;
304 char temp[1000]="\" cy=\"";
305 entity *ent_ptr = ˆ
306 strcpy(out,"<circle cx=\"");
307 coord(ent_ptr, precision,temp, units, scaling, out);
308 strcat(out,"\" r=\"");
309 strcat(out,gcvt(circ.ret_radius(),precision,temp) );
310 strcat(out,units);
311 strcat(out,"\" fill=\"none\" stroke=\"black\" stroke-width=\"1\" ");
312 ltype linfo = plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
313 //plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
314 pattern2dasharray(linfo, precision, scaling, out); // Add the linetype information
315 //pattern2dasharray(plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp)), precision, scaling, out); // Add the linetype information
316 strcat(out, " />");
317 out_ptr = out;
318 return out_ptr;
319 }
321 char* circle2path(circle circ, int precision, char * units, double scaling, tables plot_info, char *out){
322 // Conversion of DXF circle to SVG circle assuming the path will represent the circle
324 char *out_ptr;
325 char temp[20]=",";
326 entity *ent_ptr = ˆ
328 strcpy(out,"<path d=\"M");
329 // The starting point is x-r,y so subtract off the radius from the x coord
330 strcat(out,gcvt(ent_ptr->ret_x()-circ.ret_radius(),precision,temp) );
331 strcat(out," ");
332 strcat(out,gcvt(ent_ptr->ret_y(),precision,temp) );
334 strcat(out," a");
335 strcat(out,gcvt(circ.ret_radius(),precision,temp) );
336 strcat(out,",");
337 strcat(out,gcvt(circ.ret_radius(),precision,temp) );
338 strcat(out,"0 0,0 0,0\" fill=\"none\" stroke=\"black\" stroke-width=\"1\"");
340 out_ptr = out;
341 return out_ptr;
342 }
345 // DXF Line -> SVG
346 char* line2line(line ln, int precision, char * units, double scaling, tables plot_info, char *out){
347 // Directly convert DXF to SVG because it works
348 char *out_ptr;
349 char temp[20];
350 entity *ent_ptr = &ln;
352 strcpy(out,"<line x1=\"");
353 strcat(out,gcvt(ent_ptr->ret_x(),precision,temp) );
354 strcat(out,units);
355 strcat(out,"\" y1=\"");
356 strcat(out,gcvt(-1*ent_ptr->ret_y(),precision,temp) ); // Put in an extra minus because of the way SVG has defined the axis
357 strcat(out,units);
359 strcat(out,"\" x2=\"");
360 strcat(out,gcvt(ln.ret_xf(),precision,temp) );
361 strcat(out,units);
362 strcat(out,"\" y2=\"");
363 strcat(out,gcvt(-1*ln.ret_yf(),precision,temp) ); // Put in an extra minus because of the way SVG has defined the axis
364 strcat(out,units);
365 strcat(out,"\" stroke-width=\"1\" stroke=\"black\" ");
366 ltype linfo = plot_info.ret_ltype(ent_ptr->ret_ltype_name(temp), ent_ptr->ret_layer_name(temp));
367 pattern2dasharray(linfo, precision, scaling, out); // Add the linetype information
368 strcat(out, " />");
370 out_ptr = out;
371 return out_ptr;
372 }
375 char* line2path(line ln, int precision, char * units, double scaling, tables plot_info, char *out){
376 // Convert DXF line to SVG path
378 char *out_ptr;
379 char temp[20];
380 entity *ent_ptr = &ln;
382 strcpy(out,"<path d=\"M");
383 strcat(out,gcvt(scaling*ent_ptr->ret_x(),precision,temp) );
384 strcat(out," ");
385 strcat(out,gcvt(scaling*ent_ptr->ret_y(),precision,temp) );
387 strcat(out," L");
388 strcat(out,gcvt(scaling*ln.ret_xf(),precision,temp) );
389 strcat(out," ");
390 strcat(out,gcvt(scaling*ln.ret_yf(),precision,temp) );
391 strcat(out,"\" fill=\"none\" stroke=\"black\" stroke-width=\"1\" /");
393 out_ptr = out;
394 return out_ptr;
395 }
397 // DXF Text -> SVG
398 char* text2text(text txt, int precision, char * units, double scaling, tables plot_info, char *out){
399 // Directly convert DXF to SVG because it works
400 char *out_ptr;
401 char temp[10000];
402 entity *ent_ptr = &txt;
404 // If the text is rotated use the transform matrix
406 if ( txt.ret_txt_rot() > precision ){
407 double ca = cos(0.017453*txt.ret_txt_rot()); // ca = cosine(a)
408 double sa = sin(-0.017453*txt.ret_txt_rot()); // sa = sine(a)
409 double tx = ent_ptr->ret_x()*scaling;
410 double ty = -ent_ptr->ret_y()*scaling;
411 // Apply a translation to the orgin, then a rotation, then a translation back to the original position
412 double a = ca;
413 double b = sa;
414 double c = -sa;
415 double d = ca;
416 double e = -1*(tx*ca-ty*sa-tx);
417 double f = -1*(tx*sa+ty*ca-ty);
419 strcpy(out, "<g transform=\"matrix(");
420 strcat(out,gcvt(a,precision,temp) );
421 strcat(out," ");
422 strcat(out,gcvt(b,precision,temp) );
423 strcat(out," ");
424 strcat(out,gcvt(c,precision,temp) );
425 strcat(out," ");
426 strcat(out,gcvt(d,precision,temp) );
427 strcat(out," ");
428 strcat(out,gcvt(e,precision,temp) );
429 strcat(out," ");
430 strcat(out,gcvt(f,precision,temp) );
431 strcat(out,")\" >\n<text x=\"");
432 }
433 else{
434 strcpy(out,"<text x=\"");
435 }
436 /*
437 strcat(out,gcvt(ent_ptr->ret_x(),precision,temp) );
438 strcat(out,units);
439 strcat(out,"\" y=\"-"); // Put in an extra minus because of the way SVG has defined the axis
440 strcat(out,gcvt(ent_ptr->ret_y(),precision,temp) );
441 strcat(out,units);
442 */
443 strcat(out,gcvt(ent_ptr->ret_x()*scaling,precision,temp) );
444 //strcat(out,units);
445 strcat(out,"\" y=\"-"); // Put in an extra minus because of the way SVG has defined the axis
446 strcat(out,gcvt(ent_ptr->ret_y()*scaling,precision,temp) );
447 //strcat(out,units);
448 strcat(out,"\" font-family=\"Verdana\" font-size=\"");
449 strcat(out,gcvt(scaling*txt.ret_txt_ht(),precision,temp) );
450 strcat(out,"\" Fill=\"black\"");
452 strcat(out," >");
453 // Now put in the text
454 strcat(out,txt.ret_text(temp));
456 // Now close the text element
457 strcat(out,"</text>");
458 // If the text was rotated finish off the tranform group
459 if ( txt.ret_txt_rot() > precision ){
460 strcat(out,"</g>");
461 }
463 out_ptr = out;
464 return out_ptr;
465 }
469 // DXF Insert -> SVG
470 char* insert2group(insert in, int precision, char * units, double scaling, tables plot_info, blocks blks, char *out){
471 char *out_ptr;
472 char tmp_char[100000];
474 // get the block using the name from the insert information
475 block blk = blks.ret_block(in.name(tmp_char));
477 entity *ent_ptr = ∈
478 entities *ents_ptr = &blk;
479 // For now just translations MBS 22 Aug 05
480 strcpy(out, "<g transform=\"matrix(1,0,0,1,");
481 strcat(out,gcvt(scaling*ent_ptr->ret_x(),precision,tmp_char) );
482 strcat(out,",");
483 strcat(out,gcvt(-scaling*ent_ptr->ret_y(),precision,tmp_char) );
484 strcat(out,")\" >\n");
487 // Now convert the entities in the block
488 std::vector< polyline > plines = ents_ptr->ret_plines();
489 std::vector< lwpolyline > lwplines = ents_ptr->ret_lwplines();
490 std::vector< arc > arcs = ents_ptr->ret_arcs();
491 std::vector< circle > circs = ents_ptr->ret_circles();
492 std::vector< line > lns = ents_ptr->ret_lines();
493 std::vector< text > txts = ents_ptr->ret_texts();
497 for(int i = 0; i < plines.size();i++){
498 strcat( out,pline2pline(plines[i], units, scaling, plot_info ) );
499 strcat( out, "\n" );
500 }
501 for(int i = 0; i < lwplines.size();i++){
502 strcat( out,lwpline2path(lwplines[i], units, scaling, plot_info ) );
503 strcat( out, "\n" );
504 }
505 for(int i = 0; i < arcs.size();i++){
506 strcat( out, arc2path(arcs[i], 6,units, scaling, plot_info, tmp_char ) );
507 strcat( out, "\n" );
508 }
509 for(int i = 0; i < circs.size();i++){
510 strcat( out, circle2circle(circs[i], 6, units, scaling, plot_info, tmp_char) );
511 strcat( out, "\n" );
512 }
513 for(int i = 0; i < lns.size();i++){
514 strcat( out, line2line(lns[i], 6, units, scaling, plot_info, tmp_char) );
515 strcat( out, "\n" );
516 }
517 for(int i = 0; i < txts.size();i++){
518 strcat( out, text2text(txts[i], 6, units, scaling, plot_info, tmp_char) );
519 strcat( out, "\n" );
520 }
521 // End the group
522 strcat(out,"</g>");
524 out_ptr = out;
525 return out_ptr;
526 }
530 char* write_by_layer(int output_type, entities &ents, tables &tbls, blocks &blks, double scaling, char * units, char * layer, char * out){
531 // output_type = 0 is to std:out
532 // output_type = 1 is to the input filename but with .dxf on the end
534 // For now everything will go to stdout later may directed to other places
536 // Get the various file informations as dependent on the layer type
537 std::vector< polyline > plines = ents.ret_plines(layer);
538 std::vector< lwpolyline > lwplines = ents.ret_lwplines(layer);
539 std::vector< arc > arcs = ents.ret_arcs(layer);
540 std::vector< circle > circs = ents.ret_circles(layer);
541 std::vector< line > lns = ents.ret_lines(layer);
542 std::vector< text > txts = ents.ret_texts(layer);
543 std::vector< insert > ins = ents.ret_inserts(layer);
545 // It would be better to redirect stdout to different places. That would make the code cleaner but I don't think it will work better
546 char tmp_char[100000];
547 for(int i = 0; i < plines.size();i++){
548 if (output_type == 0){
549 std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl;
550 }
551 else if (output_type == 1){
552 std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl;
553 }
554 }
555 for(int i = 0; i < lwplines.size();i++){
556 if (output_type == 0){
557 std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl;
558 }
559 else if (output_type == 1){
560 std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl;
561 }
562 }
563 for(int i = 0; i < arcs.size();i++){
564 if (output_type == 0){
565 std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl;
566 }
567 else if (output_type == 1){
568 std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl;
569 }
570 }
571 for(int i = 0; i < circs.size();i++){
572 if (output_type == 0){
573 std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl;
574 }
575 else if (output_type == 1){
576 std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl;
577 }
578 }
579 for(int i = 0; i < lns.size();i++){
580 if (output_type == 0){
581 std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl;
582 }
583 else if (output_type == 1){
584 std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl;
585 }
586 }
587 for(int i = 0; i < txts.size();i++){
588 if (output_type == 0){
589 std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl;
590 }
591 else if (output_type == 1){
592 std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl;
593 }
594 }
595 for(int i = 0; i < ins.size();i++){
596 if (output_type == 0){
597 std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl;
598 }
599 else if (output_type == 1){
600 std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl;
601 }
602 }
603 }
607 char* write_all(int output_type, entities &ents, tables &tbls, blocks &blks, double scaling, char * units, char * out){
608 // output_type = 0 is to std:out
609 // output_type = 1 is to the input filename but with .dxf on the end
611 // For now everything will go to stdout later may directed to other places
613 // Get the various file informations as dependent on the layer type
614 std::vector< polyline > plines = ents.ret_plines();
615 std::vector< lwpolyline > lwplines = ents.ret_lwplines();
616 std::vector< arc > arcs = ents.ret_arcs();
617 std::vector< circle > circs = ents.ret_circles();
618 std::vector< line > lns = ents.ret_lines();
619 std::vector< text > txts = ents.ret_texts();
620 std::vector< insert > ins = ents.ret_inserts();
622 // It would be better to redirect stdout to different places. That would make the code cleaner but I don't think it will work better
623 char tmp_char[100000];
624 for(int i = 0; i < plines.size();i++){
625 if (output_type == 0){
626 std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl;
627 }
628 else if (output_type == 1){
629 std::cout << "\t" << pline2path(plines[i], NULL, scaling, tbls ) << std::endl;
630 }
631 }
632 for(int i = 0; i < lwplines.size();i++){
633 if (output_type == 0){
634 std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl;
635 }
636 else if (output_type == 1){
637 std::cout << "\t" << lwpline2path(lwplines[i], units, scaling, tbls ) << std::endl;
638 }
639 }
640 for(int i = 0; i < arcs.size();i++){
641 if (output_type == 0){
642 std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl;
643 }
644 else if (output_type == 1){
645 std::cout << "\t" << arc2path(arcs[i], 6,units, scaling, tbls, tmp_char ) << std::endl;
646 }
647 }
648 for(int i = 0; i < circs.size();i++){
649 if (output_type == 0){
650 std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl;
651 }
652 else if (output_type == 1){
653 std::cout << "\t" << circle2circle(circs[i], 6, units, scaling, tbls, tmp_char) << std::endl;
654 }
655 }
656 for(int i = 0; i < lns.size();i++){
657 if (output_type == 0){
658 std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl;
659 }
660 else if (output_type == 1){
661 std::cout << "\t" << line2line(lns[i], 6, units, scaling, tbls, tmp_char) << std::endl;
662 }
663 }
664 for(int i = 0; i < txts.size();i++){
665 if (output_type == 0){
666 std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl;
667 }
668 else if (output_type == 1){
669 std::cout << "\t" << text2text(txts[i], 6, units, scaling, tbls, tmp_char) << std::endl;
670 }
671 }
672 for(int i = 0; i < ins.size();i++){
673 if (output_type == 0){
674 std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl;
675 }
676 else if (output_type == 1){
677 std::cout << "\t" << insert2group(ins[i], 6, units, scaling, tbls, blks, tmp_char) << std::endl;
678 }
679 }
680 }