Code

Translations. French translation minor update.
[inkscape.git] / src / extension / dxf2svg / read_dxf.cpp
1 /*
2  * For reading and slight parsing of dxf files
3  *
4  * Author:
5  *   Matt Squires <squiresm@colorado.edu>
6  *
7  * Copyright (C) 2005 Matt Squires
8  *
9  * Released under GNU GPL and LGPL, read the file 'GPL.txt' and 'LGPL.txt' for details
10  */
14 #include <fstream>
15 #include <string>
16 #include "read_dxf.h"
18 #include <iostream>
19 #include <string.h>
20 #include <stdlib.h>
21 using namespace std;
24 int MAX_STR_LN = 10000;
26 int section(char* value){
27         if ( strncmp(value,"HEADER",6) == 0 ) return 0;
28         if ( strncmp(value,"CLASSES",7) == 0 ) return 1;
29         if ( strncmp(value,"TABLES",6) == 0 ) return 2;
30         if ( strncmp(value,"BLOCKS",6) == 0 ) return 3;
31         if ( strncmp(value,"ENTITIES",8) == 0 ) return 4;
32         if ( strncmp(value,"OBJECTS",7) == 0 ) return 5;
33         if ( strncmp(value,"THUMBNAILIMAGE",14) == 0 ) return 6;
34 }
37 dxfpair::dxfpair(int gcode, char val[10000]){
38                 group_code = gcode;
39                 // Dynamically save the strings, otherwise the memory uses is bad
40                 
41                 for (int i = 0; i < strlen(val); i++){
42                         value.push_back(val[i]);
43                 }               
44 }
47 dxfpair::~dxfpair(){
48         //delete [] value;
49 }
51 char * dxfpair::value_char(char *string){
52         int size = value.size();
53         while( ( size > 0 ) && int(value[size-1]) < 33){
54                 // Strip off any control characters and spaces off the end of the string
55                 size--;
56         }
57         for(int i = 0; i < size; i++){
58                 string[i] = value[i];
59         }
60         string[size]=0;
61 }
63 std::vector< std::vector< dxfpair > > dxf_get_sections(char* filename){
64         // In the dxf format information is paired into group codes that indicate the information that follows on the next line.  The information on the next line is called the value
65         
66         int n =0;
67         
68         int group_code;
69         char value[MAX_STR_LN];
70         
71         int section_num;
72         
73         
74         
75         
76         std::vector< std::vector< dxfpair > > out;
77         
78         std::vector< dxfpair > header;
79         std::vector< dxfpair > classes;
80         std::vector< dxfpair > tables;
81         std::vector< dxfpair > blocks;
82         std::vector< dxfpair > entities;
83         std::vector< dxfpair > objects;
84         std::vector< dxfpair > thumbnailimage;
85         
86         header.clear();
87         classes.clear();
88         tables.clear();
89         blocks.clear();
90         entities.clear();
91         objects.clear();
92         thumbnailimage.clear();
93         
94         
95         // Open dxf file for reading
96         std::ifstream file(filename);
97         
98         if (!file.is_open()){
99                 exit (1);  // Change this to an exception
100         }
101         
102         // Find the first SECTION header
103         
104         while ( (!file.eof()) ){ 
105                 n++;
106                 
107                 // get the first group code and value
108                 file.getline(value,MAX_STR_LN);
109                 group_code = atoi(value);
110                 file.getline(value,MAX_STR_LN);
111                 
112                 do{     
113                                 
114                         // TO DO     set all the chars to be caps for later comparison
115                 
116                         // Find the SECTION codes
117                         if ( (group_code == 0 ) && ( strncmp(value,"SECTION",7) == 0 ) ){
118                                 // Directly after a section value is the type of section ( e.g. HEADER, TABLES )
119                                 file.getline(value,MAX_STR_LN);
120                                 group_code = atoi(value);
121                                 file.getline(value,MAX_STR_LN);
122                                 section_num = section( value );
123                                 if ( group_code == 2 ){
124                                         // Make sure the the group code is 2 for the SECTION name
125                                         // This is a big block of mostly repetitive code, it will result in larger code, but would be faster than putting the switch in another while loop.  If I still live in a time when file size mattered alot I would change it
126                                         //std::cout << "section_num = " << section_num << std::endl;
127                                         switch ( section_num ){
128                                                 case 0:
129                                                         file.getline(value,MAX_STR_LN);
130                                                         group_code = atoi(value);
131                                                         file.getline(value,MAX_STR_LN);
132                                                         do{
133                                                                 header.push_back( dxfpair( group_code, value ) );
134                                                                 file.getline(value,MAX_STR_LN);
135                                                                 group_code = atoi(value);
136                                                                 file.getline(value,MAX_STR_LN);
137                                                         }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );  // I put in the (group_code != 0) in the hope that it will be a faster bool compare than the string compare.  Test this later
138                                                         break;
139                                                 case 1:
140                                                         file.getline(value,MAX_STR_LN);
141                                                         group_code = atoi(value);
142                                                         file.getline(value,MAX_STR_LN);
143                                                         if ( (group_code != 0) || (strncmp(value,"ENDSEC",6) != 0) ){
144                                                                 // Some dxf files have blank sections.  These are not handled by the do/while loop so break about if needed
145                                                                 do{
146                                                                         classes.push_back( dxfpair( group_code, value ) );
147                                                                         file.getline(value,MAX_STR_LN);
148                                                                         group_code = atoi(value);
149                                                                         file.getline(value,MAX_STR_LN);
150                                                                 }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );  // I put in the (group_code != 0) in the hope that it will be a faster bool compare than the string compare.  Test this later
151                                                         }
152                                                         break;
153                                                 case 2:
154                                                         file.getline(value,MAX_STR_LN);
155                                                         group_code = atoi(value);
156                                                         file.getline(value,MAX_STR_LN);
157                                                         do{
158                                                                 tables.push_back( dxfpair( group_code, value ) );
159                                                                 file.getline(value,MAX_STR_LN);
160                                                                 group_code = atoi(value);
161                                                                 file.getline(value,MAX_STR_LN);
162                                                         }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );
163                                                         break;
164                                                 case 3:
165                                                         file.getline(value,MAX_STR_LN);
166                                                         group_code = atoi(value);
167                                                         file.getline(value,MAX_STR_LN);
168                                                         do{
169                                                                 blocks.push_back( dxfpair( group_code, value ) );
170                                                                 file.getline(value,MAX_STR_LN);
171                                                                 group_code = atoi(value);
172                                                                 file.getline(value,MAX_STR_LN);
173                                                         }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );  // I put in the (group_code != 0) in the hope that it will be a faster bool compare than the string compare.  Test this later
174                                                         break;
175                                                 case 4:
176                                                         file.getline(value,MAX_STR_LN);
177                                                         group_code = atoi(value);
178                                                         file.getline(value,MAX_STR_LN);
179                                                         do{
180                                                                 entities.push_back( dxfpair( group_code, value ) );
181                                                                 file.getline(value,MAX_STR_LN);
182                                                                 group_code = atoi(value);
183                                                                 file.getline(value,MAX_STR_LN);
184                                                         }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );  // I put in the (group_code != 0) in the hope that it will be a faster bool compare than the string compare.  Test this later
185                                                         break;
186                                                 case 5:
187                                                         file.getline(value,MAX_STR_LN);
188                                                         group_code = atoi(value);
189                                                         file.getline(value,MAX_STR_LN);
190                                                         do{
191                                                                 objects.push_back( dxfpair( group_code, value ) );
192                                                                 file.getline(value,MAX_STR_LN);
193                                                                 group_code = atoi(value);
194                                                                 file.getline(value,MAX_STR_LN);
195                                                         }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );  // I put in the (group_code != 0) in the hope that it will be a faster bool compare than the string compare.  Test this later
196                                                         break;
197                                                 case 6:
198                                                         file.getline(value,MAX_STR_LN);
199                                                         group_code = atoi(value);
200                                                         file.getline(value,MAX_STR_LN);
201                                                         do{
202                                                                 thumbnailimage.push_back( dxfpair( group_code, value ) );
203                                                                 file.getline(value,MAX_STR_LN);
204                                                                 group_code = atoi(value);
205                                                                 file.getline(value,MAX_STR_LN);
206                                                         }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );  // I put in the (group_code != 0) in the hope that it will be a faster bool compare than the string compare.  Test this later
207                                                         break;
208                                                 default:
209                                                         file.getline(value,MAX_STR_LN);
210                                                         group_code = atoi(value);
211                                                         file.getline(value,MAX_STR_LN); 
212                                         }
213                                 }
214                         }       
215                         file.getline(value,MAX_STR_LN);
216                         group_code = atoi(value);
217                         file.getline(value,MAX_STR_LN);
218                         
219                         n++;
220                 }while( ( strncmp(value,"EOF",3) != 0 ) && (!file.eof()) ); 
221         }
222         
223         out.push_back(header);
224         out.push_back(classes);
225         out.push_back(tables);
226         out.push_back(blocks);
227         out.push_back(entities);
228         out.push_back(objects);
229         out.push_back(thumbnailimage);
230         
231         return out;
235 std::vector< std::vector< dxfpair > > separate_parts( std::vector< dxfpair > section){
236         //std::cout << "1" << std::endl;
237         //std::cout << "section.size() = " << section.size() << std::endl;
238         // Find where the major sections are and break into smaller parts
239         // Major section is defined as anything beween group_code 0 to 0
240         std::vector< dxfpair > inner;
241         std::vector< std::vector< dxfpair > > outer;
242         //std::cout << "2" << std::endl;
243         for (int i = 0; i < section.size(); i++){
244                 //std::cout << "i = " << i << std::endl;
245                 //std::cout << "section[i].value.size() = " << section[i].value.size() << std::endl;
246                 
247                 // Make sure no control codes like LF or CR are making it past this section
248                 if ( (section[i].value.size() > 0) && int(section[i].value.back()) < 32 ){
249                          section[i].value.pop_back();
250                  }
251                 //for(int j = 0;j < section[i].value.size();j++ ) std::cout << section[i].value[j];
252                 //std::cout << std::endl;
253                 
254                 inner.push_back( section[i] );
255                 
256                 // If the next group code is 0 then push the previously found info on outer and start looking for data again
257                 if (section[i+1].group_code == 0){
258                         //std::cout << "inner.push_back" << std::endl;
259                         outer.push_back( inner );
260                         inner.clear();
261                 }
262         }
263         // Because putting the data on outer depends on find a GC=0 the last bit of data may be left behind so it inner has data in it put it on outer
264         if ( inner.size() > 0 ){
265                 outer.push_back( inner );
266                 inner.clear();
267         }
268         //std::cout << "3" << std::endl;
269         if (section.back().group_code == 0){
270                 //outer.push_back( inner ); // Put the last part on if there is information, but I don't think it needs to.
271         }
272         
273         return outer;