dxf-json 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/.github/FUNDING.yml +1 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  3. package/.github/ISSUE_TEMPLATE/custom.md +10 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. package/.github/pull_request_template.md +23 -0
  6. package/.github/workflows/npm-publish.yml +55 -0
  7. package/.swcrc +8 -0
  8. package/LICENSE +674 -0
  9. package/README.md +567 -0
  10. package/jest.config.js +20 -0
  11. package/package.json +56 -0
  12. package/src/consts/block.ts +22 -0
  13. package/src/consts/color.ts +6 -0
  14. package/src/consts/config.ts +2 -0
  15. package/src/consts/dimension.ts +69 -0
  16. package/src/consts/hatch.ts +52 -0
  17. package/src/consts/header.ts +10 -0
  18. package/src/consts/index.ts +9 -0
  19. package/src/consts/lineweight.ts +5 -0
  20. package/src/consts/measurement.ts +4 -0
  21. package/src/consts/obscuredLineTypes.ts +21 -0
  22. package/src/consts/scene.ts +2 -0
  23. package/src/consts/viewport.ts +62 -0
  24. package/src/index.ts +6 -0
  25. package/src/parser/AutoCadColorIndex.ts +265 -0
  26. package/src/parser/DxfArrayScanner.ts +161 -0
  27. package/src/parser/DxfParser.ts +108 -0
  28. package/src/parser/ParseHelpers.ts +124 -0
  29. package/src/parser/blocks/blocks.test.ts +97 -0
  30. package/src/parser/blocks/index.ts +88 -0
  31. package/src/parser/blocks/types.ts +15 -0
  32. package/src/parser/entities/arc/index.ts +2 -0
  33. package/src/parser/entities/arc/parser.ts +67 -0
  34. package/src/parser/entities/arc/types.ts +13 -0
  35. package/src/parser/entities/attdef/consts.ts +12 -0
  36. package/src/parser/entities/attdef/index.ts +3 -0
  37. package/src/parser/entities/attdef/parser.ts +119 -0
  38. package/src/parser/entities/attdef/types.ts +19 -0
  39. package/src/parser/entities/attribute/consts.ts +6 -0
  40. package/src/parser/entities/attribute/index.ts +3 -0
  41. package/src/parser/entities/attribute/parser.ts +198 -0
  42. package/src/parser/entities/attribute/types.ts +31 -0
  43. package/src/parser/entities/circle/index.ts +2 -0
  44. package/src/parser/entities/circle/parser.ts +58 -0
  45. package/src/parser/entities/circle/types.ts +11 -0
  46. package/src/parser/entities/dimension/common.ts +98 -0
  47. package/src/parser/entities/dimension/index.ts +24 -0
  48. package/src/parser/entities/dimension/types.ts +65 -0
  49. package/src/parser/entities/ellipse/index.ts +2 -0
  50. package/src/parser/entities/ellipse/parser.ts +66 -0
  51. package/src/parser/entities/ellipse/types.ts +13 -0
  52. package/src/parser/entities/entities.test.ts +86 -0
  53. package/src/parser/entities/hatch/boundaryPathData/edge.ts +190 -0
  54. package/src/parser/entities/hatch/boundaryPathData/index.ts +27 -0
  55. package/src/parser/entities/hatch/boundaryPathData/polyline.ts +43 -0
  56. package/src/parser/entities/hatch/boundaryPathData/shared.ts +16 -0
  57. package/src/parser/entities/hatch/index.ts +189 -0
  58. package/src/parser/entities/hatch/patternData.ts +57 -0
  59. package/src/parser/entities/hatch/types/boundaryPath.ts +72 -0
  60. package/src/parser/entities/hatch/types/definitionLine.ts +14 -0
  61. package/src/parser/entities/hatch/types/hatch.ts +47 -0
  62. package/src/parser/entities/hatch/types/index.ts +3 -0
  63. package/src/parser/entities/index.ts +87 -0
  64. package/src/parser/entities/insert/index.ts +2 -0
  65. package/src/parser/entities/insert/parser.ts +106 -0
  66. package/src/parser/entities/insert/types.ts +19 -0
  67. package/src/parser/entities/leader/consts.ts +6 -0
  68. package/src/parser/entities/leader/index.ts +3 -0
  69. package/src/parser/entities/leader/parser.ts +119 -0
  70. package/src/parser/entities/leader/types.ts +24 -0
  71. package/src/parser/entities/line/index.ts +2 -0
  72. package/src/parser/entities/line/parser.ts +55 -0
  73. package/src/parser/entities/line/types.ts +11 -0
  74. package/src/parser/entities/lwpolyline/consts.ts +4 -0
  75. package/src/parser/entities/lwpolyline/index.ts +3 -0
  76. package/src/parser/entities/lwpolyline/parser.ts +122 -0
  77. package/src/parser/entities/lwpolyline/types.ts +21 -0
  78. package/src/parser/entities/mtext/consts.ts +5 -0
  79. package/src/parser/entities/mtext/index.ts +3 -0
  80. package/src/parser/entities/mtext/parser.ts +195 -0
  81. package/src/parser/entities/mtext/types.ts +34 -0
  82. package/src/parser/entities/point/index.ts +2 -0
  83. package/src/parser/entities/point/parser.ts +60 -0
  84. package/src/parser/entities/point/types.ts +10 -0
  85. package/src/parser/entities/polyline/consts.ts +17 -0
  86. package/src/parser/entities/polyline/index.ts +3 -0
  87. package/src/parser/entities/polyline/parser.ts +126 -0
  88. package/src/parser/entities/polyline/types.ts +20 -0
  89. package/src/parser/entities/section/index.ts +2 -0
  90. package/src/parser/entities/section/parser.ts +104 -0
  91. package/src/parser/entities/section/types.ts +20 -0
  92. package/src/parser/entities/shared.ts +166 -0
  93. package/src/parser/entities/solid/index.ts +2 -0
  94. package/src/parser/entities/solid/parser.ts +56 -0
  95. package/src/parser/entities/solid/types.ts +10 -0
  96. package/src/parser/entities/spline/consts.ts +8 -0
  97. package/src/parser/entities/spline/index.ts +3 -0
  98. package/src/parser/entities/spline/parser.ts +121 -0
  99. package/src/parser/entities/spline/types.ts +22 -0
  100. package/src/parser/entities/text/consts.ts +21 -0
  101. package/src/parser/entities/text/index.ts +3 -0
  102. package/src/parser/entities/text/parser.ts +117 -0
  103. package/src/parser/entities/text/types.ts +21 -0
  104. package/src/parser/entities/vertex/consts.ts +10 -0
  105. package/src/parser/entities/vertex/index.ts +3 -0
  106. package/src/parser/entities/vertex/parser.ts +90 -0
  107. package/src/parser/entities/vertex/types.ts +17 -0
  108. package/src/parser/entities/viewport/index.ts +178 -0
  109. package/src/parser/entities/viewport/types.ts +58 -0
  110. package/src/parser/filterDummyBlocks.ts +49 -0
  111. package/src/parser/header/index.ts +30 -0
  112. package/src/parser/objects/common.ts +55 -0
  113. package/src/parser/objects/dictionary.ts +61 -0
  114. package/src/parser/objects/index.ts +45 -0
  115. package/src/parser/objects/layout.ts +136 -0
  116. package/src/parser/objects/plotSettings.ts +231 -0
  117. package/src/parser/objects/treefy.ts +53 -0
  118. package/src/parser/objects/types.ts +17 -0
  119. package/src/parser/shared/index.ts +21 -0
  120. package/src/parser/shared/parsePoint.ts +37 -0
  121. package/src/parser/shared/parserGenerator.test.ts +164 -0
  122. package/src/parser/shared/parserGenerator.ts +180 -0
  123. package/src/parser/shared/xdata/index.ts +3 -0
  124. package/src/parser/shared/xdata/interpreter.test.ts +85 -0
  125. package/src/parser/shared/xdata/interpreter.ts +65 -0
  126. package/src/parser/shared/xdata/parser.test.ts +66 -0
  127. package/src/parser/shared/xdata/parser.ts +140 -0
  128. package/src/parser/shared/xdata/types.ts +22 -0
  129. package/src/parser/tables/blockRecord/index.ts +2 -0
  130. package/src/parser/tables/blockRecord/parser.ts +49 -0
  131. package/src/parser/tables/blockRecord/types.ts +11 -0
  132. package/src/parser/tables/dimStyle/consts.ts +428 -0
  133. package/src/parser/tables/dimStyle/index.ts +3 -0
  134. package/src/parser/tables/dimStyle/parser.ts +37 -0
  135. package/src/parser/tables/dimStyle/types.ts +164 -0
  136. package/src/parser/tables/index.ts +2 -0
  137. package/src/parser/tables/layer/index.ts +2 -0
  138. package/src/parser/tables/layer/parser.ts +58 -0
  139. package/src/parser/tables/layer/types.ts +14 -0
  140. package/src/parser/tables/ltype/consts.ts +6 -0
  141. package/src/parser/tables/ltype/index.ts +3 -0
  142. package/src/parser/tables/ltype/parser.ts +110 -0
  143. package/src/parser/tables/ltype/types.ts +23 -0
  144. package/src/parser/tables/parser.ts +100 -0
  145. package/src/parser/tables/shared.ts +32 -0
  146. package/src/parser/tables/style/index.ts +2 -0
  147. package/src/parser/tables/style/parser.ts +70 -0
  148. package/src/parser/tables/style/types.ts +15 -0
  149. package/src/parser/tables/types.ts +15 -0
  150. package/src/parser/tables/vport/index.ts +2 -0
  151. package/src/parser/tables/vport/parser.ts +205 -0
  152. package/src/parser/tables/vport/types.ts +48 -0
  153. package/src/parser/types.ts +30 -0
  154. package/src/types/color.ts +5 -0
  155. package/src/types/dxfHeader.ts +21 -0
  156. package/src/types/entity.ts +7 -0
  157. package/src/types/index.ts +30 -0
  158. package/src/utils/binarySearch.ts +20 -0
  159. package/src/utils/disjointSet.ts +52 -0
  160. package/src/utils/flooding.ts +37 -0
  161. package/src/utils/functional.ts +124 -0
  162. package/src/utils/graph.ts +53 -0
  163. package/src/utils/index.ts +102 -0
  164. package/src/utils/queue.ts +77 -0
  165. package/src/utils/triangle.ts +28 -0
  166. package/tsconfig.json +34 -0
  167. package/webpack.config.js +46 -0
