dxf-viewer
Advanced tools
Comparing version 1.0.8 to 1.0.9
{ | ||
"name": "dxf-viewer", | ||
"version": "1.0.8", | ||
"version": "1.0.9", | ||
"description": "JavaScript DXF file viewer", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -13,5 +13,5 @@ /** | ||
export default function DxfArrayScanner(data) { | ||
this._pointer = 0; | ||
this._data = data; | ||
this._eof = false; | ||
this._pointer = 0; | ||
this._data = data; | ||
this._eof = false; | ||
} | ||
@@ -25,42 +25,42 @@ | ||
DxfArrayScanner.prototype.next = function() { | ||
var group; | ||
if(!this.hasNext()) { | ||
if(!this._eof) | ||
throw new Error('Unexpected end of input: EOF group not read before end of file. Ended on code ' + this._data[this._pointer]); | ||
else | ||
throw new Error('Cannot call \'next\' after EOF group has been read'); | ||
} | ||
var group; | ||
if(!this.hasNext()) { | ||
if(!this._eof) | ||
throw new Error('Unexpected end of input: EOF group not read before end of file. Ended on code ' + this._data[this._pointer]); | ||
else | ||
throw new Error('Cannot call \'next\' after EOF group has been read'); | ||
} | ||
group = { | ||
code: parseInt(this._data[this._pointer]) | ||
}; | ||
group = { | ||
code: parseInt(this._data[this._pointer]) | ||
}; | ||
this._pointer++; | ||
this._pointer++; | ||
group.value = parseGroupValue(group.code, this._data[this._pointer].trim()); | ||
this._pointer++; | ||
group.value = parseGroupValue(group.code, this._data[this._pointer].trim()); | ||
this._pointer++; | ||
if(group.code === 0 && group.value === 'EOF') this._eof = true; | ||
if(group.code === 0 && group.value === 'EOF') this._eof = true; | ||
this.lastReadGroup = group; | ||
this.lastReadGroup = group; | ||
return group; | ||
return group; | ||
}; | ||
DxfArrayScanner.prototype.peek = function() { | ||
if(!this.hasNext()) { | ||
if(!this._eof) | ||
throw new Error('Unexpected end of input: EOF group not read before end of file. Ended on code ' + this._data[this._pointer]); | ||
else | ||
throw new Error('Cannot call \'next\' after EOF group has been read'); | ||
} | ||
var group = { | ||
code: parseInt(this._data[this._pointer]) | ||
}; | ||
if(!this.hasNext()) { | ||
if(!this._eof) | ||
throw new Error('Unexpected end of input: EOF group not read before end of file. Ended on code ' + this._data[this._pointer]); | ||
else | ||
throw new Error('Cannot call \'next\' after EOF group has been read'); | ||
} | ||
var group = { | ||
code: parseInt(this._data[this._pointer]) | ||
}; | ||
group.value = parseGroupValue(group.code, this._data[this._pointer + 1].trim()); | ||
group.value = parseGroupValue(group.code, this._data[this._pointer + 1].trim()); | ||
return group; | ||
return group; | ||
}; | ||
@@ -70,4 +70,4 @@ | ||
DxfArrayScanner.prototype.rewind = function(numberOfGroups) { | ||
numberOfGroups = numberOfGroups || 1; | ||
this._pointer = this._pointer - numberOfGroups * 2; | ||
numberOfGroups = numberOfGroups || 1; | ||
this._pointer = this._pointer - numberOfGroups * 2; | ||
}; | ||
@@ -80,12 +80,12 @@ | ||
DxfArrayScanner.prototype.hasNext = function() { | ||
// Check if we have read EOF group code | ||
if(this._eof) { | ||
return false; | ||
} | ||
// We need to be sure there are two lines available | ||
if(this._pointer > this._data.length - 2) { | ||
return false; | ||
} | ||
return true; | ||
// Check if we have read EOF group code | ||
if(this._eof) { | ||
return false; | ||
} | ||
// We need to be sure there are two lines available | ||
if(this._pointer > this._data.length - 2) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
@@ -98,3 +98,3 @@ | ||
DxfArrayScanner.prototype.isEOF = function() { | ||
return this._eof; | ||
return this._eof; | ||
}; | ||
@@ -111,28 +111,28 @@ | ||
function parseGroupValue(code, value) { | ||
if(code <= 9) return value; | ||
if(code >= 10 && code <= 59) return parseFloat(value); | ||
if(code >= 60 && code <= 99) return parseInt(value); | ||
if(code >= 100 && code <= 109) return value; | ||
if(code >= 110 && code <= 149) return parseFloat(value); | ||
if(code >= 160 && code <= 179) return parseInt(value); | ||
if(code >= 210 && code <= 239) return parseFloat(value); | ||
if(code >= 270 && code <= 289) return parseInt(value); | ||
if(code >= 290 && code <= 299) return parseBoolean(value); | ||
if(code >= 300 && code <= 369) return value; | ||
if(code >= 370 && code <= 389) return parseInt(value); | ||
if(code >= 390 && code <= 399) return value; | ||
if(code >= 400 && code <= 409) return parseInt(value); | ||
if(code >= 410 && code <= 419) return value; | ||
if(code >= 420 && code <= 429) return parseInt(value); | ||
if(code >= 430 && code <= 439) return value; | ||
if(code >= 440 && code <= 459) return parseInt(value); | ||
if(code >= 460 && code <= 469) return parseFloat(value); | ||
if(code >= 470 && code <= 481) return value; | ||
if(code === 999) return value; | ||
if(code >= 1000 && code <= 1009) return value; | ||
if(code >= 1010 && code <= 1059) return parseFloat(value); | ||
if(code >= 1060 && code <= 1071) return parseInt(value); | ||
if(code <= 9) return value; | ||
if(code >= 10 && code <= 59) return parseFloat(value); | ||
if(code >= 60 && code <= 99) return parseInt(value); | ||
if(code >= 100 && code <= 109) return value; | ||
if(code >= 110 && code <= 149) return parseFloat(value); | ||
if(code >= 160 && code <= 179) return parseInt(value); | ||
if(code >= 210 && code <= 239) return parseFloat(value); | ||
if(code >= 270 && code <= 289) return parseInt(value); | ||
if(code >= 290 && code <= 299) return parseBoolean(value); | ||
if(code >= 300 && code <= 369) return value; | ||
if(code >= 370 && code <= 389) return parseInt(value); | ||
if(code >= 390 && code <= 399) return value; | ||
if(code >= 400 && code <= 409) return parseInt(value); | ||
if(code >= 410 && code <= 419) return value; | ||
if(code >= 420 && code <= 429) return parseInt(value); | ||
if(code >= 430 && code <= 439) return value; | ||
if(code >= 440 && code <= 459) return parseInt(value); | ||
if(code >= 460 && code <= 469) return parseFloat(value); | ||
if(code >= 470 && code <= 481) return value; | ||
if(code === 999) return value; | ||
if(code >= 1000 && code <= 1009) return value; | ||
if(code >= 1010 && code <= 1059) return parseFloat(value); | ||
if(code >= 1060 && code <= 1071) return parseInt(value); | ||
console.log('WARNING: Group code does not have a defined type: %j', { code: code, value: value }); | ||
return value; | ||
console.log('WARNING: Group code does not have a defined type: %j', { code: code, value: value }); | ||
return value; | ||
} | ||
@@ -146,5 +146,5 @@ | ||
function parseBoolean(str) { | ||
if(str === '0') return false; | ||
if(str === '1') return true; | ||
throw TypeError('String \'' + str + '\' cannot be cast to Boolean type'); | ||
if(str === '0') return false; | ||
if(str === '1') return true; | ||
throw TypeError('String \'' + str + '\' cannot be cast to Boolean type'); | ||
} |
@@ -31,43 +31,43 @@ import DxfArrayScanner from './DxfArrayScanner'; | ||
function registerDefaultEntityHandlers(dxfParser) { | ||
// Supported entities here (some entity code is still being refactored into this flow) | ||
dxfParser.registerEntityHandler(Face); | ||
dxfParser.registerEntityHandler(Arc); | ||
dxfParser.registerEntityHandler(AttDef); | ||
dxfParser.registerEntityHandler(Circle); | ||
dxfParser.registerEntityHandler(Dimension); | ||
dxfParser.registerEntityHandler(Ellipse); | ||
dxfParser.registerEntityHandler(Insert); | ||
dxfParser.registerEntityHandler(Line); | ||
dxfParser.registerEntityHandler(LWPolyline); | ||
dxfParser.registerEntityHandler(MText); | ||
dxfParser.registerEntityHandler(Point); | ||
dxfParser.registerEntityHandler(Polyline); | ||
dxfParser.registerEntityHandler(Solid); | ||
dxfParser.registerEntityHandler(Spline); | ||
dxfParser.registerEntityHandler(Text); | ||
//dxfParser.registerEntityHandler(require('./entities/vertex')); | ||
// Supported entities here (some entity code is still being refactored into this flow) | ||
dxfParser.registerEntityHandler(Face); | ||
dxfParser.registerEntityHandler(Arc); | ||
dxfParser.registerEntityHandler(AttDef); | ||
dxfParser.registerEntityHandler(Circle); | ||
dxfParser.registerEntityHandler(Dimension); | ||
dxfParser.registerEntityHandler(Ellipse); | ||
dxfParser.registerEntityHandler(Insert); | ||
dxfParser.registerEntityHandler(Line); | ||
dxfParser.registerEntityHandler(LWPolyline); | ||
dxfParser.registerEntityHandler(MText); | ||
dxfParser.registerEntityHandler(Point); | ||
dxfParser.registerEntityHandler(Polyline); | ||
dxfParser.registerEntityHandler(Solid); | ||
dxfParser.registerEntityHandler(Spline); | ||
dxfParser.registerEntityHandler(Text); | ||
//dxfParser.registerEntityHandler(require('./entities/vertex')); | ||
} | ||
export default function DxfParser() { | ||
this._entityHandlers = {}; | ||
this._entityHandlers = {}; | ||
registerDefaultEntityHandlers(this); | ||
registerDefaultEntityHandlers(this); | ||
} | ||
DxfParser.prototype.parse = function(source, done) { | ||
throw new Error("read() not implemented. Use readSync()"); | ||
throw new Error("read() not implemented. Use readSync()"); | ||
}; | ||
DxfParser.prototype.registerEntityHandler = function(handlerType) { | ||
var instance = new handlerType(); | ||
this._entityHandlers[handlerType.ForEntityName] = instance; | ||
var instance = new handlerType(); | ||
this._entityHandlers[handlerType.ForEntityName] = instance; | ||
} | ||
DxfParser.prototype.parseSync = function(source) { | ||
if(typeof(source) === 'string') { | ||
return this._parse(source); | ||
}else { | ||
console.error('Cannot read dxf source of type `' + typeof(source)); | ||
return null; | ||
} | ||
if(typeof(source) === 'string') { | ||
return this._parse(source); | ||
}else { | ||
console.error('Cannot read dxf source of type `' + typeof(source)); | ||
return null; | ||
} | ||
}; | ||
@@ -77,385 +77,385 @@ | ||
var dxfString = ""; | ||
var self = this; | ||
var dxfString = ""; | ||
var self = this; | ||
stream.on('data', onData); | ||
stream.on('end', onEnd); | ||
stream.on('error', onError); | ||
stream.on('data', onData); | ||
stream.on('end', onEnd); | ||
stream.on('error', onError); | ||
function onData(chunk) { | ||
dxfString += chunk; | ||
} | ||
function onData(chunk) { | ||
dxfString += chunk; | ||
} | ||
function onEnd() { | ||
try { | ||
var dxf = self._parse(dxfString); | ||
}catch(err) { | ||
return done(err); | ||
} | ||
done(null, dxf); | ||
} | ||
function onEnd() { | ||
try { | ||
var dxf = self._parse(dxfString); | ||
}catch(err) { | ||
return done(err); | ||
} | ||
done(null, dxf); | ||
} | ||
function onError(err) { | ||
done(err); | ||
} | ||
function onError(err) { | ||
done(err); | ||
} | ||
}; | ||
DxfParser.prototype._parse = function(dxfString) { | ||
var scanner, curr, dxf = {}, lastHandle = 0; | ||
var dxfLinesArray = dxfString.split(/\r\n|\r|\n/g); | ||
var scanner, curr, dxf = {}, lastHandle = 0; | ||
var dxfLinesArray = dxfString.split(/\r\n|\r|\n/g); | ||
scanner = new DxfArrayScanner(dxfLinesArray); | ||
if(!scanner.hasNext()) throw Error('Empty file'); | ||
scanner = new DxfArrayScanner(dxfLinesArray); | ||
if(!scanner.hasNext()) throw Error('Empty file'); | ||
var self = this; | ||
var self = this; | ||
var parseAll = function() { | ||
curr = scanner.next(); | ||
while(!scanner.isEOF()) { | ||
if(curr.code === 0 && curr.value === 'SECTION') { | ||
curr = scanner.next(); | ||
var parseAll = function() { | ||
curr = scanner.next(); | ||
while(!scanner.isEOF()) { | ||
if(curr.code === 0 && curr.value === 'SECTION') { | ||
curr = scanner.next(); | ||
// Be sure we are reading a section code | ||
if (curr.code !== 2) { | ||
console.error('Unexpected code %s after 0:SECTION', debugCode(curr)); | ||
curr = scanner.next(); | ||
continue; | ||
} | ||
// Be sure we are reading a section code | ||
if (curr.code !== 2) { | ||
console.error('Unexpected code %s after 0:SECTION', debugCode(curr)); | ||
curr = scanner.next(); | ||
continue; | ||
} | ||
if (curr.value === 'HEADER') { | ||
log.debug('> HEADER'); | ||
dxf.header = parseHeader(); | ||
log.debug('<'); | ||
} else if (curr.value === 'BLOCKS') { | ||
log.debug('> BLOCKS'); | ||
dxf.blocks = parseBlocks(); | ||
log.debug('<'); | ||
} else if(curr.value === 'ENTITIES') { | ||
log.debug('> ENTITIES'); | ||
dxf.entities = parseEntities(false); | ||
log.debug('<'); | ||
} else if(curr.value === 'TABLES') { | ||
log.debug('> TABLES'); | ||
dxf.tables = parseTables(); | ||
log.debug('<'); | ||
} else if(curr.value === 'EOF') { | ||
log.debug('EOF'); | ||
} else { | ||
log.warn('Skipping section \'%s\'', curr.value); | ||
} | ||
} else { | ||
curr = scanner.next(); | ||
} | ||
// If is a new section | ||
} | ||
}; | ||
if (curr.value === 'HEADER') { | ||
log.debug('> HEADER'); | ||
dxf.header = parseHeader(); | ||
log.debug('<'); | ||
} else if (curr.value === 'BLOCKS') { | ||
log.debug('> BLOCKS'); | ||
dxf.blocks = parseBlocks(); | ||
log.debug('<'); | ||
} else if(curr.value === 'ENTITIES') { | ||
log.debug('> ENTITIES'); | ||
dxf.entities = parseEntities(false); | ||
log.debug('<'); | ||
} else if(curr.value === 'TABLES') { | ||
log.debug('> TABLES'); | ||
dxf.tables = parseTables(); | ||
log.debug('<'); | ||
} else if(curr.value === 'EOF') { | ||
log.debug('EOF'); | ||
} else { | ||
log.warn('Skipping section \'%s\'', curr.value); | ||
} | ||
} else { | ||
curr = scanner.next(); | ||
} | ||
// If is a new section | ||
} | ||
}; | ||
var groupIs = function(code, value) { | ||
return curr.code === code && curr.value === value; | ||
}; | ||
var groupIs = function(code, value) { | ||
return curr.code === code && curr.value === value; | ||
}; | ||
/** | ||
* | ||
* @return {object} header | ||
*/ | ||
var parseHeader = function() { | ||
// interesting variables: | ||
// $ACADVER, $VIEWDIR, $VIEWSIZE, $VIEWCTR, $TDCREATE, $TDUPDATE | ||
// http://www.autodesk.com/techpubs/autocad/acadr14/dxf/header_section_al_u05_c.htm | ||
// Also see VPORT table entries | ||
var currVarName = null, currVarValue = null; | ||
var header = {}; | ||
// loop through header variables | ||
curr = scanner.next(); | ||
/** | ||
* | ||
* @return {object} header | ||
*/ | ||
var parseHeader = function() { | ||
// interesting variables: | ||
// $ACADVER, $VIEWDIR, $VIEWSIZE, $VIEWCTR, $TDCREATE, $TDUPDATE | ||
// http://www.autodesk.com/techpubs/autocad/acadr14/dxf/header_section_al_u05_c.htm | ||
// Also see VPORT table entries | ||
var currVarName = null, currVarValue = null; | ||
var header = {}; | ||
// loop through header variables | ||
curr = scanner.next(); | ||
while(true) { | ||
if(groupIs(0, 'ENDSEC')) { | ||
if(currVarName) header[currVarName] = currVarValue; | ||
break; | ||
} else if(curr.code === 9) { | ||
if(currVarName) header[currVarName] = currVarValue; | ||
currVarName = curr.value; | ||
// Filter here for particular variables we are interested in | ||
} else { | ||
if(curr.code === 10) { | ||
currVarValue = { x: curr.value }; | ||
} else if(curr.code === 20) { | ||
currVarValue.y = curr.value; | ||
} else if(curr.code === 30) { | ||
currVarValue.z = curr.value; | ||
} else { | ||
currVarValue = curr.value; | ||
} | ||
} | ||
curr = scanner.next(); | ||
} | ||
// console.log(util.inspect(header, { colors: true, depth: null })); | ||
curr = scanner.next(); // swallow up ENDSEC | ||
return header; | ||
}; | ||
while(true) { | ||
if(groupIs(0, 'ENDSEC')) { | ||
if(currVarName) header[currVarName] = currVarValue; | ||
break; | ||
} else if(curr.code === 9) { | ||
if(currVarName) header[currVarName] = currVarValue; | ||
currVarName = curr.value; | ||
// Filter here for particular variables we are interested in | ||
} else { | ||
if(curr.code === 10) { | ||
currVarValue = { x: curr.value }; | ||
} else if(curr.code === 20) { | ||
currVarValue.y = curr.value; | ||
} else if(curr.code === 30) { | ||
currVarValue.z = curr.value; | ||
} else { | ||
currVarValue = curr.value; | ||
} | ||
} | ||
curr = scanner.next(); | ||
} | ||
// console.log(util.inspect(header, { colors: true, depth: null })); | ||
curr = scanner.next(); // swallow up ENDSEC | ||
return header; | ||
}; | ||
/** | ||
* | ||
*/ | ||
var parseBlocks = function() { | ||
var blocks = {}, block; | ||
/** | ||
* | ||
*/ | ||
var parseBlocks = function() { | ||
var blocks = {}, block; | ||
curr = scanner.next(); | ||
while(curr.value !== 'EOF') { | ||
if(groupIs(0, 'ENDSEC')) { | ||
break; | ||
} | ||
while(curr.value !== 'EOF') { | ||
if(groupIs(0, 'ENDSEC')) { | ||
break; | ||
} | ||
if(groupIs(0, 'BLOCK')) { | ||
log.debug('block {'); | ||
block = parseBlock(); | ||
log.debug('}'); | ||
ensureHandle(block); | ||
if(groupIs(0, 'BLOCK')) { | ||
log.debug('block {'); | ||
block = parseBlock(); | ||
log.debug('}'); | ||
ensureHandle(block); | ||
if(!block.name) | ||
log.error('block with handle "' + block.handle + '" is missing a name.'); | ||
else | ||
else | ||
blocks[block.name] = block; | ||
} else { | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
} | ||
return blocks; | ||
}; | ||
} else { | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
} | ||
return blocks; | ||
}; | ||
var parseBlock = function() { | ||
var block = {}; | ||
curr = scanner.next(); | ||
var parseBlock = function() { | ||
var block = {}; | ||
curr = scanner.next(); | ||
while(curr.value !== 'EOF') { | ||
switch(curr.code) { | ||
case 1: | ||
block.xrefPath = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 2: | ||
block.name = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 3: | ||
block.name2 = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 5: | ||
block.handle = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 8: | ||
block.layer = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 10: | ||
block.position = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 67: | ||
block.paperSpace = (curr.value && curr.value == 1) ? true : false; | ||
curr = scanner.next(); | ||
break; | ||
case 70: | ||
if (curr.value != 0) { | ||
//if(curr.value & BLOCK_ANONYMOUS_FLAG) console.log(' Anonymous block'); | ||
//if(curr.value & BLOCK_NON_CONSTANT_FLAG) console.log(' Non-constant attributes'); | ||
//if(curr.value & BLOCK_XREF_FLAG) console.log(' Is xref'); | ||
//if(curr.value & BLOCK_XREF_OVERLAY_FLAG) console.log(' Is xref overlay'); | ||
//if(curr.value & BLOCK_EXTERNALLY_DEPENDENT_FLAG) console.log(' Is externally dependent'); | ||
//if(curr.value & BLOCK_RESOLVED_OR_DEPENDENT_FLAG) console.log(' Is resolved xref or dependent of an xref'); | ||
//if(curr.value & BLOCK_REFERENCED_XREF) console.log(' This definition is a referenced xref'); | ||
block.type = curr.value; | ||
} | ||
curr = scanner.next(); | ||
break; | ||
case 100: | ||
// ignore class markers | ||
curr = scanner.next(); | ||
break; | ||
case 330: | ||
block.ownerHandle = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
if(curr.value == 'ENDBLK') | ||
break; | ||
block.entities = parseEntities(true); | ||
break; | ||
default: | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
while(curr.value !== 'EOF') { | ||
switch(curr.code) { | ||
case 1: | ||
block.xrefPath = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 2: | ||
block.name = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 3: | ||
block.name2 = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 5: | ||
block.handle = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 8: | ||
block.layer = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 10: | ||
block.position = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 67: | ||
block.paperSpace = (curr.value && curr.value == 1) ? true : false; | ||
curr = scanner.next(); | ||
break; | ||
case 70: | ||
if (curr.value != 0) { | ||
//if(curr.value & BLOCK_ANONYMOUS_FLAG) console.log(' Anonymous block'); | ||
//if(curr.value & BLOCK_NON_CONSTANT_FLAG) console.log(' Non-constant attributes'); | ||
//if(curr.value & BLOCK_XREF_FLAG) console.log(' Is xref'); | ||
//if(curr.value & BLOCK_XREF_OVERLAY_FLAG) console.log(' Is xref overlay'); | ||
//if(curr.value & BLOCK_EXTERNALLY_DEPENDENT_FLAG) console.log(' Is externally dependent'); | ||
//if(curr.value & BLOCK_RESOLVED_OR_DEPENDENT_FLAG) console.log(' Is resolved xref or dependent of an xref'); | ||
//if(curr.value & BLOCK_REFERENCED_XREF) console.log(' This definition is a referenced xref'); | ||
block.type = curr.value; | ||
} | ||
curr = scanner.next(); | ||
break; | ||
case 100: | ||
// ignore class markers | ||
curr = scanner.next(); | ||
break; | ||
case 330: | ||
block.ownerHandle = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
if(curr.value == 'ENDBLK') | ||
break; | ||
block.entities = parseEntities(true); | ||
break; | ||
default: | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
if(groupIs(0, 'ENDBLK')) { | ||
curr = scanner.next(); | ||
break; | ||
} | ||
} | ||
return block; | ||
}; | ||
if(groupIs(0, 'ENDBLK')) { | ||
curr = scanner.next(); | ||
break; | ||
} | ||
} | ||
return block; | ||
}; | ||
/** | ||
* parseTables | ||
* @return {Object} Object representing tables | ||
*/ | ||
var parseTables = function() { | ||
var tables = {}; | ||
curr = scanner.next(); | ||
while(curr.value !== 'EOF') { | ||
if(groupIs(0, 'ENDSEC')) | ||
break; | ||
/** | ||
* parseTables | ||
* @return {Object} Object representing tables | ||
*/ | ||
var parseTables = function() { | ||
var tables = {}; | ||
curr = scanner.next(); | ||
while(curr.value !== 'EOF') { | ||
if(groupIs(0, 'ENDSEC')) | ||
break; | ||
if(groupIs(0, 'TABLE')) { | ||
curr = scanner.next(); | ||
if(groupIs(0, 'TABLE')) { | ||
curr = scanner.next(); | ||
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); | ||
} | ||
} else { | ||
// else ignored | ||
curr = scanner.next(); | ||
} | ||
} | ||
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); | ||
} | ||
} else { | ||
// else ignored | ||
curr = scanner.next(); | ||
} | ||
} | ||
curr = scanner.next(); | ||
return tables; | ||
}; | ||
curr = scanner.next(); | ||
return tables; | ||
}; | ||
const END_OF_TABLE_VALUE = 'ENDTAB'; | ||
const END_OF_TABLE_VALUE = 'ENDTAB'; | ||
var parseTable = function() { | ||
var tableDefinition = tableDefinitions[curr.value], | ||
table = {}, | ||
expectedCount = 0, | ||
actualCount; | ||
var parseTable = function() { | ||
var tableDefinition = tableDefinitions[curr.value], | ||
table = {}, | ||
expectedCount = 0, | ||
actualCount; | ||
curr = scanner.next(); | ||
while(!groupIs(0, END_OF_TABLE_VALUE)) { | ||
curr = scanner.next(); | ||
while(!groupIs(0, END_OF_TABLE_VALUE)) { | ||
switch(curr.code) { | ||
case 5: | ||
table.handle = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 330: | ||
table.ownerHandle = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 100: | ||
if(curr.value === 'AcDbSymbolTable') { | ||
// ignore | ||
curr = scanner.next(); | ||
}else{ | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
break; | ||
case 70: | ||
expectedCount = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
if(curr.value === tableDefinition.dxfSymbolName) { | ||
table[tableDefinition.tableRecordsProperty] = tableDefinition.parseTableRecords(); | ||
} else { | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
break; | ||
default: | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
} | ||
var tableRecords = table[tableDefinition.tableRecordsProperty]; | ||
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; | ||
}; | ||
switch(curr.code) { | ||
case 5: | ||
table.handle = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 330: | ||
table.ownerHandle = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 100: | ||
if(curr.value === 'AcDbSymbolTable') { | ||
// ignore | ||
curr = scanner.next(); | ||
}else{ | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
break; | ||
case 70: | ||
expectedCount = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
if(curr.value === tableDefinition.dxfSymbolName) { | ||
table[tableDefinition.tableRecordsProperty] = tableDefinition.parseTableRecords(); | ||
} else { | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
break; | ||
default: | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
} | ||
} | ||
var tableRecords = table[tableDefinition.tableRecordsProperty]; | ||
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 parseViewPortRecords = function() { | ||
var viewPorts = [], // Multiple table entries may have the same name indicating a multiple viewport configuration | ||
viewPort = {}; | ||
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, END_OF_TABLE_VALUE)) { | ||
log.debug('ViewPort {'); | ||
curr = scanner.next(); | ||
while(!groupIs(0, END_OF_TABLE_VALUE)) { | ||
switch(curr.code) { | ||
case 2: // layer name | ||
viewPort.name = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 10: | ||
viewPort.lowerLeftCorner = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 11: | ||
viewPort.upperRightCorner = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 12: | ||
viewPort.center = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 13: | ||
viewPort.snapBasePoint = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 14: | ||
viewPort.snapSpacing = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 15: | ||
viewPort.gridSpacing = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 16: | ||
viewPort.viewDirectionFromTarget = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 17: | ||
viewPort.viewTarget = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 42: | ||
viewPort.lensLength = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 43: | ||
viewPort.frontClippingPlane = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
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; | ||
switch(curr.code) { | ||
case 2: // layer name | ||
viewPort.name = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 10: | ||
viewPort.lowerLeftCorner = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 11: | ||
viewPort.upperRightCorner = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 12: | ||
viewPort.center = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 13: | ||
viewPort.snapBasePoint = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 14: | ||
viewPort.snapSpacing = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 15: | ||
viewPort.gridSpacing = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 16: | ||
viewPort.viewDirectionFromTarget = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 17: | ||
viewPort.viewTarget = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 42: | ||
viewPort.lensLength = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 43: | ||
viewPort.frontClippingPlane = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
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 79: | ||
@@ -465,275 +465,279 @@ viewPort.orthographicType = curr.value; | ||
break; | ||
case 110: | ||
viewPort.ucsOrigin = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 111: | ||
viewPort.ucsXAxis = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 112: | ||
viewPort.ucsYAxis = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 110: | ||
viewPort.ucsOrigin = parsePoint(); | ||
curr = scanner.next(); | ||
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: // These are all ambient color. Perhaps should be a gradient when multiple are set. | ||
case 421: | ||
case 431: | ||
viewPort.ambientColor = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
// 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; | ||
} | ||
} | ||
// Note: do not call scanner.next() here, | ||
// parseTable() needs the current group | ||
log.debug('}'); | ||
viewPorts.push(viewPort); | ||
case 110: | ||
viewPort.ucsOrigin = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 111: | ||
viewPort.ucsXAxis = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 112: | ||
viewPort.ucsYAxis = parsePoint(); | ||
curr = scanner.next(); | ||
break; | ||
case 110: | ||
viewPort.ucsOrigin = parsePoint(); | ||
curr = scanner.next(); | ||
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: // These are all ambient color. Perhaps should be a gradient when multiple are set. | ||
case 421: | ||
case 431: | ||
viewPort.ambientColor = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
// 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; | ||
} | ||
} | ||
// Note: do not call scanner.next() here, | ||
// parseTable() needs the current group | ||
log.debug('}'); | ||
viewPorts.push(viewPort); | ||
return viewPorts; | ||
}; | ||
return viewPorts; | ||
}; | ||
var parseLineTypes = function() { | ||
var ltypes = {}, | ||
ltypeName, | ||
ltype = {}, | ||
length; | ||
var parseLineTypes = function() { | ||
var ltypes = {}, | ||
ltypeName, | ||
ltype = {}, | ||
length; | ||
log.debug('LType {'); | ||
curr = scanner.next(); | ||
while(!groupIs(0, 'ENDTAB')) { | ||
log.debug('LType {'); | ||
curr = scanner.next(); | ||
while(!groupIs(0, 'ENDTAB')) { | ||
switch(curr.code) { | ||
case 2: | ||
ltype.name = curr.value; | ||
ltypeName = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 3: | ||
ltype.description = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 73: // Number of elements for this line type (dots, dashes, spaces); | ||
length = curr.value; | ||
if(length > 0) ltype.pattern = []; | ||
curr = scanner.next(); | ||
break; | ||
case 40: // total pattern length | ||
ltype.patternLength = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 49: | ||
ltype.pattern.push(curr.value); | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
log.debug('}'); | ||
if(length > 0 && length !== ltype.pattern.length) log.warn('lengths do not match on LTYPE pattern'); | ||
ltypes[ltypeName] = ltype; | ||
ltype = {}; | ||
log.debug('LType {'); | ||
curr = scanner.next(); | ||
break; | ||
default: | ||
curr = scanner.next(); | ||
} | ||
} | ||
switch(curr.code) { | ||
case 2: | ||
ltype.name = curr.value; | ||
ltypeName = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 3: | ||
ltype.description = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 73: // Number of elements for this line type (dots, dashes, spaces); | ||
length = curr.value; | ||
if(length > 0) ltype.pattern = []; | ||
curr = scanner.next(); | ||
break; | ||
case 40: // total pattern length | ||
ltype.patternLength = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 49: | ||
ltype.pattern.push(curr.value); | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
log.debug('}'); | ||
if(length > 0 && length !== ltype.pattern.length) log.warn('lengths do not match on LTYPE pattern'); | ||
ltypes[ltypeName] = ltype; | ||
ltype = {}; | ||
log.debug('LType {'); | ||
curr = scanner.next(); | ||
break; | ||
default: | ||
curr = scanner.next(); | ||
} | ||
} | ||
log.debug('}'); | ||
ltypes[ltypeName] = ltype; | ||
return ltypes; | ||
}; | ||
log.debug('}'); | ||
ltypes[ltypeName] = ltype; | ||
return ltypes; | ||
}; | ||
var parseLayers = function() { | ||
var layers = {}, | ||
layerName, | ||
layer = {}; | ||
var parseLayers = function() { | ||
var layers = {}, | ||
layerName, | ||
layer = {}; | ||
log.debug('Layer {'); | ||
curr = scanner.next(); | ||
while(!groupIs(0, 'ENDTAB')) { | ||
log.debug('Layer {'); | ||
curr = scanner.next(); | ||
while(!groupIs(0, 'ENDTAB')) { | ||
switch(curr.code) { | ||
case 2: // layer name | ||
layer.name = curr.value; | ||
layerName = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 62: // color, visibility | ||
layer.visible = curr.value >= 0; | ||
// TODO 0 and 256 are BYBLOCK and BYLAYER respectively. Need to handle these values for layers?. | ||
layer.colorIndex = Math.abs(curr.value); | ||
layer.color = getAcadColor(layer.colorIndex); | ||
curr = scanner.next(); | ||
break; | ||
case 70: // frozen layer | ||
layer.frozen = ((curr.value & 1) != 0 || (curr.value & 2) != 0); | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
// New Layer | ||
if(curr.value === 'LAYER') { | ||
log.debug('}'); | ||
layers[layerName] = layer; | ||
log.debug('Layer {'); | ||
layer = {}; | ||
layerName = undefined; | ||
curr = scanner.next(); | ||
} | ||
break; | ||
default: | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
break; | ||
} | ||
} | ||
// Note: do not call scanner.next() here, | ||
// parseLayerTable() needs the current group | ||
log.debug('}'); | ||
layers[layerName] = layer; | ||
switch(curr.code) { | ||
case 2: // layer name | ||
layer.name = curr.value; | ||
layerName = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 62: // color, visibility | ||
layer.visible = curr.value >= 0; | ||
// TODO 0 and 256 are BYBLOCK and BYLAYER respectively. Need to handle these values for layers?. | ||
layer.colorIndex = Math.abs(curr.value); | ||
layer.color = getAcadColor(layer.colorIndex); | ||
curr = scanner.next(); | ||
break; | ||
case 70: // frozen layer | ||
layer.frozen = ((curr.value & 1) != 0 || (curr.value & 2) != 0); | ||
curr = scanner.next(); | ||
break; | ||
case 420: // TrueColor Color | ||
layer.color = curr.value; | ||
curr = scanner.next(); | ||
break; | ||
case 0: | ||
// New Layer | ||
if(curr.value === 'LAYER') { | ||
log.debug('}'); | ||
layers[layerName] = layer; | ||
log.debug('Layer {'); | ||
layer = {}; | ||
layerName = undefined; | ||
curr = scanner.next(); | ||
} | ||
break; | ||
default: | ||
logUnhandledGroup(curr); | ||
curr = scanner.next(); | ||
break; | ||
} | ||
} | ||
// Note: do not call scanner.next() here, | ||
// parseLayerTable() needs the current group | ||
log.debug('}'); | ||
layers[layerName] = layer; | ||
return layers; | ||
}; | ||
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 | ||
} | ||
}; | ||
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. | ||
* @return {Array} the resulting entities | ||
*/ | ||
var parseEntities = function(forBlock) { | ||
var entities = []; | ||
/** | ||
* Is called after the parser first reads the 0:ENTITIES group. The scanner | ||
* should be on the start of the first entity already. | ||
* @return {Array} the resulting entities | ||
*/ | ||
var parseEntities = function(forBlock) { | ||
var entities = []; | ||
var endingOnValue = forBlock ? 'ENDBLK' : 'ENDSEC'; | ||
var endingOnValue = forBlock ? 'ENDBLK' : 'ENDSEC'; | ||
if (!forBlock) { | ||
curr = scanner.next(); | ||
} | ||
while(true) { | ||
if (!forBlock) { | ||
curr = scanner.next(); | ||
} | ||
while(true) { | ||
if(curr.code === 0) { | ||
if(curr.value === endingOnValue) { | ||
break; | ||
} | ||
if(curr.code === 0) { | ||
if(curr.value === endingOnValue) { | ||
break; | ||
} | ||
var entity; | ||
var handler = self._entityHandlers[curr.value]; | ||
if(handler != null) { | ||
log.debug(curr.value + ' {'); | ||
entity = handler.parseEntity(scanner, curr); | ||
curr = scanner.lastReadGroup; | ||
log.debug('}'); | ||
} else { | ||
log.warn('Unhandled entity ' + curr.value); | ||
curr = scanner.next(); | ||
continue; | ||
} | ||
ensureHandle(entity); | ||
entities.push(entity); | ||
} else { | ||
// ignored lines from unsupported entity | ||
curr = scanner.next(); | ||
} | ||
} | ||
if(endingOnValue == 'ENDSEC') curr = scanner.next(); // swallow up ENDSEC, but not ENDBLK | ||
return entities; | ||
}; | ||
var entity; | ||
var handler = self._entityHandlers[curr.value]; | ||
if(handler != null) { | ||
log.debug(curr.value + ' {'); | ||
entity = handler.parseEntity(scanner, curr); | ||
curr = scanner.lastReadGroup; | ||
log.debug('}'); | ||
} else { | ||
log.warn('Unhandled entity ' + curr.value); | ||
curr = scanner.next(); | ||
continue; | ||
} | ||
ensureHandle(entity); | ||
entities.push(entity); | ||
} else { | ||
// ignored lines from unsupported entity | ||
curr = scanner.next(); | ||
} | ||
} | ||
if(endingOnValue == 'ENDSEC') curr = scanner.next(); // swallow up ENDSEC, but not ENDBLK | ||
return entities; | ||
}; | ||
/** | ||
* Parses a 2D or 3D point, returning it as an object with x, y, and | ||
* (sometimes) z property if it is 3D. It is assumed the current group | ||
* is x of the point being read in, and scanner.next() will return the | ||
* y. The parser will determine if there is a z point automatically. | ||
* @return {Object} The 2D or 3D point as an object with x, y[, z] | ||
*/ | ||
var parsePoint = function() { | ||
var point = {}, | ||
code = curr.code; | ||
/** | ||
* Parses a 2D or 3D point, returning it as an object with x, y, and | ||
* (sometimes) z property if it is 3D. It is assumed the current group | ||
* is x of the point being read in, and scanner.next() will return the | ||
* y. The parser will determine if there is a z point automatically. | ||
* @return {Object} The 2D or 3D point as an object with x, y[, z] | ||
*/ | ||
var parsePoint = function() { | ||
var point = {}, | ||
code = curr.code; | ||
point.x = curr.value; | ||
point.x = curr.value; | ||
code += 10; | ||
curr = scanner.next(); | ||
if(curr.code != code) | ||
throw new Error('Expected code for point value to be ' + code + | ||
' but got ' + curr.code + '.'); | ||
point.y = curr.value; | ||
code += 10; | ||
curr = scanner.next(); | ||
if(curr.code != code) | ||
throw new Error('Expected code for point value to be ' + code + | ||
' but got ' + curr.code + '.'); | ||
point.y = curr.value; | ||
code += 10; | ||
curr = scanner.next(); | ||
if(curr.code != code) | ||
{ | ||
scanner.rewind(); | ||
return point; | ||
} | ||
point.z = curr.value; | ||
return point; | ||
}; | ||
code += 10; | ||
curr = scanner.next(); | ||
if(curr.code != code) | ||
{ | ||
scanner.rewind(); | ||
return point; | ||
} | ||
point.z = curr.value; | ||
return point; | ||
}; | ||
var ensureHandle = function(entity) { | ||
if(!entity) throw new TypeError('entity cannot be undefined or null'); | ||
var ensureHandle = function(entity) { | ||
if(!entity) throw new TypeError('entity cannot be undefined or null'); | ||
if(!entity.handle) entity.handle = lastHandle++; | ||
}; | ||
if(!entity.handle) entity.handle = lastHandle++; | ||
}; | ||
parseAll(); | ||
return dxf; | ||
parseAll(); | ||
return dxf; | ||
}; | ||
function logUnhandledGroup(curr) { | ||
log.debug('unhandled group ' + debugCode(curr)); | ||
log.debug('unhandled group ' + debugCode(curr)); | ||
} | ||
@@ -743,3 +747,3 @@ | ||
function debugCode(curr) { | ||
return curr.code + ':' + curr.value; | ||
return curr.code + ':' + curr.value; | ||
} | ||
@@ -752,3 +756,3 @@ | ||
function getAcadColor(index) { | ||
return AUTO_CAD_COLOR_INDEX[index]; | ||
return AUTO_CAD_COLOR_INDEX[index]; | ||
} | ||
@@ -755,0 +759,0 @@ |
@@ -15,13 +15,13 @@ | ||
switch (curr.code) { | ||
case 70: // 1 = Closed shape, 128 = plinegen?, 0 = default | ||
entity.shape = ((curr.value & 1) === 1); | ||
entity.hasContinuousLinetypePattern = ((curr.value & 128) === 128); | ||
break; | ||
case 10: // X coordinate of point | ||
entity.vertices = parse3dFaceVertices(scanner, curr); | ||
curr = scanner.lastReadGroup; | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 70: // 1 = Closed shape, 128 = plinegen?, 0 = default | ||
entity.shape = ((curr.value & 1) === 1); | ||
entity.hasContinuousLinetypePattern = ((curr.value & 128) === 128); | ||
break; | ||
case 10: // X coordinate of point | ||
entity.vertices = parse3dFaceVertices(scanner, curr); | ||
curr = scanner.lastReadGroup; | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -46,30 +46,30 @@ curr = scanner.next(); | ||
switch (curr.code) { | ||
case 10: // X0 | ||
case 11: // X1 | ||
case 12: // X2 | ||
case 13: // X3 | ||
if (vertexIsStarted) { | ||
vertexIsFinished = true; | ||
continue; | ||
} | ||
vertex.x = curr.value; | ||
vertexIsStarted = true; | ||
break; | ||
case 20: // Y | ||
case 21: | ||
case 22: | ||
case 23: | ||
vertex.y = curr.value; | ||
break; | ||
case 30: // Z | ||
case 31: | ||
case 32: | ||
case 33: | ||
vertex.z = curr.value; | ||
break; | ||
default: | ||
// it is possible to have entity codes after the vertices. | ||
// So if code is not accounted for return to entity parser where it might be accounted for | ||
return vertices; | ||
case 10: // X0 | ||
case 11: // X1 | ||
case 12: // X2 | ||
case 13: // X3 | ||
if (vertexIsStarted) { | ||
vertexIsFinished = true; | ||
continue; | ||
} | ||
vertex.x = curr.value; | ||
vertexIsStarted = true; | ||
break; | ||
case 20: // Y | ||
case 21: | ||
case 22: | ||
case 23: | ||
vertex.y = curr.value; | ||
break; | ||
case 30: // Z | ||
case 31: | ||
case 32: | ||
case 33: | ||
vertex.z = curr.value; | ||
break; | ||
default: | ||
// it is possible to have entity codes after the vertices. | ||
// So if code is not accounted for return to entity parser where it might be accounted for | ||
return vertices; | ||
continue; | ||
} | ||
@@ -76,0 +76,0 @@ curr = scanner.next(); |
@@ -16,21 +16,21 @@ | ||
switch(curr.code) { | ||
case 10: // X coordinate of point | ||
entity.center = helpers.parsePoint(scanner); | ||
break; | ||
case 40: // radius | ||
entity.radius = curr.value; | ||
break; | ||
case 50: // start angle | ||
entity.startAngle = Math.PI / 180 * curr.value; | ||
break; | ||
case 51: // end angle | ||
entity.endAngle = Math.PI / 180 * curr.value; | ||
entity.angleLength = entity.endAngle - entity.startAngle; // angleLength is deprecated | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // ignored attribute | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 10: // X coordinate of point | ||
entity.center = helpers.parsePoint(scanner); | ||
break; | ||
case 40: // radius | ||
entity.radius = curr.value; | ||
break; | ||
case 50: // start angle | ||
entity.startAngle = Math.PI / 180 * curr.value; | ||
break; | ||
case 51: // end angle | ||
entity.endAngle = Math.PI / 180 * curr.value; | ||
entity.angleLength = entity.endAngle - entity.startAngle; // angleLength is deprecated | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // ignored attribute | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -37,0 +37,0 @@ curr = scanner.next(); |
@@ -20,64 +20,64 @@ | ||
switch(curr.code) { | ||
case 1: | ||
entity.text = curr.value; | ||
break; | ||
case 2: | ||
entity.tag = curr.value; | ||
break; | ||
case 3: | ||
entity.prompt = curr.value; | ||
break; | ||
case 7: | ||
entity.textStyle = curr.value; | ||
break; | ||
case 10: // X coordinate of 'first alignment point' | ||
entity.startPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 11: // X coordinate of 'second alignment point' | ||
entity.endPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 39: | ||
entity.thickness = curr.value; | ||
break; | ||
case 40: | ||
entity.textHeight = curr.value; | ||
break; | ||
case 41: | ||
entity.scale = curr.value; | ||
break; | ||
case 50: | ||
entity.rotation = curr.value; | ||
break; | ||
case 51: | ||
entity.obliqueAngle = curr.value; | ||
break; | ||
case 70: | ||
entity.invisible = !!(curr.value & 0x01); | ||
entity.constant = !!(curr.value & 0x02); | ||
entity.verificationRequired = !!(curr.value & 0x04); | ||
entity.preset = !!(curr.value & 0x08); | ||
break; | ||
case 71: | ||
entity.backwards = !!(curr.value & 0x02); | ||
entity.mirrored = !!(curr.value & 0x04); | ||
break; | ||
case 72: | ||
// TODO: enum values? | ||
entity.horizontalJustification = curr.value; | ||
break; | ||
case 73: | ||
entity.fieldLength = curr.value; | ||
break; | ||
case 74: | ||
// TODO: enum values? | ||
entity.verticalJustification = curr.value; | ||
break; | ||
case 100: | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 1: | ||
entity.text = curr.value; | ||
break; | ||
case 2: | ||
entity.tag = curr.value; | ||
break; | ||
case 3: | ||
entity.prompt = curr.value; | ||
break; | ||
case 7: | ||
entity.textStyle = curr.value; | ||
break; | ||
case 10: // X coordinate of 'first alignment point' | ||
entity.startPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 11: // X coordinate of 'second alignment point' | ||
entity.endPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 39: | ||
entity.thickness = curr.value; | ||
break; | ||
case 40: | ||
entity.textHeight = curr.value; | ||
break; | ||
case 41: | ||
entity.scale = curr.value; | ||
break; | ||
case 50: | ||
entity.rotation = curr.value; | ||
break; | ||
case 51: | ||
entity.obliqueAngle = curr.value; | ||
break; | ||
case 70: | ||
entity.invisible = !!(curr.value & 0x01); | ||
entity.constant = !!(curr.value & 0x02); | ||
entity.verificationRequired = !!(curr.value & 0x04); | ||
entity.preset = !!(curr.value & 0x08); | ||
break; | ||
case 71: | ||
entity.backwards = !!(curr.value & 0x02); | ||
entity.mirrored = !!(curr.value & 0x04); | ||
break; | ||
case 72: | ||
// TODO: enum values? | ||
entity.horizontalJustification = curr.value; | ||
break; | ||
case 73: | ||
entity.fieldLength = curr.value; | ||
break; | ||
case 74: | ||
// TODO: enum values? | ||
entity.verticalJustification = curr.value; | ||
break; | ||
case 100: | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -84,0 +84,0 @@ curr = scanner.next(); |
@@ -16,25 +16,25 @@ | ||
switch(curr.code) { | ||
case 10: // X coordinate of point | ||
entity.center = helpers.parsePoint(scanner); | ||
break; | ||
case 40: // radius | ||
entity.radius = curr.value; | ||
break; | ||
case 50: // start angle | ||
entity.startAngle = Math.PI / 180 * curr.value; | ||
break; | ||
case 51: // end angle | ||
endAngle = Math.PI / 180 * curr.value; | ||
if(endAngle < entity.startAngle) | ||
entity.angleLength = endAngle + 2 * Math.PI - entity.startAngle; | ||
else | ||
entity.angleLength = endAngle - entity.startAngle; | ||
entity.endAngle = endAngle; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // ignored attribute | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 10: // X coordinate of point | ||
entity.center = helpers.parsePoint(scanner); | ||
break; | ||
case 40: // radius | ||
entity.radius = curr.value; | ||
break; | ||
case 50: // start angle | ||
entity.startAngle = Math.PI / 180 * curr.value; | ||
break; | ||
case 51: // end angle | ||
endAngle = Math.PI / 180 * curr.value; | ||
if(endAngle < entity.startAngle) | ||
entity.angleLength = endAngle + 2 * Math.PI - entity.startAngle; | ||
else | ||
entity.angleLength = endAngle - entity.startAngle; | ||
entity.endAngle = endAngle; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // ignored attribute | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -41,0 +41,0 @@ curr = scanner.next(); |
@@ -10,57 +10,57 @@ | ||
var entity; | ||
entity = { type: curr.value }; | ||
curr = scanner.next(); | ||
while(curr !== 'EOF') { | ||
if(curr.code === 0) break; | ||
entity = { type: curr.value }; | ||
curr = scanner.next(); | ||
while(curr !== 'EOF') { | ||
if(curr.code === 0) break; | ||
switch(curr.code) { | ||
case 2: // Referenced block name | ||
entity.block = curr.value; | ||
break; | ||
case 10: // X coordinate of 'first alignment point' | ||
entity.anchorPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 11: | ||
entity.middleOfText = helpers.parsePoint(scanner); | ||
break; | ||
case 12: // Insertion point for clones of a dimension | ||
entity.insertionPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 13: // Definition point for linear and angular dimensions | ||
entity.linearOrAngularPoint1 = helpers.parsePoint(scanner); | ||
break; | ||
case 14: // Definition point for linear and angular dimensions | ||
entity.linearOrAngularPoint2 = helpers.parsePoint(scanner); | ||
break; | ||
case 15: // Definition point for diameter, radius, and angular dimensions | ||
entity.diameterOrRadiusPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 16: // Point defining dimension arc for angular dimensions | ||
entity.arcPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 70: // Dimension type | ||
entity.dimensionType = curr.value; | ||
break; | ||
case 71: // 5 = Middle center | ||
entity.attachmentPoint = curr.value; | ||
break; | ||
case 42: // Actual measurement | ||
entity.actualMeasurement = curr.value; | ||
break; | ||
case 1: // Text entered by user explicitly | ||
entity.text = curr.value; | ||
break; | ||
case 50: // Angle of rotated, horizontal, or vertical dimensions | ||
entity.angle = curr.value; | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
curr = scanner.next(); | ||
} | ||
switch(curr.code) { | ||
case 2: // Referenced block name | ||
entity.block = curr.value; | ||
break; | ||
case 10: // X coordinate of 'first alignment point' | ||
entity.anchorPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 11: | ||
entity.middleOfText = helpers.parsePoint(scanner); | ||
break; | ||
case 12: // Insertion point for clones of a dimension | ||
entity.insertionPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 13: // Definition point for linear and angular dimensions | ||
entity.linearOrAngularPoint1 = helpers.parsePoint(scanner); | ||
break; | ||
case 14: // Definition point for linear and angular dimensions | ||
entity.linearOrAngularPoint2 = helpers.parsePoint(scanner); | ||
break; | ||
case 15: // Definition point for diameter, radius, and angular dimensions | ||
entity.diameterOrRadiusPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 16: // Point defining dimension arc for angular dimensions | ||
entity.arcPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 70: // Dimension type | ||
entity.dimensionType = curr.value; | ||
break; | ||
case 71: // 5 = Middle center | ||
entity.attachmentPoint = curr.value; | ||
break; | ||
case 42: // Actual measurement | ||
entity.actualMeasurement = curr.value; | ||
break; | ||
case 1: // Text entered by user explicitly | ||
entity.text = curr.value; | ||
break; | ||
case 50: // Angle of rotated, horizontal, or vertical dimensions | ||
entity.angle = curr.value; | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
curr = scanner.next(); | ||
} | ||
return entity; | ||
return entity; | ||
}; | ||
@@ -16,26 +16,26 @@ | ||
switch(curr.code) { | ||
case 10: | ||
entity.center = helpers.parsePoint(scanner); | ||
break; | ||
case 11: | ||
entity.majorAxisEndPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 40: | ||
entity.axisRatio = curr.value; | ||
break; | ||
case 41: | ||
entity.startAngle = curr.value; | ||
break; | ||
case 42: | ||
entity.endAngle = curr.value; | ||
break; | ||
case 2: | ||
entity.name = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 10: | ||
entity.center = helpers.parsePoint(scanner); | ||
break; | ||
case 11: | ||
entity.majorAxisEndPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 40: | ||
entity.axisRatio = curr.value; | ||
break; | ||
case 41: | ||
entity.startAngle = curr.value; | ||
break; | ||
case 42: | ||
entity.endAngle = curr.value; | ||
break; | ||
case 2: | ||
entity.name = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -42,0 +42,0 @@ |
@@ -16,38 +16,38 @@ | ||
switch(curr.code) { | ||
case 2: | ||
entity.name = curr.value; | ||
break; | ||
case 41: | ||
entity.xScale = curr.value; | ||
break; | ||
case 42: | ||
entity.yScale = curr.value; | ||
break; | ||
case 43: | ||
entity.zScale = curr.value; | ||
break; | ||
case 10: | ||
entity.position = helpers.parsePoint(scanner); | ||
break; | ||
case 50: | ||
entity.rotation = curr.value; | ||
break; | ||
case 70: | ||
entity.columnCount = curr.value; | ||
break; | ||
case 71: | ||
entity.rowCount = curr.value; | ||
break; | ||
case 44: | ||
entity.columnSpacing = curr.value; | ||
break; | ||
case 45: | ||
entity.rowSpacing = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 2: | ||
entity.name = curr.value; | ||
break; | ||
case 41: | ||
entity.xScale = curr.value; | ||
break; | ||
case 42: | ||
entity.yScale = curr.value; | ||
break; | ||
case 43: | ||
entity.zScale = curr.value; | ||
break; | ||
case 10: | ||
entity.position = helpers.parsePoint(scanner); | ||
break; | ||
case 50: | ||
entity.rotation = curr.value; | ||
break; | ||
case 70: | ||
entity.columnCount = curr.value; | ||
break; | ||
case 71: | ||
entity.rowCount = curr.value; | ||
break; | ||
case 44: | ||
entity.columnSpacing = curr.value; | ||
break; | ||
case 45: | ||
entity.rowSpacing = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -54,0 +54,0 @@ curr = scanner.next(); |
@@ -15,16 +15,16 @@ | ||
switch(curr.code) { | ||
case 10: // X coordinate of point | ||
entity.vertices.unshift(helpers.parsePoint(scanner)); | ||
break; | ||
case 11: | ||
entity.vertices.push(helpers.parsePoint(scanner)); | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
case 100: | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 10: // X coordinate of point | ||
entity.vertices.unshift(helpers.parsePoint(scanner)); | ||
break; | ||
case 11: | ||
entity.vertices.push(helpers.parsePoint(scanner)); | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
case 100: | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -31,0 +31,0 @@ |
@@ -16,27 +16,27 @@ | ||
switch(curr.code) { | ||
case 38: | ||
entity.elevation = curr.value; | ||
break; | ||
case 39: | ||
entity.depth = curr.value; | ||
break; | ||
case 70: // 1 = Closed shape, 128 = plinegen?, 0 = default | ||
entity.shape = ((curr.value & 1) === 1); | ||
entity.hasContinuousLinetypePattern = ((curr.value & 128) === 128); | ||
break; | ||
case 90: | ||
numberOfVertices = curr.value; | ||
break; | ||
case 10: // X coordinate of point | ||
entity.vertices = parseLWPolylineVertices(numberOfVertices, scanner); | ||
break; | ||
case 43: | ||
if(curr.value !== 0) entity.width = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 38: | ||
entity.elevation = curr.value; | ||
break; | ||
case 39: | ||
entity.depth = curr.value; | ||
break; | ||
case 70: // 1 = Closed shape, 128 = plinegen?, 0 = default | ||
entity.shape = ((curr.value & 1) === 1); | ||
entity.hasContinuousLinetypePattern = ((curr.value & 128) === 128); | ||
break; | ||
case 90: | ||
numberOfVertices = curr.value; | ||
break; | ||
case 10: // X coordinate of point | ||
entity.vertices = parseLWPolylineVertices(numberOfVertices, scanner); | ||
break; | ||
case 43: | ||
if(curr.value !== 0) entity.width = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -61,32 +61,32 @@ curr = scanner.next(); | ||
switch(curr.code) { | ||
case 10: // X | ||
if(vertexIsStarted) { | ||
vertexIsFinished = true; | ||
continue; | ||
} | ||
vertex.x = curr.value; | ||
vertexIsStarted = true; | ||
break; | ||
case 20: // Y | ||
vertex.y = curr.value; | ||
break; | ||
case 30: // Z | ||
vertex.z = curr.value; | ||
break; | ||
case 40: // start width | ||
vertex.startWidth = curr.value; | ||
break; | ||
case 41: // end width | ||
vertex.endWidth = curr.value; | ||
break; | ||
case 42: // bulge | ||
if(curr.value != 0) vertex.bulge = curr.value; | ||
break; | ||
default: | ||
// if we do not hit known code return vertices. Code might belong to entity | ||
if (vertexIsStarted) { | ||
vertices.push(vertex); | ||
} | ||
scanner.rewind(); | ||
return vertices; | ||
case 10: // X | ||
if(vertexIsStarted) { | ||
vertexIsFinished = true; | ||
continue; | ||
} | ||
vertex.x = curr.value; | ||
vertexIsStarted = true; | ||
break; | ||
case 20: // Y | ||
vertex.y = curr.value; | ||
break; | ||
case 30: // Z | ||
vertex.z = curr.value; | ||
break; | ||
case 40: // start width | ||
vertex.startWidth = curr.value; | ||
break; | ||
case 41: // end width | ||
vertex.endWidth = curr.value; | ||
break; | ||
case 42: // bulge | ||
if(curr.value != 0) vertex.bulge = curr.value; | ||
break; | ||
default: | ||
// if we do not hit known code return vertices. Code might belong to entity | ||
if (vertexIsStarted) { | ||
vertices.push(vertex); | ||
} | ||
scanner.rewind(); | ||
return vertices; | ||
} | ||
@@ -93,0 +93,0 @@ curr = scanner.next(); |
@@ -10,3 +10,3 @@ | ||
var entity = { type: curr.value }; | ||
curr = scanner.next(); | ||
curr = scanner.next(); | ||
while(curr !== 'EOF') { | ||
@@ -16,30 +16,30 @@ if(curr.code === 0) break; | ||
switch(curr.code) { | ||
case 3: | ||
entity.text ? entity.text += curr.value : entity.text = curr.value; | ||
break; | ||
case 1: | ||
entity.text ? entity.text += curr.value : entity.text = curr.value; | ||
break; | ||
case 10: | ||
entity.position = helpers.parsePoint(scanner); | ||
break; | ||
case 40: | ||
//Note: this is the text height | ||
entity.height = curr.value; | ||
break; | ||
case 41: | ||
entity.width = curr.value; | ||
break; | ||
case 50: | ||
entity.rotation = curr.value; | ||
break; | ||
case 71: | ||
entity.attachmentPoint = curr.value; | ||
break; | ||
case 72: | ||
entity.drawingDirection = curr.value; | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 3: | ||
entity.text ? entity.text += curr.value : entity.text = curr.value; | ||
break; | ||
case 1: | ||
entity.text ? entity.text += curr.value : entity.text = curr.value; | ||
break; | ||
case 10: | ||
entity.position = helpers.parsePoint(scanner); | ||
break; | ||
case 40: | ||
//Note: this is the text height | ||
entity.height = curr.value; | ||
break; | ||
case 41: | ||
entity.width = curr.value; | ||
break; | ||
case 50: | ||
entity.rotation = curr.value; | ||
break; | ||
case 71: | ||
entity.attachmentPoint = curr.value; | ||
break; | ||
case 72: | ||
entity.drawingDirection = curr.value; | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -46,0 +46,0 @@ curr = scanner.next(); |
@@ -16,16 +16,16 @@ | ||
switch(curr.code) { | ||
case 10: | ||
entity.position = helpers.parsePoint(scanner); | ||
break; | ||
case 39: | ||
entity.thickness = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
case 100: | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 10: | ||
entity.position = helpers.parsePoint(scanner); | ||
break; | ||
case 39: | ||
entity.thickness = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
case 100: | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -32,0 +32,0 @@ curr = scanner.next(); |
@@ -11,53 +11,53 @@ | ||
var entity = { type: curr.value, vertices: [] }; | ||
curr = scanner.next(); | ||
while(curr !== 'EOF') { | ||
if(curr.code === 0) break; | ||
curr = scanner.next(); | ||
while(curr !== 'EOF') { | ||
if(curr.code === 0) break; | ||
switch(curr.code) { | ||
case 10: // always 0 | ||
break; | ||
case 20: // always 0 | ||
break; | ||
case 30: // elevation | ||
break; | ||
case 39: // thickness | ||
entity.thickness = curr.value; | ||
break; | ||
case 40: // start width | ||
break; | ||
case 41: // end width | ||
break; | ||
case 70: | ||
entity.shape = (curr.value & 1) !== 0; | ||
entity.includesCurveFitVertices = (curr.value & 2) !== 0; | ||
entity.includesSplineFitVertices = (curr.value & 4) !== 0; | ||
entity.is3dPolyline = (curr.value & 8) !== 0; | ||
entity.is3dPolygonMesh = (curr.value & 16) !== 0; | ||
entity.is3dPolygonMeshClosed = (curr.value & 32) !== 0; // 32 = The polygon mesh is closed in the N direction | ||
entity.isPolyfaceMesh = (curr.value & 64) !== 0; | ||
entity.hasContinuousLinetypePattern = (curr.value & 128) !== 0; | ||
break; | ||
case 71: // Polygon mesh M vertex count | ||
break; | ||
case 72: // Polygon mesh N vertex count | ||
break; | ||
case 73: // Smooth surface M density | ||
break; | ||
case 74: // Smooth surface N density | ||
break; | ||
case 75: // Curves and smooth surface type | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
curr = scanner.next(); | ||
} | ||
switch(curr.code) { | ||
case 10: // always 0 | ||
break; | ||
case 20: // always 0 | ||
break; | ||
case 30: // elevation | ||
break; | ||
case 39: // thickness | ||
entity.thickness = curr.value; | ||
break; | ||
case 40: // start width | ||
break; | ||
case 41: // end width | ||
break; | ||
case 70: | ||
entity.shape = (curr.value & 1) !== 0; | ||
entity.includesCurveFitVertices = (curr.value & 2) !== 0; | ||
entity.includesSplineFitVertices = (curr.value & 4) !== 0; | ||
entity.is3dPolyline = (curr.value & 8) !== 0; | ||
entity.is3dPolygonMesh = (curr.value & 16) !== 0; | ||
entity.is3dPolygonMeshClosed = (curr.value & 32) !== 0; // 32 = The polygon mesh is closed in the N direction | ||
entity.isPolyfaceMesh = (curr.value & 64) !== 0; | ||
entity.hasContinuousLinetypePattern = (curr.value & 128) !== 0; | ||
break; | ||
case 71: // Polygon mesh M vertex count | ||
break; | ||
case 72: // Polygon mesh N vertex count | ||
break; | ||
case 73: // Smooth surface M density | ||
break; | ||
case 74: // Smooth surface N density | ||
break; | ||
case 75: // Curves and smooth surface type | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
curr = scanner.next(); | ||
} | ||
entity.vertices = parsePolylineVertices(scanner, curr); | ||
entity.vertices = parsePolylineVertices(scanner, curr); | ||
return entity; | ||
return entity; | ||
}; | ||
@@ -64,0 +64,0 @@ |
@@ -17,20 +17,20 @@ | ||
switch(currentGroup.code) { | ||
case 10: | ||
entity.points[0] = helpers.parsePoint(scanner); | ||
break; | ||
case 11: | ||
entity.points[1] = helpers.parsePoint(scanner); | ||
break; | ||
case 12: | ||
entity.points[2] = helpers.parsePoint(scanner); | ||
break; | ||
case 13: | ||
entity.points[3] = helpers.parsePoint(scanner); | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, currentGroup); | ||
break; | ||
case 10: | ||
entity.points[0] = helpers.parsePoint(scanner); | ||
break; | ||
case 11: | ||
entity.points[1] = helpers.parsePoint(scanner); | ||
break; | ||
case 12: | ||
entity.points[2] = helpers.parsePoint(scanner); | ||
break; | ||
case 13: | ||
entity.points[3] = helpers.parsePoint(scanner); | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, currentGroup); | ||
break; | ||
} | ||
@@ -37,0 +37,0 @@ currentGroup = scanner.next(); |
@@ -17,50 +17,50 @@ | ||
switch(curr.code) { | ||
case 10: | ||
if (!entity.controlPoints) entity.controlPoints = []; | ||
entity.controlPoints.push(helpers.parsePoint(scanner)); | ||
break; | ||
case 11: | ||
if (!entity.fitPoints) entity.fitPoints = []; | ||
entity.fitPoints.push(helpers.parsePoint(scanner)); | ||
break; | ||
case 12: | ||
entity.startTangent = helpers.parsePoint(scanner); | ||
break; | ||
case 13: | ||
entity.endTangent = helpers.parsePoint(scanner); | ||
break; | ||
case 40: | ||
if (!entity.knotValues) entity.knotValues = []; | ||
entity.knotValues.push(curr.value); | ||
break; | ||
case 70: | ||
if ((curr.value & 1) != 0) entity.closed = true; | ||
if ((curr.value & 2) != 0) entity.periodic = true; | ||
if ((curr.value & 4) != 0) entity.rational = true; | ||
if ((curr.value & 8) != 0) entity.planar = true; | ||
if ((curr.value & 16) != 0) | ||
{ | ||
entity.planar = true; | ||
entity.linear = true; | ||
} | ||
break; | ||
case 71: | ||
entity.degreeOfSplineCurve = curr.value; | ||
break; | ||
case 72: | ||
entity.numberOfKnots = curr.value; | ||
break; | ||
case 73: | ||
entity.numberOfControlPoints = curr.value; | ||
break; | ||
case 74: | ||
entity.numberOfFitPoints = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 10: | ||
if (!entity.controlPoints) entity.controlPoints = []; | ||
entity.controlPoints.push(helpers.parsePoint(scanner)); | ||
break; | ||
case 11: | ||
if (!entity.fitPoints) entity.fitPoints = []; | ||
entity.fitPoints.push(helpers.parsePoint(scanner)); | ||
break; | ||
case 12: | ||
entity.startTangent = helpers.parsePoint(scanner); | ||
break; | ||
case 13: | ||
entity.endTangent = helpers.parsePoint(scanner); | ||
break; | ||
case 40: | ||
if (!entity.knotValues) entity.knotValues = []; | ||
entity.knotValues.push(curr.value); | ||
break; | ||
case 70: | ||
if ((curr.value & 1) != 0) entity.closed = true; | ||
if ((curr.value & 2) != 0) entity.periodic = true; | ||
if ((curr.value & 4) != 0) entity.rational = true; | ||
if ((curr.value & 8) != 0) entity.planar = true; | ||
if ((curr.value & 16) != 0) | ||
{ | ||
entity.planar = true; | ||
entity.linear = true; | ||
} | ||
break; | ||
case 71: | ||
entity.degreeOfSplineCurve = curr.value; | ||
break; | ||
case 72: | ||
entity.numberOfKnots = curr.value; | ||
break; | ||
case 73: | ||
entity.numberOfControlPoints = curr.value; | ||
break; | ||
case 74: | ||
entity.numberOfFitPoints = curr.value; | ||
break; | ||
case 210: | ||
entity.extrusionDirection = helpers.parsePoint(scanner); | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -67,0 +67,0 @@ curr = scanner.next(); |
@@ -10,3 +10,3 @@ | ||
var entity; | ||
entity = { type: curr.value }; | ||
entity = { type: curr.value }; | ||
curr = scanner.next(); | ||
@@ -16,30 +16,30 @@ while(curr !== 'EOF') { | ||
switch(curr.code) { | ||
case 10: // X coordinate of 'first alignment point' | ||
entity.startPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 11: // X coordinate of 'second alignment point' | ||
entity.endPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 40: // Text height | ||
entity.textHeight = curr.value; | ||
break; | ||
case 41: | ||
entity.xScale = curr.value; | ||
break; | ||
case 50: // Rotation in degrees | ||
entity.rotation = curr.value; | ||
break; | ||
case 1: // Text | ||
entity.text = curr.value; | ||
break; | ||
// NOTE: 72 and 73 are meaningless without 11 (second alignment point) | ||
case 72: // Horizontal alignment | ||
entity.halign = curr.value; | ||
break; | ||
case 73: // Vertical alignment | ||
entity.valign = curr.value; | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 10: // X coordinate of 'first alignment point' | ||
entity.startPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 11: // X coordinate of 'second alignment point' | ||
entity.endPoint = helpers.parsePoint(scanner); | ||
break; | ||
case 40: // Text height | ||
entity.textHeight = curr.value; | ||
break; | ||
case 41: | ||
entity.xScale = curr.value; | ||
break; | ||
case 50: // Rotation in degrees | ||
entity.rotation = curr.value; | ||
break; | ||
case 1: // Text | ||
entity.text = curr.value; | ||
break; | ||
// NOTE: 72 and 73 are meaningless without 11 (second alignment point) | ||
case 72: // Horizontal alignment | ||
entity.halign = curr.value; | ||
break; | ||
case 73: // Vertical alignment | ||
entity.valign = curr.value; | ||
break; | ||
default: // check common entity attributes | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -46,0 +46,0 @@ curr = scanner.next(); |
@@ -15,44 +15,44 @@ | ||
switch(curr.code) { | ||
case 10: // X | ||
entity.x = curr.value; | ||
break; | ||
case 20: // Y | ||
entity.y = curr.value; | ||
break; | ||
case 30: // Z | ||
entity.z = curr.value; | ||
break; | ||
case 40: // start width | ||
break; | ||
case 41: // end width | ||
break; | ||
case 42: // bulge | ||
if(curr.value != 0) entity.bulge = curr.value; | ||
break; | ||
case 70: // flags | ||
entity.curveFittingVertex = (curr.value & 1) !== 0; | ||
entity.curveFitTangent = (curr.value & 2) !== 0; | ||
entity.splineVertex = (curr.value & 8) !== 0; | ||
entity.splineControlPoint = (curr.value & 16) !== 0; | ||
entity.threeDPolylineVertex = (curr.value & 32) !== 0; | ||
entity.threeDPolylineMesh = (curr.value & 64) !== 0; | ||
entity.polyfaceMeshVertex = (curr.value & 128) !== 0; | ||
break; | ||
case 50: // curve fit tangent direction | ||
break; | ||
case 71: // polyface mesh vertex index | ||
entity.faceA = curr.value; | ||
break; | ||
case 72: // polyface mesh vertex index | ||
entity.faceB = curr.value; | ||
break; | ||
case 73: // polyface mesh vertex index | ||
entity.faceC = curr.value; | ||
break; | ||
case 74: // polyface mesh vertex index | ||
entity.faceD = curr.value; | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
case 10: // X | ||
entity.x = curr.value; | ||
break; | ||
case 20: // Y | ||
entity.y = curr.value; | ||
break; | ||
case 30: // Z | ||
entity.z = curr.value; | ||
break; | ||
case 40: // start width | ||
break; | ||
case 41: // end width | ||
break; | ||
case 42: // bulge | ||
if(curr.value != 0) entity.bulge = curr.value; | ||
break; | ||
case 70: // flags | ||
entity.curveFittingVertex = (curr.value & 1) !== 0; | ||
entity.curveFitTangent = (curr.value & 2) !== 0; | ||
entity.splineVertex = (curr.value & 8) !== 0; | ||
entity.splineControlPoint = (curr.value & 16) !== 0; | ||
entity.threeDPolylineVertex = (curr.value & 32) !== 0; | ||
entity.threeDPolylineMesh = (curr.value & 64) !== 0; | ||
entity.polyfaceMeshVertex = (curr.value & 128) !== 0; | ||
break; | ||
case 50: // curve fit tangent direction | ||
break; | ||
case 71: // polyface mesh vertex index | ||
entity.faceA = curr.value; | ||
break; | ||
case 72: // polyface mesh vertex index | ||
entity.faceB = curr.value; | ||
break; | ||
case 73: // polyface mesh vertex index | ||
entity.faceC = curr.value; | ||
break; | ||
case 74: // polyface mesh vertex index | ||
entity.faceD = curr.value; | ||
break; | ||
default: | ||
helpers.checkCommonEntityProperties(entity, curr); | ||
break; | ||
} | ||
@@ -59,0 +59,0 @@ |
@@ -8,3 +8,3 @@ import AUTO_CAD_COLOR_INDEX from './AutoCadColorIndex'; | ||
export function getAcadColor(index) { | ||
return AUTO_CAD_COLOR_INDEX[index]; | ||
return AUTO_CAD_COLOR_INDEX[index]; | ||
} | ||
@@ -11,0 +11,0 @@ |
251948
6507