vtkModel.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. import * as d3 from "d3-scale";
  2. import { formatDefaultLocale } from "d3-format";
  3. import "@kitware/vtk.js/Rendering/Profiles/Geometry";
  4. import vtkFullScreenRenderWindow from "@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow";
  5. import vtkGenericRenderWindow from '@kitware/vtk.js/Rendering/Misc/GenericRenderWindow';
  6. import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
  7. import vtkMapper from "@kitware/vtk.js/Rendering/Core/Mapper";
  8. import vtkScalarBarActor from "@kitware/vtk.js/Rendering/Core/ScalarBarActor";
  9. import vtkColorTransferFunction from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction";
  10. import { Representation } from "@kitware/vtk.js/Rendering/Core/Property/Constants";
  11. import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
  12. import { throttle } from '@kitware/vtk.js/macros';
  13. import {
  14. FieldDataTypes,
  15. FieldAssociations,
  16. } from '@kitware/vtk.js/Common/DataModel/DataSet/Constants';
  17. import vtkSphereSource from '@kitware/vtk.js/Filters/Sources/SphereSource';
  18. import vtkLineSource from '@kitware/vtk.js/Filters/Sources/LineSource';
  19. import vtkSphereMapper from '@kitware/vtk.js/Rendering/Core/SphereMapper';
  20. import vtk2DShape from '@kitware/vtk.js/Filters/Sources/Arrow2DSource';
  21. import vtkArrowSource from '@kitware/vtk.js/Filters/Sources/ArrowSource';
  22. import vtkArrow2DSource from '@kitware/vtk.js/Filters/Sources/Arrow2DSource';
  23. import vtkConeSource from '@kitware/vtk.js/Filters/Sources/ConeSource';
  24. import vtkAxesActor from '@kitware/vtk.js/Rendering/Core/AxesActor';
  25. import vtkAnnotatedCubeActor from '@kitware/vtk.js/Rendering/Core/AnnotatedCubeActor';
  26. import vtkOrientationMarkerWidget from '@kitware/vtk.js/Interaction/Widgets/OrientationMarkerWidget';
  27. import vtkCamera from '@kitware/vtk.js/Rendering/Core/Camera';
  28. export class VtkModel {
  29. constructor() {
  30. //当前显示 模版 还是结果
  31. this.isJg = false;
  32. /**
  33. * 选择点线
  34. */
  35. this.isSelectNode = false;
  36. /**
  37. * 选择管道
  38. */
  39. this.isSelectPipe = false;
  40. //管道节点选择对象
  41. this.selectObj = null;
  42. //X,Y
  43. this.epageX=null;
  44. this.epageY=null;
  45. //结果选择的点数据
  46. this.selectJgPointId = 0;
  47. this.validNodes = [];//节点数据
  48. this.pipes = [];//管道数据
  49. this.renderWindowWith = null;
  50. this.renderer = null;
  51. this.renderWindow = null;
  52. //选取
  53. this.lastActor = null;
  54. this.nodeActors = []; //节点actor 数据
  55. this.pipeActors = []; //管道actor 数据
  56. this.interactor = null;
  57. this.apiSpecificRenderWindow = null;
  58. this.hardwareSelector = null;
  59. //模板数据
  60. this.polyData = vtkPolyData.newInstance();
  61. this.mapper = vtkMapper.newInstance();
  62. this.actor = vtkActor.newInstance();
  63. this.actor.getProperty().setRepresentation(Representation.SURFACE); //线
  64. this.actor.getProperty().setColor(WHITE);
  65. this.mapper.setInputData(this.polyData);
  66. this.actor.setMapper(this.mapper);
  67. //点数据
  68. this.actor2 = vtkActor.newInstance();
  69. this.actor2.getProperty().setRepresentation(Representation.POINTS); //点
  70. this.actor2.getProperty().setColor(WHITE);
  71. this.actor2.getProperty().setPointSize(2);
  72. this.actor2.setMapper(this.mapper);
  73. //结果数据
  74. this.jgActor = vtkActor.newInstance();
  75. this.jgMapper = vtkMapper.newInstance();
  76. this.jgActor.getProperty().setRepresentation(Representation.SURFACE); //面
  77. this.scalarBarActor = vtkScalarBarActor.newInstance();
  78. this.scalarBarActor.setGenerateTicks(this.generateTicks(5));
  79. this.scalarBarActor.setDrawAboveRangeSwatch(true);
  80. this.scalarBarActor.setDrawNanAnnotation(false);
  81. this.scalarBarActor.setBoxPosition([1, 0]);
  82. // 修改设条颜色
  83. const ctf = vtkColorTransferFunction.newInstance();
  84. ctf.addRGBPoint(0.0, 0.0, 0.0, 1.0);
  85. ctf.addRGBPoint(1.0, 0.0, 1.0, 0.5);
  86. ctf.addRGBPoint(2.0, 0.0, 1.0, 0.0);
  87. ctf.addRGBPoint(3.0, 1.0, 0.5, 0.0);
  88. ctf.addRGBPoint(4.0, 1.0, 0.0, 0.0);
  89. this.jgMapper.setLookupTable(ctf);
  90. const lut = this.jgMapper.getLookupTable();
  91. this.scalarBarActor.setScalarsToColors(lut);
  92. this.jgActor.setMapper(this.jgMapper);
  93. this.ways = [];
  94. this.wayActors = [];
  95. }
  96. waysInit(ways) {
  97. this.renderWindowWith.resize();
  98. this.ways = ways;
  99. this.ways.forEach((way) => {
  100. let nodes1 = [];
  101. let nodes2 = [];
  102. for (let index = 0; index < way.nrows.length - 1; index++) {
  103. nodes1.push(way.nrows[index]);
  104. }
  105. for (let index = 1; index < way.nrows.length; index++) {
  106. nodes2.push(way.nrows[index]);
  107. }
  108. for (let index = 0; index < nodes2.length; index++) {
  109. const lineSource = vtkLineSource.newInstance();
  110. let snode = nodes1[index];
  111. let enode = nodes2[index];
  112. let point1 = [parseFloat(snode.x), parseFloat(snode.y), parseFloat(snode.z)];
  113. let point2 = [parseFloat(enode.x), parseFloat(enode.y), parseFloat(enode.z)];
  114. lineSource.setPoint1(point1);
  115. lineSource.setPoint2(point2);
  116. lineSource.setResolution(12);
  117. const actor = vtkActor.newInstance();
  118. const mapper = vtkMapper.newInstance();
  119. actor.setMapper(mapper);
  120. actor.getProperty().setLineWidth(3);//设置线宽
  121. if(way.safety=="safety"){
  122. actor.getProperty().setColor(GREEN);
  123. }else if(way.safety=="danger"){
  124. actor.getProperty().setColor(REA);
  125. }
  126. const initialValues = {
  127. base: 0,
  128. center: point2,
  129. height: 9,
  130. radius: 5,
  131. resolution: 8,
  132. direction: [
  133. point2[0]-point1[0],
  134. point2[1]-point1[1],
  135. point2[2]-point1[2],
  136. ]
  137. };
  138. const vtk2d = vtkConeSource.newInstance(initialValues);
  139. const mapper2 = vtkMapper.newInstance();
  140. mapper2.setInputConnection(vtk2d.getOutputPort());
  141. const actor2 = vtkActor.newInstance();
  142. actor2.setMapper(mapper2);
  143. if(way.safety=="safety"){
  144. actor2.getProperty().setColor(GREEN);
  145. }else if(way.safety=="danger"){
  146. actor2.getProperty().setColor(REA);
  147. }
  148. this.wayActors.push(actor2);
  149. mapper.setInputConnection(lineSource.getOutputPort());
  150. this.wayActors.push(actor);
  151. }
  152. });
  153. this.wayActors.forEach((wayAcotor) => {
  154. this.renderer.addActor(wayAcotor);
  155. });
  156. // vtkmodel.renderer.resetCamera();
  157. vtkmodel.renderWindow.render();
  158. }
  159. initMode(rootContainer) {
  160. this.renderWindowWith = vtkGenericRenderWindow.newInstance();
  161. this.renderWindowWith.setContainer(rootContainer);
  162. this.renderer = this.renderWindowWith.getRenderer();
  163. this.renderer.setBackground(0.0, 0.0, 0.0, 0.0)
  164. this.renderWindow = this.renderWindowWith.getRenderWindow();
  165. //选取
  166. this.lastActor = null;
  167. this.nodeActors = []; //节点actor 数据
  168. this.pipeActors = []; //管道actor 数据
  169. this.interactor = this.renderer.getRenderWindow().getInteractor();
  170. this.apiSpecificRenderWindow = this.interactor.getView();
  171. this.hardwareSelector = this.apiSpecificRenderWindow.getSelector();
  172. this.hardwareSelector.setCaptureZValues(true);
  173. // this.hardwareSelector.setFieldAssociation(FieldAssociations.FIELD_ASSOCIATION_POINTS);
  174. this.hardwareSelector.setFieldAssociation(FieldAssociations.FIELD_ASSOCIATION_CELLS);
  175. // document.addEventListener("mousemove", throttleMouseHandler);
  176. document.addEventListener('contextmenu', throttleMouseHandler,function(e){
  177. e.preventDefault();
  178. // throttleMouseHandler
  179. })
  180. // //箭头
  181. // this.arrowActors = [];
  182. // const viewColors = [
  183. // [1, 0, 0], // sagittal
  184. // [0, 1, 0], // coronal
  185. // [0, 0, 1], // axial
  186. // [0.5, 0.5, 0.5], // 3D
  187. // ];
  188. // // create axes
  189. // const axes = vtkAnnotatedCubeActor.newInstance();
  190. // axes.setDefaultStyle({
  191. // text: '+X',
  192. // fontStyle: 'bold',
  193. // fontFamily: 'Arial',
  194. // fontColor: 'black',
  195. // fontSizeScale: (res) => res / 2,
  196. // faceColor: createRGBStringFromRGBValues(viewColors[0]),
  197. // faceRotation: 0,
  198. // edgeThickness: 0.1,
  199. // edgeColor: 'black',
  200. // resolution: 400,
  201. // });
  202. // // axes.setXPlusFaceProperty({ text: '+X' });
  203. // axes.setXMinusFaceProperty({
  204. // text: '-X',
  205. // faceColor: createRGBStringFromRGBValues(viewColors[0]),
  206. // faceRotation: 90,
  207. // fontStyle: 'italic',
  208. // });
  209. // axes.setYPlusFaceProperty({
  210. // text: '+Y',
  211. // faceColor: createRGBStringFromRGBValues(viewColors[1]),
  212. // fontSizeScale: (res) => res / 4,
  213. // });
  214. // axes.setYMinusFaceProperty({
  215. // text: '-Y',
  216. // faceColor: createRGBStringFromRGBValues(viewColors[1]),
  217. // fontColor: 'white',
  218. // });
  219. // axes.setZPlusFaceProperty({
  220. // text: '+Z',
  221. // faceColor: createRGBStringFromRGBValues(viewColors[2]),
  222. // });
  223. // axes.setZMinusFaceProperty({
  224. // text: '-Z',
  225. // faceColor: createRGBStringFromRGBValues(viewColors[2]),
  226. // faceRotation: 45,
  227. // });
  228. // // const vtkAxesActor = vtkAxesActor.newInstance();
  229. // // create orientation widget
  230. // this.orientationWidget = vtkOrientationMarkerWidget.newInstance({
  231. // actor: axes,
  232. // interactor: this.renderWindow.getInteractor(),
  233. // });
  234. // this.orientationWidget.setEnabled(true);
  235. // this.orientationWidget.setViewportCorner(
  236. // vtkOrientationMarkerWidget.Corners.BOTTOM_LEFT
  237. // );
  238. // this.orientationWidget.setViewportSize(0.15);
  239. // this.orientationWidget.setMinPixelSize(100);
  240. // this.orientationWidget.setMaxPixelSize(300);
  241. }
  242. generateTicks(numberOfTicks) {
  243. return (helper) => {
  244. const lastTickBounds = helper.getLastTickBounds();
  245. // compute tick marks for axes
  246. const scale = d3
  247. .scaleLinear()
  248. .domain([0.0, 1.0])
  249. .range([lastTickBounds[0], lastTickBounds[1]]);
  250. const samples = scale.ticks(numberOfTicks);
  251. const ticks = samples.map((tick) => scale(tick));
  252. // Replace minus "\u2212" with hyphen-minus "\u002D" so that parseFloat() works
  253. formatDefaultLocale({ minus: "\u002D" });
  254. const format = scale.tickFormat(ticks[0], ticks[ticks.length - 1], numberOfTicks);
  255. const tickStrings = ticks
  256. .map(format)
  257. .map((tick) => Number(parseFloat(tick).toPrecision(12)).toPrecision()); // d3 sometimes adds unwanted whitespace
  258. helper.setTicks(ticks);
  259. helper.setTickStrings(tickStrings);
  260. };
  261. }
  262. //添加箭头
  263. addArrow(velocitys) {
  264. this.clearArrow();
  265. this.arrowActors = [];
  266. velocitys.forEach(velocity => {
  267. velocity.points.forEach(point => {
  268. // const initialValues = {
  269. // base:0,
  270. // shape: 'arrow4points',
  271. // center: [point.x,point.y,point.z],
  272. // width: 3,height:10,direction:[
  273. // velocity.vector[2],
  274. // velocity.vector[0],
  275. // velocity.vector[1]
  276. // ] };
  277. // const vtk2d = vtk2DShape.newInstance(initialValues);
  278. const initialValues = {
  279. base: 0,
  280. center: [point.x, point.y, point.z],
  281. height: 7,
  282. radius: 8,
  283. resolution: 3,
  284. direction: [
  285. velocity.vector[0],
  286. velocity.vector[1],
  287. velocity.vector[2]
  288. ]
  289. };
  290. const vtk2d = vtkConeSource.newInstance(initialValues);
  291. const mapper = vtkMapper.newInstance();
  292. mapper.setInputConnection(vtk2d.getOutputPort());
  293. const actor = vtkActor.newInstance();
  294. actor.setMapper(mapper);
  295. this.arrowActors.push(actor);
  296. // this.renderer.addActor(actor);
  297. })
  298. });
  299. // this.renderWindow.render();
  300. }
  301. clearArrow() {
  302. if (this.arrowActors) {
  303. this.arrowActors.forEach(actor => {
  304. this.renderer.removeActor(actor);
  305. });
  306. }
  307. }
  308. modelInit(validNodes, pipes) {
  309. this.renderWindowWith.resize();
  310. this.validNodes = validNodes;
  311. this.pipes = pipes;
  312. this.modelCreate();
  313. }
  314. modelCreate() {
  315. console.log("modelInit..");
  316. const points = this.polyData.getPoints();
  317. const lines = this.polyData.getLines();
  318. //无节点actor
  319. this.validNodes.forEach((node) => {
  320. points.insertNextPoint(parseFloat(node.x), parseFloat(node.y), parseFloat(node.z));
  321. });
  322. //无管道actor
  323. this.pipes.forEach((pipe) => {
  324. let sid = this.indexIdByPipeNodeId(pipe.snId);
  325. let eid = this.indexIdByPipeNodeId(pipe.enId);
  326. lines.insertNextCell([sid, eid]);
  327. });
  328. //有节点actors
  329. const sphereSource = vtkSphereSource.newInstance({
  330. center: [0, 0, 0],
  331. radius: 4.0,
  332. });
  333. const mapper = vtkMapper.newInstance();
  334. mapper.setInputConnection(sphereSource.getOutputPort());
  335. this.validNodes.forEach((node) => {
  336. const actor = vtkActor.newInstance();
  337. actor.setMapper(mapper);
  338. actor.setPosition(parseFloat(node.x), parseFloat(node.y), parseFloat(node.z));
  339. actor.getProperty().setColor(WHITE);
  340. const nodeActor = {};
  341. nodeActor.node = node;
  342. nodeActor.actor = actor;
  343. this.nodeActors.push(nodeActor);
  344. });
  345. //有管道actors
  346. this.pipes.forEach((pipe) => {
  347. const lineSource = vtkLineSource.newInstance();
  348. let point1 = this.pointByPipeNodeId(pipe.snId);
  349. let point2 = this.pointByPipeNodeId(pipe.enId);
  350. lineSource.setPoint1(point1);
  351. lineSource.setPoint2(point2);
  352. lineSource.setResolution(12);
  353. const actor = vtkActor.newInstance();
  354. const mapper = vtkMapper.newInstance();
  355. actor.setMapper(mapper);
  356. actor.getProperty().setLineWidth(3);//设置线宽
  357. actor.getProperty().setColor(WHITE);
  358. mapper.setInputConnection(lineSource.getOutputPort());
  359. const pipeActor = {};
  360. pipeActor.pipe = pipe;
  361. pipeActor.actor = actor;
  362. this.pipeActors.push(pipeActor);
  363. });
  364. this.modelShow();
  365. this.renderer.resetCamera();
  366. const cam = this.renderer.getActiveCamera();
  367. // const cam = vtkCamera.newInstance();
  368. // const cam =this.renderer.getActiveCamera();
  369. // this.renderer.setActiveCamera(cam);
  370. // cam.setFocalPoint(0, 0, 0);
  371. // cam.setPosition(0, 0, 10);
  372. // cam.setClippingRange(0.1, 2.0);
  373. // cam.setViewAngle(300);
  374. // console.log(
  375. // cam.getPosition(),//摄像头位置
  376. // cam.getViewAngle(),//相机视角 默认30
  377. // cam.getFocalPoint(),//相机焦点
  378. // cam.getViewUp(),//相机方向
  379. // );
  380. // position?: number[]; //摄像头位置
  381. // focalPoint?: number[]; //相机焦点
  382. // viewUp?: number[];//相机方向
  383. // directionOfProjection?: number[]; //相机到焦点的方向
  384. // parallelProjection?: boolean;//透视 平行
  385. // useHorizontalViewAngle?: boolean;//水平视角使用
  386. // viewAngle?: number;//相机视角
  387. // parallelScale?: number;//平行位置投影比例
  388. // clippingRange?: number[];//近远平面
  389. // windowCenter?: number[];//窗口中心位置 范围 ([-1,+1],[-1,+1])
  390. // viewPlaneNormal?: number[];//投影平面法线 (投影反方向)
  391. // useOffAxisProjection?: boolean;//离轴投影
  392. // screenBottomLeft?: number[];//左上角的点
  393. // screenBottomRight?: number[];//右上角的点
  394. // screenTopRight?: number[];//右上角的点 用于离轴投影
  395. // freezeFocalPoint?: boolean;
  396. // physicalTranslation?: number[];//物理翻译
  397. // physicalScale?: number;//物理尺度
  398. // physicalViewUp?: number[];//物理方向
  399. // physicalViewNorth?: number[];//物理北
  400. console.log("透视或平行相机", cam.getParallelProjection());
  401. // cam.setParallelProjection(true);
  402. // console.log("透视或平行相机",cam.getParallelProjection());
  403. console.log("水平视角使用", cam.getUseHorizontalViewAngle());
  404. // cam.setUseHorizontalViewAngle(true);
  405. console.log("平行位置投影比例", cam.getParallelScale());
  406. // cam.setParallelScale(600);
  407. console.log("窗口中心位置", cam.getWindowCenter());//[0, 0]
  408. // cam.setWindowCenter([1,-1]);
  409. console.log("相机视角", cam.getViewAngle());//30
  410. cam.setViewAngle(15);
  411. console.log("摄像头位置", cam.getPosition());//[495544.15625, 5403554.25, 9989.55990464236]
  412. cam.setPosition(495544.15625, 5403554.25, 9989.55990464236);
  413. console.log("相机焦点", cam.getFocalPoint());// [495544.15625, 5403554.25, 467.62999725341797]
  414. cam.setFocalPoint(495544.15625, 5403554.25, 467.62999725341797);
  415. console.log("相机方向", cam.getViewUp());//[0,1,0]
  416. // cam.setViewUp([0,1,1]);
  417. console.log("近远平面", cam.getClippingRange());// [9141.491986233214, 9913.53967078369]
  418. // cam.setClippingRange(9241.491986233214,9300.53967078369);
  419. this.renderWindow.render();
  420. }
  421. modelClearShow() {
  422. this.renderer.removeActor(this.actor);
  423. this.renderer.removeActor(this.actor2);
  424. this.nodeActors.forEach((nodeActor) => {
  425. this.renderer.removeActor(nodeActor.actor);
  426. });
  427. this.pipeActors.forEach((pipeActor) => {
  428. this.renderer.removeActor(pipeActor.actor);
  429. });
  430. }
  431. wayClearShow(){
  432. this.wayActors.forEach((wayAcotor) => {
  433. this.renderer.removeActor(wayAcotor);
  434. });
  435. }
  436. modelShow() {
  437. this.modelClearShow();
  438. if (!this.isSelectNode) {//不选择节点
  439. this.renderer.addActor(this.actor2);
  440. }
  441. if (!this.isSelectPipe) {//不选择管道
  442. this.renderer.addActor(this.actor);
  443. }
  444. if (this.isSelectNode) {//选择节点
  445. this.nodeActors.forEach((nodeActor) => {
  446. this.renderer.addActor(nodeActor.actor);
  447. });
  448. }
  449. if (this.isSelectPipe) {//选择管道
  450. this.pipeActors.forEach((pipeActor) => {
  451. this.renderer.addActor(pipeActor.actor);
  452. });
  453. }
  454. this.renderer.addActor(this.axesActor);
  455. }
  456. selectNodes() {
  457. this.isSelectNode = true;
  458. this.isSelectPipe = false;
  459. this.modelShow();
  460. document.addEventListener("mousemove", throttleMouseHandler);
  461. this.renderWindow.render();
  462. }
  463. selectPipes() {
  464. this.isSelectNode = false;
  465. this.isSelectPipe = true;
  466. document.addEventListener("mousemove", throttleMouseHandler);
  467. this.modelShow();
  468. this.renderWindow.render();
  469. }
  470. selectNoting() {
  471. this.isSelectNode = false;
  472. this.isSelectPipe = false;
  473. this.modelShow();
  474. this.renderWindow.render();
  475. }
  476. /**
  477. * 根据id 获取对应的编号
  478. */
  479. indexIdByPipeNodeId(nid) {
  480. for (let index = 0; index < this.validNodes.length; index++) {
  481. const node = this.validNodes[index];
  482. if (node.id == nid) {
  483. return index;
  484. }
  485. }
  486. return 0;
  487. }
  488. pointByPipeNodeId(nid) {
  489. for (let index = 0; index < this.validNodes.length; index++) {
  490. const node = this.validNodes[index];
  491. if (node.id == nid) {
  492. return [parseFloat(node.x), parseFloat(node.y), parseFloat(node.z)];
  493. }
  494. }
  495. return 0;
  496. }
  497. clearModeAddJg() {
  498. this.renderer.addActor(this.jgActor);
  499. this.renderer.addActor(this.scalarBarActor);
  500. this.wayClearShow();
  501. this.modelClearShow();
  502. this.isJg = true; //显示结果
  503. document.removeEventListener("mousemove", throttleMouseHandler);
  504. }
  505. clearJgAddMode() {
  506. this.renderer.removeActor(this.scalarBarActor);
  507. this.renderer.removeActor(this.jgActor);
  508. this.clearArrow();
  509. this.modelShow();
  510. this.wayClearShow();
  511. this.isJg = false; //不显示结果
  512. }
  513. clearAll() {
  514. this.renderer.removeActor(this.jgActor);
  515. this.renderer.removeActor(this.scalarBarActor);
  516. this.clearArrow();
  517. this.modelClearShow();
  518. this.wayClearShow();
  519. this.renderWindow.render();
  520. }
  521. //选中指定点
  522. selectByNodeId(nid) {
  523. console.log("selectByNodeId", nid);
  524. if (this.isSelectNode) {
  525. if (this.lastActor != null) {
  526. this.lastActor.getProperty().setColor(WHITE);
  527. }
  528. this.nodeActors.forEach(nodeActor => {
  529. if (nid == nodeActor.node.id) {
  530. nodeActor.actor.getProperty().setColor(GREEN);
  531. this.renderWindow.render();
  532. this.lastActor = nodeActor.actor;
  533. this.selectObj = nodeActor.node;
  534. return;
  535. }
  536. });
  537. }
  538. }
  539. //选中指定管道
  540. selectByPipeId(pid) {
  541. console.log("selectByPipeId", pid);
  542. if (this.isSelectPipe) {
  543. if (this.lastActor != null) {
  544. this.lastActor.getProperty().setColor(WHITE);
  545. }
  546. this.pipeActors.forEach(pipeActor => {
  547. if (pid == pipeActor.pipe.id) {
  548. pipeActor.actor.getProperty().setColor(GREEN);
  549. this.renderWindow.render();
  550. this.lastActor = pipeActor.actor;
  551. this.selectObj = pipeActor.node;
  552. return;
  553. }
  554. });
  555. }
  556. }
  557. }
  558. function createRGBStringFromRGBValues(rgb) {
  559. if (rgb.length !== 3) {
  560. return 'rgb(0, 0, 0)';
  561. }
  562. return `rgb(${(rgb[0] * 255).toString()}, ${(rgb[1] * 255).toString()}, ${(
  563. rgb[2] * 255
  564. ).toString()})`;
  565. }
  566. function pickOnMouseEvent(event) {
  567. if (vtkmodel.interactor.isAnimating()) {
  568. // We should not do picking when interacting with the scene
  569. return;
  570. }
  571. const [x, y] = eventToWindowXY(event);
  572. // console.log([x,y]);
  573. // if(!vtkmodel.getPointData){//没有数据
  574. // return ;
  575. // }
  576. // console.log(vtkmodel.hardwareSelector.getPointData());
  577. // if(!vtkmodel.renderer.getActors().size==0){
  578. // return;
  579. // }
  580. vtkmodel.hardwareSelector
  581. .getSourceDataAsync(vtkmodel.renderer, x, y, x, y)
  582. .then((result) => {
  583. if (result) {
  584. processSelections(result.generateSelection(x, y, x, y));
  585. // processSelections(result.generateSelection(x, y, x, y));
  586. } else {
  587. // processSelections(null);
  588. }
  589. });
  590. }
  591. function eventToWindowXY(event) {
  592. // We know we are full screen => window.innerXXX
  593. // Otherwise we can use pixel device ratio or else...
  594. var left = event.pageX ;
  595. var top = event.pageY ;
  596. vtkmodel.epageX=left;
  597. vtkmodel.epageY=top;
  598. const { clientX, clientY } = event;
  599. const [width, height] = vtkmodel.apiSpecificRenderWindow.getSize();
  600. const x = Math.round((width * clientX) / window.innerWidth);
  601. const y = Math.round(height * (1 - clientY / window.innerHeight)); // Need to flip Y
  602. // console.log(x,y)
  603. return [x, y];
  604. }
  605. function processSelections(selections) {
  606. if (!selections || selections.length === 0) {//没有选择
  607. if (vtkmodel.lastActor == null) {
  608. } else {
  609. // vtkmodel.lastActor.getProperty().setColor(WHITE);
  610. // vtkmodel.renderWindow.render();
  611. }
  612. // vtkmodel.lastActor = null;
  613. return;
  614. }
  615. const {
  616. worldPosition: rayHitWorldPosition,
  617. compositeID,
  618. prop,
  619. propID,
  620. attributeID,
  621. } = selections[0].getProperties();
  622. if (vtkmodel.lastActor != null) {
  623. vtkmodel.lastActor.getProperty().setColor(WHITE);
  624. vtkmodel.renderWindow.render();
  625. }
  626. vtkmodel.nodeActors.forEach((nodeActor) => {
  627. if (prop == nodeActor.actor) {
  628. vtkmodel.selectObj = nodeActor.node;
  629. prop.getProperty().setColor(GREEN);
  630. vtkmodel.lastActor = prop;
  631. // console.log(vtkmodel.selectObj );
  632. }
  633. });
  634. vtkmodel.pipeActors.forEach((pipeActor) => {
  635. if (prop == pipeActor.actor) {
  636. vtkmodel.selectObj = pipeActor.pipe;
  637. prop.getProperty().setColor(GREEN);
  638. vtkmodel.lastActor = prop;
  639. // console.log(vtkmodel.selectObj );
  640. }
  641. });
  642. if (vtkmodel.isJg) {//结果数据选择cell
  643. if (vtkmodel.hardwareSelector.getFieldAssociation() ===
  644. FieldAssociations.FIELD_ASSOCIATION_POINTS) {//选择点
  645. } else {
  646. //选择Cell
  647. const input = prop.getMapper().getInputData();
  648. if (!input.getCells()) {
  649. input.buildCells();
  650. // return;
  651. }
  652. const cellPoints = input.getCellPoints(attributeID);
  653. if (cellPoints) {
  654. const pointIds = cellPoints.cellPointIds;
  655. // Find the closest cell point, and use that as cursor position
  656. const points = Array.from(pointIds).map((pointId) =>
  657. input.getPoints().getPoint(pointId)
  658. );
  659. const scalarDataArray = input.getPointData().getScalars().getData();
  660. console.log(scalarDataArray[pointIds[0]]);//节点标量数据
  661. // pointIds.forEach(pointId=>{
  662. // console.log(input.getPointData().getScalars().getName());
  663. // console.log(scalarDataArray[pointId]);//节点标量数据
  664. // });
  665. vtkmodel.selectJgPointId = pointIds[0];
  666. }
  667. }
  668. } else {
  669. vtkmodel.renderWindow.render();
  670. }
  671. }
  672. const throttleMouseHandler = throttle(pickOnMouseEvent, 20);
  673. const WHITE = [1, 0.2, 1];
  674. const GREEN = [0.1, 0.8, 0.1];
  675. const REA = [1, 0, 0];
  676. const vtkmodel = new VtkModel();
  677. export { vtkmodel };