Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added basic Hatch support #45

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
376 changes: 375 additions & 1 deletion dist/dxf-parser.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "dist/dxf-parser.js",
"scripts": {
"test": "mocha --require @babel/register test",
"test-debug": "mocha --inspect-brk --require @babel/register test",
bzuillsmith marked this conversation as resolved.
Show resolved Hide resolved
"start": "webpack --mode development",
"build": "webpack --mode production"
},
Expand Down
4 changes: 3 additions & 1 deletion src/DxfParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import AttDef from './entities/attdef';
import Circle from './entities/circle';
import Dimension from './entities/dimension';
import Ellipse from './entities/ellipse';
import Hatch from './entities/hatch';
import Insert from './entities/insert';
import Line from './entities/line';
import LWPolyline from './entities/lwpolyline';
Expand Down Expand Up @@ -35,6 +36,7 @@ function registerDefaultEntityHandlers(dxfParser) {
dxfParser.registerEntityHandler(Circle);
dxfParser.registerEntityHandler(Dimension);
dxfParser.registerEntityHandler(Ellipse);
dxfParser.registerEntityHandler(Hatch);
dxfParser.registerEntityHandler(Insert);
dxfParser.registerEntityHandler(Line);
dxfParser.registerEntityHandler(LWPolyline);
Expand Down Expand Up @@ -717,7 +719,7 @@ DxfParser.prototype._parse = function(dxfString) {
return point;
}
point.z = curr.value;

return point;
};

Expand Down
129 changes: 129 additions & 0 deletions src/entities/hatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@

import * as helpers from '../ParseHelpers'

export default function EntityParser() { }

EntityParser.ForEntityName = 'HATCH';

EntityParser.prototype.parseEntity = function (scanner, curr) {
var entity;
entity = { type: curr.value, boundaries: [] };
curr = scanner.next();
while (curr !== 'EOF') {
if (curr.code === 0) break;
// console.log("parseHatch pointer: " + scanner._pointer);
// console.log("parseHatch code: " + curr.code);
// console.log("parseHatch value: " + curr.value);
switch (curr.code) {
case 2:
entity.patternName = curr.value;
break;
case 10:
entity.elevationX = curr.value;
break;
case 20:
entity.elevationY = curr.value;
break;
case 30:
entity.elevationZ = curr.value;
break;
case 41: // Hatch pattern scale or spacing (pattern fill only)
entity.scale = curr.value;
break;
case 47:
entity.pixelSize = curr.value;
case 70: // Solid fill flag (solid fill = 1; pattern fill = 0); for MPolygon, the version of MPolygon
entity.solidFill = (curr.value & 1) !== 0;
break;
case 71: // Associativity flag (associative = 1; non-associative = 0); for MPolygon, solid-fill flag (has solid fill = 1; lacks solid fill = 0)
entity.associativity = (curr.value & 1) !== 0;
break;
// case 72: // 16-bit integer value
case 73: // For MPolygon, boundary annotation flag (boundary is an annotated boundary = 1; boundary is not an annotated boundary = 0)
entity.annotatedBoundary = (curr.value & 1) !== 0;
break;
case 75: // Hatch style: 0 = Hatch “odd parity” area (Normal style), 1 = Hatch outermost area only (Outer style), 2 = Hatch through entire area (Ignore style)
entity.style = curr.value;
break;
case 76: // Hatch pattern type: 0 = User-defined; 1 = Predefined; 2 = Custom
entity.patternStyle = curr.value;
break;
case 91: // Number of boundary paths (loops)
entity.boundaryPathsCount = curr.value;
break;
// case 92: // Number of bytes in the proxy entity graphics represented in the subsequent 310 groups, which are binary chunk records (optional)
// This one is from common entity propierties
case 93:
var boundryVerticeCount = curr.value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should this be boundaryVertexCount.

var boundry = parseHatchVertices(boundryVerticeCount, scanner)
entity.boundaries.push(boundry);
// case 97: // 32-bit integer value
case 98:
entity.seedPointsCount = curr.value;
break;
case 210:
entity.extrusionDirectionX = curr.value;
break;
case 220:
entity.extrusionDirectionY = curr.value;
break;
case 230:
entity.extrusionDirectionZ = curr.value;
break;
default:
helpers.checkCommonEntityProperties(entity, curr);
break;
}
curr = scanner.next();
}
// console.log("parseHatch exit");

return entity;
};

