summaryrefslogtreecommitdiffstats
path: root/src/extension/dxf2svg/read_dxf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/dxf2svg/read_dxf.cpp')
-rw-r--r--src/extension/dxf2svg/read_dxf.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/src/extension/dxf2svg/read_dxf.cpp b/src/extension/dxf2svg/read_dxf.cpp
new file mode 100644
index 000000000..8a6a6d6ac
--- /dev/null
+++ b/src/extension/dxf2svg/read_dxf.cpp
@@ -0,0 +1,273 @@
+/*
+ * For reading and slight parsing of dxf files
+ *
+ * Author:
+ * Matt Squires <squiresm@colorado.edu>
+ *
+ * Copyright (C) 2005 Matt Squires
+ *
+ * Released under GNU GPL and LGPL, read the file 'GPL.txt' and 'LGPL.txt' for details
+ */
+
+
+
+#include<fstream>
+#include<string>
+#include"read_dxf.h"
+
+#include<iostream>
+using namespace std;
+
+
+int MAX_STR_LN = 10000;
+
+int section(char* value){
+ if ( strncmp(value,"HEADER",6) == 0 ) return 0;
+ if ( strncmp(value,"CLASSES",7) == 0 ) return 1;
+ if ( strncmp(value,"TABLES",6) == 0 ) return 2;
+ if ( strncmp(value,"BLOCKS",6) == 0 ) return 3;
+ if ( strncmp(value,"ENTITIES",8) == 0 ) return 4;
+ if ( strncmp(value,"OBJECTS",7) == 0 ) return 5;
+ if ( strncmp(value,"THUMBNAILIMAGE",14) == 0 ) return 6;
+}
+
+
+dxfpair::dxfpair(int gcode, char val[10000]){
+ group_code = gcode;
+ // Dynamically save the strings, otherwise the memory uses is bad
+
+ for (int i = 0; i < strlen(val); i++){
+ value.push_back(val[i]);
+ }
+}
+
+
+dxfpair::~dxfpair(){
+ //delete [] value;
+}
+
+char * dxfpair::value_char(char *string){
+ int size = value.size();
+ while( ( size > 0 ) && int(value[size-1]) < 33){
+ // Strip off any control characters and spaces off the end of the string
+ size--;
+ }
+ for(int i = 0; i < size; i++){
+ string[i] = value[i];
+ }
+ string[size]=0;
+}
+
+std::vector< std::vector< dxfpair > > dxf_get_sections(char* filename){
+ // 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
+
+ int n =0;
+
+ int group_code;
+ char value[MAX_STR_LN];
+
+ int section_num;
+
+
+
+
+ std::vector< std::vector< dxfpair > > out;
+
+ std::vector< dxfpair > header;
+ std::vector< dxfpair > classes;
+ std::vector< dxfpair > tables;
+ std::vector< dxfpair > blocks;
+ std::vector< dxfpair > entities;
+ std::vector< dxfpair > objects;
+ std::vector< dxfpair > thumbnailimage;
+
+ header.clear();
+ classes.clear();
+ tables.clear();
+ blocks.clear();
+ entities.clear();
+ objects.clear();
+ thumbnailimage.clear();
+
+
+ // Open dxf file for reading
+ std::ifstream file(filename);
+
+ if (!file.is_open()){
+ exit (1); // Change this to an exception
+ }
+
+ // Find the first SECTION header
+
+ while ( (!file.eof()) ){
+ n++;
+
+ // get the first group code and value
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+
+ do{
+
+ // TO DO set all the chars to be caps for later comparison
+
+ // Find the SECTION codes
+ if ( (group_code == 0 ) && ( strncmp(value,"SECTION",7) == 0 ) ){
+ // Directly after a section value is the type of section ( e.g. HEADER, TABLES )
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ section_num = section( value );
+ if ( group_code == 2 ){
+ // Make sure the the group code is 2 for the SECTION name
+ // 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
+ //std::cout << "section_num = " << section_num << std::endl;
+ switch ( section_num ){
+ case 0:
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ do{
+ header.push_back( dxfpair( group_code, value ) );
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ }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
+ break;
+ case 1:
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ if ( (group_code != 0) || (strncmp(value,"ENDSEC",6) != 0) ){
+ // Some dxf files have blank sections. These are not handled by the do/while loop so break about if needed
+ do{
+ classes.push_back( dxfpair( group_code, value ) );
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ }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
+ }
+ break;
+ case 2:
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ do{
+ tables.push_back( dxfpair( group_code, value ) );
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ }while( ( (group_code != 0) || strncmp(value,"ENDSEC",6) != 0 ) && (!file.eof()) );
+ break;
+ case 3:
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ do{
+ blocks.push_back( dxfpair( group_code, value ) );
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ }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
+ break;
+ case 4:
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ do{
+ entities.push_back( dxfpair( group_code, value ) );
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ }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
+ break;
+ case 5:
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ do{
+ objects.push_back( dxfpair( group_code, value ) );
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ }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
+ break;
+ case 6:
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ do{
+ thumbnailimage.push_back( dxfpair( group_code, value ) );
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ }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
+ break;
+ default:
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+ }
+ }
+ }
+ file.getline(value,MAX_STR_LN);
+ group_code = atoi(value);
+ file.getline(value,MAX_STR_LN);
+
+ n++;
+ }while( ( strncmp(value,"EOF",3) != 0 ) && (!file.eof()) );
+ }
+
+ out.push_back(header);
+ out.push_back(classes);
+ out.push_back(tables);
+ out.push_back(blocks);
+ out.push_back(entities);
+ out.push_back(objects);
+ out.push_back(thumbnailimage);
+
+ return out;
+}
+
+
+std::vector< std::vector< dxfpair > > separate_parts( std::vector< dxfpair > section){
+ //std::cout << "1" << std::endl;
+ //std::cout << "section.size() = " << section.size() << std::endl;
+ // Find where the major sections are and break into smaller parts
+ // Major section is defined as anything beween group_code 0 to 0
+ std::vector< dxfpair > inner;
+ std::vector< std::vector< dxfpair > > outer;
+ //std::cout << "2" << std::endl;
+ for (int i = 0; i < section.size(); i++){
+ //std::cout << "i = " << i << std::endl;
+ //std::cout << "section[i].value.size() = " << section[i].value.size() << std::endl;
+
+ // Make sure no control codes like LF or CR are making it past this section
+ if ( (section[i].value.size() > 0) && int(section[i].value.back()) < 32 ){
+ section[i].value.pop_back();
+ }
+ //for(int j = 0;j < section[i].value.size();j++ ) std::cout << section[i].value[j];
+ //std::cout << std::endl;
+
+ inner.push_back( section[i] );
+
+ // If the next group code is 0 then push the previously found info on outer and start looking for data again
+ if (section[i+1].group_code == 0){
+ //std::cout << "inner.push_back" << std::endl;
+ outer.push_back( inner );
+ inner.clear();
+ }
+ }
+ // 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
+ if ( inner.size() > 0 ){
+ outer.push_back( inner );
+ inner.clear();
+ }
+ //std::cout << "3" << std::endl;
+ if (section.back().group_code == 0){
+ //outer.push_back( inner ); // Put the last part on if there is information, but I don't think it needs to.
+ }
+
+ return outer;
+}
+