OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)
This commit is contained in:
8
dev/DWGViewer/libs/dxf-parser/AutoCadColorIndex.d.ts
vendored
Normal file
8
dev/DWGViewer/libs/dxf-parser/AutoCadColorIndex.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* AutoCad files sometimes use an indexed color value between 1 and 255 inclusive.
|
||||
* Each value corresponds to a color. index 1 is red, that is 16711680 or 0xFF0000.
|
||||
* index 0 and 256, while included in this array, are actually reserved for inheritance
|
||||
* values in AutoCad so they should not be used for index color lookups.
|
||||
*/
|
||||
declare const _default: number[];
|
||||
export default _default;
|
||||
264
dev/DWGViewer/libs/dxf-parser/AutoCadColorIndex.js
Normal file
264
dev/DWGViewer/libs/dxf-parser/AutoCadColorIndex.js
Normal file
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* AutoCad files sometimes use an indexed color value between 1 and 255 inclusive.
|
||||
* Each value corresponds to a color. index 1 is red, that is 16711680 or 0xFF0000.
|
||||
* index 0 and 256, while included in this array, are actually reserved for inheritance
|
||||
* values in AutoCad so they should not be used for index color lookups.
|
||||
*/
|
||||
export default [
|
||||
0,
|
||||
16711680,
|
||||
16776960,
|
||||
65280,
|
||||
65535,
|
||||
255,
|
||||
16711935,
|
||||
16777215,
|
||||
8421504,
|
||||
12632256,
|
||||
16711680,
|
||||
16744319,
|
||||
13369344,
|
||||
13395558,
|
||||
10027008,
|
||||
10046540,
|
||||
8323072,
|
||||
8339263,
|
||||
4980736,
|
||||
4990502,
|
||||
16727808,
|
||||
16752511,
|
||||
13382400,
|
||||
13401958,
|
||||
10036736,
|
||||
10051404,
|
||||
8331008,
|
||||
8343359,
|
||||
4985600,
|
||||
4992806,
|
||||
16744192,
|
||||
16760703,
|
||||
13395456,
|
||||
13408614,
|
||||
10046464,
|
||||
10056268,
|
||||
8339200,
|
||||
8347455,
|
||||
4990464,
|
||||
4995366,
|
||||
16760576,
|
||||
16768895,
|
||||
13408512,
|
||||
13415014,
|
||||
10056192,
|
||||
10061132,
|
||||
8347392,
|
||||
8351551,
|
||||
4995328,
|
||||
4997670,
|
||||
16776960,
|
||||
16777087,
|
||||
13421568,
|
||||
13421670,
|
||||
10000384,
|
||||
10000460,
|
||||
8355584,
|
||||
8355647,
|
||||
5000192,
|
||||
5000230,
|
||||
12582656,
|
||||
14679935,
|
||||
10079232,
|
||||
11717734,
|
||||
7510016,
|
||||
8755276,
|
||||
6258432,
|
||||
7307071,
|
||||
3755008,
|
||||
4344870,
|
||||
8388352,
|
||||
12582783,
|
||||
6736896,
|
||||
10079334,
|
||||
5019648,
|
||||
7510092,
|
||||
4161280,
|
||||
6258495,
|
||||
2509824,
|
||||
3755046,
|
||||
4194048,
|
||||
10485631,
|
||||
3394560,
|
||||
8375398,
|
||||
2529280,
|
||||
6264908,
|
||||
2064128,
|
||||
5209919,
|
||||
1264640,
|
||||
3099686,
|
||||
65280,
|
||||
8388479,
|
||||
52224,
|
||||
6736998,
|
||||
38912,
|
||||
5019724,
|
||||
32512,
|
||||
4161343,
|
||||
19456,
|
||||
2509862,
|
||||
65343,
|
||||
8388511,
|
||||
52275,
|
||||
6737023,
|
||||
38950,
|
||||
5019743,
|
||||
32543,
|
||||
4161359,
|
||||
19475,
|
||||
2509871,
|
||||
65407,
|
||||
8388543,
|
||||
52326,
|
||||
6737049,
|
||||
38988,
|
||||
5019762,
|
||||
32575,
|
||||
4161375,
|
||||
19494,
|
||||
2509881,
|
||||
65471,
|
||||
8388575,
|
||||
52377,
|
||||
6737074,
|
||||
39026,
|
||||
5019781,
|
||||
32607,
|
||||
4161391,
|
||||
19513,
|
||||
2509890,
|
||||
65535,
|
||||
8388607,
|
||||
52428,
|
||||
6737100,
|
||||
39064,
|
||||
5019800,
|
||||
32639,
|
||||
4161407,
|
||||
19532,
|
||||
2509900,
|
||||
49151,
|
||||
8380415,
|
||||
39372,
|
||||
6730444,
|
||||
29336,
|
||||
5014936,
|
||||
24447,
|
||||
4157311,
|
||||
14668,
|
||||
2507340,
|
||||
32767,
|
||||
8372223,
|
||||
26316,
|
||||
6724044,
|
||||
19608,
|
||||
5010072,
|
||||
16255,
|
||||
4153215,
|
||||
9804,
|
||||
2505036,
|
||||
16383,
|
||||
8364031,
|
||||
13260,
|
||||
6717388,
|
||||
9880,
|
||||
5005208,
|
||||
8063,
|
||||
4149119,
|
||||
4940,
|
||||
2502476,
|
||||
255,
|
||||
8355839,
|
||||
204,
|
||||
6710988,
|
||||
152,
|
||||
5000344,
|
||||
127,
|
||||
4145023,
|
||||
76,
|
||||
2500172,
|
||||
4129023,
|
||||
10452991,
|
||||
3342540,
|
||||
8349388,
|
||||
2490520,
|
||||
6245528,
|
||||
2031743,
|
||||
5193599,
|
||||
1245260,
|
||||
3089996,
|
||||
8323327,
|
||||
12550143,
|
||||
6684876,
|
||||
10053324,
|
||||
4980888,
|
||||
7490712,
|
||||
4128895,
|
||||
6242175,
|
||||
2490444,
|
||||
3745356,
|
||||
12517631,
|
||||
14647295,
|
||||
10027212,
|
||||
11691724,
|
||||
7471256,
|
||||
8735896,
|
||||
6226047,
|
||||
7290751,
|
||||
3735628,
|
||||
4335180,
|
||||
16711935,
|
||||
16744447,
|
||||
13369548,
|
||||
13395660,
|
||||
9961624,
|
||||
9981080,
|
||||
8323199,
|
||||
8339327,
|
||||
4980812,
|
||||
4990540,
|
||||
16711871,
|
||||
16744415,
|
||||
13369497,
|
||||
13395634,
|
||||
9961586,
|
||||
9981061,
|
||||
8323167,
|
||||
8339311,
|
||||
4980793,
|
||||
4990530,
|
||||
16711807,
|
||||
16744383,
|
||||
13369446,
|
||||
13395609,
|
||||
9961548,
|
||||
9981042,
|
||||
8323135,
|
||||
8339295,
|
||||
4980774,
|
||||
4990521,
|
||||
16711743,
|
||||
16744351,
|
||||
13369395,
|
||||
13395583,
|
||||
9961510,
|
||||
9981023,
|
||||
8323103,
|
||||
8339279,
|
||||
4980755,
|
||||
4990511,
|
||||
3355443,
|
||||
5987163,
|
||||
8684676,
|
||||
11382189,
|
||||
14079702,
|
||||
16777215
|
||||
];
|
||||
40
dev/DWGViewer/libs/dxf-parser/DxfArrayScanner.d.ts
vendored
Normal file
40
dev/DWGViewer/libs/dxf-parser/DxfArrayScanner.d.ts
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
export interface IGroup {
|
||||
code: number;
|
||||
value: number | string | boolean;
|
||||
}
|
||||
/**
|
||||
* DxfArrayScanner
|
||||
*
|
||||
* Based off the AutoCad 2012 DXF Reference
|
||||
* http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf
|
||||
*
|
||||
* Reads through an array representing lines of a dxf file. Takes an array and
|
||||
* provides an easy interface to extract group code and value pairs.
|
||||
* @param data - an array where each element represents a line in the dxf file
|
||||
* @constructor
|
||||
*/
|
||||
export default class DxfArrayScanner {
|
||||
private _pointer;
|
||||
private _eof;
|
||||
lastReadGroup: IGroup;
|
||||
private _data;
|
||||
constructor(data: string[]);
|
||||
/**
|
||||
* Gets the next group (code, value) from the array. A group is two consecutive elements
|
||||
* in the array. The first is the code, the second is the value.
|
||||
* @returns {{code: Number}|*}
|
||||
*/
|
||||
next(): IGroup;
|
||||
peek(): IGroup;
|
||||
rewind(numberOfGroups?: number): void;
|
||||
/**
|
||||
* Returns true if there is another code/value pair (2 elements in the array).
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasNext(): boolean;
|
||||
/**
|
||||
* Returns true if the scanner is at the end of the array
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isEOF(): boolean;
|
||||
}
|
||||
149
dev/DWGViewer/libs/dxf-parser/DxfArrayScanner.js
Normal file
149
dev/DWGViewer/libs/dxf-parser/DxfArrayScanner.js
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* DxfArrayScanner
|
||||
*
|
||||
* Based off the AutoCad 2012 DXF Reference
|
||||
* http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf
|
||||
*
|
||||
* Reads through an array representing lines of a dxf file. Takes an array and
|
||||
* provides an easy interface to extract group code and value pairs.
|
||||
* @param data - an array where each element represents a line in the dxf file
|
||||
* @constructor
|
||||
*/
|
||||
export default class DxfArrayScanner {
|
||||
constructor(data) {
|
||||
this._pointer = 0;
|
||||
this._eof = false;
|
||||
this._data = data;
|
||||
}
|
||||
/**
|
||||
* Gets the next group (code, value) from the array. A group is two consecutive elements
|
||||
* in the array. The first is the code, the second is the value.
|
||||
* @returns {{code: Number}|*}
|
||||
*/
|
||||
next() {
|
||||
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');
|
||||
}
|
||||
const group = {
|
||||
code: parseInt(this._data[this._pointer])
|
||||
};
|
||||
this._pointer++;
|
||||
group.value = parseGroupValue(group.code, this._data[this._pointer].trim());
|
||||
this._pointer++;
|
||||
if (group.code === 0 && group.value === 'EOF')
|
||||
this._eof = true;
|
||||
this.lastReadGroup = group;
|
||||
return group;
|
||||
}
|
||||
peek() {
|
||||
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');
|
||||
}
|
||||
const group = {
|
||||
code: parseInt(this._data[this._pointer])
|
||||
};
|
||||
group.value = parseGroupValue(group.code, this._data[this._pointer + 1].trim());
|
||||
return group;
|
||||
}
|
||||
rewind(numberOfGroups = 1) {
|
||||
this._pointer = this._pointer - numberOfGroups * 2;
|
||||
}
|
||||
/**
|
||||
* Returns true if there is another code/value pair (2 elements in the array).
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasNext() {
|
||||
// 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;
|
||||
}
|
||||
/**
|
||||
* Returns true if the scanner is at the end of the array
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isEOF() {
|
||||
return this._eof;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Parse a value to its proper type.
|
||||
* See pages 3 - 10 of the AutoCad DXF 2012 reference given at the top of this file
|
||||
*
|
||||
* @param code
|
||||
* @param value
|
||||
* @returns {*}
|
||||
*/
|
||||
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);
|
||||
console.log('WARNING: Group code does not have a defined type: %j', { code: code, value: value });
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* Parse a boolean according to a 1 or 0 value
|
||||
* @param str
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function parseBoolean(str) {
|
||||
if (str === '0')
|
||||
return false;
|
||||
if (str === '1')
|
||||
return true;
|
||||
throw TypeError('String \'' + str + '\' cannot be cast to Boolean type');
|
||||
}
|
||||
111
dev/DWGViewer/libs/dxf-parser/DxfParser.d.ts
vendored
Normal file
111
dev/DWGViewer/libs/dxf-parser/DxfParser.d.ts
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/// <reference types="node" />
|
||||
import { Readable } from 'stream';
|
||||
import IGeometry, { IEntity, IPoint } from './entities/geomtry';
|
||||
export interface IBlock {
|
||||
entities: IEntity[];
|
||||
type: number;
|
||||
ownerHandle: string;
|
||||
xrefPath: string;
|
||||
name: string;
|
||||
name2: string;
|
||||
handle: string;
|
||||
layer: string;
|
||||
position: IPoint;
|
||||
paperSpace: boolean;
|
||||
}
|
||||
export interface IViewPort {
|
||||
name: string;
|
||||
lowerLeftCorner: IPoint;
|
||||
upperRightCorner: IPoint;
|
||||
center: IPoint;
|
||||
snapBasePoint: IPoint;
|
||||
snapSpacing: IPoint;
|
||||
gridSpacing: IPoint;
|
||||
viewDirectionFromTarget: IPoint;
|
||||
viewTarget: IPoint;
|
||||
lensLength: number;
|
||||
frontClippingPlane: string | number | boolean;
|
||||
backClippingPlane: string | number | boolean;
|
||||
viewHeight: number;
|
||||
snapRotationAngle: number;
|
||||
viewTwistAngle: number;
|
||||
orthographicType: string;
|
||||
ucsOrigin: IPoint;
|
||||
ucsXAxis: IPoint;
|
||||
ucsYAxis: IPoint;
|
||||
renderMode: string;
|
||||
defaultLightingType: string;
|
||||
defaultLightingOn: string;
|
||||
ownerHandle: string;
|
||||
ambientColor: number;
|
||||
}
|
||||
export interface IViewPortTableDefinition {
|
||||
tableRecordsProperty: 'viewPorts';
|
||||
tableName: 'viewPort';
|
||||
dxfSymbolName: 'VPORT';
|
||||
parseTableRecords(): IViewPort[];
|
||||
}
|
||||
export interface ILineType {
|
||||
name: string;
|
||||
description: string;
|
||||
pattern: string[];
|
||||
patternLength: number;
|
||||
}
|
||||
export interface ILineTypeTableDefinition {
|
||||
tableRecordsProperty: 'lineTypes';
|
||||
tableName: 'lineType';
|
||||
dxfSymbolName: 'LTYPE';
|
||||
parseTableRecords(): Record<string, ILineType>;
|
||||
}
|
||||
export interface ILayer {
|
||||
name: string;
|
||||
visible: boolean;
|
||||
colorIndex: number;
|
||||
color: number;
|
||||
frozen: boolean;
|
||||
}
|
||||
export interface ILayerTableDefinition {
|
||||
tableRecordsProperty: 'layers';
|
||||
tableName: 'layer';
|
||||
dxfSymbolName: 'LAYER';
|
||||
parseTableRecords(): Record<string, ILayer>;
|
||||
}
|
||||
export interface ITableDefinitions {
|
||||
VPORT: IViewPortTableDefinition;
|
||||
LTYPE: ILineTypeTableDefinition;
|
||||
LAYER: ILayerTableDefinition;
|
||||
}
|
||||
export interface IBaseTable {
|
||||
handle: string;
|
||||
ownerHandle: string;
|
||||
}
|
||||
export interface IViewPortTable extends IBaseTable {
|
||||
viewPorts: IViewPort[];
|
||||
}
|
||||
export interface ILayerTypesTable extends IBaseTable {
|
||||
lineTypes: Record<string, ILineType>;
|
||||
}
|
||||
export interface ILayersTable extends IBaseTable {
|
||||
layers: Record<string, ILayer>;
|
||||
}
|
||||
export interface ITables {
|
||||
viewPort: IViewPortTable;
|
||||
lineType: ILayerTypesTable;
|
||||
layer: ILayersTable;
|
||||
}
|
||||
export declare type ITable = IViewPortTable | ILayerTypesTable | ILayersTable;
|
||||
export interface IDxf {
|
||||
header: Record<string, IPoint | number>;
|
||||
entities: IEntity[];
|
||||
blocks: Record<string, IBlock>;
|
||||
tables: ITables;
|
||||
}
|
||||
export default class DxfParser {
|
||||
private _entityHandlers;
|
||||
constructor();
|
||||
parse(source: string): IDxf | null;
|
||||
registerEntityHandler(handlerType: new () => IGeometry): void;
|
||||
parseSync(source: string): IDxf | null;
|
||||
parseStream(stream: Readable): Promise<IDxf>;
|
||||
private _parse;
|
||||
}
|
||||
722
dev/DWGViewer/libs/dxf-parser/DxfParser.js
Normal file
722
dev/DWGViewer/libs/dxf-parser/DxfParser.js
Normal file
@@ -0,0 +1,722 @@
|
||||
import DxfArrayScanner from './DxfArrayScanner.js';
|
||||
import AUTO_CAD_COLOR_INDEX from './AutoCadColorIndex.js';
|
||||
import Face from './entities/3dface.js';
|
||||
import Arc from './entities/arc.js';
|
||||
import AttDef from './entities/attdef.js';
|
||||
import Circle from './entities/circle.js';
|
||||
import Dimension from './entities/dimension.js';
|
||||
import Ellipse from './entities/ellipse.js';
|
||||
import Insert from './entities/insert.js';
|
||||
import Line from './entities/line.js';
|
||||
import LWPolyline from './entities/lwpolyline.js';
|
||||
import MText from './entities/mtext.js';
|
||||
import Point from './entities/point.js';
|
||||
import Polyline from './entities/polyline.js';
|
||||
import Solid from './entities/solid.js';
|
||||
import Spline from './entities/spline.js';
|
||||
import Text from './entities/text.js';
|
||||
//import Vertex from './entities/.js';
|
||||
import log from 'loglevel';
|
||||
//log.setLevel('trace');
|
||||
//log.setLevel('debug');
|
||||
//log.setLevel('info');
|
||||
//log.setLevel('warn');
|
||||
log.setLevel('error');
|
||||
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'));
|
||||
}
|
||||
export default class DxfParser {
|
||||
constructor() {
|
||||
this._entityHandlers = {};
|
||||
registerDefaultEntityHandlers(this);
|
||||
}
|
||||
parse(source) {
|
||||
if (typeof source === 'string') {
|
||||
return this._parse(source);
|
||||
}
|
||||
else {
|
||||
console.error('Cannot read dxf source of type `' + typeof (source));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
registerEntityHandler(handlerType) {
|
||||
const instance = new handlerType();
|
||||
this._entityHandlers[instance.ForEntityName] = instance;
|
||||
}
|
||||
parseSync(source) {
|
||||
return this.parse(source);
|
||||
}
|
||||
parseStream(stream) {
|
||||
let dxfString = "";
|
||||
const self = this;
|
||||
return new Promise((res, rej) => {
|
||||
stream.on('data', (chunk) => {
|
||||
dxfString += chunk;
|
||||
});
|
||||
stream.on('end', () => {
|
||||
try {
|
||||
res(self._parse(dxfString));
|
||||
}
|
||||
catch (err) {
|
||||
rej(err);
|
||||
}
|
||||
});
|
||||
stream.on('error', (err) => {
|
||||
rej(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
_parse(dxfString) {
|
||||
const dxf = {};
|
||||
let lastHandle = 0;
|
||||
const dxfLinesArray = dxfString.split(/\r\n|\r|\n/g);
|
||||
const scanner = new DxfArrayScanner(dxfLinesArray);
|
||||
if (!scanner.hasNext())
|
||||
throw Error('Empty file');
|
||||
const self = this;
|
||||
let curr;
|
||||
function parseAll() {
|
||||
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;
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return {object} header
|
||||
*/
|
||||
function parseHeader() {
|
||||
// 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
|
||||
let currVarName = null;
|
||||
let currVarValue = null;
|
||||
const header = {};
|
||||
// loop through header variables
|
||||
curr = scanner.next();
|
||||
while (true) {
|
||||
if (groupIs(curr, 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;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function parseBlocks() {
|
||||
const blocks = {};
|
||||
curr = scanner.next();
|
||||
while (curr.value !== 'EOF') {
|
||||
if (groupIs(curr, 0, 'ENDSEC')) {
|
||||
break;
|
||||
}
|
||||
if (groupIs(curr, 0, 'BLOCK')) {
|
||||
log.debug('block {');
|
||||
const block = parseBlock();
|
||||
log.debug('}');
|
||||
ensureHandle(block);
|
||||
if (!block.name)
|
||||
log.error('block with handle "' + block.handle + '" is missing a name.');
|
||||
else
|
||||
blocks[block.name] = block;
|
||||
}
|
||||
else {
|
||||
logUnhandledGroup(curr);
|
||||
curr = scanner.next();
|
||||
}
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
function parseBlock() {
|
||||
const 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);
|
||||
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(curr, 0, 'ENDBLK')) {
|
||||
curr = scanner.next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return block;
|
||||
}
|
||||
/**
|
||||
* parseTables
|
||||
* @return {Object} Object representing tables
|
||||
*/
|
||||
function parseTables() {
|
||||
const tables = {};
|
||||
curr = scanner.next();
|
||||
while (curr.value !== 'EOF') {
|
||||
if (groupIs(curr, 0, 'ENDSEC'))
|
||||
break;
|
||||
if (groupIs(curr, 0, 'TABLE')) {
|
||||
curr = scanner.next();
|
||||
const tableDefinition = tableDefinitions[curr.value];
|
||||
if (tableDefinition) {
|
||||
log.debug(curr.value + ' Table {');
|
||||
tables[tableDefinitions[curr.value].tableName] = parseTable(curr);
|
||||
log.debug('}');
|
||||
}
|
||||
else {
|
||||
log.debug('Unhandled Table ' + curr.value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// else ignored
|
||||
curr = scanner.next();
|
||||
}
|
||||
}
|
||||
curr = scanner.next();
|
||||
return tables;
|
||||
}
|
||||
const END_OF_TABLE_VALUE = 'ENDTAB';
|
||||
function parseTable(group) {
|
||||
const tableDefinition = tableDefinitions[group.value];
|
||||
const table = {};
|
||||
let expectedCount = 0;
|
||||
curr = scanner.next();
|
||||
while (!groupIs(curr, 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();
|
||||
}
|
||||
}
|
||||
const tableRecords = table[tableDefinition.tableRecordsProperty];
|
||||
if (tableRecords) {
|
||||
let actualCount = (() => {
|
||||
if (tableRecords.constructor === Array) {
|
||||
return tableRecords.length;
|
||||
}
|
||||
else if (typeof (tableRecords) === 'object') {
|
||||
return Object.keys(tableRecords).length;
|
||||
}
|
||||
return undefined;
|
||||
})();
|
||||
if (expectedCount !== actualCount)
|
||||
log.warn('Parsed ' + actualCount + ' ' + tableDefinition.dxfSymbolName + '\'s but expected ' + expectedCount);
|
||||
}
|
||||
curr = scanner.next();
|
||||
return table;
|
||||
}
|
||||
function parseViewPortRecords() {
|
||||
const viewPorts = []; // Multiple table entries may have the same name indicating a multiple viewport configuration
|
||||
let viewPort = {};
|
||||
log.debug('ViewPort {');
|
||||
curr = scanner.next();
|
||||
while (!groupIs(curr, 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);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 11:
|
||||
viewPort.upperRightCorner = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 12:
|
||||
viewPort.center = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 13:
|
||||
viewPort.snapBasePoint = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 14:
|
||||
viewPort.snapSpacing = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 15:
|
||||
viewPort.gridSpacing = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 16:
|
||||
viewPort.viewDirectionFromTarget = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 17:
|
||||
viewPort.viewTarget = parsePoint(curr);
|
||||
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:
|
||||
viewPort.orthographicType = curr.value;
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 110:
|
||||
viewPort.ucsOrigin = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 111:
|
||||
viewPort.ucsXAxis = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 112:
|
||||
viewPort.ucsYAxis = parsePoint(curr);
|
||||
curr = scanner.next();
|
||||
break;
|
||||
case 110:
|
||||
viewPort.ucsOrigin = parsePoint(curr);
|
||||
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;
|
||||
}
|
||||
function parseLineTypes() {
|
||||
const ltypes = {};
|
||||
let ltype = {};
|
||||
let length = 0;
|
||||
let ltypeName;
|
||||
log.debug('LType {');
|
||||
curr = scanner.next();
|
||||
while (!groupIs(curr, 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();
|
||||
}
|
||||
}
|
||||
log.debug('}');
|
||||
ltypes[ltypeName] = ltype;
|
||||
return ltypes;
|
||||
}
|
||||
function parseLayers() {
|
||||
const layers = {};
|
||||
let layer = {};
|
||||
let layerName;
|
||||
log.debug('Layer {');
|
||||
curr = scanner.next();
|
||||
while (!groupIs(curr, 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;
|
||||
return layers;
|
||||
}
|
||||
const 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
|
||||
*/
|
||||
function parseEntities(forBlock) {
|
||||
const entities = [];
|
||||
const endingOnValue = forBlock ? 'ENDBLK' : 'ENDSEC';
|
||||
if (!forBlock) {
|
||||
curr = scanner.next();
|
||||
}
|
||||
while (true) {
|
||||
if (curr.code === 0) {
|
||||
if (curr.value === endingOnValue) {
|
||||
break;
|
||||
}
|
||||
const handler = self._entityHandlers[curr.value];
|
||||
if (handler != null) {
|
||||
log.debug(curr.value + ' {');
|
||||
const entity = handler.parseEntity(scanner, curr);
|
||||
curr = scanner.lastReadGroup;
|
||||
log.debug('}');
|
||||
ensureHandle(entity);
|
||||
entities.push(entity);
|
||||
}
|
||||
else {
|
||||
log.warn('Unhandled entity ' + curr.value);
|
||||
curr = scanner.next();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
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]
|
||||
*/
|
||||
function parsePoint(curr) {
|
||||
const point = {};
|
||||
let code = curr.code;
|
||||
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) {
|
||||
scanner.rewind();
|
||||
return point;
|
||||
}
|
||||
point.z = curr.value;
|
||||
return point;
|
||||
}
|
||||
function ensureHandle(entity) {
|
||||
if (!entity)
|
||||
throw new TypeError('entity cannot be undefined or null');
|
||||
if (!entity.handle)
|
||||
entity.handle = lastHandle++;
|
||||
}
|
||||
parseAll();
|
||||
return dxf;
|
||||
}
|
||||
}
|
||||
function groupIs(group, code, value) {
|
||||
return group.code === code && group.value === value;
|
||||
}
|
||||
function logUnhandledGroup(curr) {
|
||||
log.debug('unhandled group ' + debugCode(curr));
|
||||
}
|
||||
function debugCode(curr) {
|
||||
return curr.code + ':' + curr.value;
|
||||
}
|
||||
/**
|
||||
* Returns the truecolor value of the given AutoCad color index value
|
||||
* @return {Number} truecolor value as a number
|
||||
*/
|
||||
function getAcadColor(index) {
|
||||
return AUTO_CAD_COLOR_INDEX[index];
|
||||
}
|
||||
// const BLOCK_ANONYMOUS_FLAG = 1;
|
||||
// const BLOCK_NON_CONSTANT_FLAG = 2;
|
||||
// const BLOCK_XREF_FLAG = 4;
|
||||
// const BLOCK_XREF_OVERLAY_FLAG = 8;
|
||||
// const BLOCK_EXTERNALLY_DEPENDENT_FLAG = 16;
|
||||
// const BLOCK_RESOLVED_OR_DEPENDENT_FLAG = 32;
|
||||
// const BLOCK_REFERENCED_XREF = 64;
|
||||
/* Notes */
|
||||
// Code 6 of an entity indicates inheritance of properties (eg. color).
|
||||
// BYBLOCK means inherits from block
|
||||
// BYLAYER (default) mean inherits from layer
|
||||
21
dev/DWGViewer/libs/dxf-parser/LICENSE
Normal file
21
dev/DWGViewer/libs/dxf-parser/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 GDS Storefront Estimating
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
20
dev/DWGViewer/libs/dxf-parser/ParseHelpers.d.ts
vendored
Normal file
20
dev/DWGViewer/libs/dxf-parser/ParseHelpers.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import DxfArrayScanner, { IGroup } from './DxfArrayScanner';
|
||||
import { IEntity, IPoint } from './entities/geomtry';
|
||||
/**
|
||||
* Returns the truecolor value of the given AutoCad color index value
|
||||
* @return {Number} truecolor value as a number
|
||||
*/
|
||||
export declare function getAcadColor(index: number): number;
|
||||
/**
|
||||
* Parses the 2D or 3D coordinate, vector, or point. When complete,
|
||||
* the scanner remains on the last group of the coordinate.
|
||||
* @param {*} scanner
|
||||
*/
|
||||
export declare function parsePoint(scanner: DxfArrayScanner): IPoint;
|
||||
/**
|
||||
* Attempts to parse codes common to all entities. Returns true if the group
|
||||
* was handled by this function.
|
||||
* @param {*} entity - the entity currently being parsed
|
||||
* @param {*} curr - the current group being parsed
|
||||
*/
|
||||
export declare function checkCommonEntityProperties(entity: IEntity, curr: IGroup, scanner: DxfArrayScanner): boolean;
|
||||
109
dev/DWGViewer/libs/dxf-parser/ParseHelpers.js
Normal file
109
dev/DWGViewer/libs/dxf-parser/ParseHelpers.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import AUTO_CAD_COLOR_INDEX from './AutoCadColorIndex.js';
|
||||
/**
|
||||
* Returns the truecolor value of the given AutoCad color index value
|
||||
* @return {Number} truecolor value as a number
|
||||
*/
|
||||
export function getAcadColor(index) {
|
||||
return AUTO_CAD_COLOR_INDEX[index];
|
||||
}
|
||||
/**
|
||||
* Parses the 2D or 3D coordinate, vector, or point. When complete,
|
||||
* the scanner remains on the last group of the coordinate.
|
||||
* @param {*} scanner
|
||||
*/
|
||||
export function parsePoint(scanner) {
|
||||
const point = {};
|
||||
// Reread group for the first coordinate
|
||||
scanner.rewind();
|
||||
let curr = scanner.next();
|
||||
let code = curr.code;
|
||||
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) {
|
||||
// Only the x and y are specified. Don't read z.
|
||||
scanner.rewind(); // Let the calling code advance off the point
|
||||
return point;
|
||||
}
|
||||
point.z = curr.value;
|
||||
return point;
|
||||
}
|
||||
/**
|
||||
* Attempts to parse codes common to all entities. Returns true if the group
|
||||
* was handled by this function.
|
||||
* @param {*} entity - the entity currently being parsed
|
||||
* @param {*} curr - the current group being parsed
|
||||
*/
|
||||
export function checkCommonEntityProperties(entity, curr, scanner) {
|
||||
switch (curr.code) {
|
||||
case 0:
|
||||
entity.type = curr.value;
|
||||
break;
|
||||
case 5:
|
||||
entity.handle = curr.value;
|
||||
break;
|
||||
case 6:
|
||||
entity.lineType = curr.value;
|
||||
break;
|
||||
case 8: // Layer name
|
||||
entity.layer = curr.value;
|
||||
break;
|
||||
case 48:
|
||||
entity.lineTypeScale = curr.value;
|
||||
break;
|
||||
case 60:
|
||||
entity.visible = curr.value === 0;
|
||||
break;
|
||||
case 62: // Acad Index Color. 0 inherits ByBlock. 256 inherits ByLayer. Default is bylayer
|
||||
entity.colorIndex = curr.value;
|
||||
entity.color = getAcadColor(Math.abs(curr.value));
|
||||
break;
|
||||
case 67:
|
||||
entity.inPaperSpace = curr.value !== 0;
|
||||
break;
|
||||
case 100:
|
||||
//ignore
|
||||
break;
|
||||
case 101: // Embedded Object in ACAD 2018.
|
||||
// See https://ezdxf.readthedocs.io/en/master/dxfinternals/dxftags.html#embedded-objects
|
||||
while (curr.code != 0) {
|
||||
curr = scanner.next();
|
||||
}
|
||||
scanner.rewind();
|
||||
break;
|
||||
case 330:
|
||||
entity.ownerHandle = curr.value;
|
||||
break;
|
||||
case 347:
|
||||
entity.materialObjectHandle = curr.value;
|
||||
break;
|
||||
case 370:
|
||||
//From https://www.woutware.com/Forum/Topic/955/lineweight?returnUrl=%2FForum%2FUserPosts%3FuserId%3D478262319
|
||||
// An integer representing 100th of mm, must be one of the following values:
|
||||
// 0, 5, 9, 13, 15, 18, 20, 25, 30, 35, 40, 50, 53, 60, 70, 80, 90, 100, 106, 120, 140, 158, 200, 211.
|
||||
// -3 = STANDARD, -2 = BYLAYER, -1 = BYBLOCK
|
||||
entity.lineweight = curr.value;
|
||||
break;
|
||||
case 420: // TrueColor Color
|
||||
entity.color = curr.value;
|
||||
break;
|
||||
case 1000:
|
||||
entity.extendedData = entity.extendedData || {};
|
||||
entity.extendedData.customStrings = entity.extendedData.customStrings || [];
|
||||
entity.extendedData.customStrings.push(curr.value);
|
||||
break;
|
||||
case 1001:
|
||||
entity.extendedData = entity.extendedData || {};
|
||||
entity.extendedData.applicationName = curr.value;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
1
dev/DWGViewer/libs/dxf-parser/dxf-parser.js
Normal file
1
dev/DWGViewer/libs/dxf-parser/dxf-parser.js
Normal file
File diff suppressed because one or more lines are too long
11
dev/DWGViewer/libs/dxf-parser/entities/3dface.d.ts
vendored
Normal file
11
dev/DWGViewer/libs/dxf-parser/entities/3dface.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface I3DfaceEntity extends IEntity {
|
||||
shape: boolean;
|
||||
hasContinuousLinetypePattern: boolean;
|
||||
vertices: IPoint[];
|
||||
}
|
||||
export default class ThreeDface implements IGeometry {
|
||||
ForEntityName: "3DFACE";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): I3DfaceEntity;
|
||||
}
|
||||
79
dev/DWGViewer/libs/dxf-parser/entities/3dface.js
Normal file
79
dev/DWGViewer/libs/dxf-parser/entities/3dface.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class ThreeDface {
|
||||
constructor() {
|
||||
this.ForEntityName = '3DFACE';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value, vertices: [] };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
function parse3dFaceVertices(scanner, curr) {
|
||||
var vertices = [];
|
||||
var vertexIsStarted = false;
|
||||
var vertexIsFinished = false;
|
||||
var verticesPer3dFace = 4; // there can be up to four vertices per face, although 3 is most used for TIN
|
||||
for (let i = 0; i <= verticesPer3dFace; i++) {
|
||||
var vertex = {};
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0 || vertexIsFinished)
|
||||
break;
|
||||
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;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
// See https://groups.google.com/forum/#!topic/comp.cad.autocad/9gn8s5O_w6E
|
||||
vertices.push(vertex);
|
||||
vertexIsStarted = false;
|
||||
vertexIsFinished = false;
|
||||
}
|
||||
scanner.rewind();
|
||||
return vertices;
|
||||
}
|
||||
;
|
||||
16
dev/DWGViewer/libs/dxf-parser/entities/arc.d.ts
vendored
Normal file
16
dev/DWGViewer/libs/dxf-parser/entities/arc.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IArcEntity extends IEntity {
|
||||
center: IPoint;
|
||||
radius: number;
|
||||
startAngle: number;
|
||||
endAngle: number;
|
||||
angleLength: number;
|
||||
extrusionDirectionX: number;
|
||||
extrusionDirectionY: number;
|
||||
extrusionDirectionZ: number;
|
||||
}
|
||||
export default class Arc implements IGeometry {
|
||||
ForEntityName: "ARC";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IArcEntity;
|
||||
}
|
||||
43
dev/DWGViewer/libs/dxf-parser/entities/arc.js
Normal file
43
dev/DWGViewer/libs/dxf-parser/entities/arc.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Arc {
|
||||
constructor() {
|
||||
this.ForEntityName = 'ARC';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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.extrusionDirectionX = curr.value;
|
||||
break;
|
||||
case 220:
|
||||
entity.extrusionDirectionY = curr.value;
|
||||
break;
|
||||
case 230:
|
||||
entity.extrusionDirectionZ = curr.value;
|
||||
break;
|
||||
default: // ignored attribute
|
||||
helpers.checkCommonEntityProperties(entity, curr, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
31
dev/DWGViewer/libs/dxf-parser/entities/attdef.d.ts
vendored
Normal file
31
dev/DWGViewer/libs/dxf-parser/entities/attdef.d.ts
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IAttdefEntity extends IEntity {
|
||||
scale: number;
|
||||
textStyle: 'STANDARD' | string;
|
||||
text: string;
|
||||
tag: string;
|
||||
prompt: string;
|
||||
startPoint: IPoint;
|
||||
endPoint: IPoint;
|
||||
thickness: number;
|
||||
textHeight: number;
|
||||
rotation: number;
|
||||
obliqueAngle: number;
|
||||
invisible: boolean;
|
||||
constant: boolean;
|
||||
verificationRequired: boolean;
|
||||
preset: boolean;
|
||||
backwards: boolean;
|
||||
mirrored: boolean;
|
||||
horizontalJustification: number;
|
||||
fieldLength: number;
|
||||
verticalJustification: number;
|
||||
extrusionDirectionX: number;
|
||||
extrusionDirectionY: number;
|
||||
extrusionDirectionZ: number;
|
||||
}
|
||||
export default class Attdef implements IGeometry {
|
||||
ForEntityName: "ATTDEF";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IAttdefEntity;
|
||||
}
|
||||
91
dev/DWGViewer/libs/dxf-parser/entities/attdef.js
Normal file
91
dev/DWGViewer/libs/dxf-parser/entities/attdef.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Attdef {
|
||||
constructor() {
|
||||
this.ForEntityName = 'ATTDEF';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
var entity = {
|
||||
type: curr.value,
|
||||
scale: 1,
|
||||
textStyle: 'STANDARD'
|
||||
};
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0) {
|
||||
break;
|
||||
}
|
||||
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.extrusionDirectionX = curr.value;
|
||||
break;
|
||||
case 220:
|
||||
entity.extrusionDirectionY = curr.value;
|
||||
break;
|
||||
case 230:
|
||||
entity.extrusionDirectionZ = curr.value;
|
||||
break;
|
||||
default:
|
||||
helpers.checkCommonEntityProperties(entity, curr, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
13
dev/DWGViewer/libs/dxf-parser/entities/circle.d.ts
vendored
Normal file
13
dev/DWGViewer/libs/dxf-parser/entities/circle.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface ICircleEntity extends IEntity {
|
||||
center: IPoint;
|
||||
radius: number;
|
||||
startAngle: number;
|
||||
endAngle: number;
|
||||
angleLength: number;
|
||||
}
|
||||
export default class Circle implements IGeometry {
|
||||
ForEntityName: "CIRCLE";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ICircleEntity;
|
||||
}
|
||||
38
dev/DWGViewer/libs/dxf-parser/entities/circle.js
Normal file
38
dev/DWGViewer/libs/dxf-parser/entities/circle.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Circle {
|
||||
constructor() {
|
||||
this.ForEntityName = 'CIRCLE';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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
|
||||
const 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;
|
||||
default: // ignored attribute
|
||||
helpers.checkCommonEntityProperties(entity, curr, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
21
dev/DWGViewer/libs/dxf-parser/entities/dimension.d.ts
vendored
Normal file
21
dev/DWGViewer/libs/dxf-parser/entities/dimension.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IDimensionEntity extends IEntity {
|
||||
block: string;
|
||||
anchorPoint: IPoint;
|
||||
middleOfText: IPoint;
|
||||
insertionPoint: IPoint;
|
||||
linearOrAngularPoint1: IPoint;
|
||||
linearOrAngularPoint2: IPoint;
|
||||
diameterOrRadiusPoint: IPoint;
|
||||
arcPoint: IPoint;
|
||||
dimensionType: number;
|
||||
attachmentPoint: number;
|
||||
actualMeasurement: number;
|
||||
text: string;
|
||||
angle: number;
|
||||
}
|
||||
export default class Dimension implements IGeometry {
|
||||
ForEntityName: "DIMENSION";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IDimensionEntity;
|
||||
}
|
||||
60
dev/DWGViewer/libs/dxf-parser/entities/dimension.js
Normal file
60
dev/DWGViewer/libs/dxf-parser/entities/dimension.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Dimension {
|
||||
constructor() {
|
||||
this.ForEntityName = 'DIMENSION';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
14
dev/DWGViewer/libs/dxf-parser/entities/ellipse.d.ts
vendored
Normal file
14
dev/DWGViewer/libs/dxf-parser/entities/ellipse.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IEllipseEntity extends IEntity {
|
||||
center: IPoint;
|
||||
majorAxisEndPoint: IPoint;
|
||||
axisRatio: number;
|
||||
startAngle: number;
|
||||
endAngle: number;
|
||||
name: string;
|
||||
}
|
||||
export default class Ellipse implements IGeometry {
|
||||
ForEntityName: "ELLIPSE";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IEllipseEntity;
|
||||
}
|
||||
39
dev/DWGViewer/libs/dxf-parser/entities/ellipse.js
Normal file
39
dev/DWGViewer/libs/dxf-parser/entities/ellipse.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Ellipse {
|
||||
constructor() {
|
||||
this.ForEntityName = 'ELLIPSE';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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;
|
||||
default: // check common entity attributes
|
||||
helpers.checkCommonEntityProperties(entity, curr, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
29
dev/DWGViewer/libs/dxf-parser/entities/geomtry.d.ts
vendored
Normal file
29
dev/DWGViewer/libs/dxf-parser/entities/geomtry.d.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import DxfArrayScanner, { IGroup } from "../DxfArrayScanner";
|
||||
export interface IPoint {
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
}
|
||||
export interface IEntity {
|
||||
lineType: string;
|
||||
layer: string;
|
||||
lineTypeScale: number;
|
||||
visible: boolean;
|
||||
colorIndex: number;
|
||||
color: number;
|
||||
inPaperSpace: boolean;
|
||||
ownerHandle: string;
|
||||
materialObjectHandle: number;
|
||||
lineweight: 0 | 5 | 9 | 13 | 15 | 18 | 20 | 25 | 30 | 35 | 40 | 50 | 53 | 60 | 70 | 80 | 90 | 100 | 106 | 120 | 140 | 158 | 200 | 211 | -3 | -2 | -1;
|
||||
extendedData: {
|
||||
customStrings: string[];
|
||||
applicationName: string;
|
||||
};
|
||||
type: string;
|
||||
handle: number;
|
||||
}
|
||||
export declare type EntityName = 'POINT' | '3DFACE' | 'ARC' | 'ATTDEF' | 'CIRCLE' | 'DIMENSION' | 'ELLIPSE' | 'INSERT' | 'LINE' | 'LWPOLYLINE' | 'MTEXT' | 'POLYLINE' | 'SOLID' | 'SPLINE' | 'TEXT' | 'VERTEX';
|
||||
export default interface IGeometry {
|
||||
ForEntityName: EntityName;
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IEntity;
|
||||
}
|
||||
1
dev/DWGViewer/libs/dxf-parser/entities/geomtry.js
Normal file
1
dev/DWGViewer/libs/dxf-parser/entities/geomtry.js
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
19
dev/DWGViewer/libs/dxf-parser/entities/insert.d.ts
vendored
Normal file
19
dev/DWGViewer/libs/dxf-parser/entities/insert.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IInsertEntity extends IEntity {
|
||||
name: string;
|
||||
xScale: number;
|
||||
yScale: number;
|
||||
zScale: number;
|
||||
position: IPoint;
|
||||
rotation: number;
|
||||
columnCount: number;
|
||||
rowCount: number;
|
||||
columnSpacing: number;
|
||||
rowSpacing: number;
|
||||
extrusionDirection: IPoint;
|
||||
}
|
||||
export default class Insert implements IGeometry {
|
||||
ForEntityName: "INSERT";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IInsertEntity;
|
||||
}
|
||||
54
dev/DWGViewer/libs/dxf-parser/entities/insert.js
Normal file
54
dev/DWGViewer/libs/dxf-parser/entities/insert.js
Normal file
@@ -0,0 +1,54 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Insert {
|
||||
constructor() {
|
||||
this.ForEntityName = 'INSERT';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
10
dev/DWGViewer/libs/dxf-parser/entities/line.d.ts
vendored
Normal file
10
dev/DWGViewer/libs/dxf-parser/entities/line.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface ILineEntity extends IEntity {
|
||||
vertices: IPoint[];
|
||||
extrusionDirection: IPoint;
|
||||
}
|
||||
export default class Line implements IGeometry {
|
||||
ForEntityName: "LINE";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ILineEntity;
|
||||
}
|
||||
32
dev/DWGViewer/libs/dxf-parser/entities/line.js
Normal file
32
dev/DWGViewer/libs/dxf-parser/entities/line.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Line {
|
||||
constructor() {
|
||||
this.ForEntityName = 'LINE';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value, vertices: [] };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
22
dev/DWGViewer/libs/dxf-parser/entities/lwpolyline.d.ts
vendored
Normal file
22
dev/DWGViewer/libs/dxf-parser/entities/lwpolyline.d.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IVertex extends IPoint {
|
||||
startWidth: number;
|
||||
endWidth: number;
|
||||
bulge: number;
|
||||
}
|
||||
export interface ILwpolylineEntity extends IEntity {
|
||||
vertices: IVertex[];
|
||||
elevation: number;
|
||||
depth: number;
|
||||
shape: boolean;
|
||||
hasContinuousLinetypePattern: boolean;
|
||||
width: number;
|
||||
extrusionDirectionX: number;
|
||||
extrusionDirectionY: number;
|
||||
extrusionDirectionZ: number;
|
||||
}
|
||||
export default class Lwpolyline implements IGeometry {
|
||||
ForEntityName: "LWPOLYLINE";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ILwpolylineEntity;
|
||||
}
|
||||
107
dev/DWGViewer/libs/dxf-parser/entities/lwpolyline.js
Normal file
107
dev/DWGViewer/libs/dxf-parser/entities/lwpolyline.js
Normal file
@@ -0,0 +1,107 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Lwpolyline {
|
||||
constructor() {
|
||||
this.ForEntityName = 'LWPOLYLINE';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value, vertices: [] };
|
||||
let numberOfVertices = 0;
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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.extrusionDirectionX = curr.value;
|
||||
break;
|
||||
case 220:
|
||||
entity.extrusionDirectionY = curr.value;
|
||||
break;
|
||||
case 230:
|
||||
entity.extrusionDirectionZ = curr.value;
|
||||
break;
|
||||
default:
|
||||
helpers.checkCommonEntityProperties(entity, curr, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
function parseLWPolylineVertices(n, scanner) {
|
||||
if (!n || n <= 0)
|
||||
throw Error('n must be greater than 0 verticies');
|
||||
const vertices = [];
|
||||
let vertexIsStarted = false;
|
||||
let vertexIsFinished = false;
|
||||
let curr = scanner.lastReadGroup;
|
||||
for (let i = 0; i < n; i++) {
|
||||
const vertex = {};
|
||||
while (!scanner.isEOF()) {
|
||||
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 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
|
||||
scanner.rewind();
|
||||
if (vertexIsStarted) {
|
||||
vertices.push(vertex);
|
||||
}
|
||||
scanner.rewind();
|
||||
return vertices;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
// See https://groups.google.com/forum/#!topic/comp.cad.autocad/9gn8s5O_w6E
|
||||
vertices.push(vertex);
|
||||
vertexIsStarted = false;
|
||||
vertexIsFinished = false;
|
||||
}
|
||||
scanner.rewind();
|
||||
return vertices;
|
||||
}
|
||||
16
dev/DWGViewer/libs/dxf-parser/entities/mtext.d.ts
vendored
Normal file
16
dev/DWGViewer/libs/dxf-parser/entities/mtext.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IMtextEntity extends IEntity {
|
||||
text: string;
|
||||
position: IPoint;
|
||||
directionVector: IPoint;
|
||||
height: number;
|
||||
width: number;
|
||||
rotation: number;
|
||||
attachmentPoint: number;
|
||||
drawingDirection: number;
|
||||
}
|
||||
export default class Mtext implements IGeometry {
|
||||
ForEntityName: "MTEXT";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IMtextEntity;
|
||||
}
|
||||
49
dev/DWGViewer/libs/dxf-parser/entities/mtext.js
Normal file
49
dev/DWGViewer/libs/dxf-parser/entities/mtext.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Mtext {
|
||||
constructor() {
|
||||
this.ForEntityName = 'MTEXT';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
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 11:
|
||||
entity.directionVector = 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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
11
dev/DWGViewer/libs/dxf-parser/entities/point.d.ts
vendored
Normal file
11
dev/DWGViewer/libs/dxf-parser/entities/point.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IPointEntity extends IEntity {
|
||||
position: IPoint;
|
||||
thickness: number;
|
||||
extrusionDirection: IPoint;
|
||||
}
|
||||
export default class Point implements IGeometry {
|
||||
ForEntityName: "POINT";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IPointEntity;
|
||||
}
|
||||
33
dev/DWGViewer/libs/dxf-parser/entities/point.js
Normal file
33
dev/DWGViewer/libs/dxf-parser/entities/point.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Point {
|
||||
constructor() {
|
||||
this.ForEntityName = 'POINT';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const type = curr.value;
|
||||
const entity = { type };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
20
dev/DWGViewer/libs/dxf-parser/entities/polyline.d.ts
vendored
Normal file
20
dev/DWGViewer/libs/dxf-parser/entities/polyline.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { IVertexEntity } from './vertex';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
export interface IPolylineEntity extends IEntity {
|
||||
vertices: IVertexEntity[];
|
||||
thickness: number;
|
||||
shape: boolean;
|
||||
includesCurveFitVertices: boolean;
|
||||
includesSplineFitVertices: boolean;
|
||||
is3dPolyline: boolean;
|
||||
is3dPolygonMesh: boolean;
|
||||
is3dPolygonMeshClosed: boolean;
|
||||
isPolyfaceMesh: boolean;
|
||||
hasContinuousLinetypePattern: boolean;
|
||||
extrusionDirection: IPoint;
|
||||
}
|
||||
export default class Polyline implements IGeometry {
|
||||
ForEntityName: "POLYLINE";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IPolylineEntity;
|
||||
}
|
||||
88
dev/DWGViewer/libs/dxf-parser/entities/polyline.js
Normal file
88
dev/DWGViewer/libs/dxf-parser/entities/polyline.js
Normal file
@@ -0,0 +1,88 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
import VertexParser from './vertex.js';
|
||||
export default class Polyline {
|
||||
constructor() {
|
||||
this.ForEntityName = 'POLYLINE';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
var entity = { type: curr.value, vertices: [] };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
entity.vertices = parsePolylineVertices(scanner, curr);
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
function parsePolylineVertices(scanner, curr) {
|
||||
const vertexParser = new VertexParser();
|
||||
const vertices = [];
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0) {
|
||||
if (curr.value === 'VERTEX') {
|
||||
vertices.push(vertexParser.parseEntity(scanner, curr));
|
||||
curr = scanner.lastReadGroup;
|
||||
}
|
||||
else if (curr.value === 'SEQEND') {
|
||||
parseSeqEnd(scanner, curr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
function parseSeqEnd(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code == 0)
|
||||
break;
|
||||
helpers.checkCommonEntityProperties(entity, curr, scanner);
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
;
|
||||
10
dev/DWGViewer/libs/dxf-parser/entities/solid.d.ts
vendored
Normal file
10
dev/DWGViewer/libs/dxf-parser/entities/solid.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface ISolidEntity extends IEntity {
|
||||
points: IPoint[];
|
||||
extrusionDirection: IPoint;
|
||||
}
|
||||
export default class Solid implements IGeometry {
|
||||
ForEntityName: "SOLID";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ISolidEntity;
|
||||
}
|
||||
36
dev/DWGViewer/libs/dxf-parser/entities/solid.js
Normal file
36
dev/DWGViewer/libs/dxf-parser/entities/solid.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Solid {
|
||||
constructor() {
|
||||
this.ForEntityName = 'SOLID';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value, points: [] };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
switch (curr.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, curr, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
23
dev/DWGViewer/libs/dxf-parser/entities/spline.d.ts
vendored
Normal file
23
dev/DWGViewer/libs/dxf-parser/entities/spline.d.ts
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface ISplineEntity extends IEntity {
|
||||
controlPoints?: IPoint[];
|
||||
fitPoints?: IPoint[];
|
||||
startTangent: IPoint;
|
||||
endTangent: IPoint;
|
||||
knotValues: number[];
|
||||
closed: boolean;
|
||||
periodic: boolean;
|
||||
rational: boolean;
|
||||
planar: boolean;
|
||||
linear: boolean;
|
||||
degreeOfSplineCurve: number;
|
||||
numberOfKnots: number;
|
||||
numberOfControlPoints: number;
|
||||
numberOfFitPoints: number;
|
||||
normalVector: IPoint;
|
||||
}
|
||||
export default class Spline implements IGeometry {
|
||||
ForEntityName: "SPLINE";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ISplineEntity;
|
||||
}
|
||||
71
dev/DWGViewer/libs/dxf-parser/entities/spline.js
Normal file
71
dev/DWGViewer/libs/dxf-parser/entities/spline.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Spline {
|
||||
constructor() {
|
||||
this.ForEntityName = 'SPLINE';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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.normalVector = helpers.parsePoint(scanner);
|
||||
break;
|
||||
default:
|
||||
helpers.checkCommonEntityProperties(entity, curr, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
16
dev/DWGViewer/libs/dxf-parser/entities/text.d.ts
vendored
Normal file
16
dev/DWGViewer/libs/dxf-parser/entities/text.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface ITextEntity extends IEntity {
|
||||
startPoint: IPoint;
|
||||
endPoint: IPoint;
|
||||
textHeight: number;
|
||||
xScale: number;
|
||||
rotation: number;
|
||||
text: string;
|
||||
halign: number;
|
||||
valign: number;
|
||||
}
|
||||
export default class Text implements IGeometry {
|
||||
ForEntityName: "TEXT";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): ITextEntity;
|
||||
}
|
||||
46
dev/DWGViewer/libs/dxf-parser/entities/text.js
Normal file
46
dev/DWGViewer/libs/dxf-parser/entities/text.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Text {
|
||||
constructor() {
|
||||
this.ForEntityName = 'TEXT';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
const entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
20
dev/DWGViewer/libs/dxf-parser/entities/vertex.d.ts
vendored
Normal file
20
dev/DWGViewer/libs/dxf-parser/entities/vertex.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import DxfArrayScanner, { IGroup } from '../DxfArrayScanner';
|
||||
import IGeometry, { IEntity, IPoint } from './geomtry';
|
||||
export interface IVertexEntity extends IEntity, IPoint {
|
||||
bulge: number;
|
||||
curveFittingVertex: boolean;
|
||||
curveFitTangent: boolean;
|
||||
splineVertex: boolean;
|
||||
splineControlPoint: boolean;
|
||||
threeDPolylineVertex: boolean;
|
||||
threeDPolylineMesh: boolean;
|
||||
polyfaceMeshVertex: boolean;
|
||||
faceA: number;
|
||||
faceB: number;
|
||||
faceC: number;
|
||||
faceD: number;
|
||||
}
|
||||
export default class Vertex implements IGeometry {
|
||||
ForEntityName: "VERTEX";
|
||||
parseEntity(scanner: DxfArrayScanner, curr: IGroup): IVertexEntity;
|
||||
}
|
||||
61
dev/DWGViewer/libs/dxf-parser/entities/vertex.js
Normal file
61
dev/DWGViewer/libs/dxf-parser/entities/vertex.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import * as helpers from '../ParseHelpers.js';
|
||||
export default class Vertex {
|
||||
constructor() {
|
||||
this.ForEntityName = 'VERTEX';
|
||||
}
|
||||
parseEntity(scanner, curr) {
|
||||
var entity = { type: curr.value };
|
||||
curr = scanner.next();
|
||||
while (!scanner.isEOF()) {
|
||||
if (curr.code === 0)
|
||||
break;
|
||||
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, scanner);
|
||||
break;
|
||||
}
|
||||
curr = scanner.next();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
21
dev/DWGViewer/libs/dxf-parser/index.d.ts
vendored
Normal file
21
dev/DWGViewer/libs/dxf-parser/index.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import DxfParser from './DxfParser';
|
||||
export { default as DxfParser } from './DxfParser';
|
||||
export { IDxf, IBlock, ILayerTypesTable, ILayersTable, ITables, IViewPortTable, IBaseTable, ILayer, ILayerTableDefinition, ILineType, ILineTypeTableDefinition, ITable, ITableDefinitions, IViewPort, IViewPortTableDefinition } from './DxfParser';
|
||||
export { IEntity, IPoint } from './entities/geomtry';
|
||||
export { I3DfaceEntity } from './entities/3dface';
|
||||
export { IArcEntity } from './entities/arc';
|
||||
export { IAttdefEntity } from './entities/attdef';
|
||||
export { ICircleEntity } from './entities/circle';
|
||||
export { IDimensionEntity } from './entities/dimension';
|
||||
export { IEllipseEntity } from './entities/ellipse';
|
||||
export { IInsertEntity } from './entities/insert';
|
||||
export { ILineEntity } from './entities/line';
|
||||
export { ILwpolylineEntity } from './entities/lwpolyline';
|
||||
export { IMtextEntity } from './entities/mtext';
|
||||
export { IPointEntity } from './entities/point';
|
||||
export { IPolylineEntity } from './entities/polyline';
|
||||
export { ISolidEntity } from './entities/solid';
|
||||
export { ISplineEntity } from './entities/spline';
|
||||
export { ITextEntity } from './entities/text';
|
||||
export { IVertexEntity } from './entities/vertex';
|
||||
export default DxfParser;
|
||||
3
dev/DWGViewer/libs/dxf-parser/index.js
Normal file
3
dev/DWGViewer/libs/dxf-parser/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import DxfParser from './DxfParser.js';
|
||||
export { default as DxfParser } from './DxfParser.js';
|
||||
export default DxfParser;
|
||||
Reference in New Issue
Block a user