function parseHatchVertices(n, scanner) {
if (!n || n <= 0) throw Error('n must be greater than 0 verticies');
var vertices = [], i;
var vertexIsStarted = false;
var vertexIsFinished = false;
var curr = scanner.next();

for (i = 0; i < n; i++) {
// console.log("parseHatchVertices.i: " + i);
var vertex = {};
while (curr !== 'EOF') {
if (curr.code === 0 || vertexIsFinished) break;

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 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);
}
// console.log("parseHatchVertices exit from default");
return vertices;
}
curr = scanner.next();
}
vertices.push(vertex);
vertexIsStarted = false;
vertexIsFinished = false;
}
// console.log("parseHatchVertices exit");
scanner.rewind();
return vertices;
};
36 changes: 27 additions & 9 deletions test/DxfParser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('Parser', function() {
tables.should.have.property('layer');

var expectedOutputFilePath = path.join(__dirname,'data','layer-table.expected.json');

var expected = fs.readFileSync(expectedOutputFilePath, {encoding: 'utf8'});
tables.layer.should.eql(JSON.parse(expected));
});
Expand All @@ -54,7 +54,7 @@ describe('Parser', function() {
var expected = fs.readFileSync(expectedOutputFilePath, {encoding: 'utf8'});
tables.lineType.should.eql(JSON.parse(expected));
});

it('should parse the dxf viewPort table', function() {
should.exist(tables);
tables.should.have.property('viewPort');
Expand All @@ -65,10 +65,28 @@ describe('Parser', function() {
tables.viewPort.should.eql(JSON.parse(expected));
});

it('should parse a complex BLOCKS section', function() {
verifyDxf(path.join(__dirname, 'data', 'blocks.dxf'))
});

it('should parse HATCH', function() {
verifyDxf
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new way to do this would be to just call verifyDxf(path.join(__dirname, 'data', 'hatch.dxf')); and the result will be suffixed with .received.json instead of .actual.json.

var file = fs.readFileSync(path.join(__dirname, 'data', 'hatch.dxf'), 'utf8');

var parser = new DxfParser();
var dxf;
try {
dxf = parser.parseSync(file);
fs.writeFileSync(path.join(__dirname, 'data', 'hatch.actual.json'), JSON.stringify(dxf, null, 2));
}catch(err) {
should.not.exist(err);
}
should.exist(dxf);

var expected = fs.readFileSync(path.join(__dirname, 'data', 'hatch.expected.json'), {encoding: 'utf8'});
dxf.should.eql(JSON.parse(expected));
});

// it('should parse a complex BLOCKS section', function() {
// verifyDxf(path.join(__dirname, 'data', 'blocks.dxf'))
// });

it('should parse a simple BLOCKS section', function() {
var file = fs.readFileSync(path.join(__dirname, 'data', 'blocks2.dxf'), 'utf8');

Expand All @@ -86,7 +104,7 @@ describe('Parser', function() {
var expected = fs.readFileSync(path.join(__dirname, 'data', 'blocks2.expected.json'), {encoding: 'utf8'});
dxf.should.eql(JSON.parse(expected));
});

it('should parse POLYLINES', function() {
verifyDxf
var file = fs.readFileSync(path.join(__dirname, 'data', 'polylines.dxf'), 'utf8');
Expand Down Expand Up @@ -123,7 +141,7 @@ describe('Parser', function() {
var expected = fs.readFileSync(path.join(__dirname, 'data', 'ellipse.expected.json'), {encoding: 'utf8'});
dxf.should.eql(JSON.parse(expected));
});

it('should parse SPLINE entities', function() {
var file = fs.readFileSync(path.join(__dirname, 'data', 'splines.dxf'), 'utf8');

Expand Down Expand Up @@ -157,7 +175,7 @@ describe('Parser', function() {
var expected = fs.readFileSync(path.join(__dirname, 'data', 'extendeddata.expected.json'), {encoding: 'utf8'});
dxf.should.eql(JSON.parse(expected));
});

it('should parse SPLINE entities that are like arcs and circles', function() {
verifyDxf(path.join(__dirname, 'data', 'arcs-as-splines.dxf'));
});
Expand Down
Loading