explode.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  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 arr=[];
  99. let currentrow1 = ref(false)
  100. let activeNames1 = ref(["2"])
  101. let starttime = ref(1)
  102. let endtime = ref(60)
  103. let count = ref(1)
  104. let newcount = ref(0)
  105. let timenum = ref(2)
  106. let playshow = ref(true)
  107. const isstop = ref(false)
  108. let suspendshow = ref(false)
  109. let showfalse = ref(false)
  110. let initFlag=false;
  111. let aid = ref()
  112. let vtkObj = {}
  113. let max, min;
  114. watch(
  115. () => [formInline.value.region, count.value, aid.value],
  116. (newVal, oldVal) => {
  117. if(initFlag){
  118. console.log(count.value);
  119. if (newVal[1] != oldVal[1]) {
  120. console.log("步数改变", newVal[1], oldVal[1]);
  121. if (vtkObj.fcon) {
  122. console.log(count.value);
  123. vtkScalarRead(count.value); //步数
  124. }
  125. }
  126. if (newVal[0] != oldVal[0]) {
  127. console.log("标量改变", newVal[0], oldVal[0]);
  128. if (vtkObj.fcon) {
  129. vtkShow();
  130. }
  131. }
  132. }
  133. },
  134. { deep: true }
  135. ); //深度监视
  136. onMounted(() => {
  137. const rootContainer = document.getElementById("expleft1")
  138. // rootContainer.style.position = "relative"
  139. // rootContainer.style.width = "100%"
  140. // rootContainer.style.height = "100%"
  141. vtkObj.fcon = createGassControl();
  142. const fcon = vtkObj.fcon;
  143. vtkObj.renderWindow = vtkGenericRenderWindow.newInstance()
  144. vtkObj.renderWindow.setContainer(rootContainer)
  145. vtkObj.jgMapper = vtkMapper.newInstance()
  146. vtkObj.jgActor = vtkActor.newInstance()
  147. vtkObj.jgActor.getProperty().setRepresentation(Representation.SURFACE) //面
  148. vtkObj.jgActor.setMapper(vtkObj.jgMapper)
  149. // vtkObj.renderWindow.getRenderer().addActor(vtkObj.jgActor);
  150. vtkObj.renderWindow.getRenderer().setBackground(0.0, 0.0, 0.0, 0.0)
  151. vtkObj.scalarBarActor = vtkScalarBarActor.newInstance()
  152. vtkObj.scalarBarActor.setGenerateTicks(generateTicks(5))
  153. vtkObj.scalarBarActor.setDrawAboveRangeSwatch(true)
  154. vtkObj.scalarBarActor.setDrawNanAnnotation(false)
  155. vtkObj.scalarBarActor.setBoxPosition([1, 0])
  156. // 修改设条颜色
  157. const ctf = vtkColorTransferFunction.newInstance()
  158. ctf.addRGBPoint(0.0, 0, 1, 154 / 255.0)
  159. ctf.addRGBPoint(1.0, 1.0, 165.0 / 255.0, 0.0)
  160. ctf.addRGBPoint(2.0, 230 / 255.0, 0.0, 92.0 / 225.0)
  161. vtkObj.jgMapper.setLookupTable(ctf)
  162. const lut = vtkObj.jgMapper.getLookupTable()
  163. vtkObj.scalarBarActor.setScalarsToColors(lut)
  164. vtkObj.renderWindow.resize()
  165. // vtkObj.renderWindow.getRenderer().addActor(vtkObj.scalarBarActor);
  166. // vtkGridRead(props.aid);
  167. // vtkObj.renderWindow.getRenderer().resetCamera();
  168. // vtkObj.renderWindow.getRenderWindow().render();
  169. // 设置环境光和光照
  170. const light = vtkLight.newInstance()
  171. light.setColor(1.0, 1.0, 1.0) // 白色环境光
  172. light.setIntensity(3.0) // 强度为1.0
  173. vtkObj.renderWindow.getRenderer().addLight(light)
  174. })
  175. function initVtk() {
  176. }
  177. function generateTicks(numberOfTicks) {
  178. return (helper) => {
  179. const lastTickBounds = helper.getLastTickBounds()
  180. // compute tick marks for axes
  181. const scale = d3
  182. .scaleLinear()
  183. .domain([0.0, 1.0])
  184. .range([lastTickBounds[0], lastTickBounds[1]])
  185. const samples = scale.ticks(numberOfTicks)
  186. const ticks = samples.map((tick) => scale(tick))
  187. // Replace minus "\u2212" with hyphen-minus "\u002D" so that parseFloat() works
  188. formatDefaultLocale({ minus: "\u002D" })
  189. const format = scale.tickFormat(
  190. ticks[0],
  191. ticks[ticks.length - 1],
  192. numberOfTicks
  193. )
  194. const tickStrings = ticks
  195. .map(format)
  196. .map((tick) => Number(parseFloat(tick).toPrecision(12)).toPrecision()) // d3 sometimes adds unwanted whitespace
  197. helper.setTicks(ticks)
  198. helper.setTickStrings(tickStrings)
  199. }
  200. }
  201. function vtkShow() {
  202. // formInline.region="Pressure";
  203. console.log("执行了1111")
  204. const scalarBarActor = vtkObj.scalarBarActor
  205. const mapper = vtkObj.jgMapper
  206. const actor = vtkObj.jgActor
  207. const fcon = vtkObj.fcon
  208. // console.log(props.region)
  209. const scalarArray = fcon.scalar.get(formInline.value.region)
  210. if (!scalarArray || !fcon.polydata) {
  211. return
  212. }
  213. console.log(" fcon.polydata.getNumberOfPoints():", fcon.polydata.getNumberOfPoints());
  214. const dataArray = vtkDataArray.newInstance({
  215. name: formInline.value.region,
  216. size: fcon.polydata.getNumberOfPoints()
  217. })
  218. // console.log(dataArray);
  219. dataArray.setData(scalarArray)
  220. fcon.polydata.getPointData().setScalars(dataArray)
  221. mapper.setInputData(fcon.polydata)
  222. getMinMax(scalarArray)
  223. mapper.setScalarRange(parseFloat(min.toFixed(3)), parseFloat(max.toFixed(3))) //设置范围
  224. scalarBarActor.setAxisLabel(formInline.value.region)
  225. mapper.clearColorArrays() //强制重建颜色
  226. actor.getProperty().setOpacity(count.value) //设置错误的透明度使得页面重新加载 不设置不刷新页面
  227. vtkObj.renderWindow.getRenderer().addActor(scalarBarActor)
  228. vtkObj.renderWindow.getRenderer().addActor(actor)
  229. vtkObj.renderWindow.getRenderer().resetCamera();
  230. vtkObj.renderWindow.getRenderWindow().render();
  231. initFlag=true;
  232. }
  233. function getMinMax(scalars) {
  234. // console.log("getMinMax:",scalars);
  235. min = scalars[0]
  236. max = scalars[0]
  237. for (let index = 0; index <= scalars.length; index++) {
  238. let scalar = scalars[index]
  239. if (min > scalar) {
  240. min = scalar
  241. }
  242. if (max < scalar) {
  243. max = scalar
  244. }
  245. }
  246. console.log("max,min:", max, min);
  247. }
  248. onBeforeUnmount(() => {
  249. vtkObj.scalarBarActor.delete()
  250. vtkObj.jgMapper.delete()
  251. vtkObj.jgActor.delete()
  252. vtkObj.renderWindow.delete()
  253. vtkObj = null
  254. })
  255. // 播放暂停
  256. const play = (time) => {
  257. const fcon = vtkObj.fcon;
  258. showfalse.value = !showfalse.value
  259. currentrow1.value = false
  260. if (showfalse.value) {
  261. suspendshow.value = true
  262. playshow.value = false
  263. isstop.value = true //播放
  264. const sleep = (timeout = time) =>
  265. new Promise((resolve, reject) => {
  266. setTimeout(resolve, timeout)
  267. })
  268. let timer = async (timeout) => {
  269. while (count.value < endtime.value && isstop.value) {
  270. if (isstop.value == true) {
  271. await sleep(time)
  272. count.value++
  273. fcon.step = count.value
  274. newcount.value = count.value
  275. // newtime();
  276. }
  277. }
  278. }
  279. timer(time)
  280. } else {
  281. isstop.value = false //暂停
  282. playshow.value = true
  283. suspendshow.value = false
  284. }
  285. }
  286. // 下一页
  287. function increment() {
  288. const fcon = vtkObj.fcon
  289. currentrow1.value = false
  290. isstop.value = false
  291. if (count.value == endtime.value) {
  292. return
  293. }
  294. count.value++
  295. newcount.value = count.value
  296. fcon.step = count.value
  297. //newtime();
  298. }
  299. //回到上一页
  300. function Prev() {
  301. const fcon = vtkObj.fcon
  302. currentrow1.value = false
  303. isstop.value = false
  304. count.value--
  305. fcon.step = count.value
  306. newcount.value = count.value
  307. //newtime();
  308. }
  309. // 时间计算
  310. const newtime = () => {
  311. timeshow.value = true
  312. time.value = null
  313. oldtime.value = sessionStorage.getItem("acctime")
  314. console.log(oldtime.value)
  315. time.value = new Date(oldtime.value).getTime() / 1000
  316. if (count.value == 2) {
  317. let time2 = (count.value - 1) * 60 + time.value
  318. timeline.value = timescount(time2)
  319. } else {
  320. let time2 = count.value * 60 + time.value
  321. timeline.value = timescount(time2)
  322. }
  323. }
  324. function sliderchange(val) {
  325. const fcon = vtkObj.fcon
  326. suspendshow.value = false
  327. playshow.value = true
  328. isstop.value = false
  329. newcount.value = count.value
  330. fcon.step = count.value
  331. }
  332. function vtkGridRead() {
  333. initVtk();
  334. const fcon = vtkObj.fcon
  335. aid.value = props.aid
  336. fcon.step = count.value
  337. fcon.aid = aid.value
  338. const params = {
  339. transCode: "D40003",
  340. aid: aid.value
  341. }
  342. request(params).then((res) => {
  343. endtime.value = res.steps
  344. fcon
  345. .initGemetry(aid.value)
  346. .then((result) => {
  347. vtkScalarRead(count.value) //步数
  348. })
  349. .catch((err) => { })
  350. }).catch((err) => { })
  351. }
  352. function vtkScalarRead(step) {
  353. arr=[];
  354. let i=0;
  355. const fcon = vtkObj.fcon
  356. fcon
  357. .getScalrsByStep(step)
  358. .then((result) => {
  359. // console.log(fcon.scalar)
  360. strResultFormatlist.value = [];
  361. fcon.scalar.forEach((value, key) => {
  362. //arr.push(key)
  363. i=i+1
  364. strResultFormatlist.value.push({
  365. id: i,
  366. name:key ,
  367. value:key ,
  368. });
  369. })
  370. console.log(strResultFormatlist.value);
  371. vtkShow()
  372. })
  373. .catch((err) => {
  374. console.log(err)
  375. })
  376. }
  377. //深度监视
  378. const regionchange=(val)=>{
  379. formInline.value.region=val;
  380. }
  381. const quding=()=>{
  382. isexpdialog.value=false;
  383. }
  384. defineExpose({ isexpdialog, vtkGridRead })
  385. </script>
  386. <style lang="scss" scoped>
  387. .exp {
  388. display: flex;
  389. .expleft {
  390. width: 70%;
  391. border-radius: 0px 0px 0px 0px;
  392. border: 1px solid;
  393. border-image: linear-gradient(180deg,
  394. rgba(31, 107, 255, 1),
  395. rgba(31, 107, 255, 0.48)) 1 1;
  396. box-shadow: inset 0px 0px 17px 5px rgba(12, 97, 197, 0.2);
  397. margin-right: 2%;
  398. height: 600px;
  399. }
  400. .expright {
  401. padding: 10px;
  402. width: 340px;
  403. border-radius: 0px 0px 0px 0px;
  404. border: 1px solid;
  405. border-image: linear-gradient(180deg,
  406. rgba(31, 107, 255, 1),
  407. rgba(31, 107, 255, 0.48)) 1 1;
  408. box-shadow: inset 0px 0px 17px 5px rgba(12, 97, 197, 0.2);
  409. }
  410. }
  411. .tanniu {
  412. display: flex;
  413. justify-content: space-between;
  414. align-items: center;
  415. }
  416. .expcontent {
  417. position: absolute;
  418. left: 25%;
  419. top: 100px;
  420. width: 50%;
  421. padding: 10px;
  422. z-index: 11111;
  423. background-color:rgba(13, 22, 57, 0.96);
  424. border: 1px solid;
  425. border-image: linear-gradient(180deg,
  426. rgba(31, 107, 255, 1),
  427. rgba(31, 107, 255, 0.48)) 1 1;
  428. box-shadow: inset 0px 0px 17px 5px rgba(12, 97, 197, 0.2);
  429. }
  430. .headertiele{
  431. color: #fff;
  432. text-align: left;
  433. padding: 0 20px;
  434. font-size: 16px;
  435. font-family: 'YouShe';
  436. }
  437. // #expleft1{
  438. // width:750px;
  439. // height:500px;
  440. // left:25%;
  441. // top: 25%;
  442. // background-color:rgba(12, 97, 197, 1);
  443. // border: 1px solid;
  444. // border-image: linear-gradient(
  445. // 180deg,
  446. // rgba(31, 107, 255, 1),
  447. // rgba(31, 107, 255, 0.48)
  448. // )
  449. // 1 1;
  450. // box-shadow: inset 0px 0px 17px 5px rgba(12, 97, 197, 0.2);
  451. // position: absolute;
  452. // z-index: 11111;
  453. // color: #fff;
  454. // }
  455. </style>