@design-core/core 0.0.1 → 0.0.3

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 (254) hide show
  1. package/.eslintrc.json +14 -7
  2. package/.github/workflows/DesignCoreQA.yml +3 -1
  3. package/README.md +11 -4
  4. package/TODO.md +19 -0
  5. package/core/core/core.js +49 -42
  6. package/core/designCore.js +61 -2
  7. package/core/dimensions/alignedDimension.js +142 -0
  8. package/core/dimensions/angularDimension.js +550 -0
  9. package/core/dimensions/baseCircularDimension.js +244 -0
  10. package/core/dimensions/baseDimension.js +558 -0
  11. package/core/dimensions/baseLinearDimension.js +371 -0
  12. package/core/dimensions/diametricDimension.js +82 -0
  13. package/core/dimensions/dimension.js +298 -0
  14. package/core/dimensions/linearDimension.js +29 -0
  15. package/core/dimensions/radialDimension.js +78 -0
  16. package/core/dimensions/rotatedDimension.js +167 -0
  17. package/core/entities/arc.js +314 -60
  18. package/core/entities/arctext.js +642 -0
  19. package/core/entities/basePolyline.js +553 -94
  20. package/core/entities/circle.js +181 -54
  21. package/core/entities/entity.js +154 -74
  22. package/core/entities/hatch.js +807 -0
  23. package/core/entities/insert.js +200 -39
  24. package/core/entities/line.js +196 -134
  25. package/core/entities/lwpolyline.js +21 -44
  26. package/core/entities/point.js +194 -29
  27. package/core/entities/polyline.js +54 -7
  28. package/core/entities/rectangle.js +43 -13
  29. package/core/entities/solid.js +43 -6
  30. package/core/entities/text.js +324 -181
  31. package/core/lib/boundingBox.js +73 -13
  32. package/core/lib/canvas.js +256 -65
  33. package/core/lib/clipboard.js +198 -0
  34. package/core/lib/colour.js +144 -0
  35. package/core/lib/colours.js +367 -301
  36. package/core/lib/commandLine.js +16 -28
  37. package/core/lib/commandManager.js +115 -58
  38. package/core/lib/constants.js +23 -0
  39. package/core/lib/dxf/dxf.js +249 -34
  40. package/core/lib/dxf/dxfFile.js +23 -38
  41. package/core/lib/dxf/dxfIterator.js +17 -5
  42. package/core/lib/dxf/dxfRead.js +23 -7
  43. package/core/lib/dxf/dxfWrite.js +39 -129
  44. package/core/lib/dxf/handleManager.js +97 -0
  45. package/core/lib/dxf/sections/blocks.js +16 -2
  46. package/core/lib/dxf/sections/entities.js +17 -3
  47. package/core/lib/dxf/sections/header.js +10 -1
  48. package/core/lib/dxf/sections/objects.js +36 -0
  49. package/core/lib/dxf/sections/section.js +43 -5
  50. package/core/lib/dxf/sections/tables.js +17 -3
  51. package/core/lib/entityManager.js +178 -0
  52. package/core/lib/fileio.js +14 -4
  53. package/core/lib/headers.js +229 -0
  54. package/core/lib/input.js +46 -0
  55. package/core/lib/inputManager.js +199 -194
  56. package/core/lib/intersect.js +341 -468
  57. package/core/lib/logging.js +25 -1
  58. package/core/lib/matrix.js +6 -8
  59. package/core/lib/mouse.js +24 -79
  60. package/core/lib/patterns.js +690 -0
  61. package/core/lib/promptOptions.js +133 -0
  62. package/core/lib/scene.js +71 -174
  63. package/core/lib/selectionManager.js +74 -48
  64. package/core/lib/selectionWindow.js +24 -10
  65. package/core/lib/settings.js +18 -11
  66. package/core/lib/snapping.js +129 -21
  67. package/core/lib/stateManager.js +288 -0
  68. package/core/lib/strings.js +57 -5
  69. package/core/lib/utils.js +95 -11
  70. package/core/objects/dictionary.js +43 -0
  71. package/core/objects/dictionaryManager.js +80 -0
  72. package/core/properties/dimType.js +117 -0
  73. package/core/properties/flags.js +66 -0
  74. package/core/properties/property.js +26 -0
  75. package/core/properties/propertyManager.js +65 -19
  76. package/core/tables/appId.js +31 -0
  77. package/core/tables/appIdManager.js +44 -0
  78. package/core/tables/block.js +323 -0
  79. package/core/tables/blockManager.js +48 -0
  80. package/core/tables/blockRecord.js +29 -0
  81. package/core/tables/blockRecordManager.js +37 -0
  82. package/core/tables/dimStyle.js +627 -0
  83. package/core/tables/dimStyleManager.js +187 -0
  84. package/core/tables/endblk.js +28 -0
  85. package/core/tables/layer.js +219 -0
  86. package/core/tables/layerManager.js +47 -0
  87. package/core/tables/ltype.js +85 -0
  88. package/core/tables/ltypeManager.js +65 -0
  89. package/core/tables/style.js +145 -0
  90. package/core/tables/styleManager.js +55 -0
  91. package/core/tables/styleManagerBase.js +110 -0
  92. package/core/tables/tableManagerBase.js +354 -0
  93. package/core/tables/ucs.js +28 -0
  94. package/core/tables/ucsManager.js +44 -0
  95. package/core/tables/view.js +28 -0
  96. package/core/tables/viewManager.js +44 -0
  97. package/core/tables/vport.js +70 -0
  98. package/core/tables/vportManager.js +65 -0
  99. package/core/tools/chamfer.js +343 -0
  100. package/core/tools/chamferFilletBase.js +162 -0
  101. package/core/tools/copy.js +68 -40
  102. package/core/tools/copybase.js +65 -0
  103. package/core/tools/copyclip.js +59 -0
  104. package/core/tools/cornerEntity.js +138 -0
  105. package/core/tools/cutclip.js +72 -0
  106. package/core/tools/distance.js +37 -9
  107. package/core/tools/erase.js +43 -13
  108. package/core/tools/explode.js +117 -0
  109. package/core/tools/extend.js +71 -32
  110. package/core/tools/fillet.js +336 -0
  111. package/core/tools/identify.js +33 -6
  112. package/core/tools/matchProp.js +106 -0
  113. package/core/tools/mirror.js +141 -0
  114. package/core/tools/move.js +65 -32
  115. package/core/tools/offset.js +321 -0
  116. package/core/tools/pan.js +54 -0
  117. package/core/tools/pasteclip.js +93 -0
  118. package/core/tools/purge.js +90 -0
  119. package/core/tools/rotate.js +105 -70
  120. package/core/tools/scale.js +166 -0
  121. package/core/tools/tool.js +14 -4
  122. package/core/tools/trim.js +71 -32
  123. package/core/tools/zoom.js +152 -0
  124. package/package.json +3 -305
  125. package/test/dimensions/alignedDimension.test.js +211 -0
  126. package/test/dimensions/angularDimension.test.js +243 -0
  127. package/test/dimensions/baseDimension.test.js +239 -0
  128. package/test/dimensions/diametricDimension.test.js +203 -0
  129. package/test/dimensions/dimension.test.js +102 -0
  130. package/test/dimensions/radialDimension.test.js +203 -0
  131. package/test/dimensions/rotatedDimension.test.js +224 -0
  132. package/test/entities/arc.test.js +463 -41
  133. package/test/entities/arctext.test.js +329 -0
  134. package/test/entities/basePolyline.test.js +459 -10
  135. package/test/entities/circle.test.js +312 -7
  136. package/test/entities/entity.test.js +28 -9
  137. package/test/entities/hatch.test.js +606 -0
  138. package/test/entities/insert.test.js +90 -0
  139. package/test/entities/line.test.js +182 -6
  140. package/test/entities/point.test.js +375 -37
  141. package/test/entities/solid.test.js +156 -0
  142. package/test/entities/text.test.js +533 -7
  143. package/test/integration/exportIntegration.reference.dxf +1706 -0
  144. package/test/integration/exportIntegration.test.js +186 -0
  145. package/test/integration/importExportIntegration.test.js +126 -0
  146. package/test/integration/intersectionIntegration.test.js +880 -0
  147. package/test/integration/userInputIntegration.reference.dxf +1410 -0
  148. package/test/integration/userInputIntegration.test.js +269 -0
  149. package/test/lib/boundingBox.test.js +26 -2
  150. package/test/lib/canvas.test.js +613 -5
  151. package/test/lib/clipboard.test.js +70 -0
  152. package/test/lib/colour.test.js +114 -0
  153. package/test/lib/colours.test.js +63 -18
  154. package/test/lib/commandLine.test.js +159 -22
  155. package/test/lib/commandManager.test.js +4 -4
  156. package/test/lib/constants.test.js +9 -0
  157. package/test/lib/dxf/dxfFile.test.js +6 -2
  158. package/test/lib/dxf/dxfIterator.test.js +1 -1
  159. package/test/lib/dxf/dxfWrite.test.js +173 -0
  160. package/test/lib/dxf/handleManager.test.js +137 -0
  161. package/test/lib/dxf/sections/blocks.test.js +5 -5
  162. package/test/lib/dxf/sections/entities.test.js +4 -4
  163. package/test/lib/dxf/sections/header.test.js +18 -4
  164. package/test/lib/dxf/sections/objects.test.js +132 -0
  165. package/test/lib/dxf/sections/section.test.js +29 -29
  166. package/test/lib/dxf/sections/tables.test.js +3 -3
  167. package/test/lib/entityManager.test.js +163 -0
  168. package/test/lib/headers.test.js +233 -0
  169. package/test/lib/inputManager.test.js +1144 -5
  170. package/test/lib/intersect.test.js +454 -331
  171. package/test/lib/logging.test.js +1 -1
  172. package/test/lib/matrix.test.js +1 -1
  173. package/test/lib/mouse.test.js +327 -4
  174. package/test/lib/patterns.test.js +105 -0
  175. package/test/lib/promptOptions.test.js +179 -0
  176. package/test/lib/scene.test.js +16 -52
  177. package/test/lib/selectionManager.test.js +17 -5
  178. package/test/lib/settings.test.js +111 -5
  179. package/test/lib/snapping.test.js +142 -4
  180. package/test/lib/stateManager.test.js +155 -0
  181. package/test/lib/utils.test.js +81 -1
  182. package/test/objects/dictionary.test.js +81 -0
  183. package/test/objects/dictionaryManager.test.js +34 -0
  184. package/test/properties/dimType.test.js +62 -0
  185. package/test/properties/flags.test.js +164 -0
  186. package/test/properties/property.test.js +13 -0
  187. package/test/properties/propertyManager.test.js +10 -11
  188. package/test/tables/appId.test.js +46 -0
  189. package/test/tables/appIdManager.test.js +72 -0
  190. package/test/tables/block.test.js +157 -0
  191. package/test/tables/blockManager.test.js +52 -0
  192. package/test/tables/blockRecord.test.js +39 -0
  193. package/test/tables/blockRecordManager.test.js +60 -0
  194. package/test/tables/dimstyle.test.js +72 -0
  195. package/test/tables/endblk.test.js +30 -0
  196. package/test/tables/layer.test.js +95 -0
  197. package/test/tables/layerManager.test.js +172 -0
  198. package/test/{styles → tables}/ltype.test.js +7 -7
  199. package/test/{styles → tables}/ltypeManager.test.js +2 -2
  200. package/test/tables/style.test.js +44 -0
  201. package/test/tables/stylemanagerbase.test.js +220 -0
  202. package/test/tables/tableManagerBase.test.js +194 -0
  203. package/test/tables/ucs.test.js +37 -0
  204. package/test/tables/ucsManager.test.js +48 -0
  205. package/test/tables/view.test.js +37 -0
  206. package/test/tables/viewManager.test.js +48 -0
  207. package/test/tables/vport.test.js +117 -0
  208. package/test/tables/vportManager.test.js +54 -0
  209. package/test/test-helpers/test-helpers.js +66 -0
  210. package/test/tools/chamfer.test.js +970 -0
  211. package/test/tools/chamferFilletBase.test.js +446 -0
  212. package/test/tools/copy.test.js +22 -14
  213. package/test/tools/copybase.test.js +93 -0
  214. package/test/tools/copyclip.test.js +92 -0
  215. package/test/tools/cornerEntity.test.js +201 -0
  216. package/test/tools/cutclip.test.js +94 -0
  217. package/test/tools/distance.test.js +140 -18
  218. package/test/tools/erase.test.js +12 -12
  219. package/test/tools/explode.test.js +45 -0
  220. package/test/tools/extend.test.js +326 -44
  221. package/test/tools/fillet.test.js +831 -0
  222. package/test/tools/identify.test.js +115 -16
  223. package/test/tools/matchProp.test.js +84 -0
  224. package/test/tools/mirror.test.js +475 -0
  225. package/test/tools/move.test.js +75 -19
  226. package/test/tools/offset.test.js +748 -0
  227. package/test/tools/pan.test.js +72 -0
  228. package/test/tools/pasteclip.test.js +100 -0
  229. package/test/tools/purge.test.js +89 -0
  230. package/test/tools/rotate.test.js +89 -23
  231. package/test/tools/scale.test.js +529 -0
  232. package/test/tools/trim.test.js +419 -84
  233. package/test/tools/zoom.test.js +504 -0
  234. package/core/entities/alignedDimension.js +0 -279
  235. package/core/entities/angularDimension.js +0 -194
  236. package/core/entities/baseDimension.js +0 -227
  237. package/core/entities/block.js +0 -247
  238. package/core/entities/diametricDimension.js +0 -133
  239. package/core/entities/dimension.js +0 -202
  240. package/core/entities/radialDimension.js +0 -126
  241. package/core/styles/dimStyle.js +0 -719
  242. package/core/styles/dimStyleManager.js +0 -47
  243. package/core/styles/layer.js +0 -133
  244. package/core/styles/layerManager.js +0 -40
  245. package/core/styles/ltype.js +0 -86
  246. package/core/styles/ltypeManager.js +0 -50
  247. package/core/styles/style.js +0 -158
  248. package/core/styles/styleManager.js +0 -43
  249. package/core/styles/styleManagerBase.js +0 -299
  250. package/test/entities/block.test.js +0 -22
  251. package/test/styles/dimstyle.test.js +0 -19
  252. package/test/styles/layerManager.test.js +0 -150
  253. package/test/styles/style.test.js +0 -33
  254. package/test/styles/stylemanagerbase.test.js +0 -219
