explode.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. <template>
  2. <div v-show="isexpdialog" class="dialog_class4 bgcolor tianjia foter_l tianjia">
  3. <div class="expcontent">
  4. <h1 class="headertiele">一维瓦斯爆炸演化</h1>
  5. <div class="exp">
  6. <div class="expleft" id="expleft1"></div>
  7. <div class="expright">
  8. <!-- 物理量 -->
  9. <div class="heigjie imgneon">
  10. <div class="he_pading1 color1">
  11. <el-form-item label="物理量:">
  12. <el-config-provider :locale="zhCn">
  13. <el-select v-model="formInline.region" @change="regionchange($event)" placeholder="请选择">
  14. <el-option v-for="item in strResultFormatlist" :key="item.id" :label="item.name"
  15. :value="item.value"></el-option>
  16. </el-select>
  17. </el-config-provider>
  18. </el-form-item>
  19. </div>
  20. </div>
  21. <!-- 动画 -->
  22. <el-aside class="L_aside L_aside1 asideg asidegbg leftbgimg1">
  23. <div class="demo-collapse jiance asideg1 jc_header collapseeion jianstyle">
  24. <el-collapse accordion v-model="activeNames1" class="bganimation">
  25. <el-collapse-item name="2" class="imgneon">
  26. <template #title>
  27. <el-icon class="iconimg Frame3" fit="contain"></el-icon>
  28. 动画展示
  29. </template>
  30. <div class="rg_content">
  31. <div class="rg-padding">
  32. <div class="animation_s">
  33. <el-slider :max="endtime" :min="1" v-model="count" @change="sliderchange">
  34. </el-slider>
  35. <div class="tanniu">
  36. <div><el-image :src="t1" fit="contain" @click="Prev"></el-image></div>
  37. <div v-show="suspendshow"><el-image :src="t2" fit="contain" @click="play(500)"></el-image></div>
  38. <div v-show="playshow"><el-image :src="t3" fit="contain" @click="play(500)"></el-image></div>
  39. <div><el-image :src="t4" fit="contain" @click="increment"></el-image></div>
  40. </div>
  41. </div>
  42. </div>
  43. </div>
  44. <!-- <div class="mgsnoe" style="height: 200px"></div> -->
  45. </el-collapse-item>
  46. </el-collapse>
  47. </div>
  48. </el-aside>
  49. </div>
  50. </div>
  51. <div class="dialog-footer footer_div l_btn">
  52. <div class="footerbtn flex1">
  53. <div class="borderimg"><el-button @click="isexpdialog = false">取消</el-button></div>
  54. </div>
  55. <div class="footerbtn flex1">
  56. <div class="borderimg"><el-button @click="quding()">
  57. 确定
  58. </el-button></div>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. <!-- 一维瓦斯爆炸弹出列表-->
  64. </template>
  65. <script setup>
  66. import zhCn from "element-plus/es/locale/lang/zh-cn"
  67. import { ref, onMounted, reactive } from "vue"
  68. import { RouterView, RouterLink } from "vue-router"
  69. import { request, uploadFile } from "@/utils/request"
  70. import { ElMessage, ElButton, ElDialog, ElSelect } from "element-plus"
  71. import { createGassControl } from "@/control/gassControl.js"
  72. import t1 from "@/assets/img/t1.png"
  73. import t2 from "@/assets/img/t2.png"
  74. import t3 from "@/assets/img/t3.png"
  75. import t4 from "@/assets/img/t4.png"
  76. import * as d3 from "d3-scale";
  77. import { formatDefaultLocale } from "d3-format";
  78. import vtkGenericRenderWindow from '@kitware/vtk.js/Rendering/Misc/GenericRenderWindow';
  79. import vtkRenderWindowWithControlBar from "@kitware/vtk.js/Rendering/Misc/RenderWindowWithControlBar";
  80. import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
  81. import vtkConeSource from "@kitware/vtk.js/Filters/Sources/ConeSource";
  82. import vtkMapper from "@kitware/vtk.js/Rendering/Core/Mapper";
  83. import { Representation } from "@kitware/vtk.js/Rendering/Core/Property/Constants";
  84. import vtkScalarBarActor from "@kitware/vtk.js/Rendering/Core/ScalarBarActor";
  85. import vtkColorTransferFunction from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction";
  86. import vtkDataArray from "@kitware/vtk.js/Common/Core/DataArray.js";
  87. import vtkLight from "@kitware/vtk.js/Rendering/Core/Light";
  88. const props = defineProps({
  89. aid: Number
  90. })
  91. let isexpdialog = ref(false)
  92. const strResultFormatlist = ref([])
  93. const formInline = ref({
  94. user: "11",
  95. region: "Pressure",
  96. date: ""
  97. })
  98. let newMap = new Map([
  99. ["Temperature", "(℃)"],
  100. ["Pressure", "(Pa)"],
  101. ["Velocity",''],
  102. ["CO", "(ppm)"],
  103. ["CO2", "(%)"],
  104. ["H2O", "(%)"],
  105. ["CH", "(ppm)"],
  106. ["Soot", "(ppm)"],
  107. ["NOx", ""],
  108. ["CO", ""],
  109. ["CH4", "(ppm)"],
  110. ["N2", "(ppm)"],
  111. ]);
  112. let arr=[];
  113. let currentrow1 = ref(false)
  114. let activeNames1 = ref(["2"])
  115. let starttime = ref(1)
  116. let endtime = ref(60)
  117. let count = ref(1)
  118. let newcount = ref(0)
  119. let timenum = ref(2)
  120. let playshow = ref(true)
  121. const isstop = ref(false)
  122. let suspendshow = ref(false)
  123. let showfalse = ref(false)
  124. let initFlag=false;
  125. let aid = ref()
  126. let vtkObj = {}
  127. let max, min;
  128. watch(
  129. () => [formInline.value.region, count.value, aid.value],
  130. (newVal, oldVal) => {
  131. if(initFlag){
  132. console.log(count.value);
  133. if (newVal[1] != oldVal[1]) {
  134. console.log("步数改变", newVal[1], oldVal[1]);
  135. if (vtkObj.fcon) {
  136. console.log(count.value);
  137. vtkScalarRead(count.value); //步数
  138. }
  139. }
  140. if (newVal[0] != oldVal[0]) {
  141. console.log("标量改变", newVal[0], oldVal[0]);
  142. if (vtkObj.fcon) {
  143. vtkShow();
  144. }
  145. }
  146. }
  147. },
  148. { deep: true }
  149. ); //深度监视
  150. onMounted(() => {
  151. const rootContainer = document.getElementById("expleft1")
  152. // rootContainer.style.position = "relative"
  153. // rootContainer.style.width = "100%"
  154. // rootContainer.style.height = "100%"
  155. vtkObj.fcon = createGassControl();
  156. const fcon = vtkObj.fcon;
  157. vtkObj.renderWindow = vtkGenericRenderWindow.newInstance()
  158. vtkObj.renderWindow.setContainer(rootContainer)
  159. vtkObj.jgMapper = vtkMapper.newInstance()
  160. vtkObj.jgActor = vtkActor.newInstance()
  161. vtkObj.jgActor.getProperty().setRepresentation(Representation.SURFACE) //面
  162. vtkObj.jgActor.setMapper(vtkObj.jgMapper)
  163. // vtkObj.renderWindow.getRenderer().addActor(vtkObj.jgActor);
  164. vtkObj.renderWindow.getRenderer().setBackground(0.0, 0.0, 0.0, 0.0)
  165. vtkObj.scalarBarActor = vtkScalarBarActor.newInstance()
  166. vtkObj.scalarBarActor.setGenerateTicks(generateTicks(5))
  167. vtkObj.scalarBarActor.setDrawAboveRangeSwatch(true)
  168. vtkObj.scalarBarActor.setDrawNanAnnotation(false)
  169. vtkObj.scalarBarActor.setBoxPosition([1, 0])
  170. // 修改设条颜色
  171. const ctf = vtkColorTransferFunction.newInstance()
  172. ctf.addRGBPoint(0.0, 0, 1, 154 / 255.0)
  173. ctf.addRGBPoint(1.0, 1.0, 165.0 / 255.0, 0.0)
  174. ctf.addRGBPoint(2.0, 230 / 255.0, 0.0, 92.0 / 225.0)
  175. vtkObj.jgMapper.setLookupTable(ctf)
  176. const lut = vtkObj.jgMapper.getLookupTable()
  177. vtkObj.scalarBarActor.setScalarsToColors(lut)
  178. vtkObj.renderWindow.resize()
  179. // vtkObj.renderWindow.getRenderer().addActor(vtkObj.scalarBarActor);
  180. // vtkGridRead(props.aid);
  181. // vtkObj.renderWindow.getRenderer().resetCamera();
  182. // vtkObj.renderWindow.getRenderWindow().render();
  183. // 设置环境光和光照
  184. const light = vtkLight.newInstance()
  185. light.setColor(1.0, 1.0, 1.0) // 白色环境光
  186. light.setIntensity(3.0) // 强度为1.0
  187. vtkObj.renderWindow.getRenderer().addLight(light)
  188. })
  189. function initVtk() {
  190. }
  191. function generateTicks(numberOfTicks) {
  192. return (helper) => {
  193. const lastTickBounds = helper.getLastTickBounds()
  194. // compute tick marks for axes
  195. const scale = d3
  196. .scaleLinear()
  197. .domain([0.0, 1.0])
  198. .range([lastTickBounds[0], lastTickBounds[1]])
  199. const samples = scale.ticks(numberOfTicks)
  200. const ticks = samples.map((tick) => scale(tick))
  201. // Replace minus "\u2212" with hyphen-minus "\u002D" so that parseFloat() works
  202. formatDefaultLocale({ minus: "\u002D" })
  203. const format = scale.tickFormat(
  204. ticks[0],
  205. ticks[ticks.length - 1],
  206. numberOfTicks
  207. )
  208. const tickStrings = ticks
  209. .map(format)
  210. .map((tick) => Number(parseFloat(tick).toPrecision(12)).toPrecision()) // d3 sometimes adds unwanted whitespace
  211. helper.setTicks(ticks)
  212. helper.setTickStrings(tickStrings)
  213. }
  214. }
  215. function vtkShow() {
  216. // formInline.region="Pressure";
  217. console.log("执行了1111")
  218. const scalarBarActor = vtkObj.scalarBarActor
  219. const mapper = vtkObj.jgMapper
  220. const actor = vtkObj.jgActor
  221. const fcon = vtkObj.fcon
  222. // console.log(props.region)
  223. const scalarArray = fcon.scalar.get(formInline.value.region)
  224. if (!scalarArray || !fcon.polydata) {
  225. return
  226. }
  227. console.log(" fcon.polydata.getNumberOfPoints():", fcon.polydata.getNumberOfPoints());
  228. const dataArray = vtkDataArray.newInstance({
  229. name: formInline.value.region,
  230. size: fcon.polydata.getNumberOfPoints()
  231. })
  232. // console.log(dataArray);
  233. dataArray.setData(scalarArray)
  234. fcon.polydata.getPointData().setScalars(dataArray)
  235. mapper.setInputData(fcon.polydata)
  236. getMinMax(scalarArray)
  237. mapper.setScalarRange(parseFloat(min.toFixed(3)), parseFloat(max.toFixed(3))) //设置范围
  238. scalarBarActor.setAxisLabel(formInline.value.region)
  239. mapper.clearColorArrays() //强制重建颜色
  240. actor.getProperty().setOpacity(count.value) //设置错误的透明度使得页面重新加载 不设置不刷新页面
  241. vtkObj.renderWindow.getRenderer().addActor(scalarBarActor)
  242. vtkObj.renderWindow.getRenderer().addActor(actor)
  243. vtkObj.renderWindow.getRenderer().resetCamera();
  244. vtkObj.renderWindow.getRenderWindow().render();
  245. vtkObj.renderWindow.resize();
  246. initFlag=true;
  247. }
  248. function getMinMax(scalars) {
  249. // console.log("getMinMax:",scalars);
  250. min = scalars[0]
  251. max = scalars[0]
  252. for (let index = 0; index <= scalars.length; index++) {
  253. let scalar = scalars[index]
  254. if (min > scalar) {
  255. min = scalar
  256. }
  257. if (max < scalar) {
  258. max = scalar
  259. }
  260. }
  261. console.log("max,min:", max, min);
  262. }
  263. onBeforeUnmount(() => {
  264. vtkObj.scalarBarActor.delete()
  265. vtkObj.jgMapper.delete()
  266. vtkObj.jgActor.delete()
  267. vtkObj.renderWindow.delete()
  268. vtkObj = null
  269. })
  270. // 播放暂停
  271. const play = (time) => {
  272. const fcon = vtkObj.fcon;
  273. showfalse.value = !showfalse.value
  274. currentrow1.value = false
  275. if (showfalse.value) {
  276. suspendshow.value = true
  277. playshow.value = false
  278. isstop.value = true //播放
  279. const sleep = (timeout = time) =>
  280. new Promise((resolve, reject) => {
  281. setTimeout(resolve, timeout)
  282. })
  283. let timer = async (timeout) => {
  284. while (count.value < endtime.value && isstop.value) {
  285. if (isstop.value == true) {
  286. await sleep(time)
  287. count.value++
  288. fcon.step = count.value
  289. newcount.value = count.value
  290. // newtime();
  291. }
  292. }
  293. isstop.value = false //暂停
  294. playshow.value = true
  295. suspendshow.value = false
  296. }
  297. timer(time)
  298. } else {
  299. isstop.value = false //暂停
  300. playshow.value = true
  301. suspendshow.value = false
  302. }
  303. }
  304. // 下一页
  305. function increment() {
  306. const fcon = vtkObj.fcon
  307. currentrow1.value = false
  308. isstop.value = false
  309. if (count.value == endtime.value) {
  310. return
  311. }
  312. count.value++
  313. newcount.value = count.value
  314. fcon.step = count.value
  315. //newtime();
  316. }
  317. //回到上一页
  318. function Prev() {
  319. const fcon = vtkObj.fcon
  320. currentrow1.value = false
  321. isstop.value = false
  322. count.value--
  323. fcon.step = count.value
  324. newcount.value = count.value
  325. //newtime();
  326. }
  327. // 时间计算
  328. const newtime = () => {
  329. timeshow.value = true
  330. time.value = null
  331. oldtime.value = sessionStorage.getItem("acctime")
  332. console.log(oldtime.value)
  333. time.value = new Date(oldtime.value).getTime() / 1000
  334. if (count.value == 2) {
  335. let time2 = (count.value - 1) * 60 + time.value
  336. timeline.value = timescount(time2)
  337. } else {
  338. let time2 = count.value * 60 + time.value
  339. timeline.value = timescount(time2)
  340. }
  341. }
  342. function sliderchange(val) {
  343. const fcon = vtkObj.fcon
  344. suspendshow.value = false
  345. playshow.value = true
  346. isstop.value = false
  347. newcount.value = count.value
  348. fcon.step = count.value
  349. }
  350. function vtkGridRead() {
  351. initVtk();
  352. const fcon = vtkObj.fcon
  353. aid.value = props.aid
  354. fcon.step = count.value
  355. fcon.aid = aid.value
  356. const params = {
  357. transCode: "D40003",
  358. aid: aid.value
  359. }
  360. request(params).then((res) => {
  361. endtime.value = res.steps
  362. fcon
  363. .initGemetry(aid.value)
  364. .then((result) => {
  365. vtkScalarRead(count.value) //步数
  366. })
  367. .catch((err) => { })
  368. }).catch((err) => { })
  369. }
  370. function vtkScalarRead(step) {
  371. arr=[];
  372. let i=0;
  373. const fcon = vtkObj.fcon
  374. fcon
  375. .getScalrsByStep(step)
  376. .then((result) => {
  377. // console.log(fcon.scalar)
  378. strResultFormatlist.value = [];
  379. fcon.scalar.forEach((value, key) => {
  380. //arr.push(key)
  381. i=i+1
  382. strResultFormatlist.value.push({
  383. id: i,
  384. name:key ,
  385. value:key ,
  386. });
  387. })
  388. console.log(strResultFormatlist.value);
  389. vtkShow()
  390. })
  391. .catch((err) => {
  392. console.log(err)
  393. })
  394. }
  395. //深度监视
  396. const regionchange=(val)=>{
  397. formInline.value.region=val;
  398. }
  399. const quding=()=>{
  400. isexpdialog.value=false;
  401. }
  402. defineExpose({ isexpdialog, vtkGridRead })
  403. </script>
  404. <style lang="scss" scoped>
  405. .exp {
  406. display: flex;
  407. .expleft {
  408. width: 70%;
  409. border-radius: 0px 0px 0px 0px;
  410. border: 1px solid;
  411. border-image: linear-gradient(180deg,
  412. rgba(31, 107, 255, 1),
  413. rgba(31, 107, 255, 0.48)) 1 1;
  414. box-shadow: inset 0px 0px 17px 5px rgba(12, 97, 197, 0.2);
  415. margin-right: 2%;
  416. height: 600px;
  417. }
  418. .expright {
  419. padding: 10px;
  420. width: 340px;
  421. border-radius: 0px 0px 0px 0px;
  422. border: 1px solid;
  423. border-image: linear-gradient(180deg,
  424. rgba(31, 107, 255, 1),
  425. rgba(31, 107, 255, 0.48)) 1 1;
  426. box-shadow: inset 0px 0px 17px 5px rgba(12, 97, 197, 0.2);
  427. }
  428. }
  429. .tanniu {
  430. display: flex;
  431. justify-content: space-between;
  432. align-items: center;
  433. }
  434. .expcontent {
  435. position: absolute;
  436. left: 25%;
  437. top: 100px;
  438. width: 50%;
  439. padding: 10px;
  440. z-index: 11111;
  441. background-color:rgba(13, 22, 57, 0.96);
  442. border: 1px solid;
  443. border-image: linear-gradient(180deg,
  444. rgba(31, 107, 255, 1),
  445. rgba(31, 107, 255, 0.48)) 1 1;
  446. box-shadow: inset 0px 0px 17px 5px rgba(12, 97, 197, 0.2);
  447. }
  448. .headertiele{
  449. color: #fff;
  450. text-align: left;
  451. padding: 0 20px;
  452. font-size: 16px;
  453. font-family: 'YouShe';
  454. }
  455. // #expleft1{
  456. // width:750px;
  457. // height:500px;
  458. // left:25%;
  459. // top: 25%;
  460. // background-color:rgba(12, 97, 197, 1);
  461. // border: 1px solid;
  462. // border-image: linear-gradient(
  463. // 180deg,
  464. // rgba(31, 107, 255, 1),
  465. // rgba(31, 107, 255, 0.48)
  466. // )
  467. // 1 1;
  468. // box-shadow: inset 0px 0px 17px 5px rgba(12, 97, 197, 0.2);
  469. // position: absolute;
  470. // z-index: 11111;
  471. // color: #fff;
  472. // }
  473. </style>