@buerli.io/core 0.4.1 → 0.5.0-beta.2

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 (86) hide show
  1. package/build/cjs/geometry/ThreeGeometryCreator.js +321 -0
  2. package/build/cjs/geometry/index.js +17 -0
  3. package/build/cjs/graphic/filters.js +25 -0
  4. package/build/cjs/index.js +25 -0
  5. package/build/cjs/store/index.js +37 -0
  6. package/build/cjs/store/states/buerli.js +98 -0
  7. package/build/cjs/store/states/cad.js +35 -0
  8. package/build/cjs/store/states/drawing.js +47 -0
  9. package/build/cjs/store/states/geometry.js +139 -0
  10. package/build/cjs/store/states/graphic.js +115 -0
  11. package/build/cjs/store/states/interaction.js +55 -0
  12. package/build/cjs/store/states/message.js +25 -0
  13. package/build/cjs/store/states/plugin.js +115 -0
  14. package/build/cjs/store/states/selection.js +258 -0
  15. package/build/cjs/store/states/structure.js +239 -0
  16. package/build/cjs/store/store.js +9 -0
  17. package/build/cjs/store/subscribtion/selection.js +46 -0
  18. package/build/cjs/store/subscribtion/subscribeToDrawing.js +13 -0
  19. package/build/cjs/types/IGraphicPackage.js +49 -0
  20. package/build/cjs/types/IStructurePatch.js +2 -0
  21. package/build/cjs/types/IStructureTree.js +27 -0
  22. package/build/cjs/types/InteractionInfo.js +11 -0
  23. package/build/cjs/types/index.js +20 -0
  24. package/build/cjs/utils/Math.js +91 -0
  25. package/build/cjs/utils/Measure.js +560 -0
  26. package/build/cjs/utils/Timing.js +34 -0
  27. package/build/{geometry → esm/geometry}/ThreeGeometryCreator.js +0 -0
  28. package/build/{geometry → esm/geometry}/index.js +0 -0
  29. package/build/{graphic → esm/graphic}/filters.js +0 -0
  30. package/build/{index.js → esm/index.js} +0 -0
  31. package/build/{store → esm/store}/index.js +0 -0
  32. package/build/{store → esm/store}/states/buerli.js +2 -2
  33. package/build/{store → esm/store}/states/cad.js +0 -0
  34. package/build/{store → esm/store}/states/drawing.js +0 -0
  35. package/build/{store → esm/store}/states/geometry.js +0 -0
  36. package/build/{store → esm/store}/states/graphic.js +0 -0
  37. package/build/{store → esm/store}/states/interaction.js +0 -0
  38. package/build/{store → esm/store}/states/message.js +0 -0
  39. package/build/{store → esm/store}/states/plugin.js +0 -0
  40. package/build/{store → esm/store}/states/selection.js +0 -0
  41. package/build/{store → esm/store}/states/structure.js +0 -0
  42. package/build/esm/store/store.js +3 -0
  43. package/build/{store → esm/store}/subscribtion/selection.js +0 -0
  44. package/build/esm/store/subscribtion/subscribeToDrawing.js +9 -0
  45. package/build/{types → esm/types}/IGraphicPackage.js +0 -0
  46. package/build/{types → esm/types}/IStructurePatch.js +0 -0
  47. package/build/{types → esm/types}/IStructureTree.js +0 -0
  48. package/build/{types → esm/types}/InteractionInfo.js +0 -0
  49. package/build/{types → esm/types}/index.js +0 -0
  50. package/build/{utils → esm/utils}/Math.js +0 -0
  51. package/build/{utils → esm/utils}/Measure.js +0 -0
  52. package/build/{utils → esm/utils}/Timing.js +0 -0
  53. package/build/{geometry → types/geometry}/ThreeGeometryCreator.d.ts +0 -0
  54. package/build/{geometry → types/geometry}/index.d.ts +0 -0
  55. package/build/{graphic → types/graphic}/filters.d.ts +0 -0
  56. package/build/types/index.d.ts +37 -4
  57. package/build/{store → types/store}/index.d.ts +2 -2
  58. package/build/types/store/states/buerli.d.ts +41 -0
  59. package/build/{store → types/store}/states/cad.d.ts +4 -4
  60. package/build/{store → types/store}/states/drawing.d.ts +3 -3
  61. package/build/{store → types/store}/states/geometry.d.ts +7 -7
  62. package/build/{store → types/store}/states/graphic.d.ts +6 -6
  63. package/build/{store → types/store}/states/interaction.d.ts +4 -4
  64. package/build/{store → types/store}/states/message.d.ts +3 -3
  65. package/build/{store → types/store}/states/plugin.d.ts +5 -5
  66. package/build/{store → types/store}/states/selection.d.ts +13 -13
  67. package/build/{store → types/store}/states/structure.d.ts +4 -4
  68. package/build/types/store/store.d.ts +2 -0
  69. package/build/types/store/subscribtion/selection.d.ts +7 -0
  70. package/build/types/store/subscribtion/subscribeToDrawing.d.ts +4 -0
  71. package/build/types/{IGraphicPackage.d.ts → types/IGraphicPackage.d.ts} +0 -0
  72. package/build/types/{IStructurePatch.d.ts → types/IStructurePatch.d.ts} +0 -0
  73. package/build/types/{IStructureTree.d.ts → types/IStructureTree.d.ts} +0 -0
  74. package/build/types/{InteractionInfo.d.ts → types/InteractionInfo.d.ts} +0 -0
  75. package/build/types/types/index.d.ts +4 -0
  76. package/build/{utils → types/utils}/Math.d.ts +0 -0
  77. package/build/{utils → types/utils}/Measure.d.ts +0 -0
  78. package/build/{utils → types/utils}/Timing.d.ts +0 -0
  79. package/package.json +11 -11
  80. package/build/index.d.ts +0 -38
  81. package/build/store/states/buerli.d.ts +0 -50
  82. package/build/store/store.d.ts +0 -5
  83. package/build/store/store.js +0 -8
  84. package/build/store/subscribtion/selection.d.ts +0 -6
  85. package/build/store/subscribtion/subscribeToDrawing.d.ts +0 -3
  86. package/build/store/subscribtion/subscribeToDrawing.js +0 -4
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createGraphicItem = exports.selectionApi = exports.selectionData = exports.BuerliScope = void 0;
4
+ const selection_1 = require("../subscribtion/selection");
5
+ ////////////////////////////////////////////////////
6
+ // CONSTANTS
7
+ ////////////////////////////////////////////////////
8
+ exports.BuerliScope = 'ClassCAD';
9
+ const selectionData = () => ({
10
+ refs: {},
11
+ active: null,
12
+ });
13
+ exports.selectionData = selectionData;
14
+ const selectionApi = (set, get, buerliApi) => ({
15
+ unselectAll(selectorId) {
16
+ const { selection, id: drawingId } = get();
17
+ const selId = (selectorId || selection.active);
18
+ if (selId) {
19
+ const unselItems = selection.refs[selId].items;
20
+ (0, selection_1.unsubscribeItems)(buerliApi, drawingId, selId, unselItems);
21
+ set(state => {
22
+ const selector = state.selection.refs[selId];
23
+ return {
24
+ selection: Object.assign(Object.assign({}, state.selection), { refs: Object.assign(Object.assign({}, state.selection.refs), { [selId]: Object.assign(Object.assign({}, selector), { items: [] }) }) }),
25
+ };
26
+ });
27
+ }
28
+ },
29
+ unselect(items, selectorId) {
30
+ const { selection, id: drawingId } = get();
31
+ const selId = (selectorId || selection.active);
32
+ if (selId) {
33
+ const unselItems = Array.isArray(items) ? items : [items];
34
+ // Remove unselItems from selector's items
35
+ const selector = selection.refs[selId];
36
+ const newItems = selector.items.filter(item => unselItems.find(uItem => uItem.id === item.id) === undefined);
37
+ (0, selection_1.unsubscribeItems)(buerliApi, drawingId, selId, unselItems);
38
+ if (selector.customUnSelect) {
39
+ // Find recently unselected items
40
+ const diff = selector.items.filter(item1 => {
41
+ return newItems.find(item2 => item2.id === item1.id) === undefined;
42
+ });
43
+ selector.customUnSelect(selId, newItems, diff);
44
+ }
45
+ else {
46
+ set(state => {
47
+ return {
48
+ selection: Object.assign(Object.assign({}, state.selection), { refs: Object.assign(Object.assign({}, state.selection.refs), { [selId]: Object.assign(Object.assign({}, state.selection.refs[selId]), { items: newItems }) }) }),
49
+ };
50
+ });
51
+ }
52
+ this.setHovered(null, selId);
53
+ }
54
+ },
55
+ select(items, selectorId) {
56
+ const { selection, api, id: drawingId } = get();
57
+ const selId = (selectorId || selection.active);
58
+ if (selId) {
59
+ const { isItemSelected } = api.selection;
60
+ const newItems = Array.isArray(items) ? items : [items];
61
+ const selector = selection.refs[selId];
62
+ const curItems = selector.items;
63
+ // Remove duplicates
64
+ let filteredItems = newItems.filter((item1, idx) => newItems.findIndex(item2 => item2.id === item1.id) === idx);
65
+ // Remove already selected items and duplicates
66
+ filteredItems = filteredItems.filter(item => !isItemSelected(item, selId));
67
+ let unsubItems = [];
68
+ let result = [...curItems, ...filteredItems];
69
+ if (selector.maxLen > 0) {
70
+ if (filteredItems.length === selector.maxLen) {
71
+ result = [...filteredItems];
72
+ unsubItems = [...curItems];
73
+ }
74
+ else if (filteredItems.length > selector.maxLen) {
75
+ const extraItems = filteredItems.length - selector.maxLen;
76
+ // If filteredItems has bigger length then selector.maxLen, remove last few items from filteredItems.
77
+ result = filteredItems.slice(0, -extraItems);
78
+ unsubItems = [...curItems];
79
+ }
80
+ else if (filteredItems.length + curItems.length >= selector.maxLen) {
81
+ const extraItems = filteredItems.length + curItems.length - selector.maxLen;
82
+ const allItems = [...curItems, ...filteredItems];
83
+ // If filteredItems.len + curItems.len > selector.maxLen, remove first few items from union of curItems and filteredItems.
84
+ result = allItems.slice(extraItems);
85
+ unsubItems = allItems.slice(0, extraItems);
86
+ }
87
+ }
88
+ if (selector.customSelect !== undefined) {
89
+ // Find items which weren't selected before.
90
+ const diff = result.filter(item1 => {
91
+ return selector.items.find(item2 => item2.id === item1.id) === undefined;
92
+ });
93
+ selector.customSelect(selId, result, diff);
94
+ }
95
+ else {
96
+ // subscribe items which will be selected
97
+ (0, selection_1.subscribeItems)(buerliApi, drawingId, selId, result);
98
+ // unsubscribe items which will be unselected
99
+ (0, selection_1.unsubscribeItems)(buerliApi, drawingId, selId, unsubItems);
100
+ set(state => {
101
+ return {
102
+ selection: Object.assign(Object.assign({}, state.selection), { refs: Object.assign(Object.assign({}, state.selection.refs), { [selId]: Object.assign(Object.assign({}, selector), { items: result, hoveredItem: null }) }) }),
103
+ };
104
+ });
105
+ }
106
+ }
107
+ },
108
+ setHovered(item, selectorId) {
109
+ const { selection } = get();
110
+ if (selection.active === null && selectorId === undefined)
111
+ return;
112
+ const selId = (selectorId || selection.active);
113
+ set(state => ({
114
+ selection: Object.assign(Object.assign({}, state.selection), { refs: Object.assign(Object.assign({}, state.selection.refs), { [selId]: Object.assign(Object.assign({}, state.selection.refs[selId]), { hoveredItem: item }) }) }),
115
+ }));
116
+ },
117
+ activateSelector(selectorId) {
118
+ set(state => {
119
+ const refs = state.selection.refs;
120
+ const curSelectorId = state.selection.active;
121
+ if (curSelectorId) {
122
+ // Reset hoveredItem
123
+ refs[curSelectorId] = Object.assign(Object.assign({}, refs[curSelectorId]), { hoveredItem: null });
124
+ }
125
+ return {
126
+ selection: Object.assign(Object.assign({}, state.selection), { active: state.selection.active === selectorId ? null : selectorId, refs: Object.assign({}, refs) }),
127
+ };
128
+ });
129
+ },
130
+ createSelector(selectorId, filter, activate = false, initialItems = [], maxLen = -1, customSelect, customUnSelect) {
131
+ if (maxLen > 0 && initialItems.length > maxLen)
132
+ console.error('Number initialItems should be less or equal to selector.maxLen');
133
+ set(state => ({
134
+ selection: Object.assign(Object.assign({}, state.selection), { active: activate ? selectorId : state.selection.active, refs: Object.assign(Object.assign({}, state.selection.refs), { [selectorId]: {
135
+ items: maxLen > 0 && initialItems.length > maxLen ? [] : initialItems,
136
+ hoveredItem: null,
137
+ isSelectable: filter,
138
+ maxLen,
139
+ customSelect,
140
+ customUnSelect,
141
+ } }) }),
142
+ }));
143
+ return () => {
144
+ if (get && get()) {
145
+ const drawingId = get().id;
146
+ (0, selection_1.unsubscribeItems)(buerliApi, drawingId, selectorId);
147
+ set(state => {
148
+ const refs = state.selection.refs;
149
+ delete refs[selectorId];
150
+ return {
151
+ selection: Object.assign(Object.assign({}, state.selection), { active: state.selection.active === selectorId ? null : state.selection.active, refs }),
152
+ };
153
+ });
154
+ }
155
+ };
156
+ },
157
+ areItemsSelected: (items, selectorId) => {
158
+ const { selection } = get();
159
+ if (selection.active === null && selectorId === undefined)
160
+ return false;
161
+ const selId = (selectorId || selection.active);
162
+ const selector = selection.refs[selId];
163
+ let res = true;
164
+ items.forEach(item => {
165
+ const itemSelected = Boolean(selector.items.find(i => areItemsEqual(i, item)));
166
+ if (!itemSelected) {
167
+ res = false;
168
+ }
169
+ });
170
+ return res;
171
+ },
172
+ isItemSelected: (item, selectorId) => {
173
+ const { selection } = get();
174
+ if (selection.active === null && selectorId === undefined)
175
+ return false;
176
+ const selId = (selectorId || selection.active);
177
+ const selector = selection.refs[selId];
178
+ return Boolean(selector.items.find(i => areItemsEqual(i, item)));
179
+ },
180
+ setItems(id, items) {
181
+ var _a;
182
+ const { selection, id: drawingId } = get();
183
+ const curItems = ((_a = selection.refs[id]) === null || _a === void 0 ? void 0 : _a.items) || [];
184
+ (0, selection_1.unsubscribeItems)(buerliApi, drawingId, id, curItems);
185
+ (0, selection_1.subscribeItems)(buerliApi, drawingId, id, items);
186
+ set(state => {
187
+ const selector = state.selection.refs[id];
188
+ return {
189
+ selection: Object.assign(Object.assign({}, state.selection), { refs: Object.assign(Object.assign({}, state.selection.refs), { [id]: Object.assign(Object.assign({}, selector), { items }) }) }),
190
+ };
191
+ });
192
+ },
193
+ selectGraphic: (selectorId, items, options) => {
194
+ const { api } = get();
195
+ const selItems = items
196
+ .map(i => api.selection.getGraphicItem(i.productId, i.containerId, i.graphicId))
197
+ .filter(i => Boolean(i));
198
+ if (options === null || options === void 0 ? void 0 : options.unselectExisting) {
199
+ api.selection.setItems(selectorId, selItems);
200
+ }
201
+ else {
202
+ api.selection.select(selItems, selectorId);
203
+ }
204
+ },
205
+ getGraphicItem: (productId, containerId, graphicId) => {
206
+ const { cache } = get().geometry;
207
+ const container = cache[containerId];
208
+ let useContainer = false;
209
+ if (container) {
210
+ if (graphicId === undefined) {
211
+ const ids = Object.getOwnPropertyNames(container.map);
212
+ graphicId = ids.length > 0 ? Number(ids[0]) : undefined;
213
+ useContainer = true;
214
+ }
215
+ if (graphicId !== undefined) {
216
+ let geomElem = container.map[graphicId];
217
+ if (!geomElem) {
218
+ geomElem = container.points.find(p => p.graphicId === graphicId);
219
+ }
220
+ if (geomElem) {
221
+ geomElem.graphicId = useContainer ? containerId : geomElem.graphicId;
222
+ geomElem.type = useContainer ? container.type : geomElem.type;
223
+ return (0, exports.createGraphicItem)(productId, geomElem);
224
+ }
225
+ }
226
+ }
227
+ return null;
228
+ },
229
+ });
230
+ exports.selectionApi = selectionApi;
231
+ ////////////////////////////////////////////////////
232
+ //#region GLOBAL FUNCTIONS
233
+ const areItemsEqual = (a, b) => a.id === b.id && a.scope === b.scope;
234
+ const getLabel = (type) => {
235
+ const uppLetters = type.replace(/[a-z]/g, '');
236
+ if (uppLetters.length >= 2) {
237
+ return uppLetters[0] + uppLetters[1];
238
+ }
239
+ else if (uppLetters.length === 1) {
240
+ return (type[0] + uppLetters[0]).toUpperCase();
241
+ }
242
+ else {
243
+ return (type[0] + type[1]).toUpperCase();
244
+ }
245
+ };
246
+ const createGraphicIdent = (productId, graphicId, type) => {
247
+ return {
248
+ id: `${productId}|${graphicId}|${type}`,
249
+ scope: exports.BuerliScope,
250
+ label: getLabel(type),
251
+ };
252
+ };
253
+ const createGraphicItem = (productId, el) => {
254
+ return Object.assign(Object.assign({}, createGraphicIdent(productId, el.graphicId, el.type)), { data: Object.assign(Object.assign({}, el), { productId }) });
255
+ };
256
+ exports.createGraphicItem = createGraphicItem;
257
+ //#endregion GLOBAL FUNCTIONS
258
+ ////////////////////////////////////////////////////
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.structureApi = exports.structureData = void 0;
30
+ const fast_json_patch_1 = __importDefault(require("fast-json-patch"));
31
+ const jsonpatch_1 = __importDefault(require("jsonpatch"));
32
+ const THREE = __importStar(require("three"));
33
+ const types_1 = require("../../types");
34
+ const Math_1 = require("../../utils/Math");
35
+ ////////////////////////////////////////////////////
36
+ // DATA
37
+ ////////////////////////////////////////////////////
38
+ const structureData = () => {
39
+ return Object.assign(Object.assign({}, (0, types_1.DEFAULT_STRUCTURE_TREE)()), { visibleContainers: [], products: [] });
40
+ };
41
+ exports.structureData = structureData;
42
+ ////////////////////////////////////////////////////
43
+ // API
44
+ ////////////////////////////////////////////////////
45
+ const structureApi = (set, get, buerliApi) => ({
46
+ get: () => {
47
+ return get().structure;
48
+ },
49
+ set: (structure) => {
50
+ const { api } = get();
51
+ // TODO: clear object selection if needed
52
+ // 1. set the state
53
+ set({
54
+ structure: Object.assign(Object.assign({}, get().structure), structure),
55
+ });
56
+ // 2. collect and cleanup data
57
+ api.graphic.cleanupGraphicRecords();
58
+ // console.log('cleanup')
59
+ api.structure.postProcessStructureUpdate();
60
+ },
61
+ applyPatches: (patches) => {
62
+ const before = get().structure.products.concat(get().structure.visibleContainers);
63
+ const applyBlock = (block) => {
64
+ if (block.length === 0)
65
+ return;
66
+ set(state => {
67
+ let structure = state.structure;
68
+ try {
69
+ // TODO: keep an eye on the patch behaviour in general.
70
+ // For large changes 'fast-json-patch' is much more performant than 'jsonpatch'.
71
+ // However, for smaller changes 'jsonpatch' is more performant than 'fast-json-patch'.
72
+ if (block.length > 100) {
73
+ structure = fast_json_patch_1.default.applyPatch(state.structure, block, false, false).newDocument;
74
+ }
75
+ else {
76
+ structure = jsonpatch_1.default.apply_patch(state.structure, block);
77
+ }
78
+ }
79
+ catch (e) {
80
+ console.error(e);
81
+ }
82
+ // console.info('currentProduct in new patched structure: ', structure.currentProduct)
83
+ return { structure: Object.assign(Object.assign({}, state.structure), structure) };
84
+ });
85
+ };
86
+ const treePatches = [];
87
+ const otherPatches = [];
88
+ for (const patch of patches) {
89
+ if (patch.path.startsWith('/tree/')) {
90
+ treePatches.push(patch);
91
+ }
92
+ else {
93
+ otherPatches.push(patch);
94
+ }
95
+ }
96
+ // console.info(JSON.stringify(otherPatches))
97
+ //////////////////////////////////////////////////////////////////////////////
98
+ // The following split of the state update helps very much in some cases to
99
+ // prevent not existing object access in many React hooks.
100
+ // 1. Perform meta information update as the first step (root, currentProduct, ...)
101
+ applyBlock(otherPatches);
102
+ // 2. Perform tree update as a second, separate step
103
+ applyBlock(treePatches);
104
+ // TODO: The update behaviour for structure updates in buerli/zustand/react-hooks
105
+ // has to be analyzed in more detail based on a very simple example.
106
+ //////////////////////////////////////////////////////////////////////////////
107
+ const { api } = get();
108
+ api.structure.postProcessStructureUpdate();
109
+ // Update the bounds, but only if products or visible containers changed.
110
+ const after = get().structure.products.concat(get().structure.visibleContainers);
111
+ if (before.sort().join() !== after.sort().join()) {
112
+ api.geometry.updateBounds();
113
+ }
114
+ },
115
+ filterTree: (tree, filter) => {
116
+ const objs = [];
117
+ Object.getOwnPropertyNames(tree).forEach(name => {
118
+ const obj = tree[name];
119
+ if (filter(obj)) {
120
+ objs.push(obj);
121
+ }
122
+ });
123
+ return objs;
124
+ },
125
+ collectUsedSolidIds: () => {
126
+ const { api, structure } = get();
127
+ const solidObjs = api.structure.filterTree(structure.tree, obj => typeof obj.geometryIdList !== 'undefined');
128
+ const solidIds = [];
129
+ solidObjs.forEach(solidObj => solidIds.push(...(solidObj.geometryIdList || [])));
130
+ return solidIds;
131
+ },
132
+ collectProducts: (root) => {
133
+ const { structure } = get();
134
+ const products = [];
135
+ const recursive = (id) => {
136
+ const obj = structure.tree[id];
137
+ if (obj) {
138
+ if ((obj.solids && obj.solids.length > 0) || obj.link) {
139
+ products.push(obj);
140
+ }
141
+ if (obj.children) {
142
+ for (const child of obj.children) {
143
+ recursive(child);
144
+ }
145
+ }
146
+ }
147
+ };
148
+ recursive(root);
149
+ return products;
150
+ },
151
+ getProductSolidIds: (productId) => {
152
+ const { structure } = get();
153
+ let solids;
154
+ const product = structure.tree[productId];
155
+ if (product.link !== undefined) {
156
+ solids = structure.tree[product.link].solids || [];
157
+ }
158
+ else {
159
+ solids = product.solids || [];
160
+ }
161
+ return [...solids];
162
+ },
163
+ postProcessStructureUpdate: () => {
164
+ const { api, structure } = get();
165
+ //////////
166
+ // 1. Collect the products
167
+ //////////
168
+ const searchRoot = structure.root; // || structure.currentNode || structure.currentProduct
169
+ const productIds = api.structure.collectProducts(searchRoot).map(p => p.id);
170
+ //////////
171
+ // 2. Collect the solid ids
172
+ //////////
173
+ let solidIds = [];
174
+ productIds.forEach(prodId => solidIds.push(...(api.structure.getProductSolidIds(prodId) || [])));
175
+ // remove duplicates
176
+ solidIds = solidIds.filter((item, index) => solidIds.indexOf(item) === index);
177
+ //////////
178
+ // 3. Add the result to the state
179
+ //////////
180
+ set(state => ({
181
+ structure: Object.assign(Object.assign({}, state.structure), { visibleContainers: solidIds, products: productIds }),
182
+ }));
183
+ },
184
+ /**
185
+ * Calculates the global transformation matrix for the given _objectId_.
186
+ *
187
+ * @param objectId The object to calculate the global transformation for.
188
+ * @param matrix The initial matrix (mainly used for recursion). It is an out parameter and in the end, it will contain the same matrix as the return value of this function.
189
+ * @returns The global transformation matrix for the given _objectId_.
190
+ */
191
+ calculateGlobalTransformation: (objectId, matrix = new THREE.Matrix4().identity()) => {
192
+ const { structure, api } = get();
193
+ const { tree, root } = structure;
194
+ const obj = tree[objectId];
195
+ if (obj && obj.coordinateSystem) {
196
+ const objMatrix = Math_1.MathUtils.convertToMatrix4(obj.coordinateSystem);
197
+ matrix = matrix.clone().premultiply(objMatrix);
198
+ }
199
+ if (objectId !== root && obj.parent) {
200
+ matrix = api.structure.calculateGlobalTransformation(obj.parent, matrix);
201
+ }
202
+ return matrix;
203
+ },
204
+ calculateProductBounds: (productId, base) => {
205
+ const { graphic, api } = get();
206
+ const posInf = Number.POSITIVE_INFINITY;
207
+ const negInf = Number.NEGATIVE_INFINITY;
208
+ const baseMin = base ? base.min.clone() : new THREE.Vector3(posInf, posInf, posInf);
209
+ const baseMax = base ? base.max.clone() : new THREE.Vector3(negInf, negInf, negInf);
210
+ let box = new THREE.Box3(baseMin, baseMax);
211
+ const productIds = api.structure.collectProducts(productId).map(p => p.id);
212
+ for (const pId of productIds) {
213
+ const matrix = api.structure.calculateGlobalTransformation(pId);
214
+ const contIds = api.structure.getProductSolidIds(pId);
215
+ for (const contId of contIds) {
216
+ const cont = graphic.containers[contId];
217
+ if (cont) {
218
+ const min = new THREE.Vector3().fromArray(cont.properties.min);
219
+ const max = new THREE.Vector3().fromArray(cont.properties.max);
220
+ const b = new THREE.Box3(min.clone(), max.clone());
221
+ b.applyMatrix4(matrix);
222
+ box = box.union(b);
223
+ }
224
+ }
225
+ }
226
+ const sphere = new THREE.Sphere();
227
+ box.getBoundingSphere(sphere);
228
+ return { center: sphere.center, radius: sphere.radius, max: box.max, min: box.min };
229
+ },
230
+ /**
231
+ * This is a workaround to get the corresponding drawing id via API.
232
+ *
233
+ * > !!! Should not be used in user code !!!
234
+ *
235
+ * @returns The drawing id.
236
+ */
237
+ getDrawingId: () => get().id,
238
+ });
239
+ exports.structureApi = structureApi;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.api = void 0;
7
+ const vanilla_1 = __importDefault(require("zustand/vanilla"));
8
+ const buerli_1 = require("./states/buerli");
9
+ exports.api = (0, vanilla_1.default)()(buerli_1.createState);
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ // This is the solution for cases when object was deleted from tree and we need to remove corresponding selectedItem.
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.unsubscribeItems = exports.subscribeItems = exports.unsubs = void 0;
5
+ const subscribeToDrawing_1 = require("./subscribeToDrawing");
6
+ // This object contains unsubscibe function for all existing selections in all drawings
7
+ exports.unsubs = {};
8
+ function getId(selectorId, itemId) {
9
+ return `${selectorId}_${itemId}`;
10
+ }
11
+ function subscribeItems(buerliApi, drawingId, selectorId, items) {
12
+ const items_ = items || buerliApi.getState().drawing.refs[drawingId].selection.refs[selectorId].items;
13
+ items_.forEach(item => {
14
+ subscribeItem(buerliApi, drawingId, selectorId, item);
15
+ });
16
+ }
17
+ exports.subscribeItems = subscribeItems;
18
+ function subscribeItem(buerliApi, drawingId, selectorId, item) {
19
+ if (item.removeCondition && !exports.unsubs[getId(selectorId, item.id)]) {
20
+ const selApi = buerliApi.getState().drawing.refs[drawingId].api.selection;
21
+ exports.unsubs[getId(selectorId, item.id)] = (0, subscribeToDrawing_1.subscribeToDrawing)(buerliApi, drawingId, (d) => item.removeCondition && item.removeCondition(d), (removeCond) => {
22
+ var _a;
23
+ // Unselect item whose removeCondition got true
24
+ if (removeCond) {
25
+ const newItems = ((_a = buerliApi.getState().drawing.refs[drawingId].selection.refs[selectorId]) === null || _a === void 0 ? void 0 : _a.items) || [];
26
+ selApi.setItems(selectorId, newItems.filter(item_ => item_.id !== item.id));
27
+ }
28
+ });
29
+ }
30
+ }
31
+ function unsubscribeItems(buerliApi, drawingId, selectorId, items) {
32
+ const items_ = items || buerliApi.getState().drawing.refs[drawingId].selection.refs[selectorId].items;
33
+ items_.forEach(item => {
34
+ unsubscribeItem(selectorId, item);
35
+ });
36
+ }
37
+ exports.unsubscribeItems = unsubscribeItems;
38
+ function unsubscribeItem(selectorId, item) {
39
+ if (item.removeCondition) {
40
+ const id = getId(selectorId, item.id);
41
+ if (exports.unsubs[id]) {
42
+ exports.unsubs[id]();
43
+ delete exports.unsubs[id];
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.subscribeToDrawing = void 0;
4
+ function subscribeToDrawing(buerliApi, drawingId, sel, callback) {
5
+ const unsub = buerliApi.subscribe((state, prev) => {
6
+ const curDrawing = state.drawing.refs[drawingId] && sel(state.drawing.refs[drawingId]);
7
+ const prevDrawing = prev.drawing.refs[drawingId] && sel(prev.drawing.refs[drawingId]);
8
+ if (curDrawing !== prevDrawing)
9
+ callback(curDrawing);
10
+ });
11
+ return unsub;
12
+ }
13
+ exports.subscribeToDrawing = subscribeToDrawing;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PointTypes = exports.EntityTypes = exports.CurveSegments = exports.Primitives = exports.LineSegments = exports.Surfaces = exports.AllTypes = exports.ContainerType = exports.GraphicType = void 0;
4
+ var GraphicType;
5
+ (function (GraphicType) {
6
+ // Primitives
7
+ GraphicType["POINT"] = "point";
8
+ GraphicType["LINE"] = "line";
9
+ GraphicType["EDGE"] = "edge";
10
+ GraphicType["ARC"] = "arc";
11
+ GraphicType["CIRCLE"] = "circle";
12
+ GraphicType["PLANE"] = "plane";
13
+ GraphicType["CYLINDER"] = "cylinder";
14
+ GraphicType["CONE"] = "cone";
15
+ GraphicType["SPHERE"] = "sphere";
16
+ GraphicType["NURBS"] = "nurbs";
17
+ GraphicType["NURBSSURFACE"] = "nurbsSurface";
18
+ // Entities
19
+ GraphicType["NONE"] = "none";
20
+ GraphicType["BREP"] = "brep";
21
+ GraphicType["POLYBREP"] = "polyBrep";
22
+ GraphicType["CURVEARRAY"] = "curveArray";
23
+ // Curve array elements
24
+ GraphicType["CURVELINE"] = "curveLine";
25
+ GraphicType["CURVESPLINE"] = "curveSpline";
26
+ GraphicType["CURVEARC"] = "curveArc";
27
+ GraphicType["CURVECIRCLE"] = "curveCircle";
28
+ GraphicType["CURVEPOINT"] = "curvePoint";
29
+ // Custom type(s) (not defined by server protocol)
30
+ GraphicType["LOOP"] = "loop";
31
+ })(GraphicType = exports.GraphicType || (exports.GraphicType = {}));
32
+ var ContainerType;
33
+ (function (ContainerType) {
34
+ ContainerType[ContainerType["NONE"] = 0] = "NONE";
35
+ ContainerType[ContainerType["BREP"] = 1] = "BREP";
36
+ ContainerType[ContainerType["CURVEARRAY"] = 2] = "CURVEARRAY";
37
+ ContainerType[ContainerType["POLYBREP"] = 3] = "POLYBREP";
38
+ // POINTARRAY = 4, // Not used at the moment
39
+ // GRAPHIC = 5, // Not used at the moment
40
+ // LIGHTWEIGHTBREP = 6, // Not used at the moment
41
+ })(ContainerType = exports.ContainerType || (exports.ContainerType = {}));
42
+ const G = GraphicType;
43
+ exports.AllTypes = Object.keys(G).map(key => G[key]);
44
+ exports.Surfaces = [G.PLANE, G.CYLINDER, G.CONE, G.SPHERE, G.NURBS, G.NURBSSURFACE];
45
+ exports.LineSegments = [G.LINE, G.EDGE, G.ARC, G.CIRCLE];
46
+ exports.Primitives = exports.Surfaces.concat(exports.LineSegments).concat([G.POINT]);
47
+ exports.CurveSegments = [G.CURVELINE, G.CURVESPLINE, G.CURVEARC, G.CURVECIRCLE];
48
+ exports.EntityTypes = [G.BREP, G.POLYBREP, G.CURVEARRAY];
49
+ exports.PointTypes = [G.POINT, G.CURVEPOINT];
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MemberType = exports.NOID = exports.DEFAULT_STRUCTURE_TREE = void 0;
4
+ /**
5
+ * Defines the default structure tree.
6
+ * Should be used to initialize a new structure tree.
7
+ */
8
+ const DEFAULT_STRUCTURE_TREE = () => {
9
+ return {
10
+ tree: {},
11
+ root: exports.NOID,
12
+ currentProduct: exports.NOID,
13
+ currentNode: exports.NOID,
14
+ testRoot: exports.NOID,
15
+ };
16
+ };
17
+ exports.DEFAULT_STRUCTURE_TREE = DEFAULT_STRUCTURE_TREE;
18
+ /** Zero is no Id in classcad, and no object will exist in the CCDatabase for Id === 0! */
19
+ exports.NOID = 0;
20
+ var MemberType;
21
+ (function (MemberType) {
22
+ MemberType["ARRAY"] = "array";
23
+ MemberType["ID"] = "id";
24
+ MemberType["POINT"] = "point";
25
+ MemberType["REAL"] = "real";
26
+ MemberType["STRING"] = "string";
27
+ })(MemberType = exports.MemberType || (exports.MemberType = {}));
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createUniqueIdent = exports.createInfo = void 0;
4
+ const createInfo = (data) => {
5
+ return Object.assign({ uniqueIdent: (0, exports.createUniqueIdent)(data) }, data);
6
+ };
7
+ exports.createInfo = createInfo;
8
+ const createUniqueIdent = (data) => {
9
+ return `${[data.prodRefId, data.objectId, data.containerId, data.graphicId]}`;
10
+ };
11
+ exports.createUniqueIdent = createUniqueIdent;