Round.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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("../ModifyCorner.js");
  20. include("scripts/ShapeAlgorithms.js");
  21. /**
  22. * \class Round
  23. * \brief Adds a rounding to two entities and optionally trims both entities.
  24. * \ingroup ecma_modify
  25. */
  26. function Round(guiAction) {
  27. ModifyCorner.call(this, guiAction);
  28. this.radius = 1.0;
  29. this.inverted = false;
  30. this.setUiOptions("Round.ui");
  31. }
  32. Round.prototype = new ModifyCorner();
  33. Round.includeBasePath = includeBasePath;
  34. Round.prototype.getOperation = function(preview) {
  35. if (!isEntity(this.entity1) || !isEntity(this.entity2)) {
  36. return undefined;
  37. }
  38. var op = new RAddObjectsOperation();
  39. op.setText(this.getToolTitle());
  40. var success = Round.round(
  41. op,
  42. this.entity1.clone(), this.clickPos1,
  43. this.entity2.clone(), this.clickPos2,
  44. this.trim,
  45. this.radius,
  46. this.posSolution,
  47. this.inverted,
  48. preview);
  49. if (!success && !preview) {
  50. EAction.handleUserWarning(qsTr("The two entities cannot be rounded."));
  51. }
  52. return op;
  53. };
  54. /**
  55. * Rounds or extends the given entity2 to the intersection point of the
  56. * entity2 and the limitingShape.
  57. *
  58. * \param op Operation to use to add new objects and modify objects.
  59. * \param entity1 First entity which will be rounded.
  60. * \param clickPos1 Coordinate that was clicked when the user selected entity1.
  61. * \param entity2 Second entity which will be rounded.
  62. * \param clickPos2 Coordinate that was clicked when the user selected entity2.
  63. * \param trim true: Trim both entities to rounding arc.
  64. * \param radius Radius of rounding.
  65. * \param solutionPos Position that determines which solution to apply (optional, defaults to clickPos1)
  66. * \param inverted Invert arc (inside rouding)
  67. * \param preview Operation is used for preview.
  68. */
  69. Round.round = function(op, entity1, clickPos1, entity2, clickPos2, trim, radius, solutionPos, inverted, preview) {
  70. if (isNull(inverted)) {
  71. inverted = false;
  72. }
  73. if (!isEntity(entity1) || !isValidVector(clickPos1) ||
  74. !isEntity(entity2) || !isValidVector(clickPos2) ||
  75. !isBoolean(trim)) {
  76. return false;
  77. }
  78. var samePolyline = (entity1.getId()===entity2.getId() && isPolylineEntity(entity1));
  79. var shape1P = entity1.getClosestShape(clickPos1);
  80. var shape2P = entity2.getClosestShape(clickPos2);
  81. var shape1 = getPtr(shape1P);
  82. var shape2 = getPtr(shape2P);
  83. var newShapes = Round.roundShapes(shape1, clickPos1, shape2, clickPos2, trim, samePolyline, radius, solutionPos);
  84. if (newShapes.length===0) {
  85. return false;
  86. }
  87. // add new trimmed entities or polyline:
  88. if (trim && !modifyEntity(op, entity1, getPtr(newShapes[0]))) {
  89. if (!preview) {
  90. EAction.handleUserWarning(qsTr("First entity cannot be trimmed."));
  91. }
  92. }
  93. if (newShapes.length<3) {
  94. // rounding was within same polyline:
  95. return true;
  96. }
  97. if (trim && !modifyEntity(op, entity2, getPtr(newShapes[2]))) {
  98. if (!preview) {
  99. EAction.handleUserWarning(qsTr("Second entity cannot be trimmed."));
  100. }
  101. }
  102. // add rounding:
  103. var d = getPtr(newShapes[1]);
  104. if (inverted) {
  105. d.mirror(new RLine(d.getStartPoint(), d.getEndPoint()));
  106. }
  107. op.addObject(new RArcEntity(entity1.getDocument(), new RArcData(d)));
  108. return true;
  109. };
  110. /**
  111. * Rounds the given shape1 against shape2.
  112. *
  113. * \param shape1 First shape which will be rounded.
  114. * \param clickPos1 Coordinate that was clicked when the user selected shape1.
  115. * \param shape2 Second shape which will be rounded.
  116. * \param clickPos2 Coordinate that was clicked when the user selected shape2.
  117. * \param trim true: Trim both shape to rounding arc.
  118. * \param radius Radius of rounding.
  119. * \param solutionPos Position that determines which solution to apply (optional, defaults to clickPos1)
  120. *
  121. * \return Array of three shapes: shape1 (trimmed), rounding, shape2 (trimmed)
  122. * or empty array.
  123. */
  124. Round.roundShapes = function(shape1, clickPos1, shape2, clickPos2, trim, samePolyline, radius, solutionPos) {
  125. if (isNull(solutionPos)) {
  126. solutionPos = clickPos2;
  127. }
  128. return RShape.roundShapes(shape1, clickPos1, shape2, clickPos2, trim, samePolyline, radius, solutionPos);
  129. };
  130. Round.prototype.getAuxPreview = function() {
  131. var ret = [];
  132. if (!isNull(this.par1)) {
  133. ret.push(this.par1);
  134. }
  135. if (!isNull(this.par2)) {
  136. ret.push(this.par2);
  137. }
  138. return ret;
  139. }
  140. Round.prototype.slotRadiusChanged = function(value) {
  141. this.radius = value;
  142. };
  143. Round.prototype.slotInvertedChanged = function(value) {
  144. this.inverted = value;
  145. };