dxf
Version:
DXF parser for node/browser
1,523 lines (1,490 loc) • 250 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.dxf = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _logger = _interopRequireDefault(require("./util/logger"));
var _parseString = _interopRequireDefault(require("./parseString"));
var _denormalise2 = _interopRequireDefault(require("./denormalise"));
var _toSVG2 = _interopRequireDefault(require("./toSVG"));
var _toPolylines2 = _interopRequireDefault(require("./toPolylines"));
var _groupEntitiesByLayer = _interopRequireDefault(require("./groupEntitiesByLayer"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var Helper = exports["default"] = /*#__PURE__*/function () {
function Helper(contents) {
_classCallCheck(this, Helper);
if (!(typeof contents === 'string')) {
throw Error('Helper constructor expects a DXF string');
}
this._contents = contents;
this._parsed = null;
this._denormalised = null;
}
return _createClass(Helper, [{
key: "parse",
value: function parse() {
this._parsed = (0, _parseString["default"])(this._contents);
_logger["default"].info('parsed:', this.parsed);
return this._parsed;
}
}, {
key: "parsed",
get: function get() {
if (this._parsed === null) {
this.parse();
}
return this._parsed;
}
}, {
key: "denormalise",
value: function denormalise() {
this._denormalised = (0, _denormalise2["default"])(this.parsed);
_logger["default"].info('denormalised:', this._denormalised);
return this._denormalised;
}
}, {
key: "denormalised",
get: function get() {
if (!this._denormalised) {
this.denormalise();
}
return this._denormalised;
}
}, {
key: "group",
value: function group() {
this._groups = (0, _groupEntitiesByLayer["default"])(this.denormalised);
}
}, {
key: "groups",
get: function get() {
if (!this._groups) {
this.group();
}
return this._groups;
}
}, {
key: "toSVG",
value: function toSVG() {
return (0, _toSVG2["default"])(this.parsed);
}
}, {
key: "toPolylines",
value: function toPolylines() {
return (0, _toPolylines2["default"])(this.parsed);
}
}]);
}();
},{"./denormalise":4,"./groupEntitiesByLayer":7,"./parseString":35,"./toPolylines":36,"./toSVG":37,"./util/logger":42}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
/**
* Apply the transforms to the polyline.
*
* @param polyline the polyline
* @param transform the transforms array
* @returns the transformed polyline
*/
var _default = exports["default"] = function _default(polyline, transforms) {
transforms.forEach(function (transform) {
polyline = polyline.map(function (p) {
// Use a copy to avoid side effects
var p2 = [p[0], p[1]];
if (transform.scaleX) {
p2[0] = p2[0] * transform.scaleX;
}
if (transform.scaleY) {
p2[1] = p2[1] * transform.scaleY;
}
if (transform.rotation) {
var angle = transform.rotation / 180 * Math.PI;
p2 = [p2[0] * Math.cos(angle) - p2[1] * Math.sin(angle), p2[1] * Math.cos(angle) + p2[0] * Math.sin(angle)];
}
if (transform.x) {
p2[0] = p2[0] + transform.x;
}
if (transform.y) {
p2[1] = p2[1] + transform.y;
}
// Observed once in a sample DXF - some cad applications
// use negative extruxion Z for flipping
if (transform.extrusionZ === -1) {
p2[0] = -p2[0];
}
return p2;
});
});
return polyline;
};
},{}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = exports["default"] = {
verbose: false
};
},{}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
var _logger = _interopRequireDefault(require("./util/logger"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var _default = exports["default"] = function _default(parseResult) {
var blocksByName = parseResult.blocks.reduce(function (acc, b) {
acc[b.name] = b;
return acc;
}, {});
var _gatherEntities = function gatherEntities(entities, transforms) {
var current = [];
entities.forEach(function (e) {
if (e.type === 'INSERT') {
var _insert$rowCount, _insert$columnCount, _insert$rowSpacing, _insert$columnSpacing, _insert$rotation;
var insert = e;
var block = blocksByName[insert.block];
if (!block) {
_logger["default"].error('no block found for insert. block:', insert.block);
return;
}
var rowCount = (_insert$rowCount = insert.rowCount) !== null && _insert$rowCount !== void 0 ? _insert$rowCount : 1;
var columnCount = (_insert$columnCount = insert.columnCount) !== null && _insert$columnCount !== void 0 ? _insert$columnCount : 1;
var rowSpacing = (_insert$rowSpacing = insert.rowSpacing) !== null && _insert$rowSpacing !== void 0 ? _insert$rowSpacing : 0;
var columnSpacing = (_insert$columnSpacing = insert.columnSpacing) !== null && _insert$columnSpacing !== void 0 ? _insert$columnSpacing : 0;
var rotation = (_insert$rotation = insert.rotation) !== null && _insert$rotation !== void 0 ? _insert$rotation : 0;
// It appears that the rectangular array is affected by rotation, but NOT by scale.
var rowVec, colVec;
if (rowCount > 1 || columnCount > 1) {
var cos = Math.cos(rotation * Math.PI / 180);
var sin = Math.sin(rotation * Math.PI / 180);
rowVec = {
x: -sin * rowSpacing,
y: cos * rowSpacing
};
colVec = {
x: cos * columnSpacing,
y: sin * columnSpacing
};
} else {
rowVec = {
x: 0,
y: 0
};
colVec = {
x: 0,
y: 0
};
}
// For rectangular arrays, add the block entities for each location in the array
for (var r = 0; r < rowCount; r++) {
for (var c = 0; c < columnCount; c++) {
// Adjust insert transform by row and column for rectangular arrays
var t = {
x: insert.x + rowVec.x * r + colVec.x * c,
y: insert.y + rowVec.y * r + colVec.y * c,
scaleX: insert.scaleX,
scaleY: insert.scaleY,
scaleZ: insert.scaleZ,
extrusionX: insert.extrusionX,
extrusionY: insert.extrusionY,
extrusionZ: insert.extrusionZ,
rotation: insert.rotation
};
// Add the insert transform and recursively add entities
var transforms2 = transforms.slice(0);
transforms2.push(t);
// Use the insert layer
var blockEntities = block.entities.map(function (be) {
var be2 = (0, _cloneDeep["default"])(be);
be2.layer = insert.layer;
// https://github.com/bjnortier/dxf/issues/52
// See Issue 52. If we don't modify the
// entity coordinates here it creates an issue with the
// transformation matrices (which are only applied AFTER
// block insertion modifications has been applied).
switch (be2.type) {
case 'LINE':
{
be2.start.x -= block.x;
be2.start.y -= block.y;
be2.end.x -= block.x;
be2.end.y -= block.y;
break;
}
case 'LWPOLYLINE':
case 'POLYLINE':
{
be2.vertices.forEach(function (v) {
v.x -= block.x;
v.y -= block.y;
});
break;
}
case 'CIRCLE':
case 'ELLIPSE':
case 'ARC':
{
be2.x -= block.x;
be2.y -= block.y;
break;
}
case 'SPLINE':
{
be2.controlPoints.forEach(function (cp) {
cp.x -= block.x;
cp.y -= block.y;
});
break;
}
}
return be2;
});
current = current.concat(_gatherEntities(blockEntities, transforms2));
}
}
} else {
// Top-level entity. Clone and add the transforms
// The transforms are reversed so they occur in
// order of application - i.e. the transform of the
// top-level insert is applied last
var e2 = (0, _cloneDeep["default"])(e);
e2.transforms = transforms.slice().reverse();
current.push(e2);
}
});
return current;
};
return _gatherEntities(parseResult.entities, []);
};
},{"./util/logger":42,"lodash/cloneDeep":139}],5:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.polyfaceOutline = exports.interpolateBSpline = exports["default"] = void 0;
var _bSpline = _interopRequireDefault(require("./util/bSpline"));
var _logger = _interopRequireDefault(require("./util/logger"));
var _createArcForLWPolyline = _interopRequireDefault(require("./util/createArcForLWPolyline"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
/**
* Rotate a set of points.
*
* @param points the points
* @param angle the rotation angle
*/
var rotate = function rotate(points, angle) {
return points.map(function (p) {
return [p[0] * Math.cos(angle) - p[1] * Math.sin(angle), p[1] * Math.cos(angle) + p[0] * Math.sin(angle)];
});
};
/**
* Interpolate an ellipse
* @param cx center X
* @param cy center Y
* @param rx radius X
* @param ry radius Y
* @param start start angle in radians
* @param start end angle in radians
*/
var interpolateEllipse = function interpolateEllipse(cx, cy, rx, ry, start, end, rotationAngle) {
if (end < start) {
end += Math.PI * 2;
}
// ----- Relative points -----
// Start point
var points = [];
var dTheta = Math.PI * 2 / 72;
var EPS = 1e-6;
for (var theta = start; theta < end - EPS; theta += dTheta) {
points.push([Math.cos(theta) * rx, Math.sin(theta) * ry]);
}
points.push([Math.cos(end) * rx, Math.sin(end) * ry]);
// ----- Rotate -----
if (rotationAngle) {
points = rotate(points, rotationAngle);
}
// ----- Offset center -----
points = points.map(function (p) {
return [cx + p[0], cy + p[1]];
});
return points;
};
/**
* Interpolate a b-spline. The algorithm examins the knot vector
* to create segments for interpolation. The parameterisation value
* is re-normalised back to [0,1] as that is what the lib expects (
* and t i de-normalised in the b-spline library)
*
* @param controlPoints the control points
* @param degree the b-spline degree
* @param knots the knot vector
* @returns the polyline
*/
var interpolateBSpline = exports.interpolateBSpline = function interpolateBSpline(controlPoints, degree, knots, interpolationsPerSplineSegment, weights) {
var polyline = [];
var controlPointsForLib = controlPoints.map(function (p) {
return [p.x, p.y];
});
var segmentTs = [knots[degree]];
var domain = [knots[degree], knots[knots.length - 1 - degree]];
for (var k = degree + 1; k < knots.length - degree; ++k) {
if (segmentTs[segmentTs.length - 1] !== knots[k]) {
segmentTs.push(knots[k]);
}
}
interpolationsPerSplineSegment = interpolationsPerSplineSegment || 25;
for (var i = 1; i < segmentTs.length; ++i) {
var uMin = segmentTs[i - 1];
var uMax = segmentTs[i];
for (var _k = 0; _k <= interpolationsPerSplineSegment; ++_k) {
var u = _k / interpolationsPerSplineSegment * (uMax - uMin) + uMin;
// Clamp t to 0, 1 to handle numerical precision issues
var t = (u - domain[0]) / (domain[1] - domain[0]);
t = Math.max(t, 0);
t = Math.min(t, 1);
var p = (0, _bSpline["default"])(t, degree, controlPointsForLib, knots, weights);
polyline.push(p);
}
}
return polyline;
};
var polyfaceOutline = exports.polyfaceOutline = function polyfaceOutline(entity) {
var vertices = [];
var faces = [];
var _iterator = _createForOfIteratorHelper(entity.vertices),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var v = _step.value;
if (v.faces) {
var _face = {
indices: [],
hiddens: []
};
var _iterator3 = _createForOfIteratorHelper(v.faces),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var i = _step3.value;
if (i === 0) {
break;
}
// Negative indices signify hidden edges
_face.indices.push(i < 0 ? -i - 1 : i - 1);
_face.hiddens.push(i < 0);
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
if ([3, 4].includes(_face.indices.length)) faces.push(_face);
} else {
vertices.push({
x: v.x,
y: v.y
});
}
}
// If a segment starts at the end of a previous line, continue it
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
var polylines = [];
var segment = function segment(a, b) {
for (var _i = 0, _polylines = polylines; _i < _polylines.length; _i++) {
var prev = _polylines[_i];
if (prev.slice(-1)[0] === a) {
return prev.push(b);
}
}
polylines.push([a, b]);
};
for (var _i2 = 0, _faces = faces; _i2 < _faces.length; _i2++) {
var face = _faces[_i2];
for (var beg = 0; beg < face.indices.length; beg++) {
if (face.hiddens[beg]) {
continue;
}
var end = (beg + 1) % face.indices.length;
segment(face.indices[beg], face.indices[end]);
}
}
// Sometimes segments are not sequential, in that case
// we need to find if they can mend gaps between others
for (var _i3 = 0, _polylines2 = polylines; _i3 < _polylines2.length; _i3++) {
var a = _polylines2[_i3];
var _iterator2 = _createForOfIteratorHelper(polylines),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var b = _step2.value;
if (a !== b && a[0] === b.slice(-1)[0]) {
b.push.apply(b, _toConsumableArray(a.slice(1)));
a.splice(0, a.length);
break;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
}
return polylines.filter(function (l) {
return l.length;
}).map(function (l) {
return l.map(function (i) {
return vertices[i];
}).map(function (v) {
return [v.x, v.y];
});
});
};
/**
* Convert a parsed DXF entity to a polyline. These can be used to render the
* the DXF in SVG, Canvas, WebGL etc., without depending on native support
* of primitive objects (ellispe, spline etc.)
*/
var _default = exports["default"] = function _default(entity, options) {
options = options || {};
var polyline;
if (entity.type === 'LINE') {
polyline = [[entity.start.x, entity.start.y], [entity.end.x, entity.end.y]];
}
if (entity.type === 'LWPOLYLINE' || entity.type === 'POLYLINE') {
polyline = [];
if (entity.polyfaceMesh) {
var _polyline;
// Only return the first polyline because we can't return many
(_polyline = polyline).push.apply(_polyline, _toConsumableArray(polyfaceOutline(entity)[0]));
} else if (entity.polygonMesh) {
// Do not attempt to render polygon meshes
} else if (entity.vertices.length) {
if (entity.closed) {
entity.vertices = entity.vertices.concat(entity.vertices[0]);
}
for (var i = 0, il = entity.vertices.length; i < il - 1; ++i) {
var from = [entity.vertices[i].x, entity.vertices[i].y];
var to = [entity.vertices[i + 1].x, entity.vertices[i + 1].y];
polyline.push(from);
if (entity.vertices[i].bulge) {
polyline = polyline.concat((0, _createArcForLWPolyline["default"])(from, to, entity.vertices[i].bulge));
}
// The last iteration of the for loop
if (i === il - 2) {
polyline.push(to);
}
}
} else {
_logger["default"].warn('Polyline entity with no vertices');
}
}
if (entity.type === 'CIRCLE') {
polyline = interpolateEllipse(entity.x, entity.y, entity.r, entity.r, 0, Math.PI * 2);
if (entity.extrusionZ === -1) {
polyline = polyline.map(function (p) {
return [-p[0], p[1]];
});
}
}
if (entity.type === 'ELLIPSE') {
var rx = Math.sqrt(entity.majorX * entity.majorX + entity.majorY * entity.majorY);
var ry = entity.axisRatio * rx;
var majorAxisRotation = -Math.atan2(-entity.majorY, entity.majorX);
polyline = interpolateEllipse(entity.x, entity.y, rx, ry, entity.startAngle, entity.endAngle, majorAxisRotation);
if (entity.extrusionZ === -1) {
polyline = polyline.map(function (p) {
return [-p[0], p[1]];
});
}
}
if (entity.type === 'ARC') {
// Why on earth DXF has degree start & end angles for arc,
// and radian start & end angles for ellipses is a mystery
polyline = interpolateEllipse(entity.x, entity.y, entity.r, entity.r, entity.startAngle, entity.endAngle, undefined, false);
// I kid you not, ARCs and ELLIPSEs handle this differently,
// as evidenced by how AutoCAD actually renders these entities
if (entity.extrusionZ === -1) {
polyline = polyline.map(function (p) {
return [-p[0], p[1]];
});
}
}
if (entity.type === 'SPLINE') {
polyline = interpolateBSpline(entity.controlPoints, entity.degree, entity.knots, options.interpolationsPerSplineSegment, entity.weights);
}
if (!polyline) {
_logger["default"].warn('unsupported entity for converting to polyline:', entity.type);
return [];
}
return polyline;
};
},{"./util/bSpline":38,"./util/createArcForLWPolyline":40,"./util/logger":42}],6:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _colors = _interopRequireDefault(require("./util/colors"));
var _logger = _interopRequireDefault(require("./util/logger"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var _default = exports["default"] = function _default(layers, entity) {
var layerTable = layers[entity.layer];
if (layerTable) {
var colorDefinedInEntity = 'colorNumber' in entity && entity.colorNumber !== 256;
var colorNumber = colorDefinedInEntity ? entity.colorNumber : layerTable.colorNumber;
var rgb = _colors["default"][colorNumber];
if (rgb) {
return rgb;
} else {
_logger["default"].warn('Color index', colorNumber, 'invalid, defaulting to black');
return [0, 0, 0];
}
} else {
_logger["default"].warn('no layer table for layer:' + entity.layer);
return [0, 0, 0];
}
};
},{"./util/colors":39,"./util/logger":42}],7:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = exports["default"] = function _default(entities) {
return entities.reduce(function (acc, entity) {
var layer = entity.layer;
if (!acc[layer]) {
acc[layer] = [];
}
acc[layer].push(entity);
return acc;
}, {});
};
},{}],8:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _entities = _interopRequireDefault(require("./entities"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var _default = exports["default"] = function _default(tuples) {
var state;
var blocks = [];
var block;
var entitiesTuples = [];
tuples.forEach(function (tuple) {
var type = tuple[0];
var value = tuple[1];
if (value === 'BLOCK') {
state = 'block';
block = {};
entitiesTuples = [];
blocks.push(block);
} else if (value === 'ENDBLK') {
if (state === 'entities') {
block.entities = (0, _entities["default"])(entitiesTuples);
} else {
block.entities = [];
}
entitiesTuples = undefined;
state = undefined;
} else if (state === 'block' && type !== 0) {
switch (type) {
case 1:
block.xref = value;
break;
case 2:
block.name = value;
break;
case 10:
block.x = value;
break;
case 20:
block.y = value;
break;
case 30:
block.z = value;
break;
case 67:
{
if (value !== 0) block.paperSpace = value;
}
break;
case 410:
block.layout = value;
break;
default:
break;
}
} else if (state === 'block' && type === 0) {
state = 'entities';
entitiesTuples.push(tuple);
} else if (state === 'entities') {
entitiesTuples.push(tuple);
}
});
return blocks;
};
},{"./entities":9}],9:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _logger = _interopRequireDefault(require("../util/logger"));
var _point = _interopRequireDefault(require("./entity/point"));
var _line = _interopRequireDefault(require("./entity/line"));
var _lwpolyline = _interopRequireDefault(require("./entity/lwpolyline"));
var _polyline = _interopRequireDefault(require("./entity/polyline"));
var _vertex = _interopRequireDefault(require("./entity/vertex"));
var _circle = _interopRequireDefault(require("./entity/circle"));
var _arc = _interopRequireDefault(require("./entity/arc"));
var _ellipse = _interopRequireDefault(require("./entity/ellipse"));
var _spline = _interopRequireDefault(require("./entity/spline"));
var _solid = _interopRequireDefault(require("./entity/solid"));
var _hatch = _interopRequireDefault(require("./entity/hatch"));
var _mtext = _interopRequireDefault(require("./entity/mtext"));
var _attdef = _interopRequireDefault(require("./entity/attdef"));
var _attrib = _interopRequireDefault(require("./entity/attrib"));
var _insert = _interopRequireDefault(require("./entity/insert"));
var _threeDFace = _interopRequireDefault(require("./entity/threeDFace"));
var _dimension = _interopRequireDefault(require("./entity/dimension"));
var _text = _interopRequireDefault(require("./entity/text"));
var _viewport = _interopRequireDefault(require("./entity/viewport"));
var _ole2Frame = _interopRequireDefault(require("./entity/ole2Frame"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var handlers = [_point["default"], _line["default"], _lwpolyline["default"], _polyline["default"], _vertex["default"], _circle["default"], _arc["default"], _ellipse["default"], _spline["default"], _solid["default"], _hatch["default"], _mtext["default"], _attdef["default"], _attrib["default"], _text["default"], _insert["default"], _dimension["default"], _threeDFace["default"], _viewport["default"], _ole2Frame["default"]].reduce(function (acc, mod) {
acc[mod.TYPE] = mod;
return acc;
}, {});
var _default = exports["default"] = function _default(tuples) {
var entities = [];
var entityGroups = [];
var currentEntityTuples;
// First group them together for easy processing
tuples.forEach(function (tuple) {
var type = tuple[0];
if (type === 0) {
currentEntityTuples = [];
entityGroups.push(currentEntityTuples);
}
currentEntityTuples.push(tuple);
});
var currentPolyline;
entityGroups.forEach(function (tuples) {
var entityType = tuples[0][1];
var contentTuples = tuples.slice(1);
if (handlers[entityType] !== undefined) {
var e = handlers[entityType].process(contentTuples);
// "POLYLINE" cannot be parsed in isolation, it is followed by
// N "VERTEX" entities and ended with a "SEQEND" entity.
// Essentially we convert POLYLINE to LWPOLYLINE - the extra
// vertex flags are not supported
if (entityType === 'POLYLINE') {
currentPolyline = e;
entities.push(e);
} else if (entityType === 'VERTEX') {
if (currentPolyline) {
currentPolyline.vertices.push(e);
} else {
_logger["default"].error('ignoring invalid VERTEX entity');
}
} else if (entityType === 'SEQEND') {
currentPolyline = undefined;
} else {
// All other entities
entities.push(e);
}
} else {
_logger["default"].warn('unsupported type in ENTITIES section:', entityType);
}
});
return entities;
};
},{"../util/logger":42,"./entity/arc":10,"./entity/attdef":11,"./entity/attrib":12,"./entity/circle":13,"./entity/dimension":15,"./entity/ellipse":16,"./entity/hatch":17,"./entity/insert":18,"./entity/line":19,"./entity/lwpolyline":20,"./entity/mtext":21,"./entity/ole2Frame":22,"./entity/point":23,"./entity/polyline":24,"./entity/solid":25,"./entity/spline":26,"./entity/text":27,"./entity/threeDFace":28,"./entity/vertex":29,"./entity/viewport":30}],10:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.process = exports["default"] = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var TYPE = exports.TYPE = 'ARC';
var process = exports.process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.x = value;
break;
case 20:
entity.y = value;
break;
case 30:
entity.z = value;
break;
case 39:
entity.thickness = value;
break;
case 40:
entity.r = value;
break;
case 50:
// *Someone* decided that ELLIPSE angles are in radians but
// ARC angles are in degrees
entity.startAngle = value / 180 * Math.PI;
break;
case 51:
entity.endAngle = value / 180 * Math.PI;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE
});
};
var _default = exports["default"] = {
TYPE: TYPE,
process: process
};
},{"./common":14}],11:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.process = exports["default"] = exports.assign = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
var _mtext = require("./mtext");
var _text = require("./text");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var TYPE = exports.TYPE = 'ATTDEF';
var process = exports.process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
assign(entity, type, value);
return entity;
}, {
type: TYPE,
subclassMarker: 'AcDbText',
thickness: 0,
scaleX: 1,
mtext: {},
text: {}
});
};
var assign = exports.assign = function assign(entity, type, value) {
switch (type) {
case 100:
{
entity.subclassMarker = value;
break;
}
case 1:
switch (entity.subclassMarker) {
case 'AcDbText':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 2:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
entity.tag = value;
break;
case 'AcDbXrecord':
entity.attdefFlag = value;
break;
}
break;
case 3:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
entity.prompt = value;
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 7:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 10:
switch (entity.subclassMarker) {
case 'AcDbText':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 'AcDbXrecord':
entity.x = value;
break;
}
break;
case 20:
switch (entity.subclassMarker) {
case 'AcDbText':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 'AcDbXrecord':
entity.y = value;
break;
}
break;
case 30:
switch (entity.subclassMarker) {
case 'AcDbText':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 'AcDbXrecord':
entity.z = value;
break;
}
break;
case 11:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
entity.x2 = value;
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 21:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
entity.y2 = value;
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 31:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
entity.z2 = value;
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 39:
(0, _text.assign)(entity.text, type, value);
break;
case 40:
switch (entity.subclassMarker) {
case 'AcDbText':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 'AcDbXrecord':
entity.annotationScale = value;
break;
}
break;
case 41:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 42:
case 43:
case 44:
case 45:
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 46:
entity.mtext.annotationHeight = value;
break;
case 48:
case 49:
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 50:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
{
(0, _mtext.assign)(entity.mtext, type, value);
}
break;
}
break;
case 51:
(0, _text.assign)(entity.text, type, value);
break;
case 63:
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 70:
{
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
entity.attributeFlags = value;
break;
case 'AcDbXrecord':
{
if (typeof entity.mTextFlag === 'undefined') entity.mTextFlag = value;else if (typeof entity.isReallyLocked === 'undefined') entity.isReallyLocked = value;else entity.secondaryAttdefCount = value;
}
break;
}
}
break;
case 71:
case 72:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
(0, _text.assign)(entity.text, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 73:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
entity.fieldLength = value;
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 74:
(0, _text.assign)(entity.text, 73, value);
break;
case 75:
case 76:
case 78:
case 79:
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 90:
(0, _mtext.assign)(entity.mtext, type, value);
break;
case 210:
case 220:
case 230:
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
(0, _text.assign)(entity.mtext, type, value);
break;
case 'AcDbMText':
(0, _mtext.assign)(entity.mtext, type, value);
break;
}
break;
case 280:
{
switch (entity.subclassMarker) {
case 'AcDbAttributeDefinition':
case 'AcDbAttribute':
entity.lock = value;
break;
case 'AcDbXrecord':
entity.clone = true;
break;
}
}
break;
case 340:
entity.attdefHandle = value;
break;
case 420:
case 421:
case 422:
case 423:
case 424:
case 425:
case 426:
case 427:
case 428:
case 429:
case 430:
case 431:
case 432:
case 433:
case 434:
case 435:
case 436:
case 437:
case 438:
case 439:
case 441:
(0, _mtext.assign)(entity.mtext, type, value);
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
};
var _default = exports["default"] = {
TYPE: TYPE,
process: process,
assign: assign
};
},{"./common":14,"./mtext":21,"./text":27}],12:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.process = exports["default"] = exports.TYPE = void 0;
var _attdef = require("./attdef");
var TYPE = exports.TYPE = 'ATTRIB';
var process = exports.process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
(0, _attdef.assign)(entity, type, value);
return entity;
}, {
type: TYPE,
subclassMarker: 'AcDbText',
thickness: 0,
scaleX: 1,
mtext: {},
text: {}
});
};
var _default = exports["default"] = {
TYPE: TYPE,
process: process
};
},{"./attdef":11}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.process = exports["default"] = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var TYPE = exports.TYPE = 'CIRCLE';
var process = exports.process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.x = value;
break;
case 20:
entity.y = value;
break;
case 30:
entity.z = value;
break;
case 40:
entity.r = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE
});
};
var _default = exports["default"] = {
TYPE: TYPE,
process: process
};
},{"./common":14}],14:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _default = exports["default"] = function _default(type, value) {
switch (type) {
case 5:
{
return {
handle: value
};
}
case 6:
// Linetype name (present if not BYLAYER).
// The special name BYBLOCK indicates a
// floating linetype. (optional)
return {
lineTypeName: value
};
case 8:
return {
layer: value
};
case 48:
// Linetype scale (optional)
return {
lineTypeScale: value
};
case 60:
// Object visibility (optional): 0 = visible, 1 = invisible.
return {
visible: value === 0
};
case 62:
// Color number (present if not BYLAYER).
// Zero indicates the BYBLOCK (floating) color.
// 256 indicates BYLAYER.
// A negative value indicates that the layer is turned off. (optional)
return {
colorNumber: value
};
case 67:
// Paper space or sheet.
// Absent or zero indicates entity is in model space. 1 indicates entity is in paper space (optional)
return value === 0 ? {} : {
paperSpace: value
};
case 68:
// Identifies whether viewport is on but fully off screen, is not active, or is off
return {
viewportOn: value
};
case 69:
// Viewport identification number
return {
viewport: value
};
case 210:
return {
extrusionX: value
};
case 220:
return {
extrusionY: value
};
case 230:
return {
extrusionZ: value
};
case 410:
return {
layout: value
};
default:
return {};
}
};
},{}],15:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.process = exports["default"] = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var TYPE = exports.TYPE = 'DIMENSION';
var process = exports.process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 2:
entity.block = value;
break;
case 10:
entity.start.x = value;
break;
case 20:
entity.start.y = value;
break;
case 30:
entity.start.z = value;
break;
case 11:
entity.textMidpoint.x = value;
break;
case 21:
entity.textMidpoint.y = value;
break;
case 31:
entity.textMidpoint.z = value;
break;
case 13:
entity.measureStart.x = value;
break;
case 23:
entity.measureStart.y = value;
break;
case 33:
entity.measureStart.z = value;
break;
case 14:
entity.measureEnd.x = value;
break;
case 24:
entity.measureEnd.y = value;
break;
case 34:
entity.measureEnd.z = value;
break;
case 50:
entity.rotation = value;
break;
case 51:
entity.horizonRotation = value;
break;
case 52:
entity.extensionRotation = value;
break;
case 53:
entity.textRotation = value;
break;
case 70:
{
var dimType = parseBitCombinationsFromValue(value);
if (dimType.ordinateType) {
entity.ordinateType = true;
}
if (dimType.uniqueBlockReference) {
entity.uniqueBlockReference = true;
}
if (dimType.userDefinedLocation) {
entity.userDefinedLocation = true;
}
entity.dimensionType = dimType.dimensionType;
break;
}
case 71:
entity.attachementPoint = value;
break;
case 210:
entity.extrudeDirection = entity.extrudeDirection || {};
entity.extrudeDirection.x = value;
break;
case 220:
entity.extrudeDirection = entity.extrudeDirection || {};
entity.extrudeDirection.y = value;
break;
case 230:
entity.extrudeDirection = entity.extrudeDirection || {};
entity.extrudeDirection.z = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE,
start: {
x: 0,
y: 0,
z: 0
},
measureStart: {
x: 0,
y: 0,
z: 0
},
measureEnd: {
x: 0,
y: 0,
z: 0
},
textMidpoint: {
x: 0,
y: 0,
z: 0
},
attachementPoint: 1,
dimensionType: 0
});
};
/**
* From DXF Reference for DIMENSION
* Values 0-6 are integer values that represent the dimension type. Values 32, 64, and 128
* are bit values, which are added to the integer values (value 32 is always set in R13 and
* later releases)
* 0 = Rotated, horizontal, or vertical; 1 = Aligned
* 2 = Angular; 3 = Diameter; 4 = Radius
* 5 = Angular 3 point; 6 = Ordinate
* 32 = Indicates that the block reference (group code 2) is referenced by this dimension only
* 64 = Ordinate type. This is a bit value (bit 7) used only with integer value 6. If set, ordinate is X-type; if not set, ordinate is Y-type
* 128 = This is a bit value (bit 8) added to the other group 70 values if the dimension text has been positioned at a user-defined location rather than at the default location
*/
function parseBitCombinationsFromValue(value) {
var uniqueBlockReference = false;
var ordinateType = false;
var userDefinedLocation = false;
// ToDo: Solve in some more clever way??
if (value > 6) {
var alt1 = value - 32;
var alt2 = value - 64;
var alt3 = value - 32 - 64;
var alt4 = value - 32 - 128;
var alt5 = value - 32 - 64 - 128;
if (alt1 >= 0 && alt1 <= 6) {
uniqueBlockReference = true;
value = alt1;
} else if (alt2 >= 0 && alt2 <= 6) {
ordinateType = true;
value = alt2;
} else if (alt3 >= 0 && alt3 <= 6) {
uniqueBlockReference = true;
ordinateType = true;
value = alt3;
} else if (alt4 >= 0 && alt4 <= 6) {
uniqueBlockReference = true;
userDefinedLocation = true;
value = alt4;
} else if (alt5 >= 0 && alt5 <= 6) {
uniqueBlockReference = true;
ordinateType = true;
userDefinedLocation = true;
value = alt5;
}
}
return {
dimensionType: value,
uniqueBlockReference: uniqueBlockReference,
ordinateType: ordinateType,
userDefinedLocation: userDefinedLocation
};
}
var _default = exports["default"] = {
TYPE: TYPE,
process: process
};
},{"./common":14}],16:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.process = exports["default"] = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var TYPE = exports.TYPE = 'ELLIPSE';
var process = exports.process = function process(tuples) {
return tuples.reduce(function (entity, tuple) {
var type = tuple[0];
var value = tuple[1];
switch (type) {
case 10:
entity.x = value;
break;
case 11:
entity.majorX = value;
break;
case 20:
entity.y = value;
break;
case 21:
entity.majorY = value;
break;
case 30:
entity.z = value;
break;
case 31:
entity.majorZ = value;
break;
case 40:
entity.axisRatio = value;
break;
case 41:
entity.startAngle = value;
break;
case 42:
entity.endAngle = value;
break;
default:
Object.assign(entity, (0, _common["default"])(type, value));
break;
}
return entity;
}, {
type: TYPE
});
};
var _default = exports["default"] = {
TYPE: TYPE,
process: process
};
},{"./common":14}],17:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.process = exports["default"] = exports.TYPE = void 0;
var _common = _interopRequireDefault(require("./common"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
var TYPE = exports.TYPE = 'HATCH';
var status = 'IDLE';
var drawEntity = {};
var drawType = 0;
var isPolyline = false;
var seed