@@ -0,0 +1,108 @@
1
+ import DxfArrayScanner from './DxfArrayScanner';
2
+ import { parseHeader } from './header';
3
+ import { parseTables } from './tables';
4
+ import { parseBlocks } from './blocks';
5
+ import { parseEntities } from './entities';
6
+ import { parseObjects } from './objects';
7
+ import { isMatched } from './shared';
8
+ import { filterDummyBlocks } from './filterDummyBlocks';
9
+ import type { ParsedDxf } from './types';
10
+ import { Readable } from 'readable-stream';
11
+ export default class DxfParser {
12
+ parseSync(dxfString: string) {
13
+ const dxfLinesArray = dxfString.split(/\r\n|\r|\n/g);
14
+ const scanner = new DxfArrayScanner(dxfLinesArray);
15
+ if (!scanner.hasNext()) {
16
+ throw Error('Empty file');
17
+ }
18
+
19
+ return this.parseAll(scanner);
20
+ }
21
+ parseStream(stream: Readable) {
22
+ let dxfString = "";
23
+ const self = this;
24
+ return new Promise<ParsedDxf>((res, rej) => {
25
+ stream.on('data', (chunk) => {
26
+ dxfString += chunk;
27
+ });
28
+ stream.on('end', () => {
29
+ try {
30
+ const dxfLinesArray = dxfString.split(/\r\n|\r|\n/g);
31
+ const scanner = new DxfArrayScanner(dxfLinesArray);
32
+ if (!scanner.hasNext()) {
33
+ throw Error('Empty file');
34
+ }
35
+ res(self.parseAll(scanner));
36
+ } catch (err) {
37
+ rej(err);
38
+ }
39
+ });
40
+ stream.on('error', (err) => {
41
+ rej(err);
42
+ });
43
+ });
44
+ }
45
+
46
+ async parseFromUrl(url: string, encoding = "utf-8", init?: RequestInit | undefined) {
47
+ const response = await fetch(url, init)
48
+
49
+ if (!response.body) return null;
50
+
51
+ const reader = response.body.getReader()
52
+ let buffer = ""
53
+ let decoder = new TextDecoder(encoding)
54
+
55
+ while (true) {
56
+ const { done, value } = await reader.read()
57
+ if (done) {
58
+ buffer += decoder.decode(new ArrayBuffer(0), { stream: false })
59
+ break
60
+ }
61
+ buffer += decoder.decode(value, { stream: true })
62
+ }
63
+ return this.parseSync(buffer)
64
+ }
65
+
66
+
67
+ parseAll(scanner: DxfArrayScanner) {
68
+ const dxf: ParsedDxf = {
69
+ // @ts-ignore
70
+ header: {},
71
+ blocks: {},
72
+ entities: [],
73
+ tables: {},
74
+ objects: {
75
+ byName: {},
76
+ byTree: undefined,
77
+ },
78
+ };
79
+ let curr = scanner.next();
80
+
81
+ while (!isMatched(curr, 0, 'EOF')) {
82
+ if (isMatched(curr, 0, 'SECTION')) {
83
+ curr = scanner.next();
84
+
85
+ if (isMatched(curr, 2, 'HEADER')) {
86
+ curr = scanner.next();
87
+ dxf.header = parseHeader(curr, scanner);
88
+ } else if (isMatched(curr, 2, 'BLOCKS')) {
89
+ curr = scanner.next();
90
+ dxf.blocks = parseBlocks(curr, scanner);
91
+ }
92
+ else if (isMatched(curr, 2, 'ENTITIES')) {
93
+ curr = scanner.next();
94
+ dxf.entities = parseEntities(curr, scanner);
95
+ }
96
+ else if (isMatched(curr, 2, 'TABLES')) {
97
+ curr = scanner.next();
98
+ dxf.tables = parseTables(curr, scanner);
99
+ } else if (isMatched(curr, 2, 'OBJECTS')) {
100
+ curr = scanner.next();
101
+ dxf.objects = parseObjects(curr, scanner);
102
+ }
103
+ }
104
+ curr = scanner.next();
105
+ }
106
+ return filterDummyBlocks(dxf);
107
+ }
108
+ }
@@ -0,0 +1,124 @@
1
+ import AUTO_CAD_COLOR_INDEX from './AutoCadColorIndex';
2
+ import DxfArrayScanner, { ScannerGroup } from './DxfArrayScanner';
3
+ import { CommonDxfEntity, skipApplicationGroups } from './entities/shared';
4
+ import { ViewportEntity } from './entities/viewport/types';
5
+ import { isMatched } from './shared';
6
+ import { parseXData } from './shared/xdata';
7
+
8
+ /**
9
+ * Returns the truecolor value of the given AutoCad color index value
10
+ * @param {import('../types').ColorIndex} index
11
+ * @return {import('../types').ColorInstance} truecolor value as a number
12
+ */
13
+ export function getAcadColor(index: number) {
14
+ return AUTO_CAD_COLOR_INDEX[index];
15
+ }
16
+
17
+ /** Some entities may contain embedded object which is started by group 101. All the rest data until
18
+ * end of entity should not be interpreted as entity attributes. There is no documentation for this
19
+ * feature.
20
+ * @param scanner
21
+ */
22
+ export function skipEmbeddedObject(scanner: DxfArrayScanner) {
23
+ /* Ensure proper start group. */
24
+ scanner.rewind();
25
+ let curr = scanner.next();
26
+ if (curr.code !== 101) {
27
+ throw new Error('Bad call for skipEmbeddedObject()');
28
+ }
29
+ do {
30
+ curr = scanner.next();
31
+ } while (curr.code !== 0);
32
+ scanner.rewind();
33
+ }
34
+
35
+ /**
36
+ * Attempts to parse codes common to all entities. Returns true if the group
37
+ * was handled by this function.
38
+ * @param {*} entity - the entity currently being parsed
39
+ * @param {*} curr - the current group being parsed
40
+ */
41
+ export function checkCommonEntityProperties(entity: CommonDxfEntity, curr: ScannerGroup, scanner: DxfArrayScanner) {
42
+ if (isMatched(curr, 102)) {
43
+ skipApplicationGroups(curr, scanner);
44
+ return true;
45
+ }
46
+
47
+ switch (curr.code) {
48
+ case 0:
49
+ entity.type = curr.value as string;
50
+ break;
51
+ case 5:
52
+ entity.handle = curr.value as string;
53
+ break;
54
+ case 330:
55
+ if (!entity.ownerDictionarySoftId) {
56
+ entity.ownerDictionarySoftId = curr.value;
57
+ } else {
58
+ entity.ownerBlockRecordSoftId = curr.value;
59
+ }
60
+ break;
61
+ case 360:
62
+ entity.ownerdictionaryHardId = curr.value;
63
+ break;
64
+ case 67:
65
+ entity.isInPaperSpace = !!curr.value;
66
+ break;
67
+ case 8:
68
+ entity.layer = curr.value;
69
+ break;
70
+ // Code 6 of an entity indicates inheritance of properties (eg. color).
71
+ // BYBLOCK means inherits from block
72
+ // BYLAYER (default) mean inherits from layer
73
+ case 6:
74
+ entity.lineType = curr.value;
75
+ break;
76
+ case 347:
77
+ entity.materialObjectHardId = curr.value;
78
+ break;
79
+ case 62: // Acad Index Color. 0 inherits ByBlock. 256 inherits ByLayer. Default is bylayer
80
+ entity.colorIndex = curr.value;
81
+ entity.color = getAcadColor(Math.abs(curr.value));
82
+ break;
83
+ case 370:
84
+ //From https://www.woutware.com/Forum/Topic/955/lineweight?returnUrl=%2FForum%2FUserPosts%3FuserId%3D478262319
85
+ // An integer representing 100th of mm, must be one of the following values:
86
+ // 0, 5, 9, 13, 15, 18, 20, 25, 30, 35, 40, 50, 53, 60, 70, 80, 90, 100, 106, 120, 140, 158, 200, 211.
87
+ // -3 = STANDARD, -2 = BYLAYER, -1 = BYBLOCK
88
+ entity.lineweight = curr.value;
89
+ break;
90
+ case 48:
91
+ entity.lineTypeScale = curr.value;
92
+ break;
93
+ case 60:
94
+ entity.isVisible = !!curr.value;
95
+ break;
96
+ case 92:
97
+ entity.proxyByte = curr.value;
98
+ break;
99
+ case 310:
100
+ entity.proxyEntity = curr.value;
101
+ break;
102
+ case 100:
103
+ // general한 목적으로는 현 구조로 여기서 처리 불가
104
+ break;
105
+ case 420:
106
+ entity.color = curr.value;
107
+ break;
108
+ case 430:
109
+ entity.transparency = curr.value;
110
+ break;
111
+ case 390:
112
+ entity.plotStyleHardId = curr.value;
113
+ break;
114
+ case 284:
115
+ entity.shadowMode = curr.value;
116
+ break;
117
+ case 1001:
118
+ entity.xdata = parseXData(curr, scanner);
119
+ break;
120
+ default:
121
+ return false;
122
+ }
123
+ return true;
124
+ }
@@ -0,0 +1,97 @@
1
+ import DxfArrayScanner from '../DxfArrayScanner';
2
+ import { parseBlock, parseBlocks } from '.';
3
+ import { isMatched } from '../shared';
4
+
5
+ const content = ` 0
6
+ BLOCK
7
+ 2
8
+ block-0
9
+ 100
10
+ AcDbEntity
11
+ 0
12
+ ENDBLK
13
+ 5
14
+ endblk-0
15
+ 100
16
+ AcDbEntity
17
+ 100
18
+ AcDbBlockEnd
19
+ 0
20
+ BLOCK
21
+ 2
22
+ block-1
23
+ 100
24
+ AcDbEntity
25
+ 0
26
+ ENDBLK
27
+ 5
28
+ endblk-1
29
+ 100
30
+ AcDbEntity
31
+ 100
32
+ AcDbBlockEnd
33
+ 0
34
+ ENDSEC
35
+ 0
36
+ SECTION
37
+ 0
38
+ EOF
39
+ `.split('\n');
40
+
41
+ describe('BLOCK section', () => {
42
+ describe('parseBlock', () => {
43
+ it('parseBlock 한 번 실행하고 나면 scanner.next()가 다음 BLOCK의 <0, BLOCK>를 반환한다.', () => {
44
+ const scanner = new DxfArrayScanner(content);
45
+ let curr = scanner.next();
46
+
47
+ curr = scanner.next(); // 집어넣을 때 이미 <0, BLOCK>을 소모한 상태여야 함
48
+ parseBlock(curr, scanner);
49
+
50
+ curr = scanner.next();
51
+
52
+ expect(curr.code).toBe(0);
53
+ expect(curr.value).toBe('BLOCK');
54
+ });
55
+
56
+ it('parseBlock은 모든 BLOCK을 소모하여야 한다.', () => {
57
+ const scanner = new DxfArrayScanner(content);
58
+ let curr = scanner.next();
59
+
60
+ curr = scanner.next();
61
+ const block0 = parseBlock(curr, scanner);
62
+
63
+ curr = scanner.next();
64
+ expect(isMatched(curr, 0, 'BLOCK')).toBeTruthy();
65
+
66
+ curr = scanner.next();
67
+ const block1 = parseBlock(curr, scanner);
68
+
69
+ expect(block0.name).toBe('block-0');
70
+ expect(block1.name).toBe('block-1');
71
+ });
72
+ });
73
+
74
+ describe('parseBlocks', () => {
75
+ it('parseBlocks 한 번 실행하고 나면 scanner.next()가 다음 SECTION의 <0, SECTION>을 반환한다.', () => {
76
+ const scanner = new DxfArrayScanner(content);
77
+ let curr = scanner.next();
78
+
79
+ parseBlocks(curr, scanner);
80
+
81
+ curr = scanner.next();
82
+
83
+ expect(curr.code).toBe(0);
84
+ expect(curr.value).toBe('SECTION');
85
+ });
86
+
87
+ it('parseBlocks는 모든 BLOCK을 반환해야 한다.', () => {
88
+ const scanner = new DxfArrayScanner(content);
89
+ let curr = scanner.next();
90
+
91
+ const blocks = parseBlocks(curr, scanner);
92
+
93
+ expect(blocks['block-0']).toMatchObject({ name: 'block-0' });
94
+ expect(blocks['block-1']).toMatchObject({ name: 'block-1' });
95
+ });
96
+ });
97
+ });
@@ -0,0 +1,88 @@
1
+ import type DxfArrayScanner from '../DxfArrayScanner';
2
+ import type { ScannerGroup } from '../DxfArrayScanner';
3
+ import { parseEntities } from '../entities';
4
+ import { parsePoint } from '../shared/parsePoint';
5
+ import { ensureHandle, isMatched } from '../shared';
6
+
7
+ export function parseBlocks(curr: ScannerGroup, scanner: DxfArrayScanner) {
8
+ let blocks: any = {};
9
+
10
+ while (!isMatched(curr, 0, 'EOF')) {
11
+ if (isMatched(curr, 0, 'ENDSEC')) {
12
+ break;
13
+ }
14
+
15
+ if (isMatched(curr, 0, 'BLOCK')) {
16
+ curr = scanner.next();
17
+ const block = parseBlock(curr, scanner);
18
+
19
+ ensureHandle(block);
20
+ if (block.name) {
21
+ blocks[block.name] = block;
22
+ }
23
+ }
24
+
25
+ curr = scanner.next();
26
+ }
27
+ return blocks;
28
+ }
29
+
30
+ export function parseBlock(curr: ScannerGroup, scanner: DxfArrayScanner) {
31
+ let block: any = {};
32
+
33
+ while (!isMatched(curr, 0, 'EOF')) {
34
+ if (isMatched(curr, 0, 'ENDBLK')) {
35
+ // 당장 ENDBLK 파싱이 없어서 임시로 대충 소비함
36
+ // 소비 안하면 ENTITY에 딸려들어가서 문제 생김
37
+ curr = scanner.next();
38
+ while (!isMatched(curr, 0, 'EOF')) {
39
+ if (isMatched(curr, 100, 'AcDbBlockEnd')) {
40
+ return block;
41
+ }
42
+ curr = scanner.next();
43
+ }
44
+ break;
45
+ }
46
+
47
+ switch (curr.code) {
48
+ case 1:
49
+ block.xrefPath = curr.value;
50
+ break;
51
+ case 2:
52
+ block.name = curr.value;
53
+ break;
54
+ case 3:
55
+ block.name2 = curr.value;
56
+ break;
57
+ case 5:
58
+ block.handle = curr.value;
59
+ break;
60
+ case 8:
61
+ block.layer = curr.value;
62
+ break;
63
+ case 10:
64
+ block.position = parsePoint(scanner);
65
+ break;
66
+ case 67:
67
+ block.paperSpace = curr.value && curr.value == 1 ? true : false;
68
+ break;
69
+ case 70:
70
+ if (curr.value !== 0) {
71
+ block.type = curr.value;
72
+ }
73
+ break;
74
+ case 100:
75
+ // ignore class markers
76
+ break;
77
+ case 330:
78
+ block.ownerHandle = curr.value;
79
+ break;
80
+ case 0:
81
+ block.entities = parseEntities(curr, scanner);
82
+ break;
83
+ }
84
+
85
+ curr = scanner.next();
86
+ }
87
+ return block;
88
+ }
@@ -0,0 +1,15 @@
1
+ import type { Point3D } from '../../types';
2
+ import type { CommonDxfEntity } from '../entities/shared';
3
+
4
+ export interface DxfBlock {
5
+ type: number; // bit flag of BlockTypeFlag
6
+ name: string;
7
+ name2: string;
8
+ handle: string;
9
+ ownerHandle: string;
10
+ layer: string;
11
+ position: Point3D;
12
+ paperSpace: boolean;
13
+ xrefPath: string;
14
+ entities?: CommonDxfEntity[];
15
+ }
@@ -0,0 +1,2 @@
1
+ export * from './types';
2
+ export * from './parser';
@@ -0,0 +1,67 @@
1
+ import type DxfArrayScanner from '../../DxfArrayScanner';
2
+ import type { ScannerGroup } from '../../DxfArrayScanner';
3
+ import {
4
+ createParser,
5
+ DXFParserSnippet,
6
+ Identity,
7
+ PointParser,
8
+ } from '../../shared/parserGenerator';
9
+ import { CommonEntitySnippets } from '../shared';
10
+
11
+ const DefaultArcEntity = {
12
+ extrusionDirection: { x: 0, y: 0, z: 1 },
13
+ };
14
+
15
+ const ArcEntityParserSnippets: DXFParserSnippet[] = [
16
+ {
17
+ code: 210,
18
+ name: 'extrusionDirection',
19
+ parser: PointParser,
20
+ },
21
+ {
22
+ code: 51,
23
+ name: 'endAngle',
24
+ parser: Identity,
25
+ },
26
+ {
27
+ code: 50,
28
+ name: 'startAngle',
29
+ parser: Identity,
30
+ },
31
+ {
32
+ code: 100,
33
+ name: 'subclassMarker',
34
+ parser: Identity,
35
+ },
36
+ {
37
+ code: 40,
38
+ name: 'radius',
39
+ parser: Identity,
40
+ },
41
+ {
42
+ code: 10,
43
+ name: 'center',
44
+ parser: PointParser,
45
+ },
46
+ {
47
+ code: 39,
48
+ name: 'thickness',
49
+ parser: Identity,
50
+ },
51
+ {
52
+ // skip for AcDbCircle
53
+ code: 100,
54
+ },
55
+ ...CommonEntitySnippets,
56
+ ];
57
+
58
+ export class ArcEntityParser {
59
+ static ForEntityName = 'ARC';
60
+ private parser = createParser(ArcEntityParserSnippets, DefaultArcEntity);
61
+
62
+ parseEntity(scanner: DxfArrayScanner, curr: ScannerGroup) {
63
+ const entity = {} as any;
64
+ this.parser(curr, scanner, entity);
65
+ return entity;
66
+ }
67
+ }
@@ -0,0 +1,13 @@
1
+ import type { Point3D } from '../../../types';
2
+ import type { CommonDxfEntity } from '../shared';
3
+
4
+ export interface ArcEntity extends CommonDxfEntity {
5
+ type: 'ARC';
6
+ subclassMarker: 'AcDbArc';
7
+ thickness: number;
8
+ center: Point3D;
9
+ radius: number;
10
+ startAngle: number;
11
+ endAngle: number;
12
+ extrusionDirection: Point3D;
13
+ }
@@ -0,0 +1,12 @@
1
+ export enum AttributeFlag {
2
+ NONE = 0,
3
+ INVISIBLE = 1,
4
+ CONSTANT = 2,
5
+ VERIFICATION_REQUIRED = 4,
6
+ PRESET = 8,
7
+ }
8
+
9
+ export enum AttDefMTextFlag {
10
+ MULTILINE = 2,
11
+ CONSTANT_MULTILINE = 4,
12
+ }
@@ -0,0 +1,3 @@
1
+ export * from './types';
2
+ export * from './consts';
3
+ export * from './parser';
@@ -0,0 +1,119 @@
1
+ import type DxfArrayScanner from '../../DxfArrayScanner';
2
+ import type { ScannerGroup } from '../../DxfArrayScanner';
3
+ import {
4
+ createParser,
5
+ DXFParserSnippet,
6
+ Identity,
7
+ PointParser,
8
+ ToBoolean,
9
+ } from '../../shared/parserGenerator';
10
+ import { DefaultTextEntity, TextEntityParserSnippets } from '../text';
11
+ import type { AttdefEntity } from './types';
12
+
13
+ const DefaultAttDefEntity = {
14
+ ...DefaultTextEntity,
15
+ };
16
+
17
+ const AttDefEntityParserSnippets: DXFParserSnippet[] = [
18
+ {
19
+ code: 2, // tag. 왜 다시 나오는지 모르겠음
20
+ },
21
+ {
22
+ code: 40,
23
+ name: 'annotationScale',
24
+ parser: Identity,
25
+ },
26
+ {
27
+ code: 10,
28
+ name: 'alignmentPoint',
29
+ parser: PointParser,
30
+ },
31
+ {
32
+ code: 340,
33
+ name: 'secondaryAttributesHardIds',
34
+ isMultiple: true,
35
+ parser: Identity,
36
+ },
37
+ {
38
+ code: 70,
39
+ name: 'numberOfSecondaryAttributes',
40
+ parser: Identity,
41
+ },
42
+ {
43
+ code: 70,
44
+ name: 'isReallyLocked',
45
+ parser: ToBoolean,
46
+ },
47
+ {
48
+ code: 70,
49
+ name: 'mtextFlag',
50
+ parser: Identity,
51
+ },
52
+ {
53
+ code: 280,
54
+ name: 'isDuplicatedRecord',
55
+ parser: ToBoolean,
56
+ },
57
+ {
58
+ code: 100, // AcDbXrecord, skip
59
+ },
60
+ {
61
+ code: 280,
62
+ name: 'isLocked',
63
+ parser: ToBoolean,
64
+ },
65
+ {
66
+ code: 74,
67
+ name: 'valign',
68
+ parser: Identity,
69
+ },
70
+ {
71
+ code: 73, // field length, useless
72
+ },
73
+ {
74
+ code: 70,
75
+ name: 'attributeFlag',
76
+ parser: Identity,
77
+ },
78
+ {
79
+ code: 2,
80
+ name: 'tag',
81
+ parser: Identity,
82
+ },
83
+ {
84
+ code: 3,
85
+ name: 'prompt',
86
+ parser: Identity,
87
+ },
88
+ {
89
+ code: 280, // version number, always 0, useless
90
+ },
91
+ {
92
+ code: 100,
93
+ name: 'subclassMarker',
94
+ parser: Identity,
95
+ },
96
+ ...TextEntityParserSnippets.slice(2),
97
+ ];
98
+
99
+ export class AttDefEntityParser {
100
+ static ForEntityName = 'ATTDEF';
101
+ private parser = createParser(
102
+ AttDefEntityParserSnippets,
103
+ DefaultAttDefEntity,
104
+ );
105
+
106
+ parseEntity(scanner: DxfArrayScanner, curr: ScannerGroup) {
107
+ const entity = {} as any;
108
+ this.parser(curr, scanner, entity);
109
+ return entity as AttdefEntity;
110
+ }
111
+ }
112
+
113
+ // entity.invisible = !!(curr.value & 0x01);
114
+ // entity.constant = !!(curr.value & 0x02);
115
+ // entity.verificationRequired = !!(curr.value & 0x04);
116
+ // entity.preset = !!(curr.value & 0x08);
117
+
118
+ // entity.backwards = !!(curr.value & 0x02);
119
+ // entity.mirrored = !!(curr.value & 0x04);
@@ -0,0 +1,19 @@
1
+ import type { Point3D } from '../../../types';
2
+ import type { TextEntity } from '../text';
3
+
4
+ export interface AttdefEntity
5
+ extends Omit<TextEntity, 'type' | 'subclassMarker'> {
6
+ type: 'ATTDEF';
7
+ subclassMarker: 'AcDbAttributeDefinition';
8
+ prompt: string;
9
+ tag: string;
10
+ attributeFlag: number;
11
+ isLocked: boolean;
12
+ isDuplicatedRecord: boolean;
13
+ mtextFlag: number;
14
+ isReallyLocked: boolean;
15
+ numberOfSecondaryAttributes: number;
16
+ secondaryAttributesHardIds: string[];
17
+ alignmentPoint: Point3D;
18
+ annotationScale: number;
19
+ }
@@ -0,0 +1,6 @@
1
+ export enum AttributeFlag {
2
+ INVISIBLE = 1,
3
+ CONSTANT = 2,
4
+ REQUIRE_VERIFICATION = 4,
5
+ PRESET = 8,
6
+ }
@@ -0,0 +1,3 @@
1
+ export * from './types';
2
+ export * from './consts';
3
+ export * from './parser';