beam: restore point cloud source colors
This commit is contained in:
parent
ff994e705d
commit
bf397ff191
|
|
@ -215,6 +215,7 @@ let gizmo = null;
|
|||
const transformStore = {}; // modelId -> objectId -> {position, rotation, scale}
|
||||
const modelTypes = {}; // modelId -> normalized type
|
||||
const sceneModels = {}; // modelId -> SceneModel
|
||||
const pointCloudColorSnapshots = new Map(); // modelId -> [{ layer, colors, workingColors }]
|
||||
let activeDisplayMode = "source";
|
||||
let activeLightingMode = "ambient";
|
||||
let activeNavigationAxis = "auto";
|
||||
|
|
@ -443,6 +444,92 @@ const getBaseEdgesForModel = (modelId) => {
|
|||
|
||||
const isPointCloudModel = (modelId) => modelTypes[modelId] === "las";
|
||||
|
||||
const getPointCloudLayers = (model) => (
|
||||
(model?.layerList || []).filter((layer) => (
|
||||
layer?.primitive === "points" &&
|
||||
layer?._state?.colorsBuf?.getData &&
|
||||
layer?._state?.colorsBuf?.setData
|
||||
))
|
||||
);
|
||||
|
||||
const snapshotPointCloudColors = (modelId) => {
|
||||
const model = sceneModels[modelId] || viewer?.scene?.models?.[modelId];
|
||||
if (!model || !isPointCloudModel(modelId) || pointCloudColorSnapshots.has(modelId)) return;
|
||||
const snapshots = getPointCloudLayers(model)
|
||||
.map((layer) => {
|
||||
try {
|
||||
const colors = layer._state.colorsBuf.getData();
|
||||
return colors?.length ? { layer, colors, workingColors: null } : null;
|
||||
} catch (err) {
|
||||
console.warn("point cloud color snapshot failed", err);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
if (snapshots.length) {
|
||||
pointCloudColorSnapshots.set(modelId, snapshots);
|
||||
}
|
||||
};
|
||||
|
||||
const clearPointCloudEntityColorState = (targets) => {
|
||||
targets.forEach((entity) => {
|
||||
if (!entity) return;
|
||||
try {
|
||||
entity.xrayed = false;
|
||||
entity.opacity = 1;
|
||||
entity.edges = false;
|
||||
(entity.meshes || []).forEach((mesh) => {
|
||||
mesh._colorizing = false;
|
||||
});
|
||||
if (entity._colorizeUpdated && viewer?.scene?._objectColorizeUpdated) {
|
||||
viewer.scene._objectColorizeUpdated(entity, false);
|
||||
entity._colorizeUpdated = false;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("point cloud entity reset failed", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const writePointCloudColors = (modelId, colorize = null) => {
|
||||
snapshotPointCloudColors(modelId);
|
||||
const snapshots = pointCloudColorSnapshots.get(modelId) || [];
|
||||
const color = colorize
|
||||
? colorize.map((v) => Math.max(0, Math.min(255, Math.round(v * 255))))
|
||||
: null;
|
||||
|
||||
snapshots.forEach((snapshot) => {
|
||||
const colorsBuf = snapshot.layer?._state?.colorsBuf;
|
||||
if (!colorsBuf?.setData) return;
|
||||
try {
|
||||
if (!color) {
|
||||
colorsBuf.setData(snapshot.colors);
|
||||
return;
|
||||
}
|
||||
const original = snapshot.colors;
|
||||
const working = snapshot.workingColors?.length === original.length
|
||||
? snapshot.workingColors
|
||||
: new Uint8Array(original.length);
|
||||
for (let i = 0; i < original.length; i += 4) {
|
||||
working[i] = color[0];
|
||||
working[i + 1] = color[1];
|
||||
working[i + 2] = color[2];
|
||||
working[i + 3] = original[i + 3];
|
||||
}
|
||||
snapshot.workingColors = working;
|
||||
colorsBuf.setData(working);
|
||||
} catch (err) {
|
||||
console.warn("point cloud color restore failed", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const applyPointCloudDisplayMode = (modelId, preset, targets) => {
|
||||
clearPointCloudEntityColorState(targets);
|
||||
writePointCloudColors(modelId, preset.colorize);
|
||||
viewer?.scene?.glRedraw?.();
|
||||
};
|
||||
|
||||
const applyDisplayModeToModel = (modelId) => {
|
||||
const model = sceneModels[modelId] || viewer?.scene?.models?.[modelId];
|
||||
if (!model) return;
|
||||
|
|
@ -450,6 +537,11 @@ const applyDisplayModeToModel = (modelId) => {
|
|||
const objects = Object.values(model.objects || {});
|
||||
const targets = objects.length ? objects : [model];
|
||||
|
||||
if (isPointCloudModel(modelId)) {
|
||||
applyPointCloudDisplayMode(modelId, preset, targets);
|
||||
return;
|
||||
}
|
||||
|
||||
targets.forEach((entity) => {
|
||||
if (!entity) return;
|
||||
try {
|
||||
|
|
@ -1599,6 +1691,7 @@ const destroyAllModels = ({ preserveMeta = false } = {}) => {
|
|||
activeModels.length = 0;
|
||||
Object.keys(sceneModels).forEach((key) => delete sceneModels[key]);
|
||||
Object.keys(modelTypes).forEach((key) => delete modelTypes[key]);
|
||||
pointCloudColorSnapshots.clear();
|
||||
if (!preserveMeta) {
|
||||
Object.keys(transformStore).forEach((key) => delete transformStore[key]);
|
||||
}
|
||||
|
|
@ -1717,6 +1810,7 @@ const deleteModelById = (modelId) => {
|
|||
activeModels.splice(idx, 1);
|
||||
delete sceneModels[modelId];
|
||||
delete modelTypes[modelId];
|
||||
pointCloudColorSnapshots.delete(modelId);
|
||||
delete transformStore[modelId];
|
||||
treeModelIds.delete(modelId);
|
||||
if (customTrees.has(modelId)) {
|
||||
|
|
@ -2929,6 +3023,9 @@ const initViewer = async () => {
|
|||
setStatus(`Загружено: ${name || inferredType}`);
|
||||
dropZone.classList.add("hidden");
|
||||
setLoading(false);
|
||||
if (inferredType === "las") {
|
||||
snapshotPointCloudColors(id);
|
||||
}
|
||||
applyDisplayModeToModel(id);
|
||||
updateNavCubeVisibility();
|
||||
updatePanelsVisibility();
|
||||
|
|
|
|||
|
|
@ -239,6 +239,6 @@
|
|||
<input id="fileInput" class="hidden" type="file"
|
||||
accept=".xkt,.glb,.gltf,.bim,.las,.laz,.obj,.stl">
|
||||
|
||||
<script type="module" src="./dcViewer.js?v=13"></script>
|
||||
<script type="module" src="./dcViewer.js?v=14"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Reference in New Issue