@2112-lab/central-plant 0.3.11 → 0.3.13
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/bundle/index.js +202 -114
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/modelManager.js +9 -0
- package/dist/cjs/src/managers/scene/viewport2DManager.js +187 -113
- package/dist/cjs/src/utils/boundingBoxUtils.js +6 -1
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/scene/modelManager.js +9 -0
- package/dist/esm/src/managers/scene/viewport2DManager.js +187 -113
- package/dist/esm/src/utils/boundingBoxUtils.js +6 -1
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -3497,7 +3497,12 @@ function computeFilteredBoundingBox(object) {
|
|
|
3497
3497
|
|
|
3498
3498
|
// Build a Set for O(1) lookups
|
|
3499
3499
|
var excludeSet = new Set(excludeTypes);
|
|
3500
|
-
|
|
3500
|
+
|
|
3501
|
+
// Force matrix updates to ensure world-space coordinates are accurate.
|
|
3502
|
+
// Using force=true ensures matrices are updated even if matrixWorldNeedsUpdate is false,
|
|
3503
|
+
// which can happen after positioning a model before the render loop runs.
|
|
3504
|
+
object.updateMatrix();
|
|
3505
|
+
object.updateMatrixWorld(true);
|
|
3501
3506
|
object.traverse(function (child) {
|
|
3502
3507
|
// Only process nodes with geometry (Mesh, SkinnedMesh, etc.)
|
|
3503
3508
|
if (!child.geometry) return;
|
|
@@ -29818,6 +29823,15 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
29818
29823
|
var jsonData = _ref2.jsonData,
|
|
29819
29824
|
glbModel = _ref2.glbModel;
|
|
29820
29825
|
if (!glbModel) return;
|
|
29826
|
+
|
|
29827
|
+
// CRITICAL: Force matrix updates before computing bbox.
|
|
29828
|
+
// After loadLibraryModel positions the model, the world matrices may not be
|
|
29829
|
+
// invalidated yet. computeFilteredBoundingBox uses updateWorldMatrix(false, true)
|
|
29830
|
+
// which only updates if matrixWorldNeedsUpdate is true. Force the update here
|
|
29831
|
+
// to ensure the bbox is computed with correct world-space coordinates.
|
|
29832
|
+
glbModel.updateMatrix();
|
|
29833
|
+
glbModel.updateMatrixWorld(true);
|
|
29834
|
+
|
|
29821
29835
|
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
29822
29836
|
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
29823
29837
|
var filteredBox = computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|
|
@@ -35440,6 +35454,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35440
35454
|
// stacking up independent renderComponents() runs
|
|
35441
35455
|
_this2._refreshPending = false;
|
|
35442
35456
|
|
|
35457
|
+
// Set of viewport keys pending refresh (collects keys across multiple refresh() calls in same frame)
|
|
35458
|
+
_this2._pendingRefreshKeys = new Set();
|
|
35459
|
+
|
|
35443
35460
|
// Event listener reference for cleanup
|
|
35444
35461
|
_this2._objectTransformedListener = null;
|
|
35445
35462
|
console.log('🔲 Viewport2DManager initialized (multi-instance support)');
|
|
@@ -35529,8 +35546,10 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35529
35546
|
viewport._instanceKey = key;
|
|
35530
35547
|
this.viewports.set(key, viewport);
|
|
35531
35548
|
|
|
35532
|
-
// Initialize the stage for this viewport
|
|
35533
|
-
|
|
35549
|
+
// Initialize the stage for this viewport (waits for DOM layout to settle)
|
|
35550
|
+
_context.n = 4;
|
|
35551
|
+
return this.initializeStage(viewport);
|
|
35552
|
+
case 4:
|
|
35534
35553
|
return _context.a(2, viewport.isReady);
|
|
35535
35554
|
}
|
|
35536
35555
|
}, _callee, this);
|
|
@@ -35624,50 +35643,67 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35624
35643
|
/**
|
|
35625
35644
|
* Initialize Konva stage for a specific viewport instance
|
|
35626
35645
|
* @param {Viewport2DInstance} viewport - The viewport instance to initialize
|
|
35646
|
+
* @returns {Promise<void>} Resolves when viewport is fully ready
|
|
35627
35647
|
*/
|
|
35628
35648
|
)
|
|
35629
35649
|
}, {
|
|
35630
35650
|
key: "initializeStage",
|
|
35631
35651
|
value: function initializeStage(viewport) {
|
|
35632
|
-
|
|
35633
|
-
|
|
35634
|
-
|
|
35635
|
-
|
|
35636
|
-
|
|
35637
|
-
|
|
35638
|
-
|
|
35639
|
-
var width = rect.width || 800;
|
|
35640
|
-
var height = rect.height || 600;
|
|
35641
|
-
console.log("\uD83D\uDCD0 Initializing Konva stage (".concat(viewport.viewType, "): ").concat(width, "x").concat(height));
|
|
35642
|
-
|
|
35643
|
-
// Create Konva stage for this viewport
|
|
35644
|
-
viewport.stage = new this.Konva.Stage({
|
|
35645
|
-
container: viewport.container,
|
|
35646
|
-
width: width,
|
|
35647
|
-
height: height
|
|
35648
|
-
});
|
|
35649
|
-
|
|
35650
|
-
// Create separate layers for grid and components
|
|
35651
|
-
viewport.gridLayer = new this.Konva.Layer();
|
|
35652
|
-
viewport.componentLayer = new this.Konva.Layer();
|
|
35653
|
-
|
|
35654
|
-
// Add layers to stage in order (grid first, then components)
|
|
35655
|
-
viewport.stage.add(viewport.gridLayer);
|
|
35656
|
-
viewport.stage.add(viewport.componentLayer);
|
|
35657
|
-
|
|
35658
|
-
// Setup resize handling
|
|
35659
|
-
this.setupResizeListener(viewport);
|
|
35652
|
+
var _this4 = this;
|
|
35653
|
+
return new Promise(function (resolve) {
|
|
35654
|
+
if (!_this4.Konva || !viewport.container) {
|
|
35655
|
+
console.error('❌ Cannot initialize stage: Konva or container missing');
|
|
35656
|
+
resolve();
|
|
35657
|
+
return;
|
|
35658
|
+
}
|
|
35660
35659
|
|
|
35661
|
-
|
|
35662
|
-
|
|
35660
|
+
// Get container dimensions
|
|
35661
|
+
var rect = viewport.container.getBoundingClientRect();
|
|
35662
|
+
var width = rect.width || 800;
|
|
35663
|
+
var height = rect.height || 600;
|
|
35664
|
+
console.log("\uD83D\uDCD0 Initializing Konva stage (".concat(viewport.viewType, "): ").concat(width, "x").concat(height));
|
|
35663
35665
|
|
|
35664
|
-
|
|
35665
|
-
|
|
35666
|
-
|
|
35666
|
+
// Create Konva stage for this viewport
|
|
35667
|
+
viewport.stage = new _this4.Konva.Stage({
|
|
35668
|
+
container: viewport.container,
|
|
35669
|
+
width: width,
|
|
35670
|
+
height: height
|
|
35671
|
+
});
|
|
35667
35672
|
|
|
35668
|
-
|
|
35669
|
-
|
|
35670
|
-
|
|
35673
|
+
// Create separate layers for grid and components
|
|
35674
|
+
viewport.gridLayer = new _this4.Konva.Layer();
|
|
35675
|
+
viewport.componentLayer = new _this4.Konva.Layer();
|
|
35676
|
+
|
|
35677
|
+
// Add layers to stage in order (grid first, then components)
|
|
35678
|
+
viewport.stage.add(viewport.gridLayer);
|
|
35679
|
+
viewport.stage.add(viewport.componentLayer);
|
|
35680
|
+
|
|
35681
|
+
// Setup resize handling
|
|
35682
|
+
_this4.setupResizeListener(viewport);
|
|
35683
|
+
|
|
35684
|
+
// Setup zoom and pan handlers
|
|
35685
|
+
_this4.setupZoomAndPanHandlers(viewport);
|
|
35686
|
+
|
|
35687
|
+
// Draw initial grid (lightweight, safe to do immediately)
|
|
35688
|
+
_this4.drawGrid(viewport);
|
|
35689
|
+
|
|
35690
|
+
// Defer component rendering to next frame to ensure DOM layout is finalized.
|
|
35691
|
+
// Without this, getBoundingClientRect() may return stale/zero dimensions
|
|
35692
|
+
// if the container hasn't been fully laid out by CSS yet.
|
|
35693
|
+
requestAnimationFrame(function () {
|
|
35694
|
+
// Re-check container dimensions after layout settles
|
|
35695
|
+
var finalRect = viewport.container.getBoundingClientRect();
|
|
35696
|
+
if (finalRect.width > 0 && finalRect.height > 0) {
|
|
35697
|
+
viewport.stage.width(finalRect.width);
|
|
35698
|
+
viewport.stage.height(finalRect.height);
|
|
35699
|
+
_this4.drawGrid(viewport);
|
|
35700
|
+
}
|
|
35701
|
+
_this4.renderComponents(viewport);
|
|
35702
|
+
viewport.isReady = true;
|
|
35703
|
+
console.log("\u2705 Viewport2DManager stage initialized (".concat(viewport.viewType, ")"));
|
|
35704
|
+
resolve();
|
|
35705
|
+
});
|
|
35706
|
+
});
|
|
35671
35707
|
}
|
|
35672
35708
|
|
|
35673
35709
|
/**
|
|
@@ -35677,12 +35713,12 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35677
35713
|
}, {
|
|
35678
35714
|
key: "setupResizeListener",
|
|
35679
35715
|
value: function setupResizeListener(viewport) {
|
|
35680
|
-
var
|
|
35716
|
+
var _this5 = this;
|
|
35681
35717
|
if (typeof window === 'undefined' || !window.ResizeObserver || !viewport.container) {
|
|
35682
35718
|
return;
|
|
35683
35719
|
}
|
|
35684
35720
|
viewport._resizeObserver = new ResizeObserver(function () {
|
|
35685
|
-
|
|
35721
|
+
_this5.resizeStage(viewport);
|
|
35686
35722
|
});
|
|
35687
35723
|
viewport._resizeObserver.observe(viewport.container);
|
|
35688
35724
|
}
|
|
@@ -35717,6 +35753,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35717
35753
|
}, {
|
|
35718
35754
|
key: "setupZoomAndPanHandlers",
|
|
35719
35755
|
value: function setupZoomAndPanHandlers(viewport) {
|
|
35756
|
+
var _this6 = this;
|
|
35720
35757
|
if (!viewport.stage) return;
|
|
35721
35758
|
|
|
35722
35759
|
// Mouse wheel zoom
|
|
@@ -35742,6 +35779,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35742
35779
|
y: pointer.y - mousePointTo.y * clampedScale
|
|
35743
35780
|
};
|
|
35744
35781
|
viewport.stage.position(newPos);
|
|
35782
|
+
_this6.drawGrid(viewport);
|
|
35745
35783
|
viewport.stage.batchDraw();
|
|
35746
35784
|
});
|
|
35747
35785
|
|
|
@@ -35761,6 +35799,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35761
35799
|
viewport.stage.x(viewport.stage.x() + dx);
|
|
35762
35800
|
viewport.stage.y(viewport.stage.y() + dy);
|
|
35763
35801
|
viewport.lastPanPoint = pos;
|
|
35802
|
+
_this6.drawGrid(viewport);
|
|
35764
35803
|
viewport.stage.batchDraw();
|
|
35765
35804
|
});
|
|
35766
35805
|
viewport.stage.on('mouseup', function () {
|
|
@@ -35785,33 +35824,40 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35785
35824
|
var width = viewport.stage.width();
|
|
35786
35825
|
var height = viewport.stage.height();
|
|
35787
35826
|
var gridSize = viewport.PIXELS_PER_UNIT;
|
|
35788
|
-
|
|
35789
|
-
|
|
35790
|
-
var
|
|
35791
|
-
|
|
35827
|
+
var stageX = viewport.stage.x();
|
|
35828
|
+
var stageY = viewport.stage.y();
|
|
35829
|
+
var scale = viewport.stage.scaleX();
|
|
35830
|
+
|
|
35831
|
+
// World origin sits at (width/2, height/2) in stage-local coordinates
|
|
35832
|
+
var originX = width / 2;
|
|
35833
|
+
var originY = height / 2;
|
|
35834
|
+
|
|
35835
|
+
// Compute the visible area in stage-local coordinates, with 1-cell padding
|
|
35836
|
+
var visLeft = -stageX / scale - gridSize;
|
|
35837
|
+
var visTop = -stageY / scale - gridSize;
|
|
35838
|
+
var visRight = (width - stageX) / scale + gridSize;
|
|
35839
|
+
var visBottom = (height - stageY) / scale + gridSize;
|
|
35792
35840
|
var gridGroup = new this.Konva.Group();
|
|
35793
|
-
|
|
35794
|
-
// Draw vertical lines centered at origin
|
|
35795
|
-
var startX = centerX % gridSize - gridSize;
|
|
35796
35841
|
var gridColor = '#dddddd';
|
|
35797
|
-
|
|
35798
|
-
|
|
35799
|
-
|
|
35842
|
+
|
|
35843
|
+
// Draw vertical lines — start at the first grid column left of the visible area
|
|
35844
|
+
var firstX = Math.floor((visLeft - originX) / gridSize) * gridSize + originX;
|
|
35845
|
+
for (var x = firstX; x <= visRight; x += gridSize) {
|
|
35846
|
+
var isOriginLine = Math.abs(x - originX) < 0.5;
|
|
35800
35847
|
gridGroup.add(new this.Konva.Line({
|
|
35801
|
-
points: [x,
|
|
35848
|
+
points: [x, visTop, x, visBottom],
|
|
35802
35849
|
stroke: gridColor,
|
|
35803
35850
|
strokeWidth: isOriginLine ? 2 : 1,
|
|
35804
35851
|
listening: false
|
|
35805
35852
|
}));
|
|
35806
35853
|
}
|
|
35807
35854
|
|
|
35808
|
-
// Draw horizontal lines
|
|
35809
|
-
var
|
|
35810
|
-
for (var y =
|
|
35811
|
-
var
|
|
35812
|
-
var _isOriginLine = _distFromCenter < 1;
|
|
35855
|
+
// Draw horizontal lines — start at the first grid row above the visible area
|
|
35856
|
+
var firstY = Math.floor((visTop - originY) / gridSize) * gridSize + originY;
|
|
35857
|
+
for (var y = firstY; y <= visBottom; y += gridSize) {
|
|
35858
|
+
var _isOriginLine = Math.abs(y - originY) < 0.5;
|
|
35813
35859
|
gridGroup.add(new this.Konva.Line({
|
|
35814
|
-
points: [
|
|
35860
|
+
points: [visLeft, y, visRight, y],
|
|
35815
35861
|
stroke: gridColor,
|
|
35816
35862
|
strokeWidth: _isOriginLine ? 2 : 1,
|
|
35817
35863
|
listening: false
|
|
@@ -35821,14 +35867,14 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35821
35867
|
// Draw center crosshair at world origin
|
|
35822
35868
|
var crosshairSize = gridSize;
|
|
35823
35869
|
gridGroup.add(new this.Konva.Line({
|
|
35824
|
-
points: [
|
|
35870
|
+
points: [originX, originY - crosshairSize, originX, originY + crosshairSize],
|
|
35825
35871
|
stroke: '#333',
|
|
35826
35872
|
strokeWidth: 1,
|
|
35827
35873
|
listening: false,
|
|
35828
35874
|
dash: [5, 5]
|
|
35829
35875
|
}));
|
|
35830
35876
|
gridGroup.add(new this.Konva.Line({
|
|
35831
|
-
points: [
|
|
35877
|
+
points: [originX - crosshairSize, originY, originX + crosshairSize, originY],
|
|
35832
35878
|
stroke: '#333',
|
|
35833
35879
|
strokeWidth: 1,
|
|
35834
35880
|
listening: false,
|
|
@@ -35845,7 +35891,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35845
35891
|
}, {
|
|
35846
35892
|
key: "renderComponents",
|
|
35847
35893
|
value: function renderComponents(viewport) {
|
|
35848
|
-
var
|
|
35894
|
+
var _this7 = this;
|
|
35849
35895
|
if (!viewport.componentLayer || !viewport.stage || !this.sceneViewer) return;
|
|
35850
35896
|
viewport.componentLayer.destroyChildren();
|
|
35851
35897
|
|
|
@@ -35856,19 +35902,18 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35856
35902
|
return;
|
|
35857
35903
|
}
|
|
35858
35904
|
|
|
35859
|
-
//
|
|
35860
|
-
if (
|
|
35861
|
-
|
|
35862
|
-
viewport._lastComponentCount = components.length;
|
|
35863
|
-
}
|
|
35905
|
+
// Track render count for debugging
|
|
35906
|
+
if (viewport._renderCount === undefined) viewport._renderCount = 0;
|
|
35907
|
+
viewport._renderCount++;
|
|
35864
35908
|
var width = viewport.stage.width();
|
|
35865
35909
|
var height = viewport.stage.height();
|
|
35866
35910
|
var centerX = width / 2;
|
|
35867
35911
|
var centerY = height / 2;
|
|
35868
35912
|
var scale = viewport.PIXELS_PER_UNIT;
|
|
35913
|
+
console.log("\uD83C\uDFA8 RENDER #".concat(viewport._renderCount, " (").concat(viewport.viewType, "): ").concat(components.length, " components, stage=").concat(width, "x").concat(height, ", center=(").concat(centerX, ", ").concat(centerY, ")"));
|
|
35869
35914
|
components.forEach(function (component) {
|
|
35870
35915
|
try {
|
|
35871
|
-
|
|
35916
|
+
_this7.renderComponent(viewport, component, centerX, centerY, scale);
|
|
35872
35917
|
} catch (err) {
|
|
35873
35918
|
console.warn('⚠️ Error rendering component in 2D:', component.name, err);
|
|
35874
35919
|
}
|
|
@@ -35899,6 +35944,11 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35899
35944
|
var screenX = centerX + posX * scale;
|
|
35900
35945
|
var screenY = centerY - posY * scale; // Flip Y for screen coords
|
|
35901
35946
|
|
|
35947
|
+
// Debug: Log ALL component positions on first render only
|
|
35948
|
+
if (viewport._renderCount === 1) {
|
|
35949
|
+
console.log("\uD83D\uDD0D [".concat(viewport.viewType, "] ").concat(component.name, ": bbox.z=").concat(bboxCenter.z.toFixed(2), ", posY=").concat(posY.toFixed(2), ", screenY=").concat(screenY.toFixed(0), ", centerY=").concat(centerY.toFixed(0)));
|
|
35950
|
+
}
|
|
35951
|
+
|
|
35902
35952
|
// Generate unique color for this component
|
|
35903
35953
|
var colors = this.generateComponentColor(component.id);
|
|
35904
35954
|
|
|
@@ -35928,18 +35978,19 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35928
35978
|
draggable: false
|
|
35929
35979
|
});
|
|
35930
35980
|
|
|
35931
|
-
// Add label
|
|
35981
|
+
// Add label (hidden by default; shown on hover)
|
|
35932
35982
|
var label = new this.Konva.Text({
|
|
35933
35983
|
x: -rectWidth / 2,
|
|
35934
35984
|
y: -rectHeight / 2 - 20,
|
|
35935
35985
|
text: component.name || 'Component',
|
|
35936
35986
|
fontSize: 12,
|
|
35937
35987
|
fill: '#333',
|
|
35938
|
-
listening: false
|
|
35988
|
+
listening: false,
|
|
35989
|
+
visible: false
|
|
35939
35990
|
});
|
|
35940
35991
|
|
|
35941
35992
|
// Add mouse event handlers
|
|
35942
|
-
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter);
|
|
35993
|
+
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter, label);
|
|
35943
35994
|
componentGroup.add(rect);
|
|
35944
35995
|
componentGroup.add(label);
|
|
35945
35996
|
viewport.componentLayer.add(componentGroup);
|
|
@@ -35976,7 +36027,14 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35976
36027
|
if (this._bboxCache.has(object.uuid)) {
|
|
35977
36028
|
return this._bboxCache.get(object.uuid);
|
|
35978
36029
|
}
|
|
35979
|
-
|
|
36030
|
+
|
|
36031
|
+
// Force matrix updates before computing bbox to ensure world-space accuracy
|
|
36032
|
+
object.updateMatrix();
|
|
36033
|
+
object.updateMatrixWorld(true);
|
|
36034
|
+
|
|
36035
|
+
// Exclude io-devices and connectors to match the stored worldBoundingBox
|
|
36036
|
+
// computed in modelManager.replaceWithGLBModels()
|
|
36037
|
+
var box = computeFilteredBoundingBox(object, ['io-device', 'connector']);
|
|
35980
36038
|
var result;
|
|
35981
36039
|
if (box.isEmpty()) {
|
|
35982
36040
|
// Object has no geometry; fall back to a point at world position
|
|
@@ -36106,8 +36164,8 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36106
36164
|
*/
|
|
36107
36165
|
}, {
|
|
36108
36166
|
key: "addComponentInteractions",
|
|
36109
|
-
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter) {
|
|
36110
|
-
var
|
|
36167
|
+
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter, label) {
|
|
36168
|
+
var _this8 = this;
|
|
36111
36169
|
if (!this.Konva) return;
|
|
36112
36170
|
var colors = this.generateComponentColor(component.id);
|
|
36113
36171
|
|
|
@@ -36118,6 +36176,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36118
36176
|
rect.stroke('#007bff');
|
|
36119
36177
|
rect.strokeWidth(3);
|
|
36120
36178
|
viewport.stage.container().style.cursor = 'grab';
|
|
36179
|
+
if (label) label.visible(true);
|
|
36121
36180
|
viewport.componentLayer.batchDraw();
|
|
36122
36181
|
}
|
|
36123
36182
|
});
|
|
@@ -36127,6 +36186,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36127
36186
|
rect.stroke(colors.stroke);
|
|
36128
36187
|
rect.strokeWidth(2);
|
|
36129
36188
|
viewport.stage.container().style.cursor = 'default';
|
|
36189
|
+
if (label) label.visible(false);
|
|
36130
36190
|
viewport.componentLayer.batchDraw();
|
|
36131
36191
|
}
|
|
36132
36192
|
});
|
|
@@ -36134,12 +36194,12 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36134
36194
|
// CLICK EVENT
|
|
36135
36195
|
rect.on('click', function () {
|
|
36136
36196
|
if (!viewport.isDragging) {
|
|
36137
|
-
var
|
|
36197
|
+
var _this8$sceneViewer;
|
|
36138
36198
|
console.log("\uD83C\uDFAF Component clicked: ".concat(component.name));
|
|
36139
36199
|
|
|
36140
36200
|
// Use centralPlant API to select component
|
|
36141
|
-
if ((
|
|
36142
|
-
|
|
36201
|
+
if ((_this8$sceneViewer = _this8.sceneViewer) !== null && _this8$sceneViewer !== void 0 && _this8$sceneViewer.centralPlant && component.uuid) {
|
|
36202
|
+
_this8.sceneViewer.centralPlant.selectComponent(component.uuid);
|
|
36143
36203
|
}
|
|
36144
36204
|
}
|
|
36145
36205
|
});
|
|
@@ -36169,7 +36229,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36169
36229
|
var worldOriginY = stageHeight / 2;
|
|
36170
36230
|
|
|
36171
36231
|
// Snap to grid
|
|
36172
|
-
var snappedPos =
|
|
36232
|
+
var snappedPos = _this8.snapScreenToGrid(viewport, currentPos.x, currentPos.y, scale, worldOriginX, worldOriginY);
|
|
36173
36233
|
componentGroup.position(snappedPos);
|
|
36174
36234
|
viewport.componentLayer.batchDraw();
|
|
36175
36235
|
});
|
|
@@ -36177,7 +36237,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36177
36237
|
// DRAG END
|
|
36178
36238
|
componentGroup.on('dragend', function () {
|
|
36179
36239
|
setTimeout(function () {
|
|
36180
|
-
var
|
|
36240
|
+
var _this8$sceneViewer2;
|
|
36181
36241
|
viewport.isDragging = false;
|
|
36182
36242
|
var finalPos = componentGroup.position();
|
|
36183
36243
|
var stageWidth = viewport.stage.width();
|
|
@@ -36187,17 +36247,17 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36187
36247
|
var worldOriginY = stageHeight / 2;
|
|
36188
36248
|
|
|
36189
36249
|
// Convert screen to world coordinates
|
|
36190
|
-
var worldCoords =
|
|
36250
|
+
var worldCoords = _this8.screenToWorldCoords(viewport, finalPos.x, finalPos.y, scale, worldOriginX, worldOriginY);
|
|
36191
36251
|
|
|
36192
36252
|
// Calculate new position: delta from old bbox center to new bbox center
|
|
36193
36253
|
var currentPos = component.position;
|
|
36194
|
-
var newPosition =
|
|
36254
|
+
var newPosition = _this8.worldCoordsToObjectPosition(viewport, worldCoords, currentPos, bboxCenter);
|
|
36195
36255
|
|
|
36196
36256
|
// Apply translation via centralPlant API
|
|
36197
36257
|
var deltaX = newPosition.x - currentPos.x;
|
|
36198
36258
|
var deltaY = newPosition.y - currentPos.y;
|
|
36199
36259
|
var deltaZ = newPosition.z - currentPos.z;
|
|
36200
|
-
if ((
|
|
36260
|
+
if ((_this8$sceneViewer2 = _this8.sceneViewer) !== null && _this8$sceneViewer2 !== void 0 && _this8$sceneViewer2.centralPlant && component.uuid) {
|
|
36201
36261
|
var success = true;
|
|
36202
36262
|
|
|
36203
36263
|
// Suppress per-axis path updates so the pathfinder only runs once,
|
|
@@ -36205,32 +36265,32 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36205
36265
|
// Running updatePaths() after each individual axis (the default
|
|
36206
36266
|
// translateComponent behaviour) produces intermediate wrong results on
|
|
36207
36267
|
// the first drag because no cached fingerprint exists yet to skip them.
|
|
36208
|
-
var wasAutoUpdate =
|
|
36209
|
-
|
|
36268
|
+
var wasAutoUpdate = _this8.sceneViewer.shouldUpdatePaths;
|
|
36269
|
+
_this8.sceneViewer.shouldUpdatePaths = false;
|
|
36210
36270
|
try {
|
|
36211
36271
|
if (Math.abs(deltaX) > 0.01) {
|
|
36212
|
-
success = success &&
|
|
36272
|
+
success = success && _this8.sceneViewer.centralPlant.translate(component.uuid, 'x', deltaX);
|
|
36213
36273
|
}
|
|
36214
36274
|
if (Math.abs(deltaY) > 0.01) {
|
|
36215
|
-
success = success &&
|
|
36275
|
+
success = success && _this8.sceneViewer.centralPlant.translate(component.uuid, 'y', deltaY);
|
|
36216
36276
|
}
|
|
36217
36277
|
if (Math.abs(deltaZ) > 0.01) {
|
|
36218
|
-
success = success &&
|
|
36278
|
+
success = success && _this8.sceneViewer.centralPlant.translate(component.uuid, 'z', deltaZ);
|
|
36219
36279
|
}
|
|
36220
36280
|
} finally {
|
|
36221
|
-
|
|
36281
|
+
_this8.sceneViewer.shouldUpdatePaths = wasAutoUpdate;
|
|
36222
36282
|
}
|
|
36223
|
-
if (!success &&
|
|
36283
|
+
if (!success && _this8.dragStartPosition) {
|
|
36224
36284
|
console.warn('⚠️ Failed to translate component, reverting position');
|
|
36225
|
-
componentGroup.position(
|
|
36285
|
+
componentGroup.position(_this8.dragStartPosition);
|
|
36226
36286
|
} else {
|
|
36227
36287
|
console.log("\u2705 Component ".concat(component.name, " translated successfully in 2D viewport"));
|
|
36228
36288
|
|
|
36229
36289
|
// Single path update with the final combined position
|
|
36230
|
-
if (wasAutoUpdate &&
|
|
36290
|
+
if (wasAutoUpdate && _this8.sceneViewer) {
|
|
36231
36291
|
console.log('🔄 Auto-updating paths after 2D viewport translation...');
|
|
36232
36292
|
try {
|
|
36233
|
-
|
|
36293
|
+
_this8.sceneViewer.updatePaths();
|
|
36234
36294
|
console.log('✅ Paths auto-updated successfully from 2D viewport');
|
|
36235
36295
|
} catch (error) {
|
|
36236
36296
|
console.error('❌ Error auto-updating paths from 2D viewport:', error);
|
|
@@ -36483,28 +36543,39 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36483
36543
|
}, {
|
|
36484
36544
|
key: "refresh",
|
|
36485
36545
|
value: function refresh() {
|
|
36486
|
-
var
|
|
36546
|
+
var _this9 = this;
|
|
36487
36547
|
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
36548
|
+
// Collect viewport keys to refresh; null means "all viewports"
|
|
36549
|
+
if (key) {
|
|
36550
|
+
this._pendingRefreshKeys.add(key);
|
|
36551
|
+
} else {
|
|
36552
|
+
// null key means refresh all — mark with special sentinel
|
|
36553
|
+
this._pendingRefreshKeys.add('__ALL__');
|
|
36554
|
+
}
|
|
36555
|
+
|
|
36556
|
+
// If already scheduled, the rAF callback will process our newly-added key
|
|
36488
36557
|
if (this._refreshPending) return;
|
|
36489
36558
|
this._refreshPending = true;
|
|
36490
36559
|
requestAnimationFrame(function () {
|
|
36491
|
-
|
|
36560
|
+
_this9._refreshPending = false;
|
|
36561
|
+
|
|
36492
36562
|
// Clear per-cycle caches so each component is measured/traversed once per paint
|
|
36493
|
-
|
|
36494
|
-
|
|
36495
|
-
|
|
36496
|
-
|
|
36497
|
-
|
|
36498
|
-
|
|
36499
|
-
|
|
36500
|
-
|
|
36501
|
-
|
|
36563
|
+
_this9._bboxCache.clear();
|
|
36564
|
+
_this9._componentListCache = null;
|
|
36565
|
+
|
|
36566
|
+
// Check if we need to refresh all viewports
|
|
36567
|
+
var refreshAll = _this9._pendingRefreshKeys.has('__ALL__');
|
|
36568
|
+
var keysToRefresh = new Set(_this9._pendingRefreshKeys);
|
|
36569
|
+
_this9._pendingRefreshKeys.clear();
|
|
36570
|
+
if (refreshAll) {
|
|
36571
|
+
// Refresh all viewports
|
|
36572
|
+
var _iterator = _createForOfIteratorHelper(_this9.viewports.values()),
|
|
36502
36573
|
_step;
|
|
36503
36574
|
try {
|
|
36504
36575
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
36505
|
-
var
|
|
36506
|
-
if (
|
|
36507
|
-
|
|
36576
|
+
var viewport = _step.value;
|
|
36577
|
+
if (viewport.isReady) {
|
|
36578
|
+
_this9.renderComponents(viewport);
|
|
36508
36579
|
}
|
|
36509
36580
|
}
|
|
36510
36581
|
} catch (err) {
|
|
@@ -36512,6 +36583,23 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36512
36583
|
} finally {
|
|
36513
36584
|
_iterator.f();
|
|
36514
36585
|
}
|
|
36586
|
+
} else {
|
|
36587
|
+
// Refresh only the specific viewports that were requested
|
|
36588
|
+
var _iterator2 = _createForOfIteratorHelper(keysToRefresh),
|
|
36589
|
+
_step2;
|
|
36590
|
+
try {
|
|
36591
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
36592
|
+
var viewportKey = _step2.value;
|
|
36593
|
+
var _viewport = _this9.viewports.get(viewportKey);
|
|
36594
|
+
if (_viewport && _viewport.isReady) {
|
|
36595
|
+
_this9.renderComponents(_viewport);
|
|
36596
|
+
}
|
|
36597
|
+
}
|
|
36598
|
+
} catch (err) {
|
|
36599
|
+
_iterator2.e(err);
|
|
36600
|
+
} finally {
|
|
36601
|
+
_iterator2.f();
|
|
36602
|
+
}
|
|
36515
36603
|
}
|
|
36516
36604
|
});
|
|
36517
36605
|
}
|
|
@@ -36532,20 +36620,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36532
36620
|
}
|
|
36533
36621
|
|
|
36534
36622
|
// Dispose all viewport instances
|
|
36535
|
-
var
|
|
36536
|
-
|
|
36623
|
+
var _iterator3 = _createForOfIteratorHelper(this.viewports.entries()),
|
|
36624
|
+
_step3;
|
|
36537
36625
|
try {
|
|
36538
|
-
for (
|
|
36539
|
-
var
|
|
36540
|
-
key =
|
|
36541
|
-
viewport =
|
|
36626
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
36627
|
+
var _step3$value = _slicedToArray(_step3.value, 2),
|
|
36628
|
+
key = _step3$value[0],
|
|
36629
|
+
viewport = _step3$value[1];
|
|
36542
36630
|
console.log("\uD83D\uDDD1\uFE0F Disposing viewport: ".concat(key));
|
|
36543
36631
|
viewport.dispose();
|
|
36544
36632
|
}
|
|
36545
36633
|
} catch (err) {
|
|
36546
|
-
|
|
36634
|
+
_iterator3.e(err);
|
|
36547
36635
|
} finally {
|
|
36548
|
-
|
|
36636
|
+
_iterator3.f();
|
|
36549
36637
|
}
|
|
36550
36638
|
this.viewports.clear();
|
|
36551
36639
|
this.Konva = null;
|
|
@@ -37946,7 +38034,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37946
38034
|
* Initialize the CentralPlant manager
|
|
37947
38035
|
*
|
|
37948
38036
|
* @constructor
|
|
37949
|
-
* @version 0.3.
|
|
38037
|
+
* @version 0.3.13
|
|
37950
38038
|
* @updated 2025-10-22
|
|
37951
38039
|
*
|
|
37952
38040
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -35,7 +35,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
35
35
|
* Initialize the CentralPlant manager
|
|
36
36
|
*
|
|
37
37
|
* @constructor
|
|
38
|
-
* @version 0.3.
|
|
38
|
+
* @version 0.3.13
|
|
39
39
|
* @updated 2025-10-22
|
|
40
40
|
*
|
|
41
41
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -585,6 +585,15 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
585
585
|
var jsonData = _ref2.jsonData,
|
|
586
586
|
glbModel = _ref2.glbModel;
|
|
587
587
|
if (!glbModel) return;
|
|
588
|
+
|
|
589
|
+
// CRITICAL: Force matrix updates before computing bbox.
|
|
590
|
+
// After loadLibraryModel positions the model, the world matrices may not be
|
|
591
|
+
// invalidated yet. computeFilteredBoundingBox uses updateWorldMatrix(false, true)
|
|
592
|
+
// which only updates if matrixWorldNeedsUpdate is true. Force the update here
|
|
593
|
+
// to ensure the bbox is computed with correct world-space coordinates.
|
|
594
|
+
glbModel.updateMatrix();
|
|
595
|
+
glbModel.updateMatrixWorld(true);
|
|
596
|
+
|
|
588
597
|
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
589
598
|
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
590
599
|
var filteredBox = boundingBoxUtils.computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|