@@ -1,17 +1,25 @@
1
- import {Strings} from '../lib/strings.js';
2
- import {DesignCore} from '../designCore.js';
1
+ import { Strings } from '../lib/strings.js';
2
+ import { DesignCore } from '../designCore.js';
3
+ import { UpdateState } from '../lib/stateManager.js';
3
4
 
5
+ /** Property Manager Class */
4
6
  export class PropertyManager {
7
+ /** Create Property Manager */
5
8
  constructor() {
6
9
  this.updateCallbackFunction; // set to external callback function
7
10
  }
8
11
 
12
+ /**
13
+ * Set the property callback function
14
+ * @param {Object} callback
15
+ */
9
16
  setPropertyCallbackFunction(callback) {
10
17
  // set the call
11
18
  this.updateCallbackFunction = callback;
12
19
  }
13
20
 
14
21
 
22
+ /** Signal the selection set has changed */
15
23
  selectionSetChanged() {
16
24
  // If a callback is set - signal that a change has been made
17
25
  if (this.updateCallbackFunction) {
@@ -19,29 +27,55 @@ export class PropertyManager {
19
27
  }
20
28
  }
21
29
 
22
- setItemProperties(property, newPropertyValue) {
23
- for (let i = 0; i <DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
30
+ /**
31
+ * Set item properties
32
+ * @param {string} property
33
+ * @param {any} newPropertyValue
34
+ * @param {string} itemType
35
+ */
36
+ setItemProperties(property, newPropertyValue, itemType='All') {
37
+ const stateChanges = [];
38
+ for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
39
+ const index = DesignCore.Scene.selectionManager.selectionSet.selectionSet[i];
40
+
41
+ const item = DesignCore.Scene.entities.get(index);
42
+
43
+ // check if the item is of the selected type
44
+ if (itemType !== 'All' && item.type !== itemType) {
45
+ continue;
46
+ }
47
+
24
48
  // check if the item has the selected property
25
- if (!DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].hasOwnProperty(property)) {
49
+ if (!item.hasOwnProperty(property)) {
26
50
  continue;
27
51
  }
28
52
 
29
- if (typeof(DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]][property]) !== typeof(newPropertyValue)) {
53
+ if (typeof (item[property]) !== typeof (newPropertyValue)) {
30
54
  DesignCore.Core.notify(Strings.Error.INPUT);
31
55
  } else {
32
- DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]][property] = newPropertyValue;
33
- DesignCore.Scene.selectionManager.reloadSelectedItems();
56
+ // update the item property
57
+ const update = {};
58
+ update[property] = newPropertyValue;
59
+ const stateChange = new UpdateState(item, update);
60
+ stateChanges.push(stateChange);
34
61
  }
35
62
  }
63
+ DesignCore.Scene.commit(stateChanges);
64
+ DesignCore.Scene.selectionManager.reloadSelectedItems();
36
65
  }
