164 lines
3.5 KiB
Vue
164 lines
3.5 KiB
Vue
<template>
|
|
<n-collapse-item name="pointCloudStressDisplay" title="试样内部应力点云显示">
|
|
<div class="panel-section">
|
|
<div class="button-group">
|
|
<n-button :disabled="hasCloud" size="small" type="primary" @click="create">创建</n-button>
|
|
<n-button :disabled="!hasCloud" size="small" type="error" @click="remove">移除</n-button>
|
|
</div>
|
|
|
|
<template v-if="hasCloud">
|
|
<div class="control-row">
|
|
<div class="control-label">粒子大小</div>
|
|
</div>
|
|
<div class="slider-container">
|
|
<n-slider v-model:value="pointSize" :max="0.02" :min="0.001" :step="0.001" @update:value="onPointSizeChange"/>
|
|
</div>
|
|
|
|
<div class="control-row">
|
|
<div class="control-label">强度过滤</div>
|
|
</div>
|
|
<div class="slider-container">
|
|
<n-slider v-model:value="intensityRange" :max="1" :min="0" :step="0.01" range @update:value="onFilterChange"/>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</n-collapse-item>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import {onUnmounted, ref} from "vue";
|
|
import {NButton, NCollapseItem, NSlider} from "naive-ui";
|
|
import {useBus} from "@/hooks";
|
|
import {PointCloud, PointCloudTool} from "@deep/engine";
|
|
|
|
//------ 点云面板升级 开始------
|
|
/**
|
|
* 点云可见状态。
|
|
*/
|
|
const hasCloud = ref(false);
|
|
|
|
/**
|
|
* 点云强度过滤范围。
|
|
*/
|
|
const intensityRange = ref<[number, number]>([0, 1]);
|
|
|
|
/**
|
|
* 点云粒子大小。
|
|
*/
|
|
const pointSize = ref<number>(0.01);
|
|
|
|
/**
|
|
* 场景总线实例。
|
|
*/
|
|
const bus = useBus();
|
|
|
|
/**
|
|
* 当前应力点云实例。
|
|
*/
|
|
let cloud: PointCloud | null = null;
|
|
|
|
/**
|
|
* 创建应力点云。
|
|
* @returns {void}
|
|
*/
|
|
const create = (): void => {
|
|
const viewer = bus.getViewer();
|
|
const pointCloudData = PointCloudTool.generateNoisePointCloudData({
|
|
min: [-2.5, -2.5, -2.5],
|
|
max: [2.5, 2.5, 2.5],
|
|
size: 170,
|
|
threshold: 0,
|
|
});
|
|
|
|
cloud = new PointCloud(viewer, {
|
|
name: "应力点云场",
|
|
pointCloudData,
|
|
pointSize: pointSize.value,
|
|
colorStops: [
|
|
{color: "#0000FF", step: 0.0},
|
|
{color: "#00FF00", step: 0.33},
|
|
{color: "#FFFF00", step: 0.66},
|
|
{color: "#FF0000", step: 1.0},
|
|
],
|
|
});
|
|
|
|
// 创建后立即同步一次过滤范围与粒子大小。
|
|
cloud.filterByIntensity(intensityRange.value[0], intensityRange.value[1]);
|
|
cloud.setPointSize(pointSize.value);
|
|
bus.triggerSceneTreeUpdate();
|
|
hasCloud.value = true;
|
|
};
|
|
|
|
/**
|
|
* 移除应力点云。
|
|
* @returns {void}
|
|
*/
|
|
const remove = (): void => {
|
|
if (cloud) {
|
|
cloud.dispose();
|
|
cloud = null;
|
|
}
|
|
hasCloud.value = false;
|
|
bus.triggerSceneTreeUpdate();
|
|
};
|
|
|
|
/**
|
|
* 响应强度过滤范围变更。
|
|
* @returns {void}
|
|
*/
|
|
const onFilterChange = (): void => {
|
|
cloud?.filterByIntensity(intensityRange.value[0], intensityRange.value[1]);
|
|
};
|
|
|
|
/**
|
|
* 响应粒子大小变更。
|
|
* @returns {void}
|
|
*/
|
|
const onPointSizeChange = (): void => {
|
|
cloud?.setPointSize(pointSize.value);
|
|
};
|
|
|
|
/**
|
|
* 组件销毁时清理点云。
|
|
* @returns {void}
|
|
*/
|
|
onUnmounted((): void => {
|
|
remove();
|
|
});
|
|
//------ 点云面板升级 结束------
|
|
</script>
|
|
|
|
<style scoped>
|
|
.panel-section {
|
|
padding: 8px 0;
|
|
}
|
|
|
|
.button-group {
|
|
display: flex;
|
|
gap: 8px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.button-group .n-button {
|
|
flex: 1;
|
|
}
|
|
|
|
.control-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.control-label {
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
color: #555;
|
|
}
|
|
|
|
.slider-container {
|
|
margin: 0 0 16px 0;
|
|
padding: 0 4px;
|
|
}
|
|
</style>
|