vtkModel.js 26 KB

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