<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>
