@2112-lab/central-plant 0.3.2 → 0.3.5
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 +168 -178
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/modelManager.js +18 -6
- package/dist/cjs/src/managers/scene/sceneExportManager.js +25 -68
- package/dist/cjs/src/managers/scene/viewport2DManager.js +128 -102
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/scene/modelManager.js +18 -6
- package/dist/esm/src/managers/scene/sceneExportManager.js +25 -68
- package/dist/esm/src/managers/scene/viewport2DManager.js +127 -103
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -11477,40 +11477,17 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
11477
11477
|
};
|
|
11478
11478
|
}
|
|
11479
11479
|
|
|
11480
|
-
// For components:
|
|
11481
|
-
//
|
|
11482
|
-
//
|
|
11480
|
+
// For components: no children exported — connector positions are defined in the component
|
|
11481
|
+
// dictionary GLB and will be re-injected at import time via _injectConnectorChildrenFromDictionary.
|
|
11482
|
+
// Exporting them here would prevent that injection (it skips if children already exist)
|
|
11483
|
+
// and would leave the pathfinder with connectors in incompatible local-position format.
|
|
11483
11484
|
if (threeObject.children && threeObject.children.length > 0) {
|
|
11484
11485
|
var exportableChildren = [];
|
|
11485
|
-
if (
|
|
11486
|
-
// Export connector children (skip mesh geometry - it lives in the component dictionary GLB)
|
|
11487
|
-
threeObject.children.forEach(function (child) {
|
|
11488
|
-
var _child$userData;
|
|
11489
|
-
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'connector') {
|
|
11490
|
-
var connectorJson = {
|
|
11491
|
-
// Use the raw Three.js UUID — connections in currentSceneData reference this exact value
|
|
11492
|
-
uuid: child.uuid,
|
|
11493
|
-
userData: _objectSpread2(_objectSpread2({
|
|
11494
|
-
objectType: 'connector'
|
|
11495
|
-
}, child.userData.direction ? {
|
|
11496
|
-
direction: child.userData.direction
|
|
11497
|
-
} : {}), child.userData.group ? {
|
|
11498
|
-
group: child.userData.group
|
|
11499
|
-
} : {}),
|
|
11500
|
-
position: {
|
|
11501
|
-
x: roundIfClose(child.position.x),
|
|
11502
|
-
y: roundIfClose(child.position.y),
|
|
11503
|
-
z: roundIfClose(child.position.z)
|
|
11504
|
-
}
|
|
11505
|
-
};
|
|
11506
|
-
exportableChildren.push(connectorJson);
|
|
11507
|
-
}
|
|
11508
|
-
});
|
|
11509
|
-
} else if (isManualSegment) {
|
|
11486
|
+
if (isManualSegment) {
|
|
11510
11487
|
// For manual segments, export their connector children
|
|
11511
11488
|
threeObject.children.forEach(function (child) {
|
|
11512
|
-
var _child$
|
|
11513
|
-
if (((_child$
|
|
11489
|
+
var _child$userData;
|
|
11490
|
+
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'segment-connector') {
|
|
11514
11491
|
// Call the class method using bound reference
|
|
11515
11492
|
var connectorJson = convertSegmentConnectorToJson(child, threeObject);
|
|
11516
11493
|
if (connectorJson) {
|
|
@@ -11529,38 +11506,18 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
11529
11506
|
// Bind the convertSegmentConnectorToJson method for use in nested function
|
|
11530
11507
|
var convertSegmentConnectorToJson = this.convertSegmentConnectorToJson.bind(this);
|
|
11531
11508
|
|
|
11532
|
-
// Extract main scene objects (components and standalone connectors
|
|
11509
|
+
// Extract main scene objects (components and standalone connectors)
|
|
11533
11510
|
var sceneChildren = [];
|
|
11534
|
-
|
|
11535
|
-
// Helper to recursively find manual segments within polylines
|
|
11536
|
-
var findManualSegments = function findManualSegments(object) {
|
|
11537
|
-
var manualSegments = [];
|
|
11538
|
-
object.traverse(function (child) {
|
|
11539
|
-
var _child$userData3;
|
|
11540
|
-
// Check if this is a manual segment
|
|
11541
|
-
if (((_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType) === 'segment') {
|
|
11542
|
-
manualSegments.push(child);
|
|
11543
|
-
}
|
|
11544
|
-
});
|
|
11545
|
-
return manualSegments;
|
|
11546
|
-
};
|
|
11547
11511
|
this.sceneViewer.scene.children.forEach(function (child) {
|
|
11548
|
-
var _child$
|
|
11549
|
-
//
|
|
11550
|
-
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
});
|
|
11558
|
-
} else {
|
|
11559
|
-
// Regular scene object export
|
|
11560
|
-
var jsonChild = convertObjectToJson(child);
|
|
11561
|
-
if (jsonChild) {
|
|
11562
|
-
sceneChildren.push(jsonChild);
|
|
11563
|
-
}
|
|
11512
|
+
var _child$userData2;
|
|
11513
|
+
// Only export components and connectors; skip segments, gateways, polylines, etc.
|
|
11514
|
+
var objectType = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType;
|
|
11515
|
+
if (objectType !== 'component' && objectType !== 'connector') {
|
|
11516
|
+
return;
|
|
11517
|
+
}
|
|
11518
|
+
var jsonChild = convertObjectToJson(child);
|
|
11519
|
+
if (jsonChild) {
|
|
11520
|
+
sceneChildren.push(jsonChild);
|
|
11564
11521
|
}
|
|
11565
11522
|
});
|
|
11566
11523
|
|
|
@@ -11738,14 +11695,14 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
11738
11695
|
BufferGeometryUtils$1 = BufferGeometryUtilsModule.BufferGeometryUtils || BufferGeometryUtilsModule.default || BufferGeometryUtilsModule; // Create a new scene for export instead of cloning
|
|
11739
11696
|
exportScene = new _THREE.Scene(); // Helper function to check if an object should be exported
|
|
11740
11697
|
shouldExport = function shouldExport(child) {
|
|
11741
|
-
var _child$
|
|
11742
|
-
if ((_child$
|
|
11698
|
+
var _child$name, _child$userData3, _child$userData4, _child$userData5, _child$userData6;
|
|
11699
|
+
if ((_child$name = child.name) !== null && _child$name !== void 0 && _child$name.includes('Polyline')) return false; // Will handle separately
|
|
11743
11700
|
if (child.name === 'fogPlane') return false; // Skip fog plane
|
|
11744
|
-
if ((_child$
|
|
11745
|
-
if ((_child$
|
|
11746
|
-
if ((_child$
|
|
11701
|
+
if ((_child$userData3 = child.userData) !== null && _child$userData3 !== void 0 && _child$userData3.isBrickWall) return false; // Skip environment
|
|
11702
|
+
if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBaseGround) return false; // Skip environment
|
|
11703
|
+
if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGrid) return false; // Skip environment
|
|
11747
11704
|
if (child.isLight) return false; // Skip lights
|
|
11748
|
-
if ((_child$
|
|
11705
|
+
if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isTransformControls) return false; // Skip transform controls
|
|
11749
11706
|
if (child.isTransformControls) return false; // Skip transform controls
|
|
11750
11707
|
if (child.type && child.type.includes('TransformControls')) return false;
|
|
11751
11708
|
if (child.type && child.type.includes('Helper')) return false; // Skip helpers
|
|
@@ -11754,8 +11711,8 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
11754
11711
|
pipeGeometries = [];
|
|
11755
11712
|
pipeMaterial = null;
|
|
11756
11713
|
this.sceneViewer.scene.children.forEach(function (child) {
|
|
11757
|
-
var _child$
|
|
11758
|
-
if ((_child$
|
|
11714
|
+
var _child$name2;
|
|
11715
|
+
if ((_child$name2 = child.name) !== null && _child$name2 !== void 0 && _child$name2.includes('Polyline')) {
|
|
11759
11716
|
// Traverse the polyline to collect all mesh geometries
|
|
11760
11717
|
child.traverse(function (obj) {
|
|
11761
11718
|
if (obj.isMesh && obj.geometry) {
|
|
@@ -29587,6 +29544,11 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
29587
29544
|
if (!libraryModel.userData) libraryModel.userData = {};
|
|
29588
29545
|
Object.assign(libraryModel.userData, jsonEntry.userData);
|
|
29589
29546
|
|
|
29547
|
+
// Preserve the original hardcoded UUID so getHardcodedUuid() can find it during export.
|
|
29548
|
+
// jsonEntry is the raw JSON object (no originalUuid), so we must set it explicitly from
|
|
29549
|
+
// originalProps.uuid (which equals the uuid string from the scene JSON, e.g. "PUMP-1").
|
|
29550
|
+
libraryModel.userData.originalUuid = originalProps.uuid;
|
|
29551
|
+
|
|
29590
29552
|
// Apply bounding box configurations
|
|
29591
29553
|
if (componentData.boundingBox) {
|
|
29592
29554
|
libraryModel.userData.boundingBox = componentData.boundingBox;
|
|
@@ -29851,15 +29813,21 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
29851
29813
|
_context5.n = 2;
|
|
29852
29814
|
return Promise.all(glbLoadingPromises);
|
|
29853
29815
|
case 2:
|
|
29854
|
-
// Update world bounding boxes for loaded models
|
|
29816
|
+
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
29855
29817
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
29856
|
-
var _jsonData$userData2;
|
|
29857
29818
|
var jsonData = _ref2.jsonData,
|
|
29858
29819
|
glbModel = _ref2.glbModel;
|
|
29859
|
-
if (glbModel
|
|
29860
|
-
|
|
29861
|
-
|
|
29862
|
-
|
|
29820
|
+
if (!glbModel) return;
|
|
29821
|
+
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
29822
|
+
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
29823
|
+
var filteredBox = computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|
|
29824
|
+
var worldBoundingBox = filteredBox.isEmpty() ? _this3._calculateWorldBoundingBox(glbModel) : {
|
|
29825
|
+
min: [filteredBox.min.x, filteredBox.min.y, filteredBox.min.z],
|
|
29826
|
+
max: [filteredBox.max.x, filteredBox.max.y, filteredBox.max.z]
|
|
29827
|
+
};
|
|
29828
|
+
// Update both the JSON data object AND the live scene object
|
|
29829
|
+
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
29830
|
+
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
29863
29831
|
});
|
|
29864
29832
|
|
|
29865
29833
|
// Dispatch completion event
|
|
@@ -35960,32 +35928,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35960
35928
|
}, {
|
|
35961
35929
|
key: "renderComponent",
|
|
35962
35930
|
value: function renderComponent(viewport, component, centerX, centerY, scale) {
|
|
35963
|
-
|
|
35964
|
-
// Get component position and rotation
|
|
35965
|
-
var pos3D = {
|
|
35966
|
-
x: (_component$position$x = (_component$position = component.position) === null || _component$position === void 0 ? void 0 : _component$position.x) !== null && _component$position$x !== void 0 ? _component$position$x : 0,
|
|
35967
|
-
y: (_component$position$y = (_component$position2 = component.position) === null || _component$position2 === void 0 ? void 0 : _component$position2.y) !== null && _component$position$y !== void 0 ? _component$position$y : 0,
|
|
35968
|
-
z: (_component$position$z = (_component$position3 = component.position) === null || _component$position3 === void 0 ? void 0 : _component$position3.z) !== null && _component$position$z !== void 0 ? _component$position$z : 0
|
|
35969
|
-
};
|
|
35970
|
-
var rot3D = {
|
|
35971
|
-
x: (_component$rotation$x = (_component$rotation = component.rotation) === null || _component$rotation === void 0 ? void 0 : _component$rotation.x) !== null && _component$rotation$x !== void 0 ? _component$rotation$x : 0,
|
|
35972
|
-
y: (_component$rotation$y = (_component$rotation2 = component.rotation) === null || _component$rotation2 === void 0 ? void 0 : _component$rotation2.y) !== null && _component$rotation$y !== void 0 ? _component$rotation$y : 0,
|
|
35973
|
-
z: (_component$rotation$z = (_component$rotation3 = component.rotation) === null || _component$rotation3 === void 0 ? void 0 : _component$rotation3.z) !== null && _component$rotation$z !== void 0 ? _component$rotation$z : 0
|
|
35974
|
-
};
|
|
35975
|
-
|
|
35976
|
-
// Get bounding box dimensions
|
|
35931
|
+
// Get world-space bounding box dimensions and center
|
|
35977
35932
|
var _this$getComponentDim = this.getComponentDimensions(component),
|
|
35978
35933
|
worldWidth = _this$getComponentDim.worldWidth,
|
|
35979
35934
|
worldDepth = _this$getComponentDim.worldDepth,
|
|
35980
|
-
worldHeight = _this$getComponentDim.worldHeight
|
|
35935
|
+
worldHeight = _this$getComponentDim.worldHeight,
|
|
35936
|
+
bboxCenter = _this$getComponentDim.bboxCenter;
|
|
35937
|
+
console.log("[2D] ".concat(component.name, " | w=").concat(worldWidth.toFixed(3), " d=").concat(worldDepth.toFixed(3), " h=").concat(worldHeight.toFixed(3), " | center=(").concat(bboxCenter.x.toFixed(2), ",").concat(bboxCenter.y.toFixed(2), ",").concat(bboxCenter.z.toFixed(2), ")"));
|
|
35981
35938
|
|
|
35982
|
-
// Project 3D
|
|
35983
|
-
var _this$project3DTo2D = this.project3DTo2D(viewport,
|
|
35939
|
+
// Project 3D bbox center to 2D based on view type
|
|
35940
|
+
var _this$project3DTo2D = this.project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight),
|
|
35984
35941
|
posX = _this$project3DTo2D.posX,
|
|
35985
35942
|
posY = _this$project3DTo2D.posY,
|
|
35986
35943
|
rectWidth = _this$project3DTo2D.rectWidth,
|
|
35987
35944
|
rectHeight = _this$project3DTo2D.rectHeight;
|
|
35988
|
-
_this$project3DTo2D.rotationDegrees;
|
|
35989
35945
|
var screenX = centerX + posX * scale;
|
|
35990
35946
|
var screenY = centerY - posY * scale; // Flip Y for screen coords
|
|
35991
35947
|
|
|
@@ -36029,105 +35985,131 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36029
35985
|
});
|
|
36030
35986
|
|
|
36031
35987
|
// Add mouse event handlers
|
|
36032
|
-
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight);
|
|
35988
|
+
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter);
|
|
36033
35989
|
componentGroup.add(rect);
|
|
36034
35990
|
componentGroup.add(label);
|
|
36035
35991
|
viewport.componentLayer.add(componentGroup);
|
|
36036
35992
|
}
|
|
36037
35993
|
|
|
36038
35994
|
/**
|
|
36039
|
-
*
|
|
35995
|
+
* Compute worldBoundingBox for a live Three.js Object3D using the same
|
|
35996
|
+
* vertex-accurate approach as computeFilteredBoundingBox (explicitly calls
|
|
35997
|
+
* geometry.computeBoundingBox() on each mesh before measuring).
|
|
35998
|
+
* @param {THREE.Object3D} object
|
|
35999
|
+
* @returns {{min: number[], max: number[]}}
|
|
36000
|
+
*/
|
|
36001
|
+
}, {
|
|
36002
|
+
key: "_getOrComputeWorldBoundingBox",
|
|
36003
|
+
value: function _getOrComputeWorldBoundingBox(object) {
|
|
36004
|
+
// computeFilteredBoundingBox with no exclusions = full object bbox
|
|
36005
|
+
var box = computeFilteredBoundingBox(object, []);
|
|
36006
|
+
if (box.isEmpty()) {
|
|
36007
|
+
// Object has no geometry; fall back to a point at world position
|
|
36008
|
+
var wp = new THREE__namespace.Vector3();
|
|
36009
|
+
object.getWorldPosition(wp);
|
|
36010
|
+
return {
|
|
36011
|
+
min: [wp.x, wp.y, wp.z],
|
|
36012
|
+
max: [wp.x, wp.y, wp.z]
|
|
36013
|
+
};
|
|
36014
|
+
}
|
|
36015
|
+
return {
|
|
36016
|
+
min: [box.min.x, box.min.y, box.min.z],
|
|
36017
|
+
max: [box.max.x, box.max.y, box.max.z]
|
|
36018
|
+
};
|
|
36019
|
+
}
|
|
36020
|
+
|
|
36021
|
+
/**
|
|
36022
|
+
* Get component dimensions and world-space center from worldBoundingBox
|
|
36040
36023
|
*/
|
|
36041
36024
|
}, {
|
|
36042
36025
|
key: "getComponentDimensions",
|
|
36043
36026
|
value: function getComponentDimensions(component) {
|
|
36044
|
-
var _component$userData, _component$
|
|
36045
|
-
|
|
36046
|
-
|
|
36047
|
-
|
|
36048
|
-
|
|
36049
|
-
|
|
36050
|
-
|
|
36051
|
-
|
|
36052
|
-
|
|
36053
|
-
|
|
36054
|
-
|
|
36055
|
-
|
|
36056
|
-
|
|
36057
|
-
|
|
36058
|
-
|
|
36059
|
-
|
|
36060
|
-
var
|
|
36061
|
-
|
|
36062
|
-
|
|
36063
|
-
|
|
36064
|
-
|
|
36065
|
-
|
|
36066
|
-
|
|
36067
|
-
|
|
36068
|
-
|
|
36069
|
-
|
|
36070
|
-
|
|
36027
|
+
var _component$userData$w, _component$userData, _component$getWorldPo;
|
|
36028
|
+
// Prefer worldBoundingBox already stored on the object — set after GLB loading
|
|
36029
|
+
// by modelManager.replaceWithGLBModels using computeFilteredBoundingBox.
|
|
36030
|
+
// Fall back to computing live if not yet available (e.g. first render before GLB load).
|
|
36031
|
+
var wbb = (_component$userData$w = (_component$userData = component.userData) === null || _component$userData === void 0 ? void 0 : _component$userData.worldBoundingBox) !== null && _component$userData$w !== void 0 ? _component$userData$w : this._getOrComputeWorldBoundingBox(component);
|
|
36032
|
+
if (wbb !== null && wbb !== void 0 && wbb.min && wbb !== null && wbb !== void 0 && wbb.max) {
|
|
36033
|
+
var _wbb$min = _slicedToArray(wbb.min, 3),
|
|
36034
|
+
minX = _wbb$min[0],
|
|
36035
|
+
minY = _wbb$min[1],
|
|
36036
|
+
minZ = _wbb$min[2];
|
|
36037
|
+
var _wbb$max = _slicedToArray(wbb.max, 3),
|
|
36038
|
+
maxX = _wbb$max[0],
|
|
36039
|
+
maxY = _wbb$max[1],
|
|
36040
|
+
maxZ = _wbb$max[2];
|
|
36041
|
+
var cx = (minX + maxX) / 2;
|
|
36042
|
+
var cy = (minY + maxY) / 2;
|
|
36043
|
+
var cz = (minZ + maxZ) / 2;
|
|
36044
|
+
// Guard against Infinity/NaN from empty or degenerate boxes
|
|
36045
|
+
if (isFinite(cx) && isFinite(cy) && isFinite(cz)) {
|
|
36046
|
+
return {
|
|
36047
|
+
worldWidth: Math.max(maxX - minX, 0.01),
|
|
36048
|
+
worldDepth: Math.max(maxY - minY, 0.01),
|
|
36049
|
+
worldHeight: Math.max(maxZ - minZ, 0.01),
|
|
36050
|
+
bboxCenter: {
|
|
36051
|
+
x: cx,
|
|
36052
|
+
y: cy,
|
|
36053
|
+
z: cz
|
|
36054
|
+
}
|
|
36055
|
+
};
|
|
36056
|
+
}
|
|
36071
36057
|
}
|
|
36058
|
+
// Fallback: world position of the object, unit dimensions
|
|
36059
|
+
var wp = new THREE__namespace.Vector3();
|
|
36060
|
+
(_component$getWorldPo = component.getWorldPosition) === null || _component$getWorldPo === void 0 || _component$getWorldPo.call(component, wp);
|
|
36072
36061
|
return {
|
|
36073
|
-
worldWidth:
|
|
36074
|
-
worldDepth:
|
|
36075
|
-
worldHeight:
|
|
36062
|
+
worldWidth: 1,
|
|
36063
|
+
worldDepth: 1,
|
|
36064
|
+
worldHeight: 1,
|
|
36065
|
+
bboxCenter: {
|
|
36066
|
+
x: wp.x,
|
|
36067
|
+
y: wp.y,
|
|
36068
|
+
z: wp.z
|
|
36069
|
+
}
|
|
36076
36070
|
};
|
|
36077
36071
|
}
|
|
36078
36072
|
|
|
36079
36073
|
/**
|
|
36080
|
-
* Project
|
|
36074
|
+
* Project world-space bbox center to 2D based on view type.
|
|
36075
|
+
* worldBoundingBox is an AABB so rotation is already encoded in the extents —
|
|
36076
|
+
* no separate rotation correction is needed.
|
|
36081
36077
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
36078
|
+
* @param {Object} bboxCenter - World-space center {x, y, z}
|
|
36079
|
+
* @param {number} worldWidth - X extent (max[0] - min[0])
|
|
36080
|
+
* @param {number} worldDepth - Y extent (max[1] - min[1])
|
|
36081
|
+
* @param {number} worldHeight - Z extent (max[2] - min[2])
|
|
36082
36082
|
*/
|
|
36083
36083
|
}, {
|
|
36084
36084
|
key: "project3DTo2D",
|
|
36085
|
-
value: function project3DTo2D(viewport,
|
|
36086
|
-
var posX, posY, rectWidth, rectHeight;
|
|
36087
|
-
var rotationAngle = rot3D.z;
|
|
36088
|
-
var rotationDegrees = rotationAngle * 180 / Math.PI;
|
|
36085
|
+
value: function project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight) {
|
|
36089
36086
|
var scale = viewport.PIXELS_PER_UNIT;
|
|
36087
|
+
var posX, posY, rectWidth, rectHeight;
|
|
36090
36088
|
switch (viewport.viewType) {
|
|
36091
36089
|
case 'top':
|
|
36092
|
-
//
|
|
36093
|
-
posX =
|
|
36094
|
-
posY =
|
|
36095
|
-
|
|
36096
|
-
|
|
36097
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
36098
|
-
rectWidth = worldDepth * scale;
|
|
36099
|
-
rectHeight = worldWidth * scale;
|
|
36100
|
-
} else {
|
|
36101
|
-
rectWidth = worldWidth * scale;
|
|
36102
|
-
rectHeight = worldDepth * scale;
|
|
36103
|
-
}
|
|
36090
|
+
// Looking down Z-axis — X/Y plane
|
|
36091
|
+
posX = bboxCenter.x;
|
|
36092
|
+
posY = bboxCenter.y;
|
|
36093
|
+
rectWidth = worldWidth * scale;
|
|
36094
|
+
rectHeight = worldDepth * scale;
|
|
36104
36095
|
break;
|
|
36105
36096
|
case 'front':
|
|
36106
|
-
//
|
|
36107
|
-
posX =
|
|
36108
|
-
posY =
|
|
36109
|
-
|
|
36110
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
36111
|
-
rectWidth = worldDepth * scale;
|
|
36112
|
-
} else {
|
|
36113
|
-
rectWidth = worldWidth * scale;
|
|
36114
|
-
}
|
|
36097
|
+
// Looking along Y-axis — X/Z plane
|
|
36098
|
+
posX = bboxCenter.x;
|
|
36099
|
+
posY = bboxCenter.z;
|
|
36100
|
+
rectWidth = worldWidth * scale;
|
|
36115
36101
|
rectHeight = worldHeight * scale;
|
|
36116
36102
|
break;
|
|
36117
36103
|
case 'side':
|
|
36118
|
-
//
|
|
36119
|
-
posX = -
|
|
36120
|
-
posY =
|
|
36121
|
-
|
|
36122
|
-
rectWidth = worldWidth * scale;
|
|
36123
|
-
} else {
|
|
36124
|
-
rectWidth = worldDepth * scale;
|
|
36125
|
-
}
|
|
36104
|
+
// Looking along X-axis — Y/Z plane (Y negated for left-right orientation)
|
|
36105
|
+
posX = -bboxCenter.y;
|
|
36106
|
+
posY = bboxCenter.z;
|
|
36107
|
+
rectWidth = worldDepth * scale;
|
|
36126
36108
|
rectHeight = worldHeight * scale;
|
|
36127
36109
|
break;
|
|
36128
36110
|
default:
|
|
36129
|
-
posX =
|
|
36130
|
-
posY =
|
|
36111
|
+
posX = bboxCenter.x;
|
|
36112
|
+
posY = bboxCenter.y;
|
|
36131
36113
|
rectWidth = worldWidth * scale;
|
|
36132
36114
|
rectHeight = worldDepth * scale;
|
|
36133
36115
|
}
|
|
@@ -36135,8 +36117,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36135
36117
|
posX: posX,
|
|
36136
36118
|
posY: posY,
|
|
36137
36119
|
rectWidth: rectWidth,
|
|
36138
|
-
rectHeight: rectHeight
|
|
36139
|
-
rotationDegrees: rotationDegrees
|
|
36120
|
+
rectHeight: rectHeight
|
|
36140
36121
|
};
|
|
36141
36122
|
}
|
|
36142
36123
|
|
|
@@ -36146,7 +36127,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36146
36127
|
*/
|
|
36147
36128
|
}, {
|
|
36148
36129
|
key: "addComponentInteractions",
|
|
36149
|
-
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight) {
|
|
36130
|
+
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter) {
|
|
36150
36131
|
var _this6 = this;
|
|
36151
36132
|
if (!this.Konva) return;
|
|
36152
36133
|
var colors = this.generateComponentColor(component.id);
|
|
@@ -36229,9 +36210,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36229
36210
|
// Convert screen to world coordinates
|
|
36230
36211
|
var worldCoords = _this6.screenToWorldCoords(viewport, finalPos.x, finalPos.y, scale, worldOriginX, worldOriginY);
|
|
36231
36212
|
|
|
36232
|
-
// Calculate new position
|
|
36213
|
+
// Calculate new position: delta from old bbox center to new bbox center
|
|
36233
36214
|
var currentPos = component.position;
|
|
36234
|
-
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos,
|
|
36215
|
+
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos, bboxCenter);
|
|
36235
36216
|
|
|
36236
36217
|
// Apply translation via centralPlant API
|
|
36237
36218
|
var deltaX = newPosition.x - currentPos.x;
|
|
@@ -36334,37 +36315,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36334
36315
|
}
|
|
36335
36316
|
|
|
36336
36317
|
/**
|
|
36337
|
-
* Convert world coordinates to 3D object position
|
|
36318
|
+
* Convert dragged 2D world coordinates to a new 3D object position.
|
|
36319
|
+
* coord1/coord2 represent where the bbox CENTER should be in the view's 2D plane;
|
|
36320
|
+
* we compute the delta from the old bbox center and apply it to the pivot position.
|
|
36338
36321
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
36322
|
+
* @param {{coord1, coord2}} worldCoords - Projected world coordinates from screen
|
|
36323
|
+
* @param {{x,y,z}} currentPosition - Current Three.js object position (pivot)
|
|
36324
|
+
* @param {{x,y,z}} bboxCenter - Old world-space bbox center
|
|
36339
36325
|
*/
|
|
36340
36326
|
}, {
|
|
36341
36327
|
key: "worldCoordsToObjectPosition",
|
|
36342
|
-
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition,
|
|
36328
|
+
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition, bboxCenter) {
|
|
36343
36329
|
var coord1 = worldCoords.coord1,
|
|
36344
36330
|
coord2 = worldCoords.coord2;
|
|
36345
36331
|
switch (viewport.viewType) {
|
|
36346
36332
|
case 'top':
|
|
36333
|
+
// coord1=X, coord2=Y in world space
|
|
36347
36334
|
return {
|
|
36348
|
-
x: coord1,
|
|
36349
|
-
y: coord2,
|
|
36335
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36336
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
36350
36337
|
z: currentPosition.z
|
|
36351
36338
|
};
|
|
36352
36339
|
case 'front':
|
|
36340
|
+
// coord1=X, coord2=Z in world space
|
|
36353
36341
|
return {
|
|
36354
|
-
x: coord1,
|
|
36342
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36355
36343
|
y: currentPosition.y,
|
|
36356
|
-
z: coord2 -
|
|
36344
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
36357
36345
|
};
|
|
36358
36346
|
case 'side':
|
|
36347
|
+
// coord1=-Y (negated), coord2=Z in world space
|
|
36359
36348
|
return {
|
|
36360
36349
|
x: currentPosition.x,
|
|
36361
|
-
y: -coord1,
|
|
36362
|
-
z: coord2 -
|
|
36350
|
+
y: currentPosition.y + (-coord1 - bboxCenter.y),
|
|
36351
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
36363
36352
|
};
|
|
36364
36353
|
default:
|
|
36365
36354
|
return {
|
|
36366
|
-
x: coord1,
|
|
36367
|
-
y: coord2,
|
|
36355
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36356
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
36368
36357
|
z: currentPosition.z
|
|
36369
36358
|
};
|
|
36370
36359
|
}
|
|
@@ -36382,8 +36371,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36382
36371
|
var components = [];
|
|
36383
36372
|
this.sceneViewer.scene.traverse(function (object) {
|
|
36384
36373
|
var _object$userData, _object$userData2;
|
|
36385
|
-
|
|
36386
|
-
|
|
36374
|
+
// Only match the ROOT component object — must have both objectType:'component'
|
|
36375
|
+
// AND libraryId (inner GLB mesh nodes don't have libraryId)
|
|
36376
|
+
if (((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.objectType) === 'component' && (_object$userData2 = object.userData) !== null && _object$userData2 !== void 0 && _object$userData2.libraryId) {
|
|
36387
36377
|
components.push(object);
|
|
36388
36378
|
}
|
|
36389
36379
|
});
|
|
@@ -37840,7 +37830,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37840
37830
|
* Initialize the CentralPlant manager
|
|
37841
37831
|
*
|
|
37842
37832
|
* @constructor
|
|
37843
|
-
* @version 0.3.
|
|
37833
|
+
* @version 0.3.5
|
|
37844
37834
|
* @updated 2025-10-22
|
|
37845
37835
|
*
|
|
37846
37836
|
* @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.5
|
|
39
39
|
* @updated 2025-10-22
|
|
40
40
|
*
|
|
41
41
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -6,6 +6,7 @@ var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHel
|
|
|
6
6
|
var THREE = require('three');
|
|
7
7
|
var ioDeviceUtils = require('../../utils/ioDeviceUtils.js');
|
|
8
8
|
var modelPreloader = require('../../rendering/modelPreloader.js');
|
|
9
|
+
var boundingBoxUtils = require('../../utils/boundingBoxUtils.js');
|
|
9
10
|
|
|
10
11
|
function _interopNamespace(e) {
|
|
11
12
|
if (e && e.__esModule) return e;
|
|
@@ -310,6 +311,11 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
310
311
|
if (!libraryModel.userData) libraryModel.userData = {};
|
|
311
312
|
Object.assign(libraryModel.userData, jsonEntry.userData);
|
|
312
313
|
|
|
314
|
+
// Preserve the original hardcoded UUID so getHardcodedUuid() can find it during export.
|
|
315
|
+
// jsonEntry is the raw JSON object (no originalUuid), so we must set it explicitly from
|
|
316
|
+
// originalProps.uuid (which equals the uuid string from the scene JSON, e.g. "PUMP-1").
|
|
317
|
+
libraryModel.userData.originalUuid = originalProps.uuid;
|
|
318
|
+
|
|
313
319
|
// Apply bounding box configurations
|
|
314
320
|
if (componentData.boundingBox) {
|
|
315
321
|
libraryModel.userData.boundingBox = componentData.boundingBox;
|
|
@@ -574,15 +580,21 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
574
580
|
_context5.n = 2;
|
|
575
581
|
return Promise.all(glbLoadingPromises);
|
|
576
582
|
case 2:
|
|
577
|
-
// Update world bounding boxes for loaded models
|
|
583
|
+
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
578
584
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
579
|
-
var _jsonData$userData2;
|
|
580
585
|
var jsonData = _ref2.jsonData,
|
|
581
586
|
glbModel = _ref2.glbModel;
|
|
582
|
-
if (glbModel
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
587
|
+
if (!glbModel) return;
|
|
588
|
+
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
589
|
+
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
590
|
+
var filteredBox = boundingBoxUtils.computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|
|
591
|
+
var worldBoundingBox = filteredBox.isEmpty() ? _this3._calculateWorldBoundingBox(glbModel) : {
|
|
592
|
+
min: [filteredBox.min.x, filteredBox.min.y, filteredBox.min.z],
|
|
593
|
+
max: [filteredBox.max.x, filteredBox.max.y, filteredBox.max.z]
|
|
594
|
+
};
|
|
595
|
+
// Update both the JSON data object AND the live scene object
|
|
596
|
+
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
597
|
+
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
586
598
|
});
|
|
587
599
|
|
|
588
600
|
// Dispatch completion event
|