InfoDistanceEE.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /**
  2. * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
  3. *
  4. * This file is part of the QCAD project.
  5. *
  6. * QCAD is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * QCAD is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with QCAD.
  18. */
  19. include("scripts/Information/Information.js");
  20. /**
  21. * \class InfoDistanceEE
  22. * \ingroup ecma_information
  23. * \brief Measure distance from entity to entity.
  24. */
  25. function InfoDistanceEE(guiAction) {
  26. Information.call(this, guiAction);
  27. this.entity1 = undefined;
  28. this.shape1 = undefined;
  29. this.point1 = undefined;
  30. this.entity2 = undefined;
  31. this.shape2 = undefined;
  32. this.point2 = undefined;
  33. this.setUiOptions("../Information.ui");
  34. }
  35. InfoDistanceEE.prototype = new Information();
  36. InfoDistanceEE.State = {
  37. SettingShape1 : 0,
  38. SettingShape2 : 1
  39. };
  40. InfoDistanceEE.prototype.beginEvent = function() {
  41. Information.prototype.beginEvent.call(this);
  42. this.setState(InfoDistanceEE.State.SettingShape1);
  43. };
  44. InfoDistanceEE.prototype.setState = function(state) {
  45. Information.prototype.setState.call(this, state);
  46. var di = this.getDocumentInterface();
  47. var appWin = RMainWindowQt.getMainWindow();
  48. switch (this.state) {
  49. case InfoDistanceEE.State.SettingShape1:
  50. di.setClickMode(RAction.PickEntity);
  51. var trFirstEntity = qsTr("Specify first entity");
  52. this.setCommandPrompt(trFirstEntity);
  53. this.setLeftMouseTip(trFirstEntity);
  54. this.setRightMouseTip(EAction.trCancel);
  55. break;
  56. case InfoDistanceEE.State.SettingShape2:
  57. this.point2 = undefined;
  58. di.setClickMode(RAction.PickEntity);
  59. var trSecondEntity = qsTr("Specify second entity");
  60. this.setCommandPrompt(trSecondEntity);
  61. this.setLeftMouseTip(trSecondEntity);
  62. this.setRightMouseTip(EAction.trDone);
  63. break;
  64. }
  65. this.setCrosshairCursor();
  66. //EAction.showSnapTools();
  67. };
  68. InfoDistanceEE.prototype.pickEntity = function(event, preview) {
  69. var di = this.getDocumentInterface();
  70. var doc = this.getDocument();
  71. var entityId = this.getEntityId(event, preview);
  72. var entity = doc.queryEntity(entityId);
  73. var pos = event.getModelPosition();
  74. // keep showing preview after 2nd point has been set:
  75. if (!this.addToDrawing) {
  76. if (!isNull(this.point1) && !isNull(this.point2)) {
  77. var op = this.getOperation(preview);
  78. if (preview) {
  79. di.previewOperation(op);
  80. }
  81. else {
  82. destr(op);
  83. }
  84. }
  85. }
  86. if (isNull(entity)) {
  87. return;
  88. }
  89. var shape = entity.getClosestSimpleShape(pos);
  90. if (!this.isShapeSupported(shape)) {
  91. if (!preview) {
  92. this.warnUnsupportedShape();
  93. }
  94. return;
  95. }
  96. switch (this.state) {
  97. case InfoDistanceEE.State.SettingShape1:
  98. this.entity1 = entity;
  99. if (!preview) {
  100. this.shape1 = shape;
  101. this.setState(InfoDistanceEE.State.SettingShape2);
  102. }
  103. break;
  104. case InfoDistanceEE.State.SettingShape2:
  105. this.entity2 = entity;
  106. this.shape2 = shape;
  107. // points on shape2 which might be closest to shape1:
  108. var candidates1 = this.getCandidatePoints(this.shape1, this.shape2);
  109. var candidates2 = this.getCandidatePoints(this.shape2, this.shape1);
  110. this.point1 = undefined;
  111. this.point2 = undefined;
  112. var minDist = undefined;
  113. for (var i1=0; i1<candidates1.length; i1++) {
  114. var c1 = candidates1[i1];
  115. for (var i2=0; i2<candidates2.length; i2++) {
  116. var c2 = candidates2[i2];
  117. var dist = c1.getDistanceTo(c2);
  118. if (isNull(minDist) || dist<minDist) {
  119. minDist = dist;
  120. this.point1 = c1;
  121. this.point2 = c2;
  122. }
  123. }
  124. }
  125. if (!isNull(this.point1) && !isNull(this.point2)) {
  126. if (this.addToDrawing) {
  127. var op = this.getOperation(preview);
  128. if (preview) {
  129. di.previewOperation(op);
  130. }
  131. else {
  132. di.applyOperation(op);
  133. di.setRelativeZero(this.point2);
  134. }
  135. }
  136. }
  137. if (!preview) {
  138. var distance = this.point1.getDistanceTo(this.point2);
  139. EAction.getMainWindow().handleUserInfo(qsTr("Distance:") + " " + this.formatLinearResultCmd(distance));
  140. if (this.autoTerminate) {
  141. this.updateLineEdit(distance);
  142. this.setNoState(false);
  143. this.terminate();
  144. return;
  145. }
  146. else {
  147. this.setState(InfoDistanceEE.State.SettingShape1);
  148. }
  149. }
  150. break;
  151. }
  152. di.highlightEntity(entity.getId());
  153. };
  154. InfoDistanceEE.prototype.isShapeSupported = function(shape) {
  155. return isLineBasedShape(shape) ||
  156. isArcShape(shape) ||
  157. isCircleShape(shape);
  158. };
  159. InfoDistanceEE.prototype.warnUnsupportedShape = function() {
  160. EAction.warnNotLineArcCircle();
  161. };
  162. /**
  163. * \return Points on shape1 which might be closest to shape2.
  164. */
  165. InfoDistanceEE.prototype.getCandidatePoints = function(shape1, shape2) {
  166. var ret = [];
  167. // var s1 = this.shape1;
  168. // var s2 = this.shape2;
  169. // // make sure s1 is line and s2 arc for line <-> arc:
  170. // // make sure s1 is circle and s2 arc for circle <-> arc:
  171. // if (((isArcShape(s1) || isCircleShape(s1)) && isLineBasedShape(s2)) ||
  172. // (isArcShape(s1) && isCircleShape(s2))) {
  173. // var d = s1;
  174. // s1 = s2;
  175. // s2 = d;
  176. // }
  177. // add start and end point for lines, xlines and arcs:
  178. // line <-> line
  179. // line <-> arc
  180. if (isLineShape(shape1) || isXLineShape(shape1) || isArcShape(shape1)) {
  181. ret.push(shape1.getStartPoint());
  182. ret.push(shape1.getEndPoint());
  183. }
  184. // add start point for rays:
  185. // line <-> ray
  186. if (isRayShape(shape1)) {
  187. ret.push(shape1.getStartPoint());
  188. }
  189. var a, p;
  190. // arc <-> arc / line / circle
  191. // circle <-> arc / line / circle
  192. if (isArcShape(shape1) || isCircleShape(shape1)) {
  193. p = shape2.getClosestPointOnShape(shape1.getCenter());
  194. a = shape1.getCenter().getAngleTo(p);
  195. p = shape1.getPointAtAngle(a);
  196. if (shape1.isOnShape(p)) {
  197. ret.push(p);
  198. }
  199. }
  200. var s2Points = [];
  201. if (isFunction(shape2.getStartPoint)) {
  202. s2Points.push(shape2.getStartPoint());
  203. }
  204. if (isFunction(shape2.getEndPoint)) {
  205. s2Points.push(shape2.getEndPoint());
  206. }
  207. if (isFunction(shape2.getCenter)) {
  208. s2Points.push(shape2.getCenter());
  209. }
  210. for (var i=0; i<s2Points.length; i++) {
  211. var s2Point = s2Points[i];
  212. p = shape1.getClosestPointOnShape(s2Point);
  213. if (shape1.isOnShape(p)) {
  214. ret.push(p);
  215. }
  216. }
  217. // add intersection points:
  218. var ips = shape1.getIntersectionPoints(getPtr(shape2));
  219. ret = ret.concat(ips);
  220. // line <-> arc / circle
  221. // if (isLineBasedShape(shape1) && (isArcShape(shape2) || isCircleShape(shape2))) {
  222. // p = shape1.getClosestPointOnShape(shape2.getCenter());
  223. // if (shape1.isOnShape(p)) {
  224. // ret.push(p);
  225. // }
  226. // }
  227. return ret;
  228. };
  229. //InfoDistanceEE.prototype.pickCoordinate = function(event, preview) {
  230. // var di = this.getDocumentInterface();
  231. // if (isNull(this.shape)) {
  232. // return;
  233. // }
  234. // this.point2 = event.getModelPosition();
  235. // if (!isValidVector(this.point2)) {
  236. // return;
  237. // }
  238. // this.point1 = this.shape.getClosestPointOnShape(this.point2, false);
  239. // if (!isValidVector(this.point1)) {
  240. // return;
  241. // }
  242. // di.highlightEntity(this.entity.getId());
  243. // var op = this.getOperation(preview);
  244. // if (preview) {
  245. // di.previewOperation(op);
  246. // }
  247. // else {
  248. // if (this.addToDrawing) {
  249. // di.applyOperation(op);
  250. // di.setRelativeZero(this.point2);
  251. // }
  252. // else {
  253. // destr(op);
  254. // }
  255. // }
  256. // if (!preview) {
  257. // this.setState(InfoDistanceEE.State.SettingShape1);
  258. // var distance = this.point1.getDistanceTo(this.point2);
  259. // EAction.getMainWindow().handleUserInfo(qsTr("Distance:") + " " + this.formatLinearResultCmd(distance));
  260. // }
  261. //};
  262. InfoDistanceEE.prototype.getOperation = function(preview) {
  263. var op = new RAddObjectsOperation();
  264. op.setText(this.getToolTitle());
  265. this.addInfoLine(op, this.point1, this.point2, preview);
  266. // var candidates1 = this.getCandidatePoints(this.shape1, this.shape2);
  267. // for (var i=0; i<candidates1.length; i++) {
  268. // this.addInfoLine(op, candidates1[i], this.point2, preview);
  269. // }
  270. return op;
  271. };