/**************************************************************************** Copyright (C) 2010-2012 the Office National des ForĂȘts (ONF), France All rights reserved. Contact : alexandre.piboule@onf.fr Developers : Alexandre PIBOULE (ONF) This file is part of PluginONF library. PluginONF is free library: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PluginONF 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 Lesser General Public License along with PluginONF. If not, see . *****************************************************************************/ #include "onf_actionmodifypositions2d.h" #include "documentinterface.h" #include "painterinterface.h" #include "ct_global/ct_context.h" #include #include #include #include #include ONF_ActionModifyPositions2D::ONF_ActionModifyPositions2D(QList &positions) : CT_AbstractActionForGraphicsView() { _positions = &positions; _selectedColor = QColor(0, 255, 0); _normalColor = QColor(255, 0, 0); _selectedPoint = nullptr; _leftButton = false; _zmin = 0; _zmax = 10; } ONF_ActionModifyPositions2D::~ONF_ActionModifyPositions2D() { } QString ONF_ActionModifyPositions2D::uniqueName() const { return "ONF_ActionModifyPositions2D"; } QString ONF_ActionModifyPositions2D::title() const { return tr("Modifier positions 2D"); } QString ONF_ActionModifyPositions2D::description() const { return tr("Modifier positions 2D"); } QIcon ONF_ActionModifyPositions2D::icon() const { return QIcon(":/icons/select_rectangular.png"); } QString ONF_ActionModifyPositions2D::type() const { return CT_AbstractAction::TYPE_MODIFICATION; } void ONF_ActionModifyPositions2D::init() { CT_AbstractActionForGraphicsView::init(); if(nOptions() == 0) { // create the option widget if it was not already created ONF_ActionModifyPositions2DOptions *option = new ONF_ActionModifyPositions2DOptions(this); // add the options to the graphics view graphicsView()->addActionOptions(option); connect(option, SIGNAL(parametersChanged()), this, SLOT(zValChanged())); // register the option to the superclass, so the hideOptions and showOptions // is managed automatically registerOption(option); updatePlane(); setDrawing3DChanged(); document()->redrawGraphics(); dynamic_cast(document()->views().first())->camera()->fitCameraToVisibleItems(); } } void ONF_ActionModifyPositions2D::updatePlane() { _min(0) = std::numeric_limits::max(); _min(1) = std::numeric_limits::max(); _max(0) = -std::numeric_limits::max(); _max(1) = -std::numeric_limits::max(); for (int i = 0 ; i < _positions->size() ; i++) { CT_Point2D *point = _positions->at(i); if (point->x() < _min(0)) {_min(0) = point->x();} if (point->y() < _min(1)) {_min(1) = point->y();} if (point->x() > _max(0)) {_max(0) = point->x();} if (point->y() > _max(1)) {_max(1) = point->y();} } } void ONF_ActionModifyPositions2D::zValChanged() { if (_positions->size()>0) { ONF_ActionModifyPositions2DOptions *option = (ONF_ActionModifyPositions2DOptions*)optionAt(0); ((CT_StandardPoint2DDrawManager*) _positions->first()->baseDrawManager())->setZValue(option->getZValue()); } setDrawing3DChanged(); //document()->redrawGraphics(); } bool ONF_ActionModifyPositions2D::mousePressEvent(QMouseEvent *e) { ONF_ActionModifyPositions2DOptions *option = (ONF_ActionModifyPositions2DOptions*)optionAt(0); if (e->button() == Qt::LeftButton) { _leftButton = true; if (option->isMovePositionSelected() || option->isRemovePositionSelected() || option->isAddPositionSelected()) { _selectedPoint = nullptr; double x, y; if (getCoordsForMousePosition(e, x, y)) { if (option->isMovePositionSelected() || option->isRemovePositionSelected()) { _selectedPoint = getNearestPosition(x, y); } else if (option->isAddPositionSelected()) { _selectedPoint = new CT_Point2D(new CT_Point2DData(x, y)); _positions->append(_selectedPoint); } if (_selectedPoint != nullptr) { document()->setColor(_selectedPoint, _selectedColor); setDrawing3DChanged(); //document()->redrawGraphics(); return true; } } } } return false; } bool ONF_ActionModifyPositions2D::mouseMoveEvent(QMouseEvent *e) { ONF_ActionModifyPositions2DOptions *option = (ONF_ActionModifyPositions2DOptions*)optionAt(0); if (_leftButton && (option->isMovePositionSelected() || option->isAddPositionSelected())) { if (_selectedPoint != nullptr) { double x, y; if (getCoordsForMousePosition(e, x, y)) { _selectedPoint->setCenterX(x); _selectedPoint->setCenterY(y); setDrawing3DChanged(); //document()->redrawGraphics(); return true; } } } return false; } bool ONF_ActionModifyPositions2D::mouseReleaseEvent(QMouseEvent *e) { ONF_ActionModifyPositions2DOptions *option = (ONF_ActionModifyPositions2DOptions*)optionAt(0); if (_leftButton) { _leftButton = false; if (_selectedPoint != nullptr) { if (option->isMovePositionSelected() || option->isAddPositionSelected()) { double x, y; if (getCoordsForMousePosition(e, x, y)) { _selectedPoint->setCenterX(x); _selectedPoint->setCenterY(y); if (option->isMovePositionSelected()) {option->selectFreeMove();} document()->setColor(_selectedPoint, _normalColor); updatePlane(); setDrawing3DChanged(); //document()->redrawGraphics(); } return true; } else if (option->isRemovePositionSelected()) { document()->removeItemDrawable(*_selectedPoint); _positions->removeOne(_selectedPoint); delete _selectedPoint; _selectedPoint = nullptr; option->selectFreeMove(); setDrawing3DChanged(); //document()->redrawGraphics(); return true; } _selectedPoint = nullptr; } } return false; } bool ONF_ActionModifyPositions2D::wheelEvent(QWheelEvent *e) { ONF_ActionModifyPositions2DOptions *option = (ONF_ActionModifyPositions2DOptions*)optionAt(0); if (e->modifiers() & Qt::ControlModifier) { if (e->angleDelta().y()>0) { option->increaseZValue(); } else if (e->angleDelta().y() < 0) { option->decreaseZValue(); } return true; } return false; } bool ONF_ActionModifyPositions2D::keyPressEvent(QKeyEvent *e) { ONF_ActionModifyPositions2DOptions *option = (ONF_ActionModifyPositions2DOptions*)optionAt(0); if((e->key() == Qt::Key_D) && !e->isAutoRepeat()) { option->selectMovePosition(); return true; } if((e->key() == Qt::Key_A) && !e->isAutoRepeat()) { option->selectAddPosition(); return true; } if((e->key() == Qt::Key_S) && !e->isAutoRepeat()) { option->selectRemovePosition(); return true; } if((e->key() == Qt::Key_F) && !e->isAutoRepeat()) { option->selectFreeMove(); return true; } return false; } bool ONF_ActionModifyPositions2D::keyReleaseEvent(QKeyEvent *e) { Q_UNUSED(e); return false; } void ONF_ActionModifyPositions2D::draw(GraphicsViewInterface &view, PainterInterface &painter) { Q_UNUSED(view) ONF_ActionModifyPositions2DOptions *option = (ONF_ActionModifyPositions2DOptions*)optionAt(0); painter.save(); if (option->isDrawLinesSelected()) { const QList& itemList = document()->getItemDrawable(); if (option->isUpdateLinesSelected()) { _zmin = option->getZValue() - 1.0; _zmax = option->getZValue() + 1.0; for (int i = 0 ; i < itemList.size() ; i++) { Eigen::Vector3d min, max; itemList.at(i)->boundingBox(min, max); if (min(2) < std::numeric_limits::max() && min(2) > -std::numeric_limits::max() && max(2) < std::numeric_limits::max() && max(2) > -std::numeric_limits::max()) { if (min(2) < _zmin) {_zmin = min(2);} if (min(2) > _zmax) {_zmax = min(2);} if (max(2) < _zmin) {_zmin = max(2);} if (max(2) > _zmax) {_zmax = max(2);} } } } painter.setColor(QColor(255, 0, 0)); for (int i = 0 ; i < _positions->size() ; i++) { const CT_Point2D *point = _positions->at(i); painter.drawLine(point->centerX(), point->centerY(), _zmin, point->centerX(), point->centerY(), _zmax); } } painter.setColor(QColor(75, 75, 75, 125)); if (option->isDrawPlaneSelected()) {painter.fillRectXY(_min, _max, option->getZValue() - 0.10);} painter.restore(); } void ONF_ActionModifyPositions2D::drawOverlay(GraphicsViewInterface &view, QPainter &painter) { Q_UNUSED(view) Q_UNUSED(painter) } CT_AbstractAction* ONF_ActionModifyPositions2D::createInstance() const { return new ONF_ActionModifyPositions2D(*_positions); } bool ONF_ActionModifyPositions2D::getCoordsForMousePosition(const QMouseEvent *e, double &x, double &y) { ONF_ActionModifyPositions2DOptions *option = (ONF_ActionModifyPositions2DOptions*)optionAt(0); Eigen::Vector3d origin, direction; GraphicsViewInterface *view = graphicsView(); view->convertClickToLine(e->pos(), origin, direction); if (direction.z() == 0) {return false;} double coef = (option->getZValue() - origin.z())/direction.z(); x = origin.x() + coef*direction.x(); y = origin.y() + coef*direction.y(); return true; } CT_Point2D *ONF_ActionModifyPositions2D::getNearestPosition(double x, double y) { double minDist = std::numeric_limits::max(); CT_Point2D* nearestPoint = nullptr; for (int i = 0 ; i < _positions->size() ; i++) { CT_Point2D *point = _positions->at(i); double dist = pow(point->x() - x, 2) + pow(point->y() - y, 2); if (dist < minDist) { minDist = dist; nearestPoint = point; } } return nearestPoint; }