@mlightcad/cad-simple-viewer 1.5.9 → 1.5.10
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.
- package/dist/cad-simple-viewer.js +8345 -7349
- package/dist/cad-simple-viewer.umd.cjs +37 -37
- package/dist/mtext-renderer-worker.js +2896 -2767
- package/lib/app/AcApDocManager.d.ts +17 -8
- package/lib/app/AcApDocManager.d.ts.map +1 -1
- package/lib/app/AcApDocManager.js +50 -13
- package/lib/app/AcApDocManager.js.map +1 -1
- package/lib/app/AcApFontLoader.d.ts +49 -26
- package/lib/app/AcApFontLoader.d.ts.map +1 -1
- package/lib/app/AcApFontLoader.js +245 -48
- package/lib/app/AcApFontLoader.js.map +1 -1
- package/lib/app/AcApOpenFileProfiler.d.ts +70 -17
- package/lib/app/AcApOpenFileProfiler.d.ts.map +1 -1
- package/lib/app/AcApOpenFileProfiler.js +96 -46
- package/lib/app/AcApOpenFileProfiler.js.map +1 -1
- package/lib/app/AcApOpenFileProgressController.d.ts +22 -5
- package/lib/app/AcApOpenFileProgressController.d.ts.map +1 -1
- package/lib/app/AcApOpenFileProgressController.js +76 -31
- package/lib/app/AcApOpenFileProgressController.js.map +1 -1
- package/lib/app/AcApProgress.d.ts +6 -0
- package/lib/app/AcApProgress.d.ts.map +1 -1
- package/lib/app/AcApProgress.js +11 -0
- package/lib/app/AcApProgress.js.map +1 -1
- package/lib/app/AcDbOpenDatabaseOptions.d.ts +15 -12
- package/lib/app/AcDbOpenDatabaseOptions.d.ts.map +1 -1
- package/lib/app/index.d.ts +1 -0
- package/lib/app/index.d.ts.map +1 -1
- package/lib/app/index.js +1 -0
- package/lib/app/index.js.map +1 -1
- package/lib/editor/view/AcEdSpatialQueryResult.d.ts +10 -0
- package/lib/editor/view/AcEdSpatialQueryResult.d.ts.map +1 -1
- package/lib/editor/view/AcEdSpatialQueryResult.js +36 -0
- package/lib/editor/view/AcEdSpatialQueryResult.js.map +1 -1
- package/lib/i18n/cs/command.d.ts +3 -0
- package/lib/i18n/cs/command.d.ts.map +1 -1
- package/lib/i18n/cs/command.js +3 -0
- package/lib/i18n/cs/command.js.map +1 -1
- package/lib/i18n/cs/main.d.ts +1 -0
- package/lib/i18n/cs/main.d.ts.map +1 -1
- package/lib/i18n/cs/main.js +1 -0
- package/lib/i18n/cs/main.js.map +1 -1
- package/lib/i18n/en/command.d.ts +3 -0
- package/lib/i18n/en/command.d.ts.map +1 -1
- package/lib/i18n/en/command.js +3 -0
- package/lib/i18n/en/command.js.map +1 -1
- package/lib/i18n/en/main.d.ts +1 -0
- package/lib/i18n/en/main.d.ts.map +1 -1
- package/lib/i18n/en/main.js +1 -0
- package/lib/i18n/en/main.js.map +1 -1
- package/lib/i18n/tr/command.d.ts +3 -0
- package/lib/i18n/tr/command.d.ts.map +1 -1
- package/lib/i18n/tr/command.js +3 -0
- package/lib/i18n/tr/command.js.map +1 -1
- package/lib/i18n/tr/main.d.ts +1 -0
- package/lib/i18n/tr/main.d.ts.map +1 -1
- package/lib/i18n/tr/main.js +1 -0
- package/lib/i18n/tr/main.js.map +1 -1
- package/lib/i18n/zh/command.d.ts +3 -0
- package/lib/i18n/zh/command.d.ts.map +1 -1
- package/lib/i18n/zh/command.js +3 -0
- package/lib/i18n/zh/command.js.map +1 -1
- package/lib/i18n/zh/main.d.ts +1 -0
- package/lib/i18n/zh/main.d.ts.map +1 -1
- package/lib/i18n/zh/main.js +1 -0
- package/lib/i18n/zh/main.js.map +1 -1
- package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.d.ts.map +1 -1
- package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.js +2 -2
- package/lib/spatialIndex/AcTrHierarchicalSpatialIndex.js.map +1 -1
- package/lib/spatialIndex/AcTrLinearSpatialIndex.d.ts +6 -1
- package/lib/spatialIndex/AcTrLinearSpatialIndex.d.ts.map +1 -1
- package/lib/spatialIndex/AcTrLinearSpatialIndex.js +68 -11
- package/lib/spatialIndex/AcTrLinearSpatialIndex.js.map +1 -1
- package/lib/spatialIndex/AcTrRBushSpatialIndex.d.ts.map +1 -1
- package/lib/spatialIndex/AcTrRBushSpatialIndex.js +58 -12
- package/lib/spatialIndex/AcTrRBushSpatialIndex.js.map +1 -1
- package/lib/view/AcTrDirectBatch.d.ts +18 -0
- package/lib/view/AcTrDirectBatch.d.ts.map +1 -0
- package/lib/view/AcTrDirectBatch.js +113 -0
- package/lib/view/AcTrDirectBatch.js.map +1 -0
- package/lib/view/AcTrLayer.d.ts +7 -1
- package/lib/view/AcTrLayer.d.ts.map +1 -1
- package/lib/view/AcTrLayer.js +29 -0
- package/lib/view/AcTrLayer.js.map +1 -1
- package/lib/view/AcTrLayout.d.ts +11 -1
- package/lib/view/AcTrLayout.d.ts.map +1 -1
- package/lib/view/AcTrLayout.js +43 -0
- package/lib/view/AcTrLayout.js.map +1 -1
- package/lib/view/AcTrProgressiveOpenFitController.d.ts +10 -6
- package/lib/view/AcTrProgressiveOpenFitController.d.ts.map +1 -1
- package/lib/view/AcTrProgressiveOpenFitController.js +35 -76
- package/lib/view/AcTrProgressiveOpenFitController.js.map +1 -1
- package/lib/view/AcTrScene.d.ts +7 -1
- package/lib/view/AcTrScene.d.ts.map +1 -1
- package/lib/view/AcTrScene.js +18 -0
- package/lib/view/AcTrScene.js.map +1 -1
- package/lib/view/AcTrView2d.d.ts +87 -12
- package/lib/view/AcTrView2d.d.ts.map +1 -1
- package/lib/view/AcTrView2d.js +501 -166
- package/lib/view/AcTrView2d.js.map +1 -1
- package/lib/view/index.d.ts +1 -0
- package/lib/view/index.d.ts.map +1 -1
- package/lib/view/index.js +1 -0
- package/lib/view/index.js.map +1 -1
- package/package.json +7 -7
package/lib/view/AcTrView2d.js
CHANGED
|
@@ -96,9 +96,9 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
96
96
|
}
|
|
97
97
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
98
98
|
};
|
|
99
|
-
import { AcDbAttribute, AcDbBlockReference, acdbHostApplicationServices, AcDbMText, AcDbRasterImage, AcDbRay, AcDbSysVarManager, AcDbViewport, AcDbXline, AcGeBox2d, AcGePoint2d, log } from '@mlightcad/data-model';
|
|
99
|
+
import { AcCmUiYieldGate, AcDbAttribute, AcDbBlockReference, acdbHostApplicationServices, AcDbMText, AcDbRasterImage, AcDbRay, AcDbSysVarManager, AcDbViewport, AcDbXline, AcGeBox2d, AcGePoint2d, log } from '@mlightcad/data-model';
|
|
100
100
|
import { AcDbSystemVariables } from '@mlightcad/data-model';
|
|
101
|
-
import { AcTrEntity, AcTrGroup, AcTrRenderer, AcTrViewportView } from '@mlightcad/three-renderer';
|
|
101
|
+
import { AcTrEntity, AcTrGlyphEntity, AcTrGroup, AcTrRenderer, AcTrViewportView } from '@mlightcad/three-renderer';
|
|
102
102
|
import { AcTrMatrixUtil } from '@mlightcad/three-renderer';
|
|
103
103
|
import * as THREE from 'three';
|
|
104
104
|
import Stats from 'three/examples/jsm/libs/stats.module';
|
|
@@ -110,6 +110,7 @@ import { isEffectiveSpatialQueryHit } from '../editor/view/AcEdSpatialQueryResul
|
|
|
110
110
|
import { AcTrGeometryUtil } from '../util';
|
|
111
111
|
import { acapRunDatabaseEdit } from '../util/AcApDatabaseEdit';
|
|
112
112
|
import { AcEdViewKeyHandler } from './AcEdViewKeyHandler';
|
|
113
|
+
import { shouldExtendBboxForDirectEntity, tryBuildDirectEntityMeta } from './AcTrDirectBatch';
|
|
113
114
|
import { AcTrEntityDisplayController } from './AcTrEntityDisplayController';
|
|
114
115
|
import { assertAcTrGroupWcsBboxesConsistent, unionGroupWcsChildBoxes } from './AcTrGroupWcsBboxAssert';
|
|
115
116
|
import { AcTrInheritedLayerMaterialMapper } from './AcTrInheritedLayerMaterialMapper';
|
|
@@ -190,7 +191,7 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
190
191
|
* Block table record ids of layouts whose entities are currently being
|
|
191
192
|
* batch-converted into the scene. Used by
|
|
192
193
|
* {@link AcTrView2d.loadLayoutEntitiesIfNeeded} to guard against
|
|
193
|
-
* re-entrant calls before the
|
|
194
|
+
* re-entrant calls before the convert drain flips
|
|
194
195
|
* `AcTrLayout.isLoaded` to `true`, which would otherwise duplicate
|
|
195
196
|
* entities when the same layout tab is clicked twice in quick succession.
|
|
196
197
|
*/
|
|
@@ -236,10 +237,36 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
236
237
|
*/
|
|
237
238
|
_this._convertingLayers = new Set();
|
|
238
239
|
/**
|
|
239
|
-
* When true, entity conversion during document open
|
|
240
|
-
*
|
|
240
|
+
* When true, entity conversion during document open yields cooperatively so
|
|
241
|
+
* geometry paints incrementally while the open overlay is still visible.
|
|
241
242
|
*/
|
|
242
243
|
_this._progressiveRendering = false;
|
|
244
|
+
/**
|
|
245
|
+
* Serial convert queue for progressive opens. Chunks from `entityAppended`
|
|
246
|
+
* enqueue here and a single drain loop runs {@link batchConvert}, so scene
|
|
247
|
+
* convert overlaps ENTITY flush instead of waiting for a post-open
|
|
248
|
+
* `setTimeout` storm after the loading overlay hides.
|
|
249
|
+
*/
|
|
250
|
+
_this._convertQueue = [];
|
|
251
|
+
/** In-flight progressive convert drain; shared so awaiters wait for the queue. */
|
|
252
|
+
_this._convertDrainPromise = null;
|
|
253
|
+
/**
|
|
254
|
+
* Bumped by {@link clear} so an in-flight {@link batchConvert} abandons
|
|
255
|
+
* scene writes and counter updates after the view has been reset for a new
|
|
256
|
+
* document open.
|
|
257
|
+
*/
|
|
258
|
+
_this._convertEpoch = 0;
|
|
259
|
+
/** Last time progressive open marked the canvas dirty for paint. */
|
|
260
|
+
_this._lastProgressivePaintAt = 0;
|
|
261
|
+
/** Mid-open WebGL paints while progressive convert was still running. */
|
|
262
|
+
_this._progressivePaintCount = 0;
|
|
263
|
+
/** Cooperative yields taken inside progressive {@link batchConvert}. */
|
|
264
|
+
_this._progressiveYieldCount = 0;
|
|
265
|
+
/**
|
|
266
|
+
* In-flight glyph/group geometry jobs that await fonts via asyncDraw.
|
|
267
|
+
* Counted separately so linework convert can continue while text waits.
|
|
268
|
+
*/
|
|
269
|
+
_this._pendingGeometryJobs = 0;
|
|
243
270
|
_this.animate = function () {
|
|
244
271
|
var _a;
|
|
245
272
|
_this._rafId = requestAnimationFrame(_this.animate);
|
|
@@ -253,12 +280,20 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
253
280
|
return;
|
|
254
281
|
if (deferRenderWhileLoading)
|
|
255
282
|
return;
|
|
283
|
+
if (!_this._isDirty)
|
|
284
|
+
return;
|
|
285
|
+
if (_this._progressiveRendering && stillLoading) {
|
|
286
|
+
_this._progressivePaintCount++;
|
|
287
|
+
}
|
|
256
288
|
var needsRedraw = _this._layoutViewManager.render(_this._scene);
|
|
257
289
|
if (_this.internalCamera) {
|
|
258
290
|
_this._css2dRenderer.render(_this._scene.internalScene, _this.internalCamera);
|
|
259
291
|
}
|
|
260
292
|
(_a = _this._stats) === null || _a === void 0 ? void 0 : _a.update();
|
|
261
|
-
|
|
293
|
+
// Do not re-dirty every frame during progressive open — paint is throttled
|
|
294
|
+
// from geometry batches to keep total open time down. Counter hitting 0
|
|
295
|
+
// still forces a final dirty in decreaseNumOfEntitiesToProcess().
|
|
296
|
+
_this._isDirty = needsRedraw;
|
|
262
297
|
};
|
|
263
298
|
_this._gripManager = new AcEdGripManager(_this);
|
|
264
299
|
_this._keyHandler = new AcEdViewKeyHandler(_this);
|
|
@@ -482,6 +517,7 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
482
517
|
_this._isDirty = true;
|
|
483
518
|
_this.startAnimationLoop();
|
|
484
519
|
_this._numOfEntitiesToProcess = 0;
|
|
520
|
+
_this._pendingGeometryJobs = 0;
|
|
485
521
|
return _this;
|
|
486
522
|
}
|
|
487
523
|
AcTrView2d.prototype.getPointerSelectionAction = function (e) {
|
|
@@ -564,14 +600,15 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
564
600
|
});
|
|
565
601
|
Object.defineProperty(AcTrView2d.prototype, "isProcessingEntities", {
|
|
566
602
|
/**
|
|
567
|
-
* True while
|
|
603
|
+
* True while batch conversion or deferred glyph/group geometry is still
|
|
604
|
+
* running.
|
|
568
605
|
*
|
|
569
606
|
* Parsing can report 100% before this reaches zero; callers opening files
|
|
570
607
|
* should wait on this (as {@link zoomToFitDrawing} does) before hiding
|
|
571
608
|
* progress UI or assuming the canvas is ready.
|
|
572
609
|
*/
|
|
573
610
|
get: function () {
|
|
574
|
-
return this._numOfEntitiesToProcess > 0;
|
|
611
|
+
return this._numOfEntitiesToProcess > 0 || this._pendingGeometryJobs > 0;
|
|
575
612
|
},
|
|
576
613
|
enumerable: false,
|
|
577
614
|
configurable: true
|
|
@@ -585,10 +622,30 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
585
622
|
},
|
|
586
623
|
set: function (value) {
|
|
587
624
|
this._progressiveRendering = value;
|
|
625
|
+
this.resetProgressiveOpenStats();
|
|
626
|
+
},
|
|
627
|
+
enumerable: false,
|
|
628
|
+
configurable: true
|
|
629
|
+
});
|
|
630
|
+
Object.defineProperty(AcTrView2d.prototype, "progressiveOpenStats", {
|
|
631
|
+
/**
|
|
632
|
+
* Progressive-open counters for OPENPROF / palette (paints while converting,
|
|
633
|
+
* cooperative yields). Reset when progressive mode is enabled for an open.
|
|
634
|
+
*/
|
|
635
|
+
get: function () {
|
|
636
|
+
return {
|
|
637
|
+
paintCount: this._progressivePaintCount,
|
|
638
|
+
yieldCount: this._progressiveYieldCount
|
|
639
|
+
};
|
|
588
640
|
},
|
|
589
641
|
enumerable: false,
|
|
590
642
|
configurable: true
|
|
591
643
|
});
|
|
644
|
+
AcTrView2d.prototype.resetProgressiveOpenStats = function () {
|
|
645
|
+
this._progressivePaintCount = 0;
|
|
646
|
+
this._progressiveYieldCount = 0;
|
|
647
|
+
this._lastProgressivePaintAt = 0;
|
|
648
|
+
};
|
|
592
649
|
/**
|
|
593
650
|
* Enables progressive camera framing while entities are batch-converted at
|
|
594
651
|
* document open. Pair with {@link zoomToFitDrawing} for the final accurate fit.
|
|
@@ -1078,7 +1135,9 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
1078
1135
|
AcTrView2d.prototype.zoomToFitDrawing = function (timeout, layoutBtrId) {
|
|
1079
1136
|
var _this = this;
|
|
1080
1137
|
if (timeout === void 0) { timeout = 0; }
|
|
1081
|
-
var waiter = new AcEdConditionWaiter(
|
|
1138
|
+
var waiter = new AcEdConditionWaiter(
|
|
1139
|
+
// Include deferred glyph/group jobs so text extents land before final fit.
|
|
1140
|
+
function () { return !_this.isProcessingEntities; }, function () {
|
|
1082
1141
|
if (layoutBtrId && _this._externallyFramedLayouts.delete(layoutBtrId)) {
|
|
1083
1142
|
_this.endProgressiveOpenFit();
|
|
1084
1143
|
return;
|
|
@@ -1466,16 +1525,34 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
1466
1525
|
* @param entity Input one or multiple transient entities
|
|
1467
1526
|
*/
|
|
1468
1527
|
AcTrView2d.prototype.addTransientEntity = function (entity) {
|
|
1528
|
+
var _this = this;
|
|
1469
1529
|
var entities = Array.isArray(entity) ? entity : [entity];
|
|
1470
|
-
|
|
1530
|
+
var epoch = this._convertEpoch;
|
|
1531
|
+
var _loop_2 = function (i) {
|
|
1471
1532
|
var entity_1 = entities[i];
|
|
1472
|
-
var threeEntity =
|
|
1533
|
+
var threeEntity = this_1.drawEntity(entity_1, true);
|
|
1473
1534
|
if (threeEntity) {
|
|
1474
1535
|
threeEntity.objectId = entity_1.objectId;
|
|
1475
|
-
threeEntity
|
|
1476
|
-
|
|
1477
|
-
|
|
1536
|
+
void threeEntity
|
|
1537
|
+
.asyncDraw()
|
|
1538
|
+
.then(function () {
|
|
1539
|
+
// Drop stale transients started before clear()/regen invalidated the view.
|
|
1540
|
+
if (epoch !== _this._convertEpoch) {
|
|
1541
|
+
threeEntity.dispose();
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
_this._scene.addTransientEntity(threeEntity);
|
|
1545
|
+
_this._isDirty = true;
|
|
1546
|
+
})
|
|
1547
|
+
.catch(function (error) {
|
|
1548
|
+
log.error('[AcTrView2d] Transient entity geometry failed:', error);
|
|
1549
|
+
threeEntity.dispose();
|
|
1550
|
+
});
|
|
1478
1551
|
}
|
|
1552
|
+
};
|
|
1553
|
+
var this_1 = this;
|
|
1554
|
+
for (var i = 0; i < entities.length; ++i) {
|
|
1555
|
+
_loop_2(i);
|
|
1479
1556
|
}
|
|
1480
1557
|
};
|
|
1481
1558
|
/**
|
|
@@ -1533,25 +1610,15 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
1533
1610
|
* @inheritdoc
|
|
1534
1611
|
*/
|
|
1535
1612
|
AcTrView2d.prototype.addEntity = function (entity) {
|
|
1536
|
-
var
|
|
1613
|
+
var _a;
|
|
1537
1614
|
var entities = Array.isArray(entity) ? entity : [entity];
|
|
1538
1615
|
this._numOfEntitiesToProcess += entities.length;
|
|
1539
|
-
var convert = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1540
|
-
return __generator(this, function (_a) {
|
|
1541
|
-
switch (_a.label) {
|
|
1542
|
-
case 0: return [4 /*yield*/, this.batchConvert(entities)];
|
|
1543
|
-
case 1:
|
|
1544
|
-
_a.sent();
|
|
1545
|
-
return [2 /*return*/];
|
|
1546
|
-
}
|
|
1547
|
-
});
|
|
1548
|
-
}); };
|
|
1549
1616
|
if (this._progressiveRendering) {
|
|
1550
|
-
|
|
1551
|
-
this.
|
|
1617
|
+
(_a = this._convertQueue).push.apply(_a, __spreadArray([], __read(entities), false));
|
|
1618
|
+
void this.drainConvertQueue();
|
|
1552
1619
|
}
|
|
1553
1620
|
else {
|
|
1554
|
-
void
|
|
1621
|
+
void this.batchConvert(entities);
|
|
1555
1622
|
}
|
|
1556
1623
|
};
|
|
1557
1624
|
/**
|
|
@@ -1629,12 +1696,23 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
1629
1696
|
}
|
|
1630
1697
|
// Reconvert through the same path as initial load so block references are
|
|
1631
1698
|
// split by layer correctly and deferred MTEXT/SHAPE geometry is drawn.
|
|
1632
|
-
void
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1699
|
+
void (function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1700
|
+
return __generator(this, function (_a) {
|
|
1701
|
+
switch (_a.label) {
|
|
1702
|
+
case 0: return [4 /*yield*/, this.batchConvert(entities)];
|
|
1703
|
+
case 1:
|
|
1704
|
+
_a.sent();
|
|
1705
|
+
return [4 /*yield*/, this.waitUntilDeferredGeometryIdle()];
|
|
1706
|
+
case 2:
|
|
1707
|
+
_a.sent();
|
|
1708
|
+
if (selectedIds.length > 0) {
|
|
1709
|
+
this.highlight(selectedIds);
|
|
1710
|
+
}
|
|
1711
|
+
this._gripManager.refresh();
|
|
1712
|
+
return [2 /*return*/];
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
}); })();
|
|
1638
1716
|
this._isDirty = true;
|
|
1639
1717
|
// Not sure why texture for image entity isn't updated even if 'isDirty' flag is already set to true.
|
|
1640
1718
|
// So add one timeout event to set 'isDirty' flag to true again to make it work
|
|
@@ -1743,16 +1821,17 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
1743
1821
|
* **Critically, this runs through `AcEdConditionWaiter`**: at the
|
|
1744
1822
|
* moment `layoutSwitched` fires, the layout's entities (including its
|
|
1745
1823
|
* `AcDbViewport`s) have not yet been batch-converted into the scene
|
|
1746
|
-
* — `loadLayoutEntitiesIfNeeded` chunked-converts via
|
|
1824
|
+
* — `loadLayoutEntitiesIfNeeded` chunked-converts via the progressive
|
|
1825
|
+
* convert queue (or direct `batchConvert`).
|
|
1747
1826
|
* Without the waiter, `viewportsBoundingBox` returns undefined and
|
|
1748
1827
|
* the strategy degrades into (1) zooming to garbage `limits`, or
|
|
1749
1828
|
* (4) zooming to an empty scene box. The waiter polls
|
|
1750
|
-
*
|
|
1751
|
-
* conversion
|
|
1829
|
+
* {@link isProcessingEntities} (convert queue + deferred glyph jobs)
|
|
1830
|
+
* and only fires the heuristic once conversion and text geometry finish.
|
|
1752
1831
|
*/
|
|
1753
1832
|
AcTrView2d.prototype.applyInitialZoom = function (btrId, layout) {
|
|
1754
1833
|
var _this = this;
|
|
1755
|
-
var waiter = new AcEdConditionWaiter(function () { return _this.
|
|
1834
|
+
var waiter = new AcEdConditionWaiter(function () { return !_this.isProcessingEntities; }, function () {
|
|
1756
1835
|
if (_this._externallyFramedLayouts.delete(btrId)) {
|
|
1757
1836
|
return;
|
|
1758
1837
|
}
|
|
@@ -1793,11 +1872,80 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
1793
1872
|
* @inheritdoc
|
|
1794
1873
|
*/
|
|
1795
1874
|
AcTrView2d.prototype.clear = function () {
|
|
1875
|
+
// Invalidate any in-flight progressive convert so it neither paints into
|
|
1876
|
+
// the cleared scene nor double-decrements the processing counter.
|
|
1877
|
+
this._convertEpoch++;
|
|
1878
|
+
this._convertQueue.length = 0;
|
|
1879
|
+
this._numOfEntitiesToProcess = 0;
|
|
1880
|
+
this._pendingGeometryJobs = 0;
|
|
1796
1881
|
this._scene.clear();
|
|
1797
1882
|
this._isDirty = true;
|
|
1798
1883
|
this._missedImages.clear();
|
|
1799
1884
|
this._renderer.dispose();
|
|
1800
1885
|
};
|
|
1886
|
+
/**
|
|
1887
|
+
* Drains the progressive convert queue on a single serial worker so ENTITY
|
|
1888
|
+
* flush chunks can enqueue while conversion overlaps the loading overlay.
|
|
1889
|
+
*
|
|
1890
|
+
* Concurrent callers share the same promise; if more entities are queued
|
|
1891
|
+
* after a drain finishes, a follow-up drain is started.
|
|
1892
|
+
*/
|
|
1893
|
+
AcTrView2d.prototype.drainConvertQueue = function () {
|
|
1894
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1895
|
+
var _this = this;
|
|
1896
|
+
return __generator(this, function (_a) {
|
|
1897
|
+
switch (_a.label) {
|
|
1898
|
+
case 0:
|
|
1899
|
+
if (!this._convertDrainPromise) return [3 /*break*/, 4];
|
|
1900
|
+
return [4 /*yield*/, this._convertDrainPromise];
|
|
1901
|
+
case 1:
|
|
1902
|
+
_a.sent();
|
|
1903
|
+
if (!(this._convertQueue.length > 0)) return [3 /*break*/, 3];
|
|
1904
|
+
return [4 /*yield*/, this.drainConvertQueue()];
|
|
1905
|
+
case 2:
|
|
1906
|
+
_a.sent();
|
|
1907
|
+
_a.label = 3;
|
|
1908
|
+
case 3: return [2 /*return*/];
|
|
1909
|
+
case 4:
|
|
1910
|
+
this._convertDrainPromise = (function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1911
|
+
var batch;
|
|
1912
|
+
return __generator(this, function (_a) {
|
|
1913
|
+
switch (_a.label) {
|
|
1914
|
+
case 0:
|
|
1915
|
+
if (!(this._convertQueue.length > 0)) return [3 /*break*/, 2];
|
|
1916
|
+
batch = this._convertQueue.splice(0, this._convertQueue.length);
|
|
1917
|
+
return [4 /*yield*/, this.batchConvert(batch)];
|
|
1918
|
+
case 1:
|
|
1919
|
+
_a.sent();
|
|
1920
|
+
return [3 /*break*/, 0];
|
|
1921
|
+
case 2: return [2 /*return*/];
|
|
1922
|
+
}
|
|
1923
|
+
});
|
|
1924
|
+
}); })().finally(function () {
|
|
1925
|
+
_this._convertDrainPromise = null;
|
|
1926
|
+
});
|
|
1927
|
+
return [4 /*yield*/, this._convertDrainPromise];
|
|
1928
|
+
case 5:
|
|
1929
|
+
_a.sent();
|
|
1930
|
+
return [2 /*return*/];
|
|
1931
|
+
}
|
|
1932
|
+
});
|
|
1933
|
+
});
|
|
1934
|
+
};
|
|
1935
|
+
/**
|
|
1936
|
+
* Marks the canvas dirty for progressive open, throttled to avoid painting
|
|
1937
|
+
* on every entity (which dominated total open time).
|
|
1938
|
+
*/
|
|
1939
|
+
AcTrView2d.prototype.markProgressiveDirty = function (force) {
|
|
1940
|
+
if (force === void 0) { force = false; }
|
|
1941
|
+
var now = performance.now();
|
|
1942
|
+
if (force ||
|
|
1943
|
+
now - this._lastProgressivePaintAt >=
|
|
1944
|
+
AcTrView2d.PROGRESSIVE_OPEN_PAINT_INTERVAL_MS) {
|
|
1945
|
+
this._isDirty = true;
|
|
1946
|
+
this._lastProgressivePaintAt = now;
|
|
1947
|
+
}
|
|
1948
|
+
};
|
|
1801
1949
|
/**
|
|
1802
1950
|
* @inheritdoc
|
|
1803
1951
|
*/
|
|
@@ -1886,7 +2034,7 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
1886
2034
|
* on it would silently miss layouts that are pre-loaded ahead of
|
|
1887
2035
|
* becoming active (e.g. background prefetch).
|
|
1888
2036
|
* 2. The `_loadingLayouts` guard prevents re-entrance while the
|
|
1889
|
-
*
|
|
2037
|
+
* convert drain is still in flight. Without it,
|
|
1890
2038
|
* clicking the same layout tab twice in quick succession (or
|
|
1891
2039
|
* `layoutSwitched` firing twice during the async window) would iterate
|
|
1892
2040
|
* the block table record again and duplicate every entity in the
|
|
@@ -1988,31 +2136,35 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
1988
2136
|
this._numOfEntitiesToProcess += entities_2.length;
|
|
1989
2137
|
var convert = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1990
2138
|
var layout;
|
|
1991
|
-
|
|
1992
|
-
|
|
2139
|
+
var _a;
|
|
2140
|
+
return __generator(this, function (_b) {
|
|
2141
|
+
switch (_b.label) {
|
|
1993
2142
|
case 0:
|
|
1994
|
-
|
|
1995
|
-
return [
|
|
2143
|
+
_b.trys.push([0, , 5, 6]);
|
|
2144
|
+
if (!this._progressiveRendering) return [3 /*break*/, 2];
|
|
2145
|
+
(_a = this._convertQueue).push.apply(_a, __spreadArray([], __read(entities_2), false));
|
|
2146
|
+
return [4 /*yield*/, this.drainConvertQueue()];
|
|
1996
2147
|
case 1:
|
|
1997
|
-
|
|
2148
|
+
_b.sent();
|
|
2149
|
+
return [3 /*break*/, 4];
|
|
2150
|
+
case 2: return [4 /*yield*/, this.batchConvert(entities_2)];
|
|
2151
|
+
case 3:
|
|
2152
|
+
_b.sent();
|
|
2153
|
+
_b.label = 4;
|
|
2154
|
+
case 4:
|
|
1998
2155
|
layout = this._scene.layouts.get(layoutBtrId);
|
|
1999
2156
|
if (layout) {
|
|
2000
2157
|
layout.isLoaded = true;
|
|
2001
2158
|
}
|
|
2002
|
-
return [3 /*break*/,
|
|
2003
|
-
case
|
|
2159
|
+
return [3 /*break*/, 6];
|
|
2160
|
+
case 5:
|
|
2004
2161
|
this._loadingLayouts.delete(layoutBtrId);
|
|
2005
2162
|
return [7 /*endfinally*/];
|
|
2006
|
-
case
|
|
2163
|
+
case 6: return [2 /*return*/];
|
|
2007
2164
|
}
|
|
2008
2165
|
});
|
|
2009
2166
|
}); };
|
|
2010
|
-
|
|
2011
|
-
setTimeout(convert);
|
|
2012
|
-
}
|
|
2013
|
-
else {
|
|
2014
|
-
void convert();
|
|
2015
|
-
}
|
|
2167
|
+
void convert();
|
|
2016
2168
|
}
|
|
2017
2169
|
catch (error) {
|
|
2018
2170
|
log.error('[AcTrView2d] Error loading layout entities:', error);
|
|
@@ -2087,21 +2239,25 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
2087
2239
|
return entity.worldDraw(this._renderer, delay);
|
|
2088
2240
|
};
|
|
2089
2241
|
/**
|
|
2090
|
-
* Finishes geometry for a converted entity.
|
|
2091
|
-
*
|
|
2092
|
-
*
|
|
2093
|
-
* {@link
|
|
2242
|
+
* Finishes geometry for a converted entity.
|
|
2243
|
+
*
|
|
2244
|
+
* Glyph entities and block groups use {@link AcTrEntity.asyncDraw} so
|
|
2245
|
+
* {@link FontManager.awaitFontsBeforeDraw} can wait for fonts without
|
|
2246
|
+
* relying on a full-scene regen. Other entities keep the sync finalize path.
|
|
2094
2247
|
*/
|
|
2095
|
-
AcTrView2d.prototype.finishEntityGeometry = function (threeEntity,
|
|
2248
|
+
AcTrView2d.prototype.finishEntityGeometry = function (threeEntity, _progressive) {
|
|
2096
2249
|
return __awaiter(this, void 0, void 0, function () {
|
|
2097
2250
|
return __generator(this, function (_a) {
|
|
2098
2251
|
switch (_a.label) {
|
|
2099
2252
|
case 0:
|
|
2100
|
-
if (threeEntity instanceof AcTrGroup)
|
|
2101
|
-
|
|
2253
|
+
if (!(threeEntity instanceof AcTrGroup)) return [3 /*break*/, 2];
|
|
2254
|
+
// Compacted INSERT templates may skip syncDraw when fonts are awaited
|
|
2255
|
+
// later; still walk for empty glyph shells. Skip only when there is
|
|
2256
|
+
// nothing left to finalize (incl. post-cache ATTRIBs).
|
|
2257
|
+
if (threeEntity.getSourceEntities().length === 0 &&
|
|
2258
|
+
!this.groupHasPendingGlyphGeometry(threeEntity)) {
|
|
2102
2259
|
return [2 /*return*/];
|
|
2103
2260
|
}
|
|
2104
|
-
if (!progressive) return [3 /*break*/, 2];
|
|
2105
2261
|
return [4 /*yield*/, threeEntity.asyncDraw()];
|
|
2106
2262
|
case 1:
|
|
2107
2263
|
_a.sent();
|
|
@@ -2110,12 +2266,82 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
2110
2266
|
if (threeEntity.hasDrawableGeometry()) {
|
|
2111
2267
|
return [2 /*return*/];
|
|
2112
2268
|
}
|
|
2113
|
-
threeEntity.
|
|
2269
|
+
return [4 /*yield*/, threeEntity.asyncDraw()];
|
|
2270
|
+
case 3:
|
|
2271
|
+
_a.sent();
|
|
2114
2272
|
return [2 /*return*/];
|
|
2115
2273
|
}
|
|
2116
2274
|
});
|
|
2117
2275
|
});
|
|
2118
2276
|
};
|
|
2277
|
+
AcTrView2d.prototype.needsDeferredFontGeometry = function (threeEntity) {
|
|
2278
|
+
return (threeEntity instanceof AcTrGlyphEntity ||
|
|
2279
|
+
threeEntity instanceof AcTrGroup);
|
|
2280
|
+
};
|
|
2281
|
+
AcTrView2d.prototype.groupHasPendingGlyphGeometry = function (group) {
|
|
2282
|
+
var pending = false;
|
|
2283
|
+
group.traverse(function (child) {
|
|
2284
|
+
if (child instanceof AcTrGlyphEntity &&
|
|
2285
|
+
!child.hasDrawableGeometry()) {
|
|
2286
|
+
pending = true;
|
|
2287
|
+
}
|
|
2288
|
+
});
|
|
2289
|
+
return pending;
|
|
2290
|
+
};
|
|
2291
|
+
/**
|
|
2292
|
+
* Runs glyph/group geometry finalize off the main convert loop so other
|
|
2293
|
+
* entities keep converting while fonts download.
|
|
2294
|
+
*/
|
|
2295
|
+
AcTrView2d.prototype.enqueueDeferredGeometry = function (run, epoch) {
|
|
2296
|
+
var _this = this;
|
|
2297
|
+
if (epoch !== this._convertEpoch) {
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
2300
|
+
this._pendingGeometryJobs++;
|
|
2301
|
+
void run()
|
|
2302
|
+
.then(function () {
|
|
2303
|
+
// Convert counter often hits 0 before fonts finish; without this,
|
|
2304
|
+
// text added later never paints until the user pans/zooms.
|
|
2305
|
+
if (epoch === _this._convertEpoch) {
|
|
2306
|
+
_this._isDirty = true;
|
|
2307
|
+
}
|
|
2308
|
+
})
|
|
2309
|
+
.catch(function (error) {
|
|
2310
|
+
log.error('[AcTrView2d] Deferred entity geometry failed:', error);
|
|
2311
|
+
})
|
|
2312
|
+
.finally(function () {
|
|
2313
|
+
if (epoch === _this._convertEpoch) {
|
|
2314
|
+
_this._pendingGeometryJobs = Math.max(0, _this._pendingGeometryJobs - 1);
|
|
2315
|
+
if (_this._pendingGeometryJobs === 0) {
|
|
2316
|
+
_this._isDirty = true;
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
});
|
|
2320
|
+
};
|
|
2321
|
+
/**
|
|
2322
|
+
* Waits until side-pool glyph/group jobs for the current convert epoch finish.
|
|
2323
|
+
* Used by entity updates that must highlight after text is in the scene.
|
|
2324
|
+
*/
|
|
2325
|
+
AcTrView2d.prototype.waitUntilDeferredGeometryIdle = function () {
|
|
2326
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2327
|
+
var epoch;
|
|
2328
|
+
return __generator(this, function (_a) {
|
|
2329
|
+
switch (_a.label) {
|
|
2330
|
+
case 0:
|
|
2331
|
+
epoch = this._convertEpoch;
|
|
2332
|
+
_a.label = 1;
|
|
2333
|
+
case 1:
|
|
2334
|
+
if (!(epoch === this._convertEpoch &&
|
|
2335
|
+
this._pendingGeometryJobs > 0)) return [3 /*break*/, 3];
|
|
2336
|
+
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 0); })];
|
|
2337
|
+
case 2:
|
|
2338
|
+
_a.sent();
|
|
2339
|
+
return [3 /*break*/, 1];
|
|
2340
|
+
case 3: return [2 /*return*/];
|
|
2341
|
+
}
|
|
2342
|
+
});
|
|
2343
|
+
});
|
|
2344
|
+
};
|
|
2119
2345
|
/**
|
|
2120
2346
|
* Walks the given block table record once and creates one
|
|
2121
2347
|
* `AcTrViewportView` for every real `AcDbViewport` entity it finds
|
|
@@ -2163,116 +2389,206 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
2163
2389
|
*/
|
|
2164
2390
|
AcTrView2d.prototype.batchConvert = function (entities_3) {
|
|
2165
2391
|
return __awaiter(this, arguments, void 0, function (entities, options) {
|
|
2166
|
-
var
|
|
2392
|
+
var epoch, progressive, yieldGate, yieldToEventLoop, _loop_3, this_2, i;
|
|
2167
2393
|
var _this = this;
|
|
2168
2394
|
if (options === void 0) { options = {}; }
|
|
2169
2395
|
return __generator(this, function (_a) {
|
|
2170
2396
|
switch (_a.label) {
|
|
2171
2397
|
case 0:
|
|
2398
|
+
epoch = this._convertEpoch;
|
|
2172
2399
|
progressive = this._progressiveRendering && !options.forExport;
|
|
2400
|
+
yieldGate = progressive
|
|
2401
|
+
? new AcCmUiYieldGate(AcTrView2d.PROGRESSIVE_OPEN_YIELD_BUDGET_MS)
|
|
2402
|
+
: undefined;
|
|
2403
|
+
yieldToEventLoop = function () {
|
|
2404
|
+
return new Promise(function (resolve) { return setTimeout(resolve, 0); });
|
|
2405
|
+
};
|
|
2406
|
+
_loop_3 = function (i) {
|
|
2407
|
+
var entity, shouldConvert, directMeta, added, threeEntity_1, isMultiLayerGroup, deferGeometry, isExtendBbox_1, commitEntity, layoutView, viewportView, fileName, error_2, didYield;
|
|
2408
|
+
return __generator(this, function (_b) {
|
|
2409
|
+
switch (_b.label) {
|
|
2410
|
+
case 0:
|
|
2411
|
+
entity = entities[i];
|
|
2412
|
+
_b.label = 1;
|
|
2413
|
+
case 1:
|
|
2414
|
+
_b.trys.push([1, 9, 10, 11]);
|
|
2415
|
+
// Document was cleared / replaced while this batch was draining.
|
|
2416
|
+
if (epoch !== this_2._convertEpoch) {
|
|
2417
|
+
return [2 /*return*/, "continue"];
|
|
2418
|
+
}
|
|
2419
|
+
// Skip the default paper-space viewport (`*Paper_Space`) entirely:
|
|
2420
|
+
// it is an AutoCAD-internal viewport that exists in every paper
|
|
2421
|
+
// layout and must not be drawn (would render a giant rectangle in
|
|
2422
|
+
// the paper coordinate system), nor added to the spatial index
|
|
2423
|
+
// (would stretch the layout's bounding box and break
|
|
2424
|
+
// zoomToFitDrawing), nor turned into an AcTrViewportView (would
|
|
2425
|
+
// setScissor over most of the canvas and squeeze the real user
|
|
2426
|
+
// viewports into a corner). See
|
|
2427
|
+
// `AcTrViewportView.isDefaultPaperSpaceViewport` for the criterion
|
|
2428
|
+
// and the rationale (legacy `number === 1` is unreliable across
|
|
2429
|
+
// parsers).
|
|
2430
|
+
if (entity instanceof AcDbViewport &&
|
|
2431
|
+
AcTrViewportView.isDefaultPaperSpaceViewport(entity)) {
|
|
2432
|
+
return [2 /*return*/, "continue"];
|
|
2433
|
+
}
|
|
2434
|
+
shouldConvert = options.forExport
|
|
2435
|
+
? this_2._entityDisplay.shouldConvertForExport(entity)
|
|
2436
|
+
: this_2._entityDisplay.shouldConvert(entity);
|
|
2437
|
+
if (!shouldConvert) {
|
|
2438
|
+
return [2 /*return*/, "continue"];
|
|
2439
|
+
}
|
|
2440
|
+
directMeta = tryBuildDirectEntityMeta(entity, this_2._renderer);
|
|
2441
|
+
if (directMeta) {
|
|
2442
|
+
added = false;
|
|
2443
|
+
try {
|
|
2444
|
+
added = this_2._scene.addDirectEntity(directMeta, shouldExtendBboxForDirectEntity(entity));
|
|
2445
|
+
if (added) {
|
|
2446
|
+
this_2.applySessionHiddenObjectState(entity.objectId);
|
|
2447
|
+
if (progressive) {
|
|
2448
|
+
this_2.markProgressiveDirty();
|
|
2449
|
+
this_2._progressiveOpenFit.afterGeometryBatch(function () { return _this.resolveLayoutFitBox(); }, i);
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
finally {
|
|
2454
|
+
directMeta.geometry.dispose();
|
|
2455
|
+
}
|
|
2456
|
+
if (added) {
|
|
2457
|
+
return [2 /*return*/, "continue"];
|
|
2458
|
+
}
|
|
2459
|
+
// Append refused (e.g. invisible) — fall through to the legacy path.
|
|
2460
|
+
}
|
|
2461
|
+
threeEntity_1 = this_2.drawEntity(entity, false);
|
|
2462
|
+
// Viewports may produce no border geometry (e.g. on a no-plot layer) while
|
|
2463
|
+
// still needing an AcTrViewportView for model content below.
|
|
2464
|
+
if (!threeEntity_1 && !(entity instanceof AcDbViewport))
|
|
2465
|
+
return [2 /*return*/, "continue"];
|
|
2466
|
+
if (!threeEntity_1) return [3 /*break*/, 8];
|
|
2467
|
+
threeEntity_1.objectId = entity.objectId;
|
|
2468
|
+
threeEntity_1.ownerId = entity.ownerId;
|
|
2469
|
+
threeEntity_1.layerName = entity.layer;
|
|
2470
|
+
threeEntity_1.visible = entity.visibility !== false;
|
|
2471
|
+
if (threeEntity_1 instanceof AcTrGroup &&
|
|
2472
|
+
threeEntity_1.isOnTheSameLayer) {
|
|
2473
|
+
// Even when a block expands to a single layer bucket, children authored on
|
|
2474
|
+
// layer "0" still inherit the INSERT layer for ByLayer traits (color, etc.).
|
|
2475
|
+
this_2._inheritedLayerMaterialMapper.remap(threeEntity_1.children, '0', threeEntity_1.layerName);
|
|
2476
|
+
threeEntity_1.userData.insertLayerName = threeEntity_1.layerName;
|
|
2477
|
+
}
|
|
2478
|
+
isMultiLayerGroup = threeEntity_1 instanceof AcTrGroup &&
|
|
2479
|
+
!threeEntity_1.isOnTheSameLayer;
|
|
2480
|
+
deferGeometry = !options.forExport && this_2.needsDeferredFontGeometry(threeEntity_1);
|
|
2481
|
+
if (!isMultiLayerGroup) return [3 /*break*/, 5];
|
|
2482
|
+
if (!deferGeometry) return [3 /*break*/, 2];
|
|
2483
|
+
this_2.enqueueDeferredGeometry(function () {
|
|
2484
|
+
return _this.handleGroup(threeEntity_1, progressive, epoch);
|
|
2485
|
+
}, epoch);
|
|
2486
|
+
return [3 /*break*/, 4];
|
|
2487
|
+
case 2: return [4 /*yield*/, this_2.handleGroup(threeEntity_1, progressive, epoch)];
|
|
2488
|
+
case 3:
|
|
2489
|
+
_b.sent();
|
|
2490
|
+
_b.label = 4;
|
|
2491
|
+
case 4: return [3 /*break*/, 8];
|
|
2492
|
+
case 5:
|
|
2493
|
+
isExtendBbox_1 = !(entity instanceof AcDbRay || entity instanceof AcDbXline);
|
|
2494
|
+
commitEntity = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
2495
|
+
var _this = this;
|
|
2496
|
+
return __generator(this, function (_a) {
|
|
2497
|
+
switch (_a.label) {
|
|
2498
|
+
case 0: return [4 /*yield*/, this.finishEntityGeometry(threeEntity_1, progressive)];
|
|
2499
|
+
case 1:
|
|
2500
|
+
_a.sent();
|
|
2501
|
+
if (epoch !== this._convertEpoch) {
|
|
2502
|
+
threeEntity_1.dispose();
|
|
2503
|
+
return [2 /*return*/];
|
|
2504
|
+
}
|
|
2505
|
+
if (threeEntity_1 instanceof AcTrGroup) {
|
|
2506
|
+
this.syncGroupSpatialBoundsForIndexing(threeEntity_1);
|
|
2507
|
+
}
|
|
2508
|
+
this._scene.addEntity(threeEntity_1, isExtendBbox_1);
|
|
2509
|
+
this.applySessionHiddenObjectState(entity.objectId);
|
|
2510
|
+
// Release memory occupied by this entity
|
|
2511
|
+
threeEntity_1.dispose();
|
|
2512
|
+
if (progressive) {
|
|
2513
|
+
this.markProgressiveDirty();
|
|
2514
|
+
this._progressiveOpenFit.afterGeometryBatch(function () { return _this.resolveLayoutFitBox(); }, i);
|
|
2515
|
+
}
|
|
2516
|
+
return [2 /*return*/];
|
|
2517
|
+
}
|
|
2518
|
+
});
|
|
2519
|
+
}); };
|
|
2520
|
+
if (!deferGeometry) return [3 /*break*/, 6];
|
|
2521
|
+
this_2.enqueueDeferredGeometry(commitEntity, epoch);
|
|
2522
|
+
return [3 /*break*/, 8];
|
|
2523
|
+
case 6: return [4 /*yield*/, commitEntity()];
|
|
2524
|
+
case 7:
|
|
2525
|
+
_b.sent();
|
|
2526
|
+
_b.label = 8;
|
|
2527
|
+
case 8:
|
|
2528
|
+
if (epoch !== this_2._convertEpoch) {
|
|
2529
|
+
return [2 /*return*/, "continue"];
|
|
2530
|
+
}
|
|
2531
|
+
if (entity instanceof AcDbViewport) {
|
|
2532
|
+
// Default paper-space viewport was already filtered out at the
|
|
2533
|
+
// top of the loop, so anything that reaches here is a real
|
|
2534
|
+
// user-created viewport. The redundant check below is kept as
|
|
2535
|
+
// a defensive guard in case a future refactor reorders the
|
|
2536
|
+
// early-skip — it costs ~nothing and prevents a regression.
|
|
2537
|
+
if (!AcTrViewportView.isDefaultPaperSpaceViewport(entity)) {
|
|
2538
|
+
layoutView = this_2._layoutViewManager.getAt(entity.ownerId);
|
|
2539
|
+
if (layoutView) {
|
|
2540
|
+
viewportView = new AcTrViewportView(layoutView, entity.toGiViewport(), this_2._renderer);
|
|
2541
|
+
layoutView.addViewport(viewportView);
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
else if (entity instanceof AcDbRasterImage) {
|
|
2546
|
+
fileName = entity.imageFileName;
|
|
2547
|
+
if (fileName && !entity.image) {
|
|
2548
|
+
this_2._missedImages.set(entity.objectId, fileName);
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
return [3 /*break*/, 11];
|
|
2552
|
+
case 9:
|
|
2553
|
+
error_2 = _b.sent();
|
|
2554
|
+
log.error("[AcTrView2d] Failed to convert entity ".concat(entity.objectId, " (").concat(entity.type, "):"), error_2);
|
|
2555
|
+
return [3 /*break*/, 11];
|
|
2556
|
+
case 10:
|
|
2557
|
+
// Counter was reset in clear() when the epoch advanced; do not
|
|
2558
|
+
// decrease again or isProcessingEntities can go negative/warn.
|
|
2559
|
+
if (epoch === this_2._convertEpoch) {
|
|
2560
|
+
this_2.decreaseNumOfEntitiesToProcess();
|
|
2561
|
+
}
|
|
2562
|
+
return [7 /*endfinally*/];
|
|
2563
|
+
case 11:
|
|
2564
|
+
if (epoch !== this_2._convertEpoch) {
|
|
2565
|
+
return [2 /*return*/, "continue"];
|
|
2566
|
+
}
|
|
2567
|
+
if (!yieldGate) return [3 /*break*/, 13];
|
|
2568
|
+
return [4 /*yield*/, yieldGate.maybeYield(yieldToEventLoop)];
|
|
2569
|
+
case 12:
|
|
2570
|
+
didYield = _b.sent();
|
|
2571
|
+
if (didYield) {
|
|
2572
|
+
this_2._progressiveYieldCount++;
|
|
2573
|
+
}
|
|
2574
|
+
_b.label = 13;
|
|
2575
|
+
case 13: return [2 /*return*/];
|
|
2576
|
+
}
|
|
2577
|
+
});
|
|
2578
|
+
};
|
|
2579
|
+
this_2 = this;
|
|
2173
2580
|
i = 0;
|
|
2174
2581
|
_a.label = 1;
|
|
2175
2582
|
case 1:
|
|
2176
|
-
if (!(i < entities.length)) return [3 /*break*/,
|
|
2177
|
-
|
|
2178
|
-
_a.label = 2;
|
|
2583
|
+
if (!(i < entities.length)) return [3 /*break*/, 4];
|
|
2584
|
+
return [5 /*yield**/, _loop_3(i)];
|
|
2179
2585
|
case 2:
|
|
2180
|
-
_a.trys.push([2, 8, 9, 10]);
|
|
2181
|
-
// Skip the default paper-space viewport (`*Paper_Space`) entirely:
|
|
2182
|
-
// it is an AutoCAD-internal viewport that exists in every paper
|
|
2183
|
-
// layout and must not be drawn (would render a giant rectangle in
|
|
2184
|
-
// the paper coordinate system), nor added to the spatial index
|
|
2185
|
-
// (would stretch the layout's bounding box and break
|
|
2186
|
-
// zoomToFitDrawing), nor turned into an AcTrViewportView (would
|
|
2187
|
-
// setScissor over most of the canvas and squeeze the real user
|
|
2188
|
-
// viewports into a corner). See
|
|
2189
|
-
// `AcTrViewportView.isDefaultPaperSpaceViewport` for the criterion
|
|
2190
|
-
// and the rationale (legacy `number === 1` is unreliable across
|
|
2191
|
-
// parsers).
|
|
2192
|
-
if (entity instanceof AcDbViewport &&
|
|
2193
|
-
AcTrViewportView.isDefaultPaperSpaceViewport(entity)) {
|
|
2194
|
-
return [3 /*break*/, 10];
|
|
2195
|
-
}
|
|
2196
|
-
shouldConvert = options.forExport
|
|
2197
|
-
? this._entityDisplay.shouldConvertForExport(entity)
|
|
2198
|
-
: this._entityDisplay.shouldConvert(entity);
|
|
2199
|
-
if (!shouldConvert) {
|
|
2200
|
-
return [3 /*break*/, 10];
|
|
2201
|
-
}
|
|
2202
|
-
threeEntity = this.drawEntity(entity, progressive);
|
|
2203
|
-
// Viewports may produce no border geometry (e.g. on a no-plot layer) while
|
|
2204
|
-
// still needing an AcTrViewportView for model content below.
|
|
2205
|
-
if (!threeEntity && !(entity instanceof AcDbViewport))
|
|
2206
|
-
return [3 /*break*/, 10];
|
|
2207
|
-
if (!threeEntity) return [3 /*break*/, 7];
|
|
2208
|
-
threeEntity.objectId = entity.objectId;
|
|
2209
|
-
threeEntity.ownerId = entity.ownerId;
|
|
2210
|
-
threeEntity.layerName = entity.layer;
|
|
2211
|
-
threeEntity.visible = entity.visibility !== false;
|
|
2212
|
-
if (threeEntity instanceof AcTrGroup &&
|
|
2213
|
-
threeEntity.isOnTheSameLayer) {
|
|
2214
|
-
// Even when a block expands to a single layer bucket, children authored on
|
|
2215
|
-
// layer "0" still inherit the INSERT layer for ByLayer traits (color, etc.).
|
|
2216
|
-
this._inheritedLayerMaterialMapper.remap(threeEntity.children, '0', threeEntity.layerName);
|
|
2217
|
-
threeEntity.userData.insertLayerName = threeEntity.layerName;
|
|
2218
|
-
}
|
|
2219
|
-
if (!(threeEntity instanceof AcTrGroup &&
|
|
2220
|
-
!threeEntity.isOnTheSameLayer)) return [3 /*break*/, 4];
|
|
2221
|
-
return [4 /*yield*/, this.handleGroup(threeEntity, progressive)];
|
|
2222
|
-
case 3:
|
|
2223
|
-
_a.sent();
|
|
2224
|
-
return [3 /*break*/, 7];
|
|
2225
|
-
case 4:
|
|
2226
|
-
isExtendBbox = !(entity instanceof AcDbRay || entity instanceof AcDbXline);
|
|
2227
|
-
return [4 /*yield*/, this.finishEntityGeometry(threeEntity, progressive)];
|
|
2228
|
-
case 5:
|
|
2229
|
-
_a.sent();
|
|
2230
|
-
if (threeEntity instanceof AcTrGroup) {
|
|
2231
|
-
this.syncGroupSpatialBoundsForIndexing(threeEntity);
|
|
2232
|
-
}
|
|
2233
|
-
this._scene.addEntity(threeEntity, isExtendBbox);
|
|
2234
|
-
this.applySessionHiddenObjectState(entity.objectId);
|
|
2235
|
-
// Release memory occupied by this entity
|
|
2236
|
-
threeEntity.dispose();
|
|
2237
|
-
if (!progressive) return [3 /*break*/, 7];
|
|
2238
|
-
this._isDirty = true;
|
|
2239
|
-
return [4 /*yield*/, this._progressiveOpenFit.afterGeometryBatch(function () { return _this.resolveLayoutFitBox(); }, i)];
|
|
2240
|
-
case 6:
|
|
2241
2586
|
_a.sent();
|
|
2242
|
-
_a.label =
|
|
2243
|
-
case
|
|
2244
|
-
if (entity instanceof AcDbViewport) {
|
|
2245
|
-
// Default paper-space viewport was already filtered out at the
|
|
2246
|
-
// top of the loop, so anything that reaches here is a real
|
|
2247
|
-
// user-created viewport. The redundant check below is kept as
|
|
2248
|
-
// a defensive guard in case a future refactor reorders the
|
|
2249
|
-
// early-skip — it costs ~nothing and prevents a regression.
|
|
2250
|
-
if (!AcTrViewportView.isDefaultPaperSpaceViewport(entity)) {
|
|
2251
|
-
layoutView = this._layoutViewManager.getAt(entity.ownerId);
|
|
2252
|
-
if (layoutView) {
|
|
2253
|
-
viewportView = new AcTrViewportView(layoutView, entity.toGiViewport(), this._renderer);
|
|
2254
|
-
layoutView.addViewport(viewportView);
|
|
2255
|
-
}
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
else if (entity instanceof AcDbRasterImage) {
|
|
2259
|
-
fileName = entity.imageFileName;
|
|
2260
|
-
if (fileName && !entity.image) {
|
|
2261
|
-
this._missedImages.set(entity.objectId, fileName);
|
|
2262
|
-
}
|
|
2263
|
-
}
|
|
2264
|
-
return [3 /*break*/, 10];
|
|
2265
|
-
case 8:
|
|
2266
|
-
error_2 = _a.sent();
|
|
2267
|
-
log.error("[AcTrView2d] Failed to convert entity ".concat(entity.objectId, " (").concat(entity.type, "):"), error_2);
|
|
2268
|
-
return [3 /*break*/, 10];
|
|
2269
|
-
case 9:
|
|
2270
|
-
this.decreaseNumOfEntitiesToProcess();
|
|
2271
|
-
return [7 /*endfinally*/];
|
|
2272
|
-
case 10:
|
|
2587
|
+
_a.label = 3;
|
|
2588
|
+
case 3:
|
|
2273
2589
|
++i;
|
|
2274
2590
|
return [3 /*break*/, 1];
|
|
2275
|
-
case
|
|
2591
|
+
case 4: return [2 /*return*/];
|
|
2276
2592
|
}
|
|
2277
2593
|
});
|
|
2278
2594
|
});
|
|
@@ -2297,16 +2613,21 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
2297
2613
|
var userData = group.userData;
|
|
2298
2614
|
userData.spatialIndexChildBoxes = childBoxes;
|
|
2299
2615
|
};
|
|
2300
|
-
AcTrView2d.prototype.handleGroup = function (
|
|
2301
|
-
return __awaiter(this,
|
|
2616
|
+
AcTrView2d.prototype.handleGroup = function (group_1, progressive_1) {
|
|
2617
|
+
return __awaiter(this, arguments, void 0, function (group, progressive, epoch) {
|
|
2302
2618
|
var children, objectsGroupByLayer, children_1, children_1_1, child, renderContext, groupObjectId, groupLayerName, groupChildBoxes, aggregateSpatialBbox;
|
|
2303
2619
|
var e_11, _a;
|
|
2304
2620
|
var _this = this;
|
|
2621
|
+
if (epoch === void 0) { epoch = this._convertEpoch; }
|
|
2305
2622
|
return __generator(this, function (_b) {
|
|
2306
2623
|
switch (_b.label) {
|
|
2307
2624
|
case 0: return [4 /*yield*/, this.finishEntityGeometry(group, progressive)];
|
|
2308
2625
|
case 1:
|
|
2309
2626
|
_b.sent();
|
|
2627
|
+
if (epoch !== this._convertEpoch) {
|
|
2628
|
+
group.dispose();
|
|
2629
|
+
return [2 /*return*/];
|
|
2630
|
+
}
|
|
2310
2631
|
this.syncGroupSpatialBoundsForIndexing(group);
|
|
2311
2632
|
children = group.children;
|
|
2312
2633
|
objectsGroupByLayer = new Map();
|
|
@@ -2410,9 +2731,9 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
2410
2731
|
entity.dispose();
|
|
2411
2732
|
});
|
|
2412
2733
|
group.dispose();
|
|
2413
|
-
if (
|
|
2414
|
-
this.
|
|
2415
|
-
|
|
2734
|
+
if (progressive) {
|
|
2735
|
+
this.markProgressiveDirty();
|
|
2736
|
+
this._progressiveOpenFit.afterGeometryBatch(function () {
|
|
2416
2737
|
return _this.resolveLayoutFitBox();
|
|
2417
2738
|
});
|
|
2418
2739
|
}
|
|
@@ -2427,11 +2748,25 @@ var AcTrView2d = /** @class */ (function (_super) {
|
|
|
2427
2748
|
this._numOfEntitiesToProcess = 0;
|
|
2428
2749
|
log.warn('Something wrong! The number of entities to process should not be less than 0.');
|
|
2429
2750
|
}
|
|
2430
|
-
else if (this._numOfEntitiesToProcess === 0
|
|
2431
|
-
|
|
2751
|
+
else if (this._numOfEntitiesToProcess === 0) {
|
|
2752
|
+
// Always mark dirty when the queue drains. Progressive open throttles
|
|
2753
|
+
// mid-open paints, so the last batch would otherwise never redraw until
|
|
2754
|
+
// the user pans/zooms (animate bails when !_isDirty && !stillLoading).
|
|
2432
2755
|
this._isDirty = true;
|
|
2433
2756
|
}
|
|
2434
2757
|
};
|
|
2758
|
+
/**
|
|
2759
|
+
* Wall-time between cooperative yields during progressive open (ms).
|
|
2760
|
+
* Kept relatively large so convert throughput stays close to the
|
|
2761
|
+
* non-progressive path; smaller budgets made open 2–3× slower.
|
|
2762
|
+
*/
|
|
2763
|
+
AcTrView2d.PROGRESSIVE_OPEN_YIELD_BUDGET_MS = 300;
|
|
2764
|
+
/**
|
|
2765
|
+
* Minimum interval between progressive mid-open paints (ms).
|
|
2766
|
+
* Full-scene WebGL paints dominate open wall time on large drawings;
|
|
2767
|
+
* paint much less often than we yield.
|
|
2768
|
+
*/
|
|
2769
|
+
AcTrView2d.PROGRESSIVE_OPEN_PAINT_INTERVAL_MS = 1000;
|
|
2435
2770
|
return AcTrView2d;
|
|
2436
2771
|
}(AcEdBaseView));
|
|
2437
2772
|
export { AcTrView2d };
|