/** * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved. * * This file is part of the QCAD project. * * QCAD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * QCAD is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with QCAD. */ include("../ModifyCorner.js"); include("scripts/ShapeAlgorithms.js"); /** * \class Round * \brief Adds a rounding to two entities and optionally trims both entities. * \ingroup ecma_modify */ function Round(guiAction) { ModifyCorner.call(this, guiAction); this.radius = 1.0; this.inverted = false; this.setUiOptions("Round.ui"); } Round.prototype = new ModifyCorner(); Round.includeBasePath = includeBasePath; Round.prototype.getOperation = function(preview) { if (!isEntity(this.entity1) || !isEntity(this.entity2)) { return undefined; } var op = new RAddObjectsOperation(); op.setText(this.getToolTitle()); var success = Round.round( op, this.entity1.clone(), this.clickPos1, this.entity2.clone(), this.clickPos2, this.trim, this.radius, this.posSolution, this.inverted, preview); if (!success && !preview) { EAction.handleUserWarning(qsTr("The two entities cannot be rounded.")); } return op; }; /** * Rounds or extends the given entity2 to the intersection point of the * entity2 and the limitingShape. * * \param op Operation to use to add new objects and modify objects. * \param entity1 First entity which will be rounded. * \param clickPos1 Coordinate that was clicked when the user selected entity1. * \param entity2 Second entity which will be rounded. * \param clickPos2 Coordinate that was clicked when the user selected entity2. * \param trim true: Trim both entities to rounding arc. * \param radius Radius of rounding. * \param solutionPos Position that determines which solution to apply (optional, defaults to clickPos1) * \param inverted Invert arc (inside rouding) * \param preview Operation is used for preview. */ Round.round = function(op, entity1, clickPos1, entity2, clickPos2, trim, radius, solutionPos, inverted, preview) { if (isNull(inverted)) { inverted = false; } if (!isEntity(entity1) || !isValidVector(clickPos1) || !isEntity(entity2) || !isValidVector(clickPos2) || !isBoolean(trim)) { return false; } var samePolyline = (entity1.getId()===entity2.getId() && isPolylineEntity(entity1)); var shape1P = entity1.getClosestShape(clickPos1); var shape2P = entity2.getClosestShape(clickPos2); var shape1 = getPtr(shape1P); var shape2 = getPtr(shape2P); var newShapes = Round.roundShapes(shape1, clickPos1, shape2, clickPos2, trim, samePolyline, radius, solutionPos); if (newShapes.length===0) { return false; } // add new trimmed entities or polyline: if (trim && !modifyEntity(op, entity1, getPtr(newShapes[0]))) { if (!preview) { EAction.handleUserWarning(qsTr("First entity cannot be trimmed.")); } } if (newShapes.length<3) { // rounding was within same polyline: return true; } if (trim && !modifyEntity(op, entity2, getPtr(newShapes[2]))) { if (!preview) { EAction.handleUserWarning(qsTr("Second entity cannot be trimmed.")); } } // add rounding: var d = getPtr(newShapes[1]); if (inverted) { d.mirror(new RLine(d.getStartPoint(), d.getEndPoint())); } op.addObject(new RArcEntity(entity1.getDocument(), new RArcData(d))); return true; }; /** * Rounds the given shape1 against shape2. * * \param shape1 First shape which will be rounded. * \param clickPos1 Coordinate that was clicked when the user selected shape1. * \param shape2 Second shape which will be rounded. * \param clickPos2 Coordinate that was clicked when the user selected shape2. * \param trim true: Trim both shape to rounding arc. * \param radius Radius of rounding. * \param solutionPos Position that determines which solution to apply (optional, defaults to clickPos1) * * \return Array of three shapes: shape1 (trimmed), rounding, shape2 (trimmed) * or empty array. */ Round.roundShapes = function(shape1, clickPos1, shape2, clickPos2, trim, samePolyline, radius, solutionPos) { if (isNull(solutionPos)) { solutionPos = clickPos2; } return RShape.roundShapes(shape1, clickPos1, shape2, clickPos2, trim, samePolyline, radius, solutionPos); }; Round.prototype.getAuxPreview = function() { var ret = []; if (!isNull(this.par1)) { ret.push(this.par1); } if (!isNull(this.par2)) { ret.push(this.par2); } return ret; } Round.prototype.slotRadiusChanged = function(value) { this.radius = value; }; Round.prototype.slotInvertedChanged = function(value) { this.inverted = value; };