Code

fix compile
[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 using namespace std;
22 int MAX_STR_LN = 10000;
24 int section(char* value){
25         if ( strncmp(value,"HEADER",6) == 0 ) return 0;
26         if ( strncmp(value,"CLASSES",7) == 0 ) return 1;
27         if ( strncmp(value,"TABLES",6) == 0 ) return 2;
28         if ( strncmp(value,"BLOCKS",6) == 0 ) return 3;
29         if ( strncmp(value,"ENTITIES",8) == 0 ) return 4;
30         if ( strncmp(value,"OBJECTS",7) == 0 ) return 5;
31         if ( strncmp(value,"THUMBNAILIMAGE",14) == 0 ) return 6;
32 }
35 dxfpair::dxfpair(int gcode, char val[10000]){
36                 group_code = gcode;
37                 // Dynamically save the strings, otherwise the memory uses is bad
38                 
39                 for (int i = 0; i < strlen(val); i++){
40                         value.push_back(val[i]);
41                 }               
42 }
45 dxfpair::~dxfpair(){
46         //delete [] value;
47 }
49 char * dxfpair::value_char(char *string){
50         int size = value.size();
51         while( ( size > 0 ) && int(value[size-1]) < 33){
52                 // Strip off any control characters and spaces off the end of the string
53                 size--;
54         }
55         for(int i = 0; i < size; i++){
56                 string[i] = value[i];
57         }
58         string[size]=0;
59 }
61 std::vector< std::vector< dxfpair > > dxf_get_sections(char* filename){
62         // 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
63         
64         int n =0;
65         
66         int group_code;
67         char value[MAX_STR_LN];
68         
69         int section_num;
70         
71         
72         
73         
74         std::vector< std::vector< dxfpair > > out;
75         
76         std::vector< dxfpair > header;
77         std::vector< dxfpair > classes;
78         std::vector< dxfpair > tables;
79         std::vector< dxfpair > blocks;
80         std::vector< dxfpair > entities;
81         std::vector< dxfpair > objects;
82         std::vector< dxfpair > thumbnailimage;
83         
84         header.clear();
85         classes.clear();
86         tables.clear();
87         blocks.clear();
88         entities.clear();
89         objects.clear();
90         thumbnailimage.clear();
91         
92         
93         // Open dxf file for reading
94         std::ifstream file(filename);
95         
96         if (!file.is_open()){
97                 exit (1);  // Change this to an exception
98         }
99         
100         // Find the first SECTION header
101         
102         while ( (!file.eof()) ){ 
103                 n++;
104                 
105                 // get the first group code and value
106                 file.getline(value,MAX_STR_LN);
107                 group_code = atoi(value);
108                 file.getline(value,MAX_STR_LN);
109                 
110                 do{     
111                                 
112                         // TO DO     set all the chars to be caps for later comparison
113                 
114                         // Find the SECTION codes
115                         if ( (group_code == 0 ) && ( strncmp(value,"SECTION",7) == 0 ) ){
116                                 // Directly after a section value is the type of section ( e.g. HEADER, TABLES )
117                                 file.getline(value,MAX_STR_LN);
118                                 group_code = atoi(value);
119                                 file.getline(value,MAX_STR_LN);
120                                 section_num = section( value );
121                                 if ( group_code == 2 ){
122                                         // Make sure the the group code is 2 for the SECTION name
123                                         // 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
124                                         //std::cout << "section_num = " << section_num << std::endl;
125                                         switch ( section_num ){
126                                                 case 0:
127                                                         file.getline(value,MAX_STR_LN);
128                                                         group_code = atoi(value);
129                                                         file.getline(value,MAX_STR_LN);
130                                                         do{
131                                                                 header.push_back( dxfpair( group_code, value ) );
132                                                                 file.getline(value,MAX_STR_LN);
133                                                                 group_code = atoi(value);
134                                                                 file.getline(value,MAX_STR_LN);
135                                                         }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
136                                                         break;
137                                                 case 1:
138                                                         file.getline(value,MAX_STR_LN);
139                                                         group_code = atoi(value);
140                                                         file.getline(value,MAX_STR_LN);
141                                                         if ( (group_code != 0) || (strncmp(value,"ENDSEC",6) != 0) ){
142                                                                 // Some dxf files have blank sections.  These are not handled by the do/while loop so break about if needed
143                                                                 do{
144                                                                         classes.push_back( dxfpair( group_code, value ) );
145                                                                         file.getline(value,MAX_STR_LN);
146                                                                         group_code = atoi(value);
147                                                                         file.getline(value,MAX_STR_LN);
148                                                                 }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
149                                                         }
150                                                         break;
151                                                 case 2:
152                                                         file.getline(value,MAX_STR_LN);
153                                                         group_code = atoi(value);
154                                                         file.getline(value,MAX_STR_LN);
155                                                         do{
156                                                                 tables.push_back( dxfpair( group_code, value ) );
157                                                                 file.getline(value,MAX_STR_LN);
158                                                                 group_code = atoi(value);
159                                                                 file.getline(value,MAX_STR_LN);
160                                                         }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );
161                                                         break;
162                                                 case 3:
163                                                         file.getline(value,MAX_STR_LN);
164                                                         group_code = atoi(value);
165                                                         file.getline(value,MAX_STR_LN);
166                                                         do{
167                                                                 blocks.push_back( dxfpair( group_code, value ) );
168                                                                 file.getline(value,MAX_STR_LN);
169                                                                 group_code = atoi(value);
170                                                                 file.getline(value,MAX_STR_LN);
171                                                         }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
172                                                         break;
173                                                 case 4:
174                                                         file.getline(value,MAX_STR_LN);
175                                                         group_code = atoi(value);
176                                                         file.getline(value,MAX_STR_LN);
177                                                         do{
178                                                                 entities.push_back( dxfpair( group_code, value ) );
179                                                                 file.getline(value,MAX_STR_LN);
180                                                                 group_code = atoi(value);
181                                                                 file.getline(value,MAX_STR_LN);
182                                                         }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
183                                                         break;
184                                                 case 5:
185                                                         file.getline(value,MAX_STR_LN);
186                                                         group_code = atoi(value);
187                                                         file.getline(value,MAX_STR_LN);
188                                                         do{
189                                                                 objects.push_back( dxfpair( group_code, value ) );
190                                                                 file.getline(value,MAX_STR_LN);
191                                                                 group_code = atoi(value);
192                                                                 file.getline(value,MAX_STR_LN);
193                                                         }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
194                                                         break;
195                                                 case 6:
196                                                         file.getline(value,MAX_STR_LN);
197                                                         group_code = atoi(value);
198                                                         file.getline(value,MAX_STR_LN);
199                                                         do{
200                                                                 thumbnailimage.push_back( dxfpair( group_code, value ) );
201                                                                 file.getline(value,MAX_STR_LN);
202                                                                 group_code = atoi(value);
203                                                                 file.getline(value,MAX_STR_LN);
204                                                         }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
205                                                         break;
206                                                 default:
207                                                         file.getline(value,MAX_STR_LN);
208                                                         group_code = atoi(value);
209                                                         file.getline(value,MAX_STR_LN); 
210                                         }
211                                 }
212                         }       
213                         file.getline(value,MAX_STR_LN);
214                         group_code = atoi(value);
215                         file.getline(value,MAX_STR_LN);
216                         
217                         n++;
218                 }while( ( strncmp(value,"EOF",3) != 0 ) && (!file.eof()) ); 
219         }
220         
221         out.push_back(header);
222         out.push_back(classes);
223         out.push_back(tables);
224         out.push_back(blocks);
225         out.push_back(entities);
226         out.push_back(objects);
227         out.push_back(thumbnailimage);
228         
229         return out;
233 std::vector< std::vector< dxfpair > > separate_parts( std::vector< dxfpair > section){
234         //std::cout << "1" << std::endl;
235         //std::cout << "section.size() = " << section.size() << std::endl;
236         // Find where the major sections are and break into smaller parts
237         // Major section is defined as anything beween group_code 0 to 0
238         std::vector< dxfpair > inner;
239         std::vector< std::vector< dxfpair > > outer;
240         //std::cout << "2" << std::endl;
241         for (int i = 0; i < section.size(); i++){
242                 //std::cout << "i = " << i << std::endl;
243                 //std::cout << "section[i].value.size() = " << section[i].value.size() << std::endl;
244                 
245                 // Make sure no control codes like LF or CR are making it past this section
246                 if ( (section[i].value.size() > 0) && int(section[i].value.back()) < 32 ){
247                          section[i].value.pop_back();
248                  }
249                 //for(int j = 0;j < section[i].value.size();j++ ) std::cout << section[i].value[j];
250                 //std::cout << std::endl;
251                 
252                 inner.push_back( section[i] );
253                 
254                 // If the next group code is 0 then push the previously found info on outer and start looking for data again
255                 if (section[i+1].group_code == 0){
256                         //std::cout << "inner.push_back" << std::endl;
257                         outer.push_back( inner );
258                         inner.clear();
259                 }
260         }
261         // 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
262         if ( inner.size() > 0 ){
263                 outer.push_back( inner );
264                 inner.clear();
265         }
266         //std::cout << "3" << std::endl;
267         if (section.back().group_code == 0){
268                 //outer.push_back( inner ); // Put the last part on if there is information, but I don't think it needs to.
269         }
270         
271         return outer;