Skip to content

Commit

Permalink
Added support for reading the VPort (view port) table. Also made corr…
Browse files Browse the repository at this point in the history
…ections and additions to the README.
  • Loading branch information
bzuillsmith committed May 1, 2015
1 parent a0ec314 commit ea36c86
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 45 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ var fileText = ...;
var parser = new DxfParser();
try {
var dxf = parser.parseSync();
var dxf = parser.parseSync(fileText);
}catch(err) {
return console.error(err.stack);
}
```

See the [wiki Example Output page](https://github.com/gdsestimating/dxf-parser/wiki/Example-Output) to get an idea of what the results look like.

#### Run Samples
node.js
```
Expand All @@ -40,7 +42,8 @@ Support
* Most 2D entities
* Layers
* LType table
* Block Tables (not inserts)
* Block table (not inserts)
* VPort table
* Text and some MTEXT

Does not yet support
Expand Down
189 changes: 146 additions & 43 deletions lib/DxfParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ var DxfArrayScanner = require('./DxfArrayScanner.js'),
var log = require('loglevel');

//log.setLevel('trace');
//log.setLevel('debug');
log.setLevel('info');
log.setLevel('debug');
//log.setLevel('info');
//log.setLevel('warn');
//log.setLevel('error');
//log.setLevel('silent');
Expand Down Expand Up @@ -250,13 +250,11 @@ DxfParser.prototype._parse = function(dxfString) {

if(groupIs(0, 'TABLE')) {
curr = scanner.next();
if(groupIs(2, 'LAYER')) {
log.debug('LayerTable {');
tables.layer = parseLayerTable();
log.debug('}')
} else if(groupIs(2, 'LTYPE')) {
log.debug('LType Table {');
tables.lineType = parseLineTypeTable();

var tableDefinition = tableDefinitions[curr.value];
if(tableDefinition) {
log.debug(curr.value + ' Table {');
tables[tableDefinitions[curr.value].tableName] = parseTable();
log.debug('}');
} else {
log.debug('Unhandled Table ' + curr.value);
Expand All @@ -271,12 +269,16 @@ DxfParser.prototype._parse = function(dxfString) {
return tables;
};

var parseLayerTable = function() {
var table = {},
const END_OF_TABLE_VALUE = 'ENDTAB';

var parseTable = function() {
var tableDefinition = tableDefinitions[curr.value],
table = {},
expectedCount = 0,
actualCount;

curr = scanner.next();
while(!groupIs(0, 'ENDTAB')) {
while(!groupIs(0, END_OF_TABLE_VALUE)) {

switch(curr.code) {
case 5:
Expand All @@ -301,8 +303,8 @@ DxfParser.prototype._parse = function(dxfString) {
curr = scanner.next();
break;
case 0:
if(curr.value === 'LAYER') {
table.layers = parseLayers();
if(curr.value === tableDefinition.dxfSymbolName) {
table[tableDefinition.tableRecordsProperty] = tableDefinition.parseTableRecords();
} else {
logUnhandledGroup(curr);
curr = scanner.next();
Expand All @@ -313,58 +315,138 @@ DxfParser.prototype._parse = function(dxfString) {
curr = scanner.next();
}
}
actualCount = Object.keys(table.layers).length;
if(expectedCount !== actualCount) log.warn('Parsed ' + actualCount + ' LAYER\'s but expected ' + expectedCount);
var tableRecords = table[tableDefinition.tableRecordsProperty];
console.error(typeof(tableRecords));
if(tableRecords) {
if(tableRecords.constructor === Array){
actualCount = tableRecords.length;
} else if(typeof(tableRecords) === 'object') {
actualCount = Object.keys(tableRecords).length;
}
if(expectedCount !== actualCount) log.warn('Parsed ' + actualCount + ' ' + tableDefinition.dxfSymbolName + '\'s but expected ' + expectedCount);
}
curr = scanner.next();
return table;
};

var parseLineTypeTable = function() {
var table = {},
expectedCount = 0,
actualCount;
var parseViewPortRecords = function() {
var viewPorts = [], // Multiple table entries may have the same name indicating a multiple viewport configuration
viewPort = {};

log.debug('ViewPort {');
curr = scanner.next();
while(!groupIs(0, 'ENDTAB')) {
while(!groupIs(0, END_OF_TABLE_VALUE)) {

switch(curr.code) {
case 5:
table.handle = curr.value;
case 2: // layer name
viewPort.name = curr.value;
curr = scanner.next();
break;
case 330:
table.ownerHandle = curr.value;
case 10:
viewPort.lowerLeftCorner = parsePoint();
break;
case 11:
viewPort.upperRightCorner = parsePoint();
break;
case 12:
viewPort.center = parsePoint();
break;
case 13:
viewPort.snapBasePoint = parsePoint();
break;
case 14:
viewPort.snapSpacing = parsePoint();
break;
case 15:
viewPort.gridSpacing = parsePoint();
break;
case 16:
viewPort.viewDirectionFromTarget = parsePoint();
break;
case 17:
viewPort.viewTarget = parsePoint();
break;
case 42:
viewPort.lensLength = curr.value;
curr = scanner.next();
break;
case 100:
if(curr.value === 'AcDbSymbolTable') {
// ignore
curr = scanner.next();
}else{
logUnhandledGroup(curr);
curr = scanner.next();
}
case 43:
viewPort.frontClippingPlane = curr.value;
curr = scanner.next();
break;
case 70:
expectedCount = curr.value;
case 44:
viewPort.backClippingPlane = curr.value;
curr = scanner.next();
break;
case 45:
viewPort.viewHeight = curr.value;
curr = scanner.next();
break;
case 50:
viewPort.snapRotationAngle = curr.value;
curr = scanner.next();
break;
case 51:
viewPort.viewTwistAngle = curr.value;
curr = scanner.next();
break;
case 110:
viewPort.ucsOrigin = parsePoint();
break;
case 111:
viewPort.ucsXAxis = parsePoint();
break;
case 112:
viewPort.ucsYAxis = parsePoint();
break;
case 110:
viewPort.ucsOrigin = parsePoint();
break;
case 281:
viewPort.renderMode = curr.value;
curr = scanner.next();
break;
case 281:
// 0 is one distant light, 1 is two distant lights
viewPort.defaultLightingType = curr.value;
curr = scanner.next();
break;
case 292:
viewPort.defaultLightingOn = curr.value;
curr = scanner.next();
break;
case 330:
viewPort.ownerHandle = curr.value;
curr = scanner.next();
break;
case 63:
case 421:
case 431:
viewPort.ambientColor = curr.value;
curr = scanner.next();
break;
case 0:
if(curr.value === 'LTYPE') {
table.lineTypes = parseLineTypes();
} else {
logUnhandledGroup(curr);
// New ViewPort
if(curr.value === 'VPORT') {
log.debug('}');
viewPorts.push(viewPort);
log.debug('ViewPort {');
viewPort = {};
curr = scanner.next();
}
break;
default:
logUnhandledGroup(curr);
curr = scanner.next();
break;
}
}
actualCount = Object.keys(table.lineTypes).length;
if(expectedCount !== actualCount) log.warn('Parsed ' + actualCount + ' LTYPE\'s but expected ' + expectedCount);
curr = scanner.next();
return table;
// Note: do not call scanner.next() here,
// parseTable() needs the current group
log.debug('}');
viewPorts.push(viewPort);

return viewPorts;
};

var parseLineTypes = function() {
Expand Down Expand Up @@ -464,6 +546,27 @@ DxfParser.prototype._parse = function(dxfString) {
return layers;
};

var tableDefinitions = {
VPORT: {
tableRecordsProperty: 'viewPorts',
tableName: 'viewPort',
dxfSymbolName: 'VPORT',
parseTableRecords: parseViewPortRecords
},
LTYPE: {
tableRecordsProperty: 'lineTypes',
tableName: 'lineType',
dxfSymbolName: 'LTYPE',
parseTableRecords: parseLineTypes
},
LAYER: {
tableRecordsProperty: 'layers',
tableName: 'layer',
dxfSymbolName: 'LAYER',
parseTableRecords: parseLayers
}
};

/**
* Is called after the parser first reads the 0:ENTITIES group. The scanner
* should be on the start of the first entity already.
Expand Down

0 comments on commit ea36c86

Please sign in to comment.