1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom 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  TrenchBroom 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 TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "MoveBrushVerticesCommand.h"
21 
22 #include "Model/Brush.h"
23 #include "Model/Snapshot.h"
24 #include "View/MapDocument.h"
25 #include "View/MapDocumentCommandFacade.h"
26 #include "View/VertexHandleManager.h"
27 
28 namespace TrenchBroom {
29     namespace View {
30         const Command::CommandType MoveBrushVerticesCommand::Type = Command::freeType();
31 
move(const Model::VertexToBrushesMap & vertices,const Vec3 & delta)32         MoveBrushVerticesCommand::Ptr MoveBrushVerticesCommand::move(const Model::VertexToBrushesMap& vertices, const Vec3& delta) {
33             Model::BrushList brushes;
34             Model::BrushVerticesMap brushVertices;
35             Vec3::List vertexPositions;
36             extractVertexMap(vertices, brushes, brushVertices, vertexPositions);
37 
38             return Ptr(new MoveBrushVerticesCommand(brushes, brushVertices, vertexPositions, delta));
39         }
40 
hasRemainingVertices() const41         bool MoveBrushVerticesCommand::hasRemainingVertices() const {
42             return !m_newVertexPositions.empty();
43         }
44 
MoveBrushVerticesCommand(const Model::BrushList & brushes,const Model::BrushVerticesMap & vertices,const Vec3::List & vertexPositions,const Vec3 & delta)45         MoveBrushVerticesCommand::MoveBrushVerticesCommand(const Model::BrushList& brushes, const Model::BrushVerticesMap& vertices, const Vec3::List& vertexPositions, const Vec3& delta) :
46         VertexCommand(Type, "Move Brush Vertices", brushes),
47         m_vertices(vertices),
48         m_oldVertexPositions(vertexPositions),
49         m_delta(delta) {
50             assert(!m_delta.null());
51         }
52 
doCanDoVertexOperation(const MapDocument * document) const53         bool MoveBrushVerticesCommand::doCanDoVertexOperation(const MapDocument* document) const {
54             const BBox3& worldBounds = document->worldBounds();
55             Model::BrushVerticesMap::const_iterator it, end;
56             for (it = m_vertices.begin(), end = m_vertices.end(); it != end; ++it) {
57                 Model::Brush* brush = it->first;
58                 const Vec3::List& vertices = it->second;
59                 if (!brush->canMoveVertices(worldBounds, vertices, m_delta))
60                     return false;
61             }
62             return true;
63         }
64 
doVertexOperation(MapDocumentCommandFacade * document)65         bool MoveBrushVerticesCommand::doVertexOperation(MapDocumentCommandFacade* document) {
66             m_newVertexPositions = document->performMoveVertices(m_vertices, m_delta);
67             return true;
68         }
69 
doSelectNewHandlePositions(VertexHandleManager & manager,const Model::BrushList & brushes)70         void MoveBrushVerticesCommand::doSelectNewHandlePositions(VertexHandleManager& manager, const Model::BrushList& brushes) {
71             manager.selectVertexHandles(m_newVertexPositions);
72         }
73 
doSelectOldHandlePositions(VertexHandleManager & manager,const Model::BrushList & brushes)74         void MoveBrushVerticesCommand::doSelectOldHandlePositions(VertexHandleManager& manager, const Model::BrushList& brushes) {
75             manager.selectVertexHandles(m_oldVertexPositions);
76         }
77 
doCollateWith(UndoableCommand::Ptr command)78         bool MoveBrushVerticesCommand::doCollateWith(UndoableCommand::Ptr command) {
79             MoveBrushVerticesCommand* other = static_cast<MoveBrushVerticesCommand*>(command.get());
80 
81             if (!VectorUtils::equals(m_newVertexPositions, other->m_oldVertexPositions))
82                 return false;
83 
84             m_newVertexPositions = other->m_newVertexPositions;
85             m_delta += other->m_delta;
86 
87             return true;
88         }
89     }
90 }
91