2
* For reading and slight parsing of dxf files
5
* Matt Squires <squiresm@colorado.edu>
7
* Copyright (C) 2005 Matt Squires
9
* Released under GNU GPL and LGPL, read the file 'GPL.txt' and 'LGPL.txt' for details
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;
35
dxfpair::dxfpair(int gcode, char val[10000]){
37
// Dynamically save the strings, otherwise the memory uses is bad
39
for (int i = 0; i < strlen(val); i++){
40
value.push_back(val[i]);
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
55
for(int i = 0; i < size; i++){
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
67
char value[MAX_STR_LN];
74
std::vector< std::vector< dxfpair > > out;
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;
90
thumbnailimage.clear();
93
// Open dxf file for reading
94
std::ifstream file(filename);
97
exit (1); // Change this to an exception
100
// Find the first SECTION header
102
while ( (!file.eof()) ){
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);
112
// TO DO set all the chars to be caps for later comparison
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 ){
127
file.getline(value,MAX_STR_LN);
128
group_code = atoi(value);
129
file.getline(value,MAX_STR_LN);
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
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
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
152
file.getline(value,MAX_STR_LN);
153
group_code = atoi(value);
154
file.getline(value,MAX_STR_LN);
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()) );
163
file.getline(value,MAX_STR_LN);
164
group_code = atoi(value);
165
file.getline(value,MAX_STR_LN);
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
174
file.getline(value,MAX_STR_LN);
175
group_code = atoi(value);
176
file.getline(value,MAX_STR_LN);
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
185
file.getline(value,MAX_STR_LN);
186
group_code = atoi(value);
187
file.getline(value,MAX_STR_LN);
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
196
file.getline(value,MAX_STR_LN);
197
group_code = atoi(value);
198
file.getline(value,MAX_STR_LN);
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
207
file.getline(value,MAX_STR_LN);
208
group_code = atoi(value);
209
file.getline(value,MAX_STR_LN);
213
file.getline(value,MAX_STR_LN);
214
group_code = atoi(value);
215
file.getline(value,MAX_STR_LN);
218
}while( ( strncmp(value,"EOF",3) != 0 ) && (!file.eof()) );
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);
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;
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();
249
//for(int j = 0;j < section[i].value.size();j++ ) std::cout << section[i].value[j];
250
//std::cout << std::endl;
252
inner.push_back( section[i] );
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 );
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 );
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.