37
66
 
67
+ /**
68
+ * Get the types of items selected
69
+ * @return {Array}
70
+ */
38
71
  getItemTypes() {
39
72
  // Loop through the items and get a list of item types.
40
73
  const itemTypes = [];
41
74
 
42
75
  if (DesignCore.Scene.selectionManager.selectionSet.selectionSet.length > 0) {
43
- for (let i = 0; i <DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
44
- const itemType = DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].type;
76
+ for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
77
+ const item = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]);
78
+ const itemType = item.type;
45
79
 
46
80
  if (itemTypes.indexOf(itemType, 0) === -1) {
47
81
  itemTypes.push(itemType);
@@ -57,11 +91,16 @@ export class PropertyManager {
57
91
  return itemTypes;
58
92
  }
59
93
 
94
+ /**
95
+ * Get a list of common propertie
96
+ * @param {string} itemType
97
+ * @return {Array}
98
+ */
60
99
  getItemProperties(itemType) {
61
100
  // Loop through the items and get a list of common properties.
62
101
 
63
102
  // check for valid itemType and selectionSet
64
- if (itemType === undefined || itemType === null ||DesignCore.Scene.selectionManager.selectionSet.selectionSet.length <= 0) {
103
+ if (itemType === undefined || itemType === null || DesignCore.Scene.selectionManager.selectionSet.selectionSet.length <= 0) {
65
104
  return;
66
105
  }
67
106
 
@@ -69,7 +108,7 @@ export class PropertyManager {
69
108
 
70
109
  // create subset array of selectionSet
71
110
  DesignCore.Scene.selectionManager.selectionSet.selectionSet.forEach((index) => {
72
- subset.push(DesignCore.Scene.items[index]);
111
+ subset.push(DesignCore.Scene.entities.get(index));
73
112
  });
74
113
 
75
114
  // get a subset of the selectionSet
@@ -81,11 +120,11 @@ export class PropertyManager {
81
120
 
82
121
  subset.forEach((el) => {
83
122
  // get list of keys
84
- Object.keys(el).forEach( (key) => {
123
+ Object.keys(el).forEach((key) => {
85
124
  // check if the key is already in the propertiesList
86
125
  if (propertiesList.includes(key) === false) {
87
- // check if all subset items contain the key
88
- if (subset.every((el) => el.hasOwnProperty(key))) {
126
+ // check if all subset items contain the key and the key is enumberable
127
+ if (subset.every((el) => el.hasOwnProperty(key) && Object.getOwnPropertyDescriptor(el, key).enumerable)) {
89
128
  propertiesList.push(key);
90
129
  }
91
130
  }
@@ -96,19 +135,26 @@ export class PropertyManager {
96
135
  }
97
136
 
98
137
 
138
+ /**
139
+ * Get a list the property values
140
+ * @param {string} itemType
141
+ * @param {string} property
142
+ * @return {Array}
143
+ */
99
144
  getItemPropertyValue(itemType, property) {
100
145
  // Loop through the items and get a list the property values
101
146
  const propertiesValueList = [];
102
147
  if (DesignCore.Scene.selectionManager.selectionSet.selectionSet.length > 0) {
103
- for (let i = 0; i <DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
104
- if (DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]].type === itemType || itemType === 'All') {
105
- const prop = DesignCore.Scene.items[DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]][property];
148
+ for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
149
+ if (DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]).type === itemType || itemType === 'All') {
150
+ const prop = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i])[property];
106
151
  propertiesValueList.push(prop);
107
152
  }
108
153
  }
109
154
  }
110
155
 
111
- if (propertiesValueList.every(function(prop) {
156
+ // Check if every item in the selection set has the same value for the property
157
+ if (propertiesValueList.every((prop) => {
112
158
  return prop === propertiesValueList[0];
113
159
  })) {
114
160
  return propertiesValueList[0];
@@ -0,0 +1,31 @@
1
+ import { DXFFile } from '../lib/dxf/dxfFile.js';
2
+ import { Property } from '../properties/property.js';
3
+
4
+ /** AppID Class */
5
+ export class AppID {
6
+ /**
7
+ * Create an AppID
8
+ * @param {Object} data
9
+ */
10
+ constructor(data) {
11
+ // DXF Groupcode 5 - Handle
12
+ this.handle = Property.loadValue([data?.handle, data?.[5]]);
13
+ // DXF Groupcode 2 - Name
14
+ this.name = Property.loadValue([data?.name, data?.[2]], '');
15
+ // DXF Groupcode 70 - Flags
16
+ this.flags = Property.loadValue([data?.flags, data?.[70]], 0);
17
+ }
18
+
19
+ /**
20
+ * Write the item to file in the dxf format
21
+ * @param {DXFFile} file
22
+ */
23
+ dxf(file) {
24
+ file.writeGroupCode('0', 'APPID', DXFFile.Version.R2000);
25
+ file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
26
+ file.writeGroupCode('100', 'AcDbSymbolTableRecord', DXFFile.Version.R2000);
27
+ file.writeGroupCode('100', 'AcDbRegAppTableRecord', DXFFile.Version.R2000);
28
+ file.writeGroupCode('2', this.name, DXFFile.Version.R2000);
29
+ file.writeGroupCode('70', this.flags.toString(), DXFFile.Version.R2000);
30
+ }
31
+ }
@@ -0,0 +1,44 @@
1
+ import { DXFFile } from '../lib/dxf/dxfFile.js';
2
+ import { TableManagerBase } from './tableManagerBase.js';
3
+ import { AppID } from './appId.js';
4
+
5
+ /**
6
+ * AppIDManager Class
7
+ * @extends TableManagerBase
8
+ */
9
+ export class AppIDManager extends TableManagerBase {
10
+ /** Create an AppIDManager */
11
+ constructor() {
12
+ super();
13
+
14
+ this.indelibleItems.push('ACAD');
15
+ this.itemProperty = 'appid';
16
+ }
17
+
18
+ /** Get the item class */
19
+ get itemClass() {
20
+ return AppID;
21
+ }
22
+
23
+ /** Add standard items */
24
+ addStandardItems() {
25
+ this.addItem({ 'name': 'ACAD' });
26
+ }
27
+
28
+ /**
29
+ * Write the table to file in the dxf format
30
+ * @param {DXFFile} file
31
+ */
32
+ dxf(file) {
33
+ file.writeGroupCode('0', 'TABLE', DXFFile.Version.R2000);
34
+ file.writeGroupCode('2', 'APPID', DXFFile.Version.R2000);
35
+ file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
36
+ file.writeGroupCode('100', 'AcDbSymbolTable', DXFFile.Version.R2000);
37
+
38
+ for (let i = 0; i < this.itemCount(); i++) {
39
+ this.getItemByIndex(i).dxf(file);
40
+ }
41
+
42
+ file.writeGroupCode('0', 'ENDTAB', DXFFile.Version.R2000);
43
+ }
44
+ }
@@ -0,0 +1,323 @@
1
+ import { Point } from '../entities/point.js';
2
+ import { Entity } from '../entities/entity.js';
3
+ import { EndBlock } from './endblk.js';
4
+ import { DXFFile } from '../lib/dxf/dxfFile.js';
5
+ import { BoundingBox } from '../lib/boundingBox.js';
6
+ import { Strings } from '../lib/strings.js';
7
+ import { Input, PromptOptions } from '../lib/inputManager.js';
8
+ import { Flags } from '../properties/flags.js';
9
+ import { Property } from '../properties/property.js';
10
+ import { AddState, RemoveState } from '../lib/stateManager.js';
11
+
12
+ import { DesignCore } from '../designCore.js';
13
+ import { Utils } from '../lib/utils.js';
14
+
15
+ /**
16
+ * Block Entity Class
17
+ * @extends Entity
18
+ */
19
+ export class Block extends Entity {
20
+ /**
21
+ * Create a Block Entity
22
+ * @param {Array} data
23
+ */
24
+ constructor(data) {
25
+ super(data);
26
+ this.name = '';
27
+ this.points = [new Point()];
28
+ // Store the block record handle and endblk handle for use when writing to dxf file
29
+ this.blockRecordHandle = data?.blockRecordHandle;
30
+ this.endblkHandle = data?.endblkHandle;
31
+
32
+ Object.defineProperty(this, 'flags', {
33
+ value: new Flags(),
34
+ writable: true,
35
+ });
36
+
37
+ Object.defineProperty(this, 'items', {
38
+ value: [],
39
+ writable: true,
40
+ });
41
+
42
+ if (data) {
43
+ if (data.hasOwnProperty('name') || data.hasOwnProperty('2')) {
44
+ // DXF Groupcode 2 - Block Name
45
+ this.name = data.name || data[2];
46
+ }
47
+
48
+ if (data.hasOwnProperty('items')) {
49
+ this.items = data.items;
50
+ }
51
+
52
+ if (data.hasOwnProperty('flags') || data.hasOwnProperty('70')) {
53
+ // DXF Groupcode 70 - Block-type flags (bit-coded):
54
+ // 0 = Indicates none of the following flags apply
55
+ // 1 = This is an anonymous block generated by hatching, associative dimensioning, other internal operations, or an application
56
+ // 2 = This block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all)
57
+ // 4 = This block is an external reference (xref)
58
+ // 8 = This block is an xref overlay
59
+ // 16 = This block is externally dependent
60
+ // 32 = This is a resolved external reference, or dependent of an external reference (ignored on input)
61
+ // 64 = This definition is a referenced external reference (ignored on input)
62
+
63
+ this.flags.setFlagValue(Property.loadValue([data.flags, data[70]], 0));
64
+ }
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Register the command
70
+ * @return {Object}
71
+ * command = name of the command
72
+ * shortcut = shortcut for the command
73
+ * type = type to group command in toolbars (omitted if not shown)
74
+ */
75
+ static register() {
76
+ const command = { command: 'Block', shortcut: 'B' };
77
+ return command;
78
+ }
79
+
80
+ /**
81
+ * Execute method
82
+ * executes the workflow, requesting input required to create an entity
83
+ */
84
+ async execute() {
85
+ try {
86
+ // set a name
87
+ const defaultName = `Block-${DesignCore.Scene.blockManager.itemCount()}`;
88
+ const nameOp = new PromptOptions(Strings.Input.NAME, [Input.Type.STRING], [], defaultName);
89
+ const selectedName = await DesignCore.Scene.inputManager.requestInput(nameOp);
90
+
91
+ // get the insertion point
92
+ const op2 = new PromptOptions(Strings.Input.BASEPOINT, [
93
+ Input.Type.POINT,
94
+ ]);
95
+ const insertPoint = await DesignCore.Scene.inputManager.requestInput(op2);
96
+
97
+ // get the block entities
98
+ const op = new PromptOptions(Strings.Input.SELECTIONSET, [
99
+ Input.Type.SELECTIONSET,
100
+ ]);
101
+
102
+ if (!DesignCore.Scene.selectionManager.selectionSet.selectionSet.length) {
103
+ await DesignCore.Scene.inputManager.requestInput(op);
104
+ }
105
+
106
+ // create block
107
+ const block = DesignCore.Scene.blockManager.addItem({ name: selectedName });
108
+ // get a copy of the selection set
109
+ const selections = DesignCore.Scene.selectionManager.selectionSet.selectionSet.slice();
110
+ // sort the selection in descending order
111
+ selections.sort((a, b) => b - a);
112
+ // array to hold state changes
113
+ const stateChanges = [];
114
+
115
+ // move selected items from scene to block
116
+ selections.forEach((index) => {
117
+ const item = DesignCore.Scene.entities.get(index);
118
+ // remove item from scene
119
+ const copyofitem = Utils.cloneObject(item);
120
+ // adjust the items points to reflect the insert point
121
+ const delta = new Point(-insertPoint.x, -insertPoint.y);
122
+ if (item.hasOwnProperty('points')) {
123
+ const points = copyofitem.points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).add(delta));
124
+ copyofitem.setProperty('points', points);
125
+ }
126
+ block.items.push(copyofitem);
127
+ const stateChangeRemove = new RemoveState(item);
128
+ stateChanges.push(stateChangeRemove);
129
+ });
130
+
131
+ // define insert data
132
+ const insertData = {
133
+ type: 'Insert',
134
+ points: [new Point(insertPoint.x, insertPoint.y)],
135
+ blockName: selectedName,
136
+ };
137
+
138
+ const insert = DesignCore.CommandManager.createNew(insertData.type, insertData);
139
+ const stateChangeAdd = new AddState(insert);
140
+ stateChanges.push(stateChangeAdd);
141
+
142
+ // commit the changes to the scene
143
+ DesignCore.Scene.commit(stateChanges);
144
+
145
+ DesignCore.Scene.inputManager.executeCommand();
146
+ } catch (err) {
147
+ Logging.instance.error(`${this.type} - ${err}`);
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Preview the entity during creation
153
+ */
154
+ preview() { }
155
+
156
+ /**
157
+ * Write the entity to file in the dxf format
158
+ * @param {DXFFile} file
159
+ */
160
+ dxf(file) {
161
+ file.writeGroupCode('0', 'BLOCK');
162
+ file.writeGroupCode('5', this.handle, DXFFile.Version.R2000); // Handle
163
+ file.writeGroupCode('100', 'AcDbEntity', DXFFile.Version.R2000);
164
+ file.writeGroupCode('8', this.layer);
165
+ file.writeGroupCode('100', 'AcDbBlockBegin', DXFFile.Version.R2000);
166
+ file.writeGroupCode('2', this.name);
167
+ file.writeGroupCode('70', this.flags.getFlagValue());
168
+ file.writeGroupCode('10', this.points[0].x);
169
+ file.writeGroupCode('20', this.points[0].y);
170
+ file.writeGroupCode('30', 0.0);
171
+ file.writeGroupCode('3', this.name); // Name again
172
+ file.writeGroupCode('1', '');
173
+
174
+ for (let i = 0; i < this.items.length; i++) {
175
+ this.items[i].dxf(file);
176
+ }
177
+
178
+ const endblk = new EndBlock({ handle: this.endblkHandle });
179
+ endblk.dxf(file);
180
+ }
181
+
182
+ /**
183
+ * Clear items from the block
184
+ */
185
+ clearItems() {
186
+ this.items = [];
187
+ }
188
+
189
+ /**
190
+ * Add an item to the block
191
+ * @param {Object} item
192
+ */
193
+ addItem(item) {
194
+ this.items.push(item);
195
+ }
196
+
197
+ /**
198
+ * Draw the entity
199
+ * @param {Object} ctx - context
200
+ * @param {number} scale
201
+ * @param {Object} insert - insert entity
202
+ */
203
+ draw(ctx, scale, insert = undefined) {
204
+ if (!this.items.length) {
205
+ // nothing to draw
206
+ return;
207
+ }
208
+
209
+ this.items.forEach((item) => {
210
+ ctx.save();
211
+ // Use the current item and block insert to set the context
212
+ // insert required for colour ByBlock
213
+ DesignCore.Canvas.setContext(item, ctx, insert);
214
+
215
+ item.draw(ctx, scale);
216
+ ctx.restore();
217
+ });
218
+
219
+ /*
220
+ //////////////////////////////////////////
221
+ // draw test point for location
222
+ ctx.strokeStyle = Colours.rgbToString(colour);
223
+ ctx.lineWidth = 1 / scale;
224
+ ctx.beginPath()
225
+ ctx.moveTo(this.points[0].x, this.points[0].y);
226
+ ctx.arc(this.points[0].x, this.points[0].y, 5 / scale, radians2degrees(0), radians2degrees(360), false);
227
+ ctx.stroke();
228
+ //////////////////////////////////////////
229
+ */
230
+ }
231
+
232
+ /**
233
+ * Get snap points
234
+ * @param {Point} mousePoint
235
+ * @param {number} delta
236
+ * @return {Array} - array of snap points
237
+ */
238
+ snaps(mousePoint, delta) {
239
+ const snaps = [];
240
+
241
+ if (!this.items.length) {
242
+ // nothing to draw
243
+ return snaps;
244
+ }
245
+
246
+ for (let item = 0; item < this.items.length; item++) {
247
+ // collect the child item snaps
248
+ const itemSnaps = this.items[item].snaps(mousePoint, delta);
249
+ snaps.push(...itemSnaps);
250
+ }
251
+
252
+ return snaps;
253
+ }
254
+
255
+ /**
256
+ * Get closest point on entity
257
+ * @param {Point} P
258
+ * @return {Array} - [Point, distance]
259
+ */
260
+ closestPoint(P) {
261
+ let distance = Infinity;
262
+ let minPnt = P;
263
+
264
+ if (!this.items.length) {
265
+ // nothing to draw
266
+ return [minPnt, distance];
267
+ }
268
+
269
+ for (let idx = 0; idx < this.items.length; idx++) {
270
+ const itemClosestPoint = this.items[idx].closestPoint(P);
271
+ const itemPnt = itemClosestPoint[0];
272
+ const itemDist = itemClosestPoint[1];
273
+
274
+ if (itemDist < distance) {
275
+ distance = itemDist;
276
+ minPnt = itemPnt;
277
+ }
278
+ }
279
+
280
+ return [minPnt, distance];
281
+ }
282
+
283
+ /**
284
+ * Return boundingbox for entity
285
+ * @return {BoundingBox}
286
+ */
287
+ boundingBox() {
288
+ let xmin = Infinity;
289
+ let xmax = -Infinity;
290
+ let ymin = Infinity;
291
+ let ymax = -Infinity;
292
+
293
+ for (let idx = 0; idx < this.items.length; idx++) {
294
+ const itemBoundingBox = this.items[idx].boundingBox();
295
+
296
+ xmin = Math.min(xmin, itemBoundingBox.xMin);
297
+ xmax = Math.max(xmax, itemBoundingBox.xMax);
298
+ ymin = Math.min(ymin, itemBoundingBox.yMin);
299
+ ymax = Math.max(ymax, itemBoundingBox.yMax);
300
+ }
301
+
302
+ const topLeft = new Point(xmin, ymax);
303
+ const bottomRight = new Point(xmax, ymin);
304
+
305
+ return new BoundingBox(topLeft, bottomRight);
306
+ }
307
+
308
+ /**
309
+ * Determine if the entity is touch the selection window
310
+ * @param {Object} selection - {min: Point, max: Point}
311
+ * @return {boolean} true if touched
312
+ */
313
+ touched(selection) {
314
+ for (let idx = 0; idx < this.items.length; idx++) {
315
+ const touched = this.items[idx].touched(selection);
316
+ if (touched) {
317
+ return true;
318
+ }
319
+ }
320
+
321
+ return false;
322
+ }
323
+ }
@@ -0,0 +1,48 @@
1
+ // import {DesignCore} from '../designCore.js';
2
+ // import {Strings} from '../lib/strings.js';
3
+ import { TableManagerBase } from './tableManagerBase.js';
4
+ import { Block } from './block.js';
5
+ import { DesignCore } from '../designCore.js';
6
+
7
+ /**
8
+ * BlockManager Class
9
+ * @extends TableManagerBase
10
+ */
11
+ export class BlockManager extends TableManagerBase {
12
+ /** Create a BlockManager */
13
+ constructor() {
14
+ super();
15
+ this.itemProperty = 'block';
16
+ this.indelibleItems.push('*Model_Space', '*Paper_Space');
17
+ }
18
+
19
+ /** Get the item class */
20
+ get itemClass() {
21
+ return Block;
22
+ }
23
+
24
+ /**
25
+ * Add standard blocks
26
+ */
27
+ addStandardItems() {
28
+ this.addItem({ 'name': '*Model_Space' });
29
+ this.addItem({ 'name': '*Paper_Space' });
30
+ }
31
+
32
+ /**
33
+ * Add a block to the list of items and assign a block record handle
34
+ * @param {Object} item
35
+ * @param {boolean} overwrite
36
+ * @return {Object}
37
+ */
38
+ addItem(item, overwrite = false) {
39
+ const newItem = super.addItem(item, overwrite);
40
+ if (newItem.blockRecordHandle === undefined) {
41
+ newItem.blockRecordHandle = DesignCore.HandleManager.next();
42
+ }
43
+ if (newItem.endblkHandle === undefined) {
44
+ newItem.endblkHandle = DesignCore.HandleManager.next();
45
+ }
46
+ return newItem;
47
+ }
48
+ }
@@ -0,0 +1,29 @@
1
+ import { DXFFile } from '../lib/dxf/dxfFile.js';
2
+ import { Property } from '../properties/property.js';
3
+
4
+ /** BlockRecord Class */
5
+ export class BlockRecord {
6
+ /**
7
+ * Create a BlockRecord
8
+ * @param {Object} data
9
+ */
10
+ constructor(data) {
11
+ // DXF Groupcode 5 - Handle
12
+ this.handle = Property.loadValue([data?.handle, data?.[5]]);
13
+ // DXF Groupcode 2 - Name
14
+ this.name = Property.loadValue([data?.name, data?.[2]], '');
15
+ }
16
+
17
+ /**
18
+ * Write the item to file in the dxf format
19
+ * @param {DXFFile} file
20
+ */
21
+ dxf(file) {
22
+ file.writeGroupCode('0', 'BLOCK_RECORD', DXFFile.Version.R2000);
23
+ file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
24
+ file.writeGroupCode('100', 'AcDbSymbolTableRecord', DXFFile.Version.R2000);
25
+ file.writeGroupCode('100', 'AcDbBlockTableRecord', DXFFile.Version.R2000);
26
+ file.writeGroupCode('2', this.name, DXFFile.Version.R2000);
27
+ file.writeGroupCode('340', '0', DXFFile.Version.R2000);
28
+ }
29
+ }
@@ -0,0 +1,37 @@
1
+ import { DXFFile } from '../lib/dxf/dxfFile.js';
2
+ import { BlockRecord } from './blockRecord.js';
3
+
4
+ import { DesignCore } from '../designCore.js';
5
+
6
+ /**
7
+ * BlockRecordManager Class
8
+ * Writes BLOCK_RECORD table entries based on the scene's block manager
9
+ */
10
+ export class BlockRecordManager {
11
+ /** Create a BlockRecordManager */
12
+ constructor() {
13
+ this.handle = DesignCore.HandleManager.next();
14
+ }
15
+
16
+ /**
17
+ * Write the table to file in the dxf format
18
+ * @param {DXFFile} file
19
+ */
20
+ dxf(file) {
21
+ const blocks = DesignCore.Scene.blockManager.items;
22
+
23
+ file.writeGroupCode('0', 'TABLE', DXFFile.Version.R2000);
24
+ file.writeGroupCode('2', 'BLOCK_RECORD', DXFFile.Version.R2000);
25
+ file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
26
+ file.writeGroupCode('100', 'AcDbSymbolTable', DXFFile.Version.R2000);
27
+ file.writeGroupCode('70', blocks.length.toString(), DXFFile.Version.R2000);
28
+
29
+ for (let i = 0; i < blocks.length; i++) {
30
+ // Temp hack for block record handle
31
+ const record = new BlockRecord({ name: blocks[i].name, handle: blocks[i].blockRecordHandle });
32
+ record.dxf(file);
33
+ }
34
+
35
+ file.writeGroupCode('0', 'ENDTAB', DXFFile.Version.R2000);
36
+ }
37
+ }