kitchen-simulator 5.0.0-test.66 → 5.0.0-test.68

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.
@@ -1,528 +1,528 @@
1
- import React from 'react';
2
- import Ruler3D from './ruler3D';
3
- import convert from 'convert-units';
4
- import { GeometryUtils } from '../../../utils/export';
5
- import { returnReplaceableDeepSearchType } from '../../../components/viewer2d/utils';
6
- import { DELTA, DISTANCE_EPSILON, DECIMAL_PLACES_2 } from '../../../constants';
7
- import { formatNumber, isNonZeroText } from '../../../utils/math';
8
-
9
- export default function Layer3D({
10
- layer,
11
- frontRect,
12
- lineLength,
13
- ceilHeight,
14
- catalog,
15
- scene,
16
- scale,
17
- mode,
18
- line,
19
- viewScale,
20
- downloadFlag
21
- }) {
22
- const { width, height } = frontRect;
23
- let v0 = layer.vertices.get(line.vertices.get(0));
24
- let v1 = layer.vertices.get(line.vertices.get(1));
25
- const l0 = { x: v0.x, y: v0.y };
26
- const l1 = { x: v1.x, y: v1.y };
27
- const rulerSpace = 50 * viewScale;
28
- const lineSpace = 25 * viewScale;
29
- let rulerLines = [],
30
- rulerData = [],
31
- baseItems = [],
32
- wallItems = [],
33
- basePosArray = [
34
- { x: width / 2, y: height / 2 },
35
- { x: -width / 2, y: height / 2 }
36
- ],
37
- wallPosArray = [
38
- { x: -width / 2, y: -height / 2 },
39
- { x: width / 2, y: -height / 2 }
40
- ],
41
- left_count = 0,
42
- right_count = 0,
43
- leftBaseItems = [],
44
- rightBaseItems = [],
45
- leftWallItems = [],
46
- rightWallItems = [],
47
- toler_unit = 'mm';
48
-
49
- // get length between 2 points
50
- const getLength = (vertex0, vertex1) => {
51
- return Math.sqrt(
52
- Math.pow(vertex0.x - vertex1.x, 2) + Math.pow(vertex0.y - vertex1.y, 2)
53
- );
54
- };
55
-
56
- // determin if this line(vertex0, vertex1) is snapped into wall
57
- const isSnapped = (vertex0, vertex1) => {
58
- let itemSnapped = false;
59
- let delta = GeometryUtils.distancePointFromLineSegment(
60
- l0,
61
- l1,
62
- (vertex0.x + vertex1.x) / 2,
63
- (vertex0.y + vertex1.y) / 2
64
- );
65
- if (delta < DISTANCE_EPSILON) {
66
- itemSnapped = true;
67
- }
68
- return itemSnapped;
69
- };
70
-
71
- // get array of wallItem and baseITem in layer
72
- layer.items.forEach(item => {
73
- let val = {
74
- pos: { x: item.x, y: item.y },
75
- rotRad: (item.rotation / 180) * Math.PI
76
- };
77
- let catid = item.type;
78
- let cat = catalog.elements[catid];
79
- if (!cat) cat = catalog.elements[returnReplaceableDeepSearchType(catid)];
80
- let width = convert(item.properties.getIn(['width', '_length']))
81
- .from(item.properties.getIn(['width', '_unit']))
82
- .to(scene.unit);
83
- let height = convert(item.properties.getIn(['height', '_length']))
84
- .from(item.properties.getIn(['height', '_unit']))
85
- .to(scene.unit);
86
- let depth = convert(item.properties.getIn(['depth', '_length']))
87
- .from(item.properties.getIn(['depth', '_unit']))
88
- .to(scene.unit);
89
- let altitude = convert(item.properties.getIn(['altitude', '_length']))
90
- .from(item.properties.getIn(['altitude', '_unit']))
91
- .to(scene.unit);
92
- val.size = { width, height, depth, altitude };
93
- val.layoutpos = cat && cat.info.layoutpos;
94
- val.is_corner = cat && cat.info.is_corner;
95
- val.item = item.toJS();
96
- let calcrect = GeometryUtils.getCalcRectFromItem3D(val);
97
-
98
- if (
99
- isSnapped(calcrect.rect[3], calcrect.rect[2]) ||
100
- isSnapped(calcrect.rect[2], calcrect.rect[1]) ||
101
- isSnapped(calcrect.rect[0], calcrect.rect[3])
102
- ) {
103
- if (calcrect.itemInfo.properties.altitude.length) {
104
- wallItems.push(calcrect);
105
- } else {
106
- baseItems.push(calcrect);
107
- }
108
- }
109
- });
110
-
111
- // sort function
112
- const sortFunc = (a, b) => {
113
- return a.pos.x - b.pos.x;
114
- };
115
- const negSortFunc = (a, b) => -sortFunc(a, b);
116
-
117
- // get item's pos array about baseItem, then sort - baseItems' order is right: (width/2) -> left: (-width/2)
118
- if (baseItems.length) {
119
- baseItems.forEach(item => {
120
- let vertex0, vertex1;
121
- if (isSnapped(item.rect[3], item.rect[2])) {
122
- vertex0 = {
123
- x:
124
- -frontRect.width / 2 +
125
- convert(getLength(item.rect[3], v0)).from('cm').to(layer.unit) *
126
- scale,
127
- y: height / 2
128
- };
129
- vertex1 = {
130
- x:
131
- -frontRect.width / 2 +
132
- convert(getLength(item.rect[2], v0)).from('cm').to(layer.unit) *
133
- scale,
134
- y: height / 2
135
- };
136
- } else if (isSnapped(item.rect[2], item.rect[1])) {
137
- vertex0 = {
138
- x:
139
- -frontRect.width / 2 +
140
- convert(getLength(item.rect[2], v0)).from('cm').to(layer.unit) *
141
- scale,
142
- y: height / 2
143
- };
144
- vertex1 = {
145
- x:
146
- -frontRect.width / 2 +
147
- convert(getLength(item.rect[1], v0)).from('cm').to(layer.unit) *
148
- scale,
149
- y: height / 2
150
- };
151
- } else if (isSnapped(item.rect[0], item.rect[3])) {
152
- vertex0 = {
153
- x:
154
- -frontRect.width / 2 +
155
- convert(getLength(item.rect[0], v0)).from('cm').to(layer.unit) *
156
- scale,
157
- y: height / 2
158
- };
159
- vertex1 = {
160
- x:
161
- -frontRect.width / 2 +
162
- convert(getLength(item.rect[3], v0)).from('cm').to(layer.unit) *
163
- scale,
164
- y: height / 2
165
- };
166
- }
167
- basePosArray.push(vertex0);
168
- basePosArray.push(vertex1);
169
-
170
- // determin which side(left or right) item is closer to. If item is closer to left side, it will be included in leftBaseITems
171
- let distLeft = getLength(item.pos, v0);
172
- let distRight = getLength(item.pos, v1);
173
- if (distLeft < distRight) {
174
- leftBaseItems.push(item);
175
- } else {
176
- rightBaseItems.push(item);
177
- }
178
- });
179
- }
180
- basePosArray.sort((a, b) => {
181
- return b.x - a.x;
182
- });
183
-
184
- // get item's pos array about wallItem, then sort - wallItems' order is left: (-width/2) -> right: (width/2)
185
- if (wallItems.length) {
186
- wallItems.forEach(item => {
187
- let vertex0, vertex1;
188
- if (isSnapped(item.rect[3], item.rect[2])) {
189
- vertex0 = {
190
- x:
191
- -frontRect.width / 2 +
192
- convert(getLength(item.rect[3], v0)).from('cm').to(layer.unit) *
193
- scale,
194
- y: -height / 2
195
- };
196
- vertex1 = {
197
- x:
198
- -frontRect.width / 2 +
199
- convert(getLength(item.rect[2], v0)).from('cm').to(layer.unit) *
200
- scale,
201
- y: -height / 2
202
- };
203
- } else if (isSnapped(item.rect[2], item.rect[1])) {
204
- vertex0 = {
205
- x:
206
- -frontRect.width / 2 +
207
- convert(getLength(item.rect[2], v0)).from('cm').to(layer.unit) *
208
- scale,
209
- y: -height / 2
210
- };
211
- vertex1 = {
212
- x:
213
- -frontRect.width / 2 +
214
- convert(getLength(item.rect[1], v0)).from('cm').to(layer.unit) *
215
- scale,
216
- y: -height / 2
217
- };
218
- } else if (isSnapped(item.rect[0], item.rect[3])) {
219
- vertex0 = {
220
- x:
221
- -frontRect.width / 2 +
222
- convert(getLength(item.rect[0], v0)).from('cm').to(layer.unit) *
223
- scale,
224
- y: -height / 2
225
- };
226
- vertex1 = {
227
- x:
228
- -frontRect.width / 2 +
229
- convert(getLength(item.rect[3], v0)).from('cm').to(layer.unit) *
230
- scale,
231
- y: -height / 2
232
- };
233
- }
234
- wallPosArray.push(vertex0);
235
- wallPosArray.push(vertex1);
236
-
237
- // determin which side(left or right) item is closer to. If item is closer to left side, it will be included in leftBaseITems
238
- let distLeft = getLength(item.pos, v0);
239
- let distRight = getLength(item.pos, v1);
240
- if (distLeft < distRight) {
241
- rightWallItems.push(item);
242
- } else {
243
- leftWallItems.push(item);
244
- }
245
- });
246
- }
247
- wallPosArray.sort((a, b) => {
248
- return a.x - b.x;
249
- });
250
-
251
- // leftItems = leftBaseItems + inverted leftWallItems : Here, it's different between BaseItem's order and WallItem's order
252
- leftBaseItems.sort(sortFunc);
253
- leftWallItems.sort(negSortFunc);
254
-
255
- rightBaseItems.sort(negSortFunc);
256
- rightWallItems.sort(sortFunc);
257
- let leftItems = leftBaseItems.concat(leftWallItems);
258
- let rightItems = rightBaseItems.concat(rightWallItems);
259
-
260
- // To display side dimensions, set rulerLines about leftItems
261
- leftItems.forEach((item, idx) => {
262
- let forwardItems = [];
263
- let distLine = 0;
264
- let itemHeight = convert(item.size.height).from(scene.unit).to(layer.unit);
265
- for (let i = 0; i < idx; i++) {
266
- forwardItems.push(leftItems[i]);
267
- }
268
- if (
269
- !forwardItems.filter(
270
- it =>
271
- it.itemInfo.properties.altitude._length ===
272
- item.itemInfo.properties.altitude._length &&
273
- it.itemInfo.properties.height._length ===
274
- item.itemInfo.properties.height._length
275
- ).length
276
- ) {
277
- if (item.itemInfo.properties.altitude._length) {
278
- if (isSnapped(item.rect[3], item.rect[2])) {
279
- distLine = convert(getLength(item.rect[2], v1))
280
- .from(scene.unit)
281
- .to(layer.unit);
282
- } else if (isSnapped(item.rect[2], item.rect[1])) {
283
- distLine = convert(getLength(item.rect[1], v1))
284
- .from(scene.unit)
285
- .to(layer.unit);
286
- }
287
- let itemAltitude = convert(item.size.altitude)
288
- .from(scene.unit)
289
- .to(layer.unit);
290
-
291
- if (
292
- ceilHeight - (itemAltitude + itemHeight) >
293
- convert(DELTA).from(toler_unit).to(layer.unit)
294
- ) {
295
- rulerLines.push({
296
- v0: { x: width / 2, y: -height / 2 },
297
- v1: {
298
- x: width / 2,
299
- y: height / 2 - (itemHeight + itemAltitude) * scale
300
- },
301
- text: formatNumber(
302
- ceilHeight - (itemAltitude + itemHeight),
303
- DECIMAL_PLACES_2
304
- ),
305
- space: rulerSpace + right_count * lineSpace
306
- });
307
- }
308
- rulerLines.push({
309
- v0: {
310
- x: width / 2 - distLine * scale,
311
- y: height / 2 - (itemHeight + itemAltitude) * scale
312
- },
313
- v1: {
314
- x: width / 2 - distLine * scale,
315
- y: height / 2 - itemAltitude * scale
316
- },
317
- text: formatNumber(itemHeight, DECIMAL_PLACES_2),
318
- space: rulerSpace + distLine * scale + right_count * lineSpace
319
- });
320
- rulerLines.push({
321
- v0: {
322
- x: width / 2,
323
- y: height / 2 - itemAltitude * scale
324
- },
325
- v1: { x: width / 2, y: height / 2 },
326
- text: formatNumber(itemAltitude, DECIMAL_PLACES_2),
327
- space: rulerSpace + right_count * lineSpace
328
- });
329
- right_count++;
330
- } else {
331
- if (isSnapped(item.rect[3], item.rect[2])) {
332
- distLine = convert(getLength(item.rect[3], v0))
333
- .from(scene.unit)
334
- .to(layer.unit);
335
- } else if (isSnapped(item.rect[2], item.rect[1])) {
336
- distLine = convert(getLength(item.rect[2], v0))
337
- .from(scene.unit)
338
- .to(layer.unit);
339
- }
340
- rulerLines.push({
341
- v0: { x: -width / 2 + distLine * scale, y: height / 2 },
342
- v1: {
343
- x: -width / 2 + distLine * scale,
344
- y: height / 2 - itemHeight * scale
345
- },
346
- text: formatNumber(itemHeight, DECIMAL_PLACES_2),
347
- space: rulerSpace + distLine * scale + left_count * lineSpace
348
- });
349
- rulerLines.push({
350
- v0: { x: -width / 2, y: height / 2 - itemHeight * scale },
351
- v1: { x: -width / 2, y: -height / 2 },
352
- text: formatNumber(ceilHeight - itemHeight, DECIMAL_PLACES_2),
353
- space: rulerSpace + left_count * lineSpace
354
- });
355
- left_count++;
356
- }
357
- }
358
- });
359
-
360
- // To display side dimensions, set rulerLines about rightItems
361
- rightItems.forEach((item, idx) => {
362
- let forwardItems = [];
363
- let distLine = 0;
364
- let itemHeight = convert(item.size.height).from(scene.unit).to(layer.unit);
365
- for (let i = 0; i < idx; i++) {
366
- forwardItems.push(rightItems[i]);
367
- }
368
- if (
369
- !forwardItems.filter(
370
- it =>
371
- it.itemInfo.properties.altitude._length ===
372
- item.itemInfo.properties.altitude._length &&
373
- it.itemInfo.properties.height._length ===
374
- item.itemInfo.properties.height._length
375
- ).length
376
- ) {
377
- if (item.itemInfo.properties.altitude._length) {
378
- if (isSnapped(item.rect[3], item.rect[2])) {
379
- distLine = convert(getLength(item.rect[3], v0))
380
- .from(scene.unit)
381
- .to(layer.unit);
382
- } else if (isSnapped(item.rect[2], item.rect[1])) {
383
- distLine = convert(getLength(item.rect[2], v0))
384
- .from(scene.unit)
385
- .to(layer.unit);
386
- }
387
- let itemHeight = convert(item.size.height)
388
- .from(scene.unit)
389
- .to(layer.unit);
390
- let itemAltitude = convert(item.size.altitude)
391
- .from(scene.unit)
392
- .to(layer.unit);
393
- rulerLines.push({
394
- v0: { x: -width / 2, y: height / 2 },
395
- v1: {
396
- x: -width / 2,
397
- y: height / 2 - itemAltitude * scale
398
- },
399
- text: formatNumber(itemAltitude, DECIMAL_PLACES_2),
400
- space: rulerSpace + left_count * lineSpace
401
- });
402
- rulerLines.push({
403
- v0: {
404
- x: -width / 2 + distLine * scale,
405
- y: height / 2 - itemAltitude * scale
406
- },
407
- v1: {
408
- x: -width / 2 + distLine * scale,
409
- y: height / 2 - (itemAltitude + itemHeight) * scale
410
- },
411
- text: formatNumber(itemHeight, DECIMAL_PLACES_2),
412
- space: rulerSpace + +distLine * scale + left_count * lineSpace
413
- });
414
- if (
415
- ceilHeight - (itemAltitude + itemHeight) >
416
- convert(DELTA).from(toler_unit).to(layer.unit)
417
- ) {
418
- rulerLines.push({
419
- v0: {
420
- x: -width / 2,
421
- y: height / 2 - (itemAltitude + itemHeight) * scale
422
- },
423
- v1: { x: -width / 2, y: -height / 2 },
424
- text: formatNumber(
425
- ceilHeight - (itemAltitude + itemHeight),
426
- DECIMAL_PLACES_2
427
- ),
428
- space: rulerSpace + left_count * lineSpace
429
- });
430
- }
431
-
432
- left_count++;
433
- } else {
434
- if (isSnapped(item.rect[3], item.rect[2])) {
435
- distLine = convert(getLength(item.rect[2], v1))
436
- .from(scene.unit)
437
- .to(layer.unit);
438
- } else if (isSnapped(item.rect[2], item.rect[1])) {
439
- distLine = convert(getLength(item.rect[1], v1))
440
- .from(scene.unit)
441
- .to(layer.unit);
442
- }
443
- rulerLines.push({
444
- v0: { x: width / 2, y: -height / 2 },
445
- v1: { x: width / 2, y: height / 2 - itemHeight * scale },
446
- text: formatNumber(ceilHeight - itemHeight, DECIMAL_PLACES_2),
447
- space: rulerSpace + right_count * lineSpace
448
- });
449
- rulerLines.push({
450
- v0: {
451
- x: width / 2 - distLine * scale,
452
- y: height / 2 - itemHeight * scale
453
- },
454
- v1: { x: width / 2 - distLine * scale, y: height / 2 },
455
- text: formatNumber(itemHeight, DECIMAL_PLACES_2),
456
- space: rulerSpace + distLine * scale + right_count * lineSpace
457
- });
458
- right_count++;
459
- }
460
- }
461
- });
462
-
463
- // To display wall line dimensions, set rulerLines
464
- rulerLines.push({
465
- v0: { x: width / 2, y: -height / 2 },
466
- v1: { x: width / 2, y: height / 2 },
467
- text: ceilHeight,
468
- space: rulerSpace + lineSpace * right_count
469
- });
470
- rulerLines.push({
471
- v0: { x: -width / 2, y: height / 2 },
472
- v1: { x: -width / 2, y: -height / 2 },
473
- text: ceilHeight,
474
- space: rulerSpace + lineSpace * left_count
475
- });
476
- rulerLines.push({
477
- v0: { x: width / 2, y: height / 2 },
478
- v1: { x: -width / 2, y: height / 2 },
479
- text: formatNumber(lineLength, DECIMAL_PLACES_2),
480
- space: rulerSpace + (baseItems.length ? lineSpace : 0)
481
- });
482
- rulerLines.push({
483
- v0: { x: -width / 2, y: -height / 2 },
484
- v1: { x: width / 2, y: -height / 2 },
485
- text: formatNumber(lineLength, DECIMAL_PLACES_2),
486
- space: rulerSpace + (wallItems.length ? lineSpace : 0)
487
- });
488
-
489
- // To display wallItems dimensions, set rulerLines with wallPosArray
490
- if (wallItems.length) {
491
- for (let i = 0; i < wallPosArray.length - 1; i++) {
492
- let dist = getLength(wallPosArray[i], wallPosArray[i + 1]) / scale;
493
- rulerLines.push({
494
- v0: wallPosArray[i],
495
- v1: wallPosArray[i + 1],
496
- space: rulerSpace,
497
- text: formatNumber(dist, DECIMAL_PLACES_2)
498
- });
499
- }
500
- }
501
-
502
- // To display baseItems dimensions, set rulerLines with basePosArray
503
- if (baseItems.length) {
504
- for (let j = 0; j < basePosArray.length - 1; j++) {
505
- let dist = getLength(basePosArray[j], basePosArray[j + 1]) / scale;
506
- rulerLines.push({
507
- v0: basePosArray[j],
508
- v1: basePosArray[j + 1],
509
- space: rulerSpace,
510
- text: formatNumber(dist, DECIMAL_PLACES_2)
511
- });
512
- }
513
- }
514
-
515
- rulerLines.forEach(line => {
516
- if (isNonZeroText(line.text))
517
- rulerData.push(
518
- <Ruler3D
519
- line={line}
520
- layer={layer}
521
- viewScale={viewScale}
522
- downloadFlag={downloadFlag}
523
- />
524
- );
525
- });
526
-
527
- return <g opacity={layer.opacity}>{rulerData}</g>;
528
- }
1
+ import React from 'react';
2
+ import Ruler3D from './ruler3D';
3
+ import * as convert from 'convert-units';
4
+ import { GeometryUtils } from '../../../utils/export';
5
+ import { returnReplaceableDeepSearchType } from '../../../components/viewer2d/utils';
6
+ import { DELTA, DISTANCE_EPSILON, DECIMAL_PLACES_2 } from '../../../constants';
7
+ import { formatNumber, isNonZeroText } from '../../../utils/math';
8
+
9
+ export default function Layer3D({
10
+ layer,
11
+ frontRect,
12
+ lineLength,
13
+ ceilHeight,
14
+ catalog,
15
+ scene,
16
+ scale,
17
+ mode,
18
+ line,
19
+ viewScale,
20
+ downloadFlag
21
+ }) {
22
+ const { width, height } = frontRect;
23
+ let v0 = layer.vertices.get(line.vertices.get(0));
24
+ let v1 = layer.vertices.get(line.vertices.get(1));
25
+ const l0 = { x: v0.x, y: v0.y };
26
+ const l1 = { x: v1.x, y: v1.y };
27
+ const rulerSpace = 50 * viewScale;
28
+ const lineSpace = 25 * viewScale;
29
+ let rulerLines = [],
30
+ rulerData = [],
31
+ baseItems = [],
32
+ wallItems = [],
33
+ basePosArray = [
34
+ { x: width / 2, y: height / 2 },
35
+ { x: -width / 2, y: height / 2 }
36
+ ],
37
+ wallPosArray = [
38
+ { x: -width / 2, y: -height / 2 },
39
+ { x: width / 2, y: -height / 2 }
40
+ ],
41
+ left_count = 0,
42
+ right_count = 0,
43
+ leftBaseItems = [],
44
+ rightBaseItems = [],
45
+ leftWallItems = [],
46
+ rightWallItems = [],
47
+ toler_unit = 'mm';
48
+
49
+ // get length between 2 points
50
+ const getLength = (vertex0, vertex1) => {
51
+ return Math.sqrt(
52
+ Math.pow(vertex0.x - vertex1.x, 2) + Math.pow(vertex0.y - vertex1.y, 2)
53
+ );
54
+ };
55
+
56
+ // determin if this line(vertex0, vertex1) is snapped into wall
57
+ const isSnapped = (vertex0, vertex1) => {
58
+ let itemSnapped = false;
59
+ let delta = GeometryUtils.distancePointFromLineSegment(
60
+ l0,
61
+ l1,
62
+ (vertex0.x + vertex1.x) / 2,
63
+ (vertex0.y + vertex1.y) / 2
64
+ );
65
+ if (delta < DISTANCE_EPSILON) {
66
+ itemSnapped = true;
67
+ }
68
+ return itemSnapped;
69
+ };
70
+
71
+ // get array of wallItem and baseITem in layer
72
+ layer.items.forEach(item => {
73
+ let val = {
74
+ pos: { x: item.x, y: item.y },
75
+ rotRad: (item.rotation / 180) * Math.PI
76
+ };
77
+ let catid = item.type;
78
+ let cat = catalog.elements[catid];
79
+ if (!cat) cat = catalog.elements[returnReplaceableDeepSearchType(catid)];
80
+ let width = convert(item.properties.getIn(['width', '_length']))
81
+ .from(item.properties.getIn(['width', '_unit']))
82
+ .to(scene.unit);
83
+ let height = convert(item.properties.getIn(['height', '_length']))
84
+ .from(item.properties.getIn(['height', '_unit']))
85
+ .to(scene.unit);
86
+ let depth = convert(item.properties.getIn(['depth', '_length']))
87
+ .from(item.properties.getIn(['depth', '_unit']))
88
+ .to(scene.unit);
89
+ let altitude = convert(item.properties.getIn(['altitude', '_length']))
90
+ .from(item.properties.getIn(['altitude', '_unit']))
91
+ .to(scene.unit);
92
+ val.size = { width, height, depth, altitude };
93
+ val.layoutpos = cat && cat.info.layoutpos;
94
+ val.is_corner = cat && cat.info.is_corner;
95
+ val.item = item.toJS();
96
+ let calcrect = GeometryUtils.getCalcRectFromItem3D(val);
97
+
98
+ if (
99
+ isSnapped(calcrect.rect[3], calcrect.rect[2]) ||
100
+ isSnapped(calcrect.rect[2], calcrect.rect[1]) ||
101
+ isSnapped(calcrect.rect[0], calcrect.rect[3])
102
+ ) {
103
+ if (calcrect.itemInfo.properties.altitude.length) {
104
+ wallItems.push(calcrect);
105
+ } else {
106
+ baseItems.push(calcrect);
107
+ }
108
+ }
109
+ });
110
+
111
+ // sort function
112
+ const sortFunc = (a, b) => {
113
+ return a.pos.x - b.pos.x;
114
+ };
115
+ const negSortFunc = (a, b) => -sortFunc(a, b);
116
+
117
+ // get item's pos array about baseItem, then sort - baseItems' order is right: (width/2) -> left: (-width/2)
118
+ if (baseItems.length) {
119
+ baseItems.forEach(item => {
120
+ let vertex0, vertex1;
121
+ if (isSnapped(item.rect[3], item.rect[2])) {
122
+ vertex0 = {
123
+ x:
124
+ -frontRect.width / 2 +
125
+ convert(getLength(item.rect[3], v0)).from('cm').to(layer.unit) *
126
+ scale,
127
+ y: height / 2
128
+ };
129
+ vertex1 = {
130
+ x:
131
+ -frontRect.width / 2 +
132
+ convert(getLength(item.rect[2], v0)).from('cm').to(layer.unit) *
133
+ scale,
134
+ y: height / 2
135
+ };
136
+ } else if (isSnapped(item.rect[2], item.rect[1])) {
137
+ vertex0 = {
138
+ x:
139
+ -frontRect.width / 2 +
140
+ convert(getLength(item.rect[2], v0)).from('cm').to(layer.unit) *
141
+ scale,
142
+ y: height / 2
143
+ };
144
+ vertex1 = {
145
+ x:
146
+ -frontRect.width / 2 +
147
+ convert(getLength(item.rect[1], v0)).from('cm').to(layer.unit) *
148
+ scale,
149
+ y: height / 2
150
+ };
151
+ } else if (isSnapped(item.rect[0], item.rect[3])) {
152
+ vertex0 = {
153
+ x:
154
+ -frontRect.width / 2 +
155
+ convert(getLength(item.rect[0], v0)).from('cm').to(layer.unit) *
156
+ scale,
157
+ y: height / 2
158
+ };
159
+ vertex1 = {
160
+ x:
161
+ -frontRect.width / 2 +
162
+ convert(getLength(item.rect[3], v0)).from('cm').to(layer.unit) *
163
+ scale,
164
+ y: height / 2
165
+ };
166
+ }
167
+ basePosArray.push(vertex0);
168
+ basePosArray.push(vertex1);
169
+
170
+ // determin which side(left or right) item is closer to. If item is closer to left side, it will be included in leftBaseITems
171
+ let distLeft = getLength(item.pos, v0);
172
+ let distRight = getLength(item.pos, v1);
173
+ if (distLeft < distRight) {
174
+ leftBaseItems.push(item);
175
+ } else {
176
+ rightBaseItems.push(item);
177
+ }
178
+ });
179
+ }
180
+ basePosArray.sort((a, b) => {
181
+ return b.x - a.x;
182
+ });
183
+
184
+ // get item's pos array about wallItem, then sort - wallItems' order is left: (-width/2) -> right: (width/2)
185
+ if (wallItems.length) {
186
+ wallItems.forEach(item => {
187
+ let vertex0, vertex1;
188
+ if (isSnapped(item.rect[3], item.rect[2])) {
189
+ vertex0 = {
190
+ x:
191
+ -frontRect.width / 2 +
192
+ convert(getLength(item.rect[3], v0)).from('cm').to(layer.unit) *
193
+ scale,
194
+ y: -height / 2
195
+ };
196
+ vertex1 = {
197
+ x:
198
+ -frontRect.width / 2 +
199
+ convert(getLength(item.rect[2], v0)).from('cm').to(layer.unit) *
200
+ scale,
201
+ y: -height / 2
202
+ };
203
+ } else if (isSnapped(item.rect[2], item.rect[1])) {
204
+ vertex0 = {
205
+ x:
206
+ -frontRect.width / 2 +
207
+ convert(getLength(item.rect[2], v0)).from('cm').to(layer.unit) *
208
+ scale,
209
+ y: -height / 2
210
+ };
211
+ vertex1 = {
212
+ x:
213
+ -frontRect.width / 2 +
214
+ convert(getLength(item.rect[1], v0)).from('cm').to(layer.unit) *
215
+ scale,
216
+ y: -height / 2
217
+ };
218
+ } else if (isSnapped(item.rect[0], item.rect[3])) {
219
+ vertex0 = {
220
+ x:
221
+ -frontRect.width / 2 +
222
+ convert(getLength(item.rect[0], v0)).from('cm').to(layer.unit) *
223
+ scale,
224
+ y: -height / 2
225
+ };
226
+ vertex1 = {
227
+ x:
228
+ -frontRect.width / 2 +
229
+ convert(getLength(item.rect[3], v0)).from('cm').to(layer.unit) *
230
+ scale,
231
+ y: -height / 2
232
+ };
233
+ }
234
+ wallPosArray.push(vertex0);
235
+ wallPosArray.push(vertex1);
236
+
237
+ // determin which side(left or right) item is closer to. If item is closer to left side, it will be included in leftBaseITems
238
+ let distLeft = getLength(item.pos, v0);
239
+ let distRight = getLength(item.pos, v1);
240
+ if (distLeft < distRight) {
241
+ rightWallItems.push(item);
242
+ } else {
243
+ leftWallItems.push(item);
244
+ }
245
+ });
246
+ }
247
+ wallPosArray.sort((a, b) => {
248
+ return a.x - b.x;
249
+ });
250
+
251
+ // leftItems = leftBaseItems + inverted leftWallItems : Here, it's different between BaseItem's order and WallItem's order
252
+ leftBaseItems.sort(sortFunc);
253
+ leftWallItems.sort(negSortFunc);
254
+
255
+ rightBaseItems.sort(negSortFunc);
256
+ rightWallItems.sort(sortFunc);
257
+ let leftItems = leftBaseItems.concat(leftWallItems);
258
+ let rightItems = rightBaseItems.concat(rightWallItems);
259
+
260
+ // To display side dimensions, set rulerLines about leftItems
261
+ leftItems.forEach((item, idx) => {
262
+ let forwardItems = [];
263
+ let distLine = 0;
264
+ let itemHeight = convert(item.size.height).from(scene.unit).to(layer.unit);
265
+ for (let i = 0; i < idx; i++) {
266
+ forwardItems.push(leftItems[i]);
267
+ }
268
+ if (
269
+ !forwardItems.filter(
270
+ it =>
271
+ it.itemInfo.properties.altitude._length ===
272
+ item.itemInfo.properties.altitude._length &&
273
+ it.itemInfo.properties.height._length ===
274
+ item.itemInfo.properties.height._length
275
+ ).length
276
+ ) {
277
+ if (item.itemInfo.properties.altitude._length) {
278
+ if (isSnapped(item.rect[3], item.rect[2])) {
279
+ distLine = convert(getLength(item.rect[2], v1))
280
+ .from(scene.unit)
281
+ .to(layer.unit);
282
+ } else if (isSnapped(item.rect[2], item.rect[1])) {
283
+ distLine = convert(getLength(item.rect[1], v1))
284
+ .from(scene.unit)
285
+ .to(layer.unit);
286
+ }
287
+ let itemAltitude = convert(item.size.altitude)
288
+ .from(scene.unit)
289
+ .to(layer.unit);
290
+
291
+ if (
292
+ ceilHeight - (itemAltitude + itemHeight) >
293
+ convert(DELTA).from(toler_unit).to(layer.unit)
294
+ ) {
295
+ rulerLines.push({
296
+ v0: { x: width / 2, y: -height / 2 },
297
+ v1: {
298
+ x: width / 2,
299
+ y: height / 2 - (itemHeight + itemAltitude) * scale
300
+ },
301
+ text: formatNumber(
302
+ ceilHeight - (itemAltitude + itemHeight),
303
+ DECIMAL_PLACES_2
304
+ ),
305
+ space: rulerSpace + right_count * lineSpace
306
+ });
307
+ }
308
+ rulerLines.push({
309
+ v0: {
310
+ x: width / 2 - distLine * scale,
311
+ y: height / 2 - (itemHeight + itemAltitude) * scale
312
+ },
313
+ v1: {
314
+ x: width / 2 - distLine * scale,
315
+ y: height / 2 - itemAltitude * scale
316
+ },
317
+ text: formatNumber(itemHeight, DECIMAL_PLACES_2),
318
+ space: rulerSpace + distLine * scale + right_count * lineSpace
319
+ });
320
+ rulerLines.push({
321
+ v0: {
322
+ x: width / 2,
323
+ y: height / 2 - itemAltitude * scale
324
+ },
325
+ v1: { x: width / 2, y: height / 2 },
326
+ text: formatNumber(itemAltitude, DECIMAL_PLACES_2),
327
+ space: rulerSpace + right_count * lineSpace
328
+ });
329
+ right_count++;
330
+ } else {
331
+ if (isSnapped(item.rect[3], item.rect[2])) {
332
+ distLine = convert(getLength(item.rect[3], v0))
333
+ .from(scene.unit)
334
+ .to(layer.unit);
335
+ } else if (isSnapped(item.rect[2], item.rect[1])) {
336
+ distLine = convert(getLength(item.rect[2], v0))
337
+ .from(scene.unit)
338
+ .to(layer.unit);
339
+ }
340
+ rulerLines.push({
341
+ v0: { x: -width / 2 + distLine * scale, y: height / 2 },
342
+ v1: {
343
+ x: -width / 2 + distLine * scale,
344
+ y: height / 2 - itemHeight * scale
345
+ },
346
+ text: formatNumber(itemHeight, DECIMAL_PLACES_2),
347
+ space: rulerSpace + distLine * scale + left_count * lineSpace
348
+ });
349
+ rulerLines.push({
350
+ v0: { x: -width / 2, y: height / 2 - itemHeight * scale },
351
+ v1: { x: -width / 2, y: -height / 2 },
352
+ text: formatNumber(ceilHeight - itemHeight, DECIMAL_PLACES_2),
353
+ space: rulerSpace + left_count * lineSpace
354
+ });
355
+ left_count++;
356
+ }
357
+ }
358
+ });
359
+
360
+ // To display side dimensions, set rulerLines about rightItems
361
+ rightItems.forEach((item, idx) => {
362
+ let forwardItems = [];
363
+ let distLine = 0;
364
+ let itemHeight = convert(item.size.height).from(scene.unit).to(layer.unit);
365
+ for (let i = 0; i < idx; i++) {
366
+ forwardItems.push(rightItems[i]);
367
+ }
368
+ if (
369
+ !forwardItems.filter(
370
+ it =>
371
+ it.itemInfo.properties.altitude._length ===
372
+ item.itemInfo.properties.altitude._length &&
373
+ it.itemInfo.properties.height._length ===
374
+ item.itemInfo.properties.height._length
375
+ ).length
376
+ ) {
377
+ if (item.itemInfo.properties.altitude._length) {
378
+ if (isSnapped(item.rect[3], item.rect[2])) {
379
+ distLine = convert(getLength(item.rect[3], v0))
380
+ .from(scene.unit)
381
+ .to(layer.unit);
382
+ } else if (isSnapped(item.rect[2], item.rect[1])) {
383
+ distLine = convert(getLength(item.rect[2], v0))
384
+ .from(scene.unit)
385
+ .to(layer.unit);
386
+ }
387
+ let itemHeight = convert(item.size.height)
388
+ .from(scene.unit)
389
+ .to(layer.unit);
390
+ let itemAltitude = convert(item.size.altitude)
391
+ .from(scene.unit)
392
+ .to(layer.unit);
393
+ rulerLines.push({
394
+ v0: { x: -width / 2, y: height / 2 },
395
+ v1: {
396
+ x: -width / 2,
397
+ y: height / 2 - itemAltitude * scale
398
+ },
399
+ text: formatNumber(itemAltitude, DECIMAL_PLACES_2),
400
+ space: rulerSpace + left_count * lineSpace
401
+ });
402
+ rulerLines.push({
403
+ v0: {
404
+ x: -width / 2 + distLine * scale,
405
+ y: height / 2 - itemAltitude * scale
406
+ },
407
+ v1: {
408
+ x: -width / 2 + distLine * scale,
409
+ y: height / 2 - (itemAltitude + itemHeight) * scale
410
+ },
411
+ text: formatNumber(itemHeight, DECIMAL_PLACES_2),
412
+ space: rulerSpace + +distLine * scale + left_count * lineSpace
413
+ });
414
+ if (
415
+ ceilHeight - (itemAltitude + itemHeight) >
416
+ convert(DELTA).from(toler_unit).to(layer.unit)
417
+ ) {
418
+ rulerLines.push({
419
+ v0: {
420
+ x: -width / 2,
421
+ y: height / 2 - (itemAltitude + itemHeight) * scale
422
+ },
423
+ v1: { x: -width / 2, y: -height / 2 },
424
+ text: formatNumber(
425
+ ceilHeight - (itemAltitude + itemHeight),
426
+ DECIMAL_PLACES_2
427
+ ),
428
+ space: rulerSpace + left_count * lineSpace
429
+ });
430
+ }
431
+
432
+ left_count++;
433
+ } else {
434
+ if (isSnapped(item.rect[3], item.rect[2])) {
435
+ distLine = convert(getLength(item.rect[2], v1))
436
+ .from(scene.unit)
437
+ .to(layer.unit);
438
+ } else if (isSnapped(item.rect[2], item.rect[1])) {
439
+ distLine = convert(getLength(item.rect[1], v1))
440
+ .from(scene.unit)
441
+ .to(layer.unit);
442
+ }
443
+ rulerLines.push({
444
+ v0: { x: width / 2, y: -height / 2 },
445
+ v1: { x: width / 2, y: height / 2 - itemHeight * scale },
446
+ text: formatNumber(ceilHeight - itemHeight, DECIMAL_PLACES_2),
447
+ space: rulerSpace + right_count * lineSpace
448
+ });
449
+ rulerLines.push({
450
+ v0: {
451
+ x: width / 2 - distLine * scale,
452
+ y: height / 2 - itemHeight * scale
453
+ },
454
+ v1: { x: width / 2 - distLine * scale, y: height / 2 },
455
+ text: formatNumber(itemHeight, DECIMAL_PLACES_2),
456
+ space: rulerSpace + distLine * scale + right_count * lineSpace
457
+ });
458
+ right_count++;
459
+ }
460
+ }
461
+ });
462
+
463
+ // To display wall line dimensions, set rulerLines
464
+ rulerLines.push({
465
+ v0: { x: width / 2, y: -height / 2 },
466
+ v1: { x: width / 2, y: height / 2 },
467
+ text: ceilHeight,
468
+ space: rulerSpace + lineSpace * right_count
469
+ });
470
+ rulerLines.push({
471
+ v0: { x: -width / 2, y: height / 2 },
472
+ v1: { x: -width / 2, y: -height / 2 },
473
+ text: ceilHeight,
474
+ space: rulerSpace + lineSpace * left_count
475
+ });
476
+ rulerLines.push({
477
+ v0: { x: width / 2, y: height / 2 },
478
+ v1: { x: -width / 2, y: height / 2 },
479
+ text: formatNumber(lineLength, DECIMAL_PLACES_2),
480
+ space: rulerSpace + (baseItems.length ? lineSpace : 0)
481
+ });
482
+ rulerLines.push({
483
+ v0: { x: -width / 2, y: -height / 2 },
484
+ v1: { x: width / 2, y: -height / 2 },
485
+ text: formatNumber(lineLength, DECIMAL_PLACES_2),
486
+ space: rulerSpace + (wallItems.length ? lineSpace : 0)
487
+ });
488
+
489
+ // To display wallItems dimensions, set rulerLines with wallPosArray
490
+ if (wallItems.length) {
491
+ for (let i = 0; i < wallPosArray.length - 1; i++) {
492
+ let dist = getLength(wallPosArray[i], wallPosArray[i + 1]) / scale;
493
+ rulerLines.push({
494
+ v0: wallPosArray[i],
495
+ v1: wallPosArray[i + 1],
496
+ space: rulerSpace,
497
+ text: formatNumber(dist, DECIMAL_PLACES_2)
498
+ });
499
+ }
500
+ }
501
+
502
+ // To display baseItems dimensions, set rulerLines with basePosArray
503
+ if (baseItems.length) {
504
+ for (let j = 0; j < basePosArray.length - 1; j++) {
505
+ let dist = getLength(basePosArray[j], basePosArray[j + 1]) / scale;
506
+ rulerLines.push({
507
+ v0: basePosArray[j],
508
+ v1: basePosArray[j + 1],
509
+ space: rulerSpace,
510
+ text: formatNumber(dist, DECIMAL_PLACES_2)
511
+ });
512
+ }
513
+ }
514
+
515
+ rulerLines.forEach(line => {
516
+ if (isNonZeroText(line.text))
517
+ rulerData.push(
518
+ <Ruler3D
519
+ line={line}
520
+ layer={layer}
521
+ viewScale={viewScale}
522
+ downloadFlag={downloadFlag}
523
+ />
524
+ );
525
+ });
526
+
527
+ return <g opacity={layer.opacity}>{rulerData}</g>;
528
+ }