ClippingTool.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import * as THREE from "../../libs/three.js/build/three.module.js";
  2. import {ClipVolume} from "./ClipVolume.js";
  3. import {PolygonClipVolume} from "./PolygonClipVolume.js";
  4. import { EventDispatcher } from "../EventDispatcher.js";
  5. export class ClippingTool extends EventDispatcher{
  6. constructor(viewer){
  7. super();
  8. this.viewer = viewer;
  9. this.maxPolygonVertices = 8;
  10. this.addEventListener("start_inserting_clipping_volume", e => {
  11. this.viewer.dispatchEvent({
  12. type: "cancel_insertions"
  13. });
  14. });
  15. this.sceneMarker = new THREE.Scene();
  16. this.sceneVolume = new THREE.Scene();
  17. this.sceneVolume.name = "scene_clip_volume";
  18. this.viewer.inputHandler.registerInteractiveScene(this.sceneVolume);
  19. this.onRemove = e => {
  20. this.sceneVolume.remove(e.volume);
  21. };
  22. this.onAdd = e => {
  23. this.sceneVolume.add(e.volume);
  24. };
  25. this.viewer.inputHandler.addEventListener("delete", e => {
  26. let volumes = e.selection.filter(e => (e instanceof ClipVolume));
  27. volumes.forEach(e => this.viewer.scene.removeClipVolume(e));
  28. let polyVolumes = e.selection.filter(e => (e instanceof PolygonClipVolume));
  29. polyVolumes.forEach(e => this.viewer.scene.removePolygonClipVolume(e));
  30. });
  31. //----
  32. /* var a = new ClipVolume()
  33. viewer.scene.addVolume(a);
  34. viewer.setObjectLayers(a, 'volume' ) */
  35. }
  36. setScene(scene){
  37. if(this.scene === scene){
  38. return;
  39. }
  40. if(this.scene){
  41. this.scene.removeEventListeners("clip_volume_added", this.onAdd);
  42. this.scene.removeEventListeners("clip_volume_removed", this.onRemove);
  43. this.scene.removeEventListeners("polygon_clip_volume_added", this.onAdd);
  44. this.scene.removeEventListeners("polygon_clip_volume_removed", this.onRemove);
  45. }
  46. this.scene = scene;
  47. this.scene.addEventListener("clip_volume_added", this.onAdd);
  48. this.scene.addEventListener("clip_volume_removed", this.onRemove);
  49. this.scene.addEventListener("polygon_clip_volume_added", this.onAdd);
  50. this.scene.addEventListener("polygon_clip_volume_removed", this.onRemove);
  51. }
  52. startInsertion(args = {}) {
  53. let type = args.type || null;
  54. if(!type) return null;
  55. let domElement = this.viewer.renderer.domElement;
  56. let canvasSize = this.viewer.renderer.getSize(new THREE.Vector2());
  57. let svg = $(`
  58. <svg height="${canvasSize.height}" width="${canvasSize.width}" style="position:absolute; pointer-events: none">
  59. <defs>
  60. <marker id="diamond" markerWidth="24" markerHeight="24" refX="12" refY="12"
  61. markerUnits="userSpaceOnUse">
  62. <circle cx="12" cy="12" r="6" fill="white" stroke="black" stroke-width="3"/>
  63. </marker>
  64. </defs>
  65. <polyline fill="none" stroke="black"
  66. style="stroke:rgb(0, 0, 0);
  67. stroke-width:6;"
  68. stroke-dasharray="9, 6"
  69. stroke-dashoffset="2"
  70. />
  71. <polyline fill="none" stroke="black"
  72. style="stroke:rgb(255, 255, 255);
  73. stroke-width:2;"
  74. stroke-dasharray="5, 10"
  75. marker-start="url(#diamond)"
  76. marker-mid="url(#diamond)"
  77. marker-end="url(#diamond)"
  78. />
  79. </svg>`);
  80. $(domElement.parentElement).append(svg);
  81. let polyClipVol = new PolygonClipVolume(this.viewer.scene.getActiveCamera().clone());
  82. this.dispatchEvent({"type": "start_inserting_clipping_volume"});
  83. this.viewer.scene.addPolygonClipVolume(polyClipVol);
  84. this.sceneMarker.add(polyClipVol);
  85. let cancel = {
  86. callback: null
  87. };
  88. let insertionCallback = (e) => {
  89. if(e.button === THREE.MOUSE.LEFT){
  90. polyClipVol.addMarker();
  91. // SVC Screen Line
  92. svg.find("polyline").each((index, target) => {
  93. let newPoint = svg[0].createSVGPoint();
  94. newPoint.x = e.offsetX;
  95. newPoint.y = e.offsetY;
  96. let polyline = target.points.appendItem(newPoint);
  97. });
  98. if(polyClipVol.markers.length > this.maxPolygonVertices){
  99. cancel.callback();
  100. }
  101. this.viewer.inputHandler.startDragging(
  102. polyClipVol.markers[polyClipVol.markers.length - 1]);
  103. }else if(e.button === THREE.MOUSE.RIGHT){
  104. cancel.callback(e);
  105. }
  106. };
  107. cancel.callback = e => {
  108. //let first = svg.find("polyline")[0].points[0];
  109. //svg.find("polyline").each((index, target) => {
  110. // let newPoint = svg[0].createSVGPoint();
  111. // newPoint.x = first.x;
  112. // newPoint.y = first.y;
  113. // let polyline = target.points.appendItem(newPoint);
  114. //});
  115. svg.remove();
  116. if(polyClipVol.markers.length > 3) {
  117. polyClipVol.removeLastMarker();
  118. polyClipVol.initialized = true;
  119. } else {
  120. this.viewer.scene.removePolygonClipVolume(polyClipVol);
  121. }
  122. this.viewer.renderer.domElement.removeEventListener("mouseup", insertionCallback, true);
  123. this.viewer.removeEventListener("cancel_insertions", cancel.callback);
  124. this.viewer.inputHandler.enabled = true;
  125. };
  126. this.viewer.addEventListener("cancel_insertions", cancel.callback);
  127. this.viewer.renderer.domElement.addEventListener("mouseup", insertionCallback , true);
  128. this.viewer.inputHandler.enabled = false;
  129. polyClipVol.addMarker();
  130. this.viewer.inputHandler.startDragging(
  131. polyClipVol.markers[polyClipVol.markers.length - 1]);
  132. return polyClipVol;
  133. }
  134. update() {
  135. }
  136. };