소스 검색

[Fixed 0000] 新增了工作面瓦斯抽采单元的绘制

hongrunxia 1 개월 전
부모
커밋
f40eddcb3d

+ 28 - 2
src/views/vent/gas/gasAssessment/components/workFace.vue

@@ -65,7 +65,7 @@
   import { ref, onMounted, watch } from 'vue';
   import ventBox1 from '/@/components/vent/ventBox1.vue';
   import CustomBadges from './customHeader.vue';
-  import { gasMonitor, headerBadges, gasPumpValve, gasUnitBarOption, mockData, gasUnitPieOption, mockPieData } from '../gasAssessment.data';
+  import { gasMonitor, gasPumpValve, gasUnitBarOption, mockData, gasUnitPieOption, mockPieData } from '../gasAssessment.data';
   import ListItem from '@/views/vent/gas/components/list/listItem.vue';
   import { get } from '@/utils/ventutil';
   import CustomChart from '@/views/vent/home/configurable/components/detail/CustomChart.vue';
@@ -80,7 +80,33 @@
   const loading = ref(false);
   const gasUnitDataSource = ref<DeviceType>(); // 抽采单元监测数据
   const workFaceData = ref<any>({}); // 工作面基础数据
-
+  const headerBadges = ref([
+    {
+      value: get(workFaceData.value, 'gasReserves'),
+      desc: '瓦斯总储量',
+      code: '',
+    },
+    {
+      value: get(workFaceData.value, 'totalGasVolume'),
+      desc: '抽采达标量',
+      code: '',
+    },
+    {
+      value: get(workFaceData.value, 'cumulativeFlow'),
+      desc: '累计抽采量',
+      code: '',
+    },
+    {
+      value: get(workFaceData.value, 'scalarRecognition'),
+      desc: '预抽确认量',
+      code: '',
+    },
+    {
+      value: get(workFaceData.value, 'totalDate'),
+      desc: '已抽时间',
+      code: '',
+    },
+  ]);
   watch(
     () => props.dataSource,
     (newValue: DeviceType[]) => {

+ 1 - 1
src/views/vent/gas/gasAssessment/gasAssessment.data.ts

@@ -527,7 +527,7 @@ export function getBezierControlPoint(A = { x: 1, y: 1 }, alpha_degrees = 45, d
 
 export const headerBadges = ref([
   {
-    value: 'T1',
+    value: 'T1', //
     desc: '瓦斯总储量',
     code: '',
   },

+ 29 - 19
src/views/vent/gas/gasAssessment/index.vue

@@ -55,7 +55,7 @@
   import { onBeforeMount, ref, onMounted, onUnmounted, nextTick, watch } from 'vue';
   import CustomHeader from '/@/components/vent/customHeader.vue';
   import { gasUnitDetail, monitorNav } from './gasAssessment.data';
-  import { mountedThree, destroy, setModelType, setCss3D } from './threejs/gasAssessmen.threejs';
+  import { mountedThree, destroy, setModelType, setCss3D, setPlanes, clearCss3D } from './threejs/gasAssessmen.threejs';
   import { useSystemSelect } from '/@/hooks/vent/useSystemSelect';
   import gasUnit from './components/gasUnit.vue';
   import GasEcharts from './components/gasEcharts.vue';
@@ -71,15 +71,18 @@
   const dataSource = ref<DeviceType[]>([]);
   const pageType = ref('workFace');
   const activeUnitId = ref('');
-
+  const gasUnitDataSource = ref<DeviceType>();
+  let isRefreshUnit = false;
   function changeActive(activeValue) {
     activeKey.value = activeValue;
   }
 
   // 获取模型类型
   const changeModalType = (currentData) => {
-    gasUnitNum.value = 4;
-    setModelType(modalType, gasUnitNum.value);
+    // 根据抽采单元
+
+    setModelType(modalType);
+    isRefreshUnit = true;
   };
 
   const { options, optionValue, deviceActive, deviceValue, getSelectRow, getSysDataSource, getDeviceList } = useSystemSelect(
@@ -92,23 +95,31 @@
 
   // // 监测数据
   const selectData = ref([]);
-  const monitorDataGroupNum = ref(3);
+  const monitorDataGroupNum = ref(0);
   // // https获取监测数据
   let timer: null | NodeJS.Timeout = null;
   function getMonitor(flag?) {
     if (Object.prototype.toString.call(timer) === '[object Null]') {
-      timer = setTimeout(
-        async () => {
-          debugger;
-          dataSource.value = await getDeviceList();
-          if (timer) {
-            timer = null;
-          }
-          await getMonitor();
-          loading.value = false;
-        },
-        flag ? 0 : 1000
-      );
+      return new Promise((resolve) => {
+        timer = setTimeout(
+          async () => {
+            dataSource.value = await getDeviceList();
+            gasUnitDataSource.value = dataSource.value.find((item) => item.deviceType.startsWith('unit'));
+            if (gasUnitDataSource.value) monitorDataGroupNum.value = gasUnitDataSource.value.datalist.length;
+            if (isRefreshUnit) {
+              setPlanes(gasUnitDataSource.value?.datalist);
+              isRefreshUnit = false;
+            }
+            if (timer) {
+              timer = null;
+            }
+            resolve(1);
+            await getMonitor();
+            loading.value = false;
+          },
+          flag ? 0 : 1000
+        );
+      });
     }
   }
 
@@ -131,13 +142,12 @@
     timer = null;
 
     mountedThree(pageType, activeUnitId).then(async () => {
-      // gasUnitNum.value = Math.ceil(Math.random() * 10)
       gasUnitNum.value = 4;
       loading.value = false;
       await getSysDataSource();
       nextTick(async () => {
         await getMonitor(true);
-        setCss3D();
+        setCss3D(gasUnitDataSource.value?.datalist);
       });
     });
   });

+ 135 - 15
src/views/vent/gas/gasAssessment/threejs/gasAssessmen.threejs.base.ts

@@ -55,7 +55,7 @@ class GasAssessmen {
     this.model.renderer?.render(this.model.scene as THREE.Scene, this.model.camera as THREE.PerspectiveCamera);
   }
 
-  setPlanes = (n) => {
+  setPlanes1 = (n) => {
     // const sizeList = [0.2, 0.3, 0.1, 0.2, 0.2];
     const colors = {
       c1: new THREE.Color(0x00fe00), // >90
@@ -218,6 +218,115 @@ class GasAssessmen {
     this.group.add(this.planeGroup);
   };
 
+  setPlanes = (unitList: any[]) => {
+    if (!unitList || unitList.length === 0) return;
+    // 要根据unitList来计算比例
+    type Point = { u: number; v: number };
+    let max = 0;
+    const unitLen = unitList[unitList.length - 1]['unitLen'].split(',');
+    max = Math.max(max, ...unitLen);
+    const regions = <{ points: Point[]; color: any[] }[]>[];
+    for (let i = 0; i < unitList.length; i++) {
+      const item = unitList[i];
+      const unitRatio: Point[] = [];
+      const color = new THREE.Color(item['unitColor']);
+      if (item['unitLen']) {
+        const unitLen = item['unitLen'].split(',');
+        const sortList = [1, 0, 2, 3];
+        for (let j = 0; j < sortList.length; j++) {
+          const x = unitLen[sortList[j]];
+          const unitU = Number((x / max).toFixed(2));
+          const unitV = sortList[j] % 2 === 0 ? 0.0 : 1.0;
+          unitRatio.push({
+            u: unitU == 0 ? 0.0 : unitU,
+            v: unitV == 0 ? 0.0 : unitV,
+          });
+        }
+      }
+      regions.push({
+        points: unitRatio,
+        color: [color.r, color.g, color.b],
+        // color: [1, 0, 0],
+      });
+    }
+
+    // 自定义着色器
+    const vertexShader = `
+    varying vec2 vUv;
+    void main() {
+        vUv = uv; // 传递纹理坐标
+        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
+    }
+`;
+
+    const fragmentShader = `
+    uniform vec3 regionColors[${regions.length}]; // 区域颜色数组
+    uniform vec4 regionPoints[${regions.length * 4}]; // 区域顶点数组 (每个区域4个点)
+    varying vec2 vUv;
+
+    // 判断点是否在四边形内(通过叉积法)
+    bool isPointInQuad(vec2 p, vec2 a, vec2 b, vec2 c, vec2 d) {
+        vec2 ab = b - a;
+        vec2 bc = c - b;
+        vec2 cd = d - c;
+        vec2 da = a - d;
+
+        vec2 ap = p - a;
+        vec2 bp = p - b;
+        vec2 cp = p - c;
+        vec2 dp = p - d;
+
+        float cross1 = ab.x * ap.y - ab.y * ap.x;
+        float cross2 = bc.x * bp.y - bc.y * bp.x;
+        float cross3 = cd.x * cp.y - cd.y * cp.x;
+        float cross4 = da.x * dp.y - da.y * dp.x;
+
+        return (cross1 >= 0.0 && cross2 >= 0.0 && cross3 >= 0.0 && cross4 >= 0.0) ||
+               (cross1 <= 0.0 && cross2 <= 0.0 && cross3 <= 0.0 && cross4 <= 0.0);
+    }
+
+    void main() {
+        vec3 finalColor = vec3(0.0);
+        for (int i = 0; i < ${regions.length}; i++) {
+            vec4 p1 = regionPoints[i * 4];
+            vec4 p2 = regionPoints[i * 4 + 1];
+            vec4 p3 = regionPoints[i * 4 + 2];
+            vec4 p4 = regionPoints[i * 4 + 3];
+
+            // 判断当前片段是否在梯形区域内
+            if (isPointInQuad(vUv, p1.xy, p2.xy, p3.xy, p4.xy)) {
+                finalColor = regionColors[i];
+                break;
+            }
+        }
+        gl_FragColor = vec4(finalColor, 1.0);
+    }
+`;
+
+    const geometry = new THREE.PlaneGeometry(7.723, 3.72, 1, 1);
+    // 创建材质
+    const material = new THREE.ShaderMaterial({
+      vertexShader,
+      fragmentShader,
+      uniforms: {
+        regionColors: { value: regions.map((region) => new THREE.Vector3(...region.color)) },
+        regionPoints: {
+          value: regions.flatMap((region) => region.points.map((p) => new THREE.Vector4(p.u, p.v, 0, 0))),
+        },
+      },
+      depthTest: false,
+      depthWrite: false,
+    });
+
+    // 创建网格并添加到场景中
+    const plane = new THREE.Mesh(geometry, material);
+    plane.rotation.x = -Math.PI / 2;
+    plane.position.set(-0.2, 0.15, -0.03);
+    plane.name = 'unit';
+    this.planeGroup.add(plane);
+    this.group.add(this.planeGroup);
+  };
+
   // 清除抽采单元绘制面
   clearPlanes = () => {
     for (let i = 0; i < this.planeNum; i++) {
@@ -228,10 +337,19 @@ class GasAssessmen {
     }
   };
   // 抽采单元内容显示
-  setCss3D = () => {
-    const sizeList = [0.5, 0.3, 0.2];
-    // const sizeList = [0.4, 0.5, 0.1];
-    // width = 7.713 height =3.717
+  setCss3D = (unitList: any[]) => {
+    const sizeList: number[] = [];
+    if (!unitList || unitList.length === 0) return;
+    let max = 0;
+    const unitLen = unitList[unitList.length - 1]['unitLen'].split(',');
+    max = Math.max(max, ...unitLen);
+    for (let i = 0; i < unitList.length; i++) {
+      const item = unitList[i];
+      const unitLen = item['unitLen'].split(',');
+      const unitMax = Math.max(...unitLen);
+      const unitMin = Math.min(...unitLen);
+      sizeList.push((unitMax - unitMin) / max);
+    }
     let leftW = 0;
     for (let i = 0; i < sizeList.length; i++) {
       const label = setTag3D(`抽采单元${i + 1}`, 'gas_unit_text');
@@ -267,16 +385,18 @@ class GasAssessmen {
   };
   // 清除抽采单元显示内容
   clearCss3D = () => {
-    const obj = this.group.getObjectByName(`unitText`);
-    if (obj) this.group.remove(obj);
-    const element = document.getElementById(`gasUnitBox`) as HTMLElement;
-    if (element) {
-      element.remove();
-    }
-    for (let i = 0; i < this.planeNum; i++) {
-      const label = this.planeGroup.getObjectByName(`planeText${i}`);
-      if (label) this.planeGroup.remove(label);
-    }
+    // const obj = this.group.getObjectByName(`unitText`);
+    // if (obj) this.group.remove(obj);
+    // const element = document.getElementById(`gasUnitBox`) as HTMLElement;
+    // if (element) {
+    //   element.remove();
+    // }
+    // for (let i = 0; i < this.planeNum; i++) {
+    //   const label = this.planeGroup.getObjectByName(`planeText${i}`);
+    //   if (label) this.planeGroup.remove(label);
+    // }
+    this.model.clearGroup(this.planeGroup);
+    this.planeGroup = new THREE.Group();
   };
 
   /* 点击 */

+ 7 - 5
src/views/vent/gas/gasAssessment/threejs/gasAssessmen.threejs.ts

@@ -55,15 +55,18 @@ const render = () => {
   }
 };
 
-export const setCss3D = () => {
-  workFaceObj?.setCss3D();
+export const setCss3D = (unitList: any[]) => {
+  workFaceObj?.setCss3D(unitList);
 };
 export const clearCss3D = () => {
   workFaceObj?.clearCss3D();
 };
-
+export const setPlanes = (unitList) => {
+  workFaceObj?.setPlanes(unitList);
+};
 // 切换风窗类型
-export const setModelType = (type, n = Math.ceil(Math.random() * 4)) => {
+export const setModelType = (type) => {
+  debugger;
   return new Promise((resolve) => {
     const newCameraPosition = { x: -0.1077663653208413, y: 3.730662630250735, z: 5.174545297338427 };
     const newControlsPosition = { x: -0.0997084705839992, y: -0.050186843433472336, z: -0.3263852289773498 };
@@ -125,7 +128,6 @@ export const setModelType = (type, n = Math.ceil(Math.random() * 4)) => {
     } else {
       // 初始加载
       group = workFaceObj.group;
-      workFaceObj?.setPlanes(n);
       showOrHideGasPlane(true);
       const oldControlsPosition = { x: -0.086221, y: -0.612538, z: 0.33468 };
       const oldCameraPosition = { x: 19.589025920044726, y: 7.437905524957071, z: 23.032636074396976 };

+ 1 - 1
src/views/vent/monitorManager/windowMonitor/shuangdaoFcBlt.threejs.ts

@@ -74,7 +74,7 @@ class sdFc_3 {
         y: 145,
       },
       {
-        text: `${selectData.OpenDegree2 ? '后窗开度值(°)' : selectData.forntArea ? '后窗过风面积(㎡)' : '后窗过风面积(㎡)'}:`,
+        text: `${selectData.OpenDegree2 ? '后窗开度值(°)' : selectData.rearArea ? '后窗过风面积(㎡)' : '后窗过风面积(㎡)'}:`,
         font: 'normal 30px Arial',
         color: '#009900',
         strokeStyle: '#002200',