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 "MoveBrushEdgesCommand.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 MoveBrushEdgesCommand::Type = Command::freeType();
31 
move(const Model::VertexToEdgesMap & edges,const Vec3 & delta)32         MoveBrushEdgesCommand::Ptr MoveBrushEdgesCommand::move(const Model::VertexToEdgesMap& edges, const Vec3& delta) {
33             Model::BrushList brushes;
34             Model::BrushEdgesMap brushEdges;
35             Edge3::List edgePositions;
36             extractEdgeMap(edges, brushes, brushEdges, edgePositions);
37 
38             return Ptr(new MoveBrushEdgesCommand(brushes, brushEdges, edgePositions, delta));
39         }
40 
MoveBrushEdgesCommand(const Model::BrushList & brushes,const Model::BrushEdgesMap & edges,const Edge3::List & edgePositions,const Vec3 & delta)41         MoveBrushEdgesCommand::MoveBrushEdgesCommand(const Model::BrushList& brushes, const Model::BrushEdgesMap& edges, const Edge3::List& edgePositions, const Vec3& delta) :
42         VertexCommand(Type, "Move Brush Edges", brushes),
43         m_edges(edges),
44         m_oldEdgePositions(edgePositions),
45         m_delta(delta) {
46             assert(!m_delta.null());
47         }
48 
doCanDoVertexOperation(const MapDocument * document) const49         bool MoveBrushEdgesCommand::doCanDoVertexOperation(const MapDocument* document) const {
50             const BBox3& worldBounds = document->worldBounds();
51             Model::BrushEdgesMap::const_iterator it, end;
52             for (it = m_edges.begin(), end = m_edges.end(); it != end; ++it) {
53                 Model::Brush* brush = it->first;
54                 const Edge3::List& edges = it->second;
55                 if (!brush->canMoveEdges(worldBounds, edges, m_delta))
56                     return false;
57             }
58             return true;
59         }
60 
doVertexOperation(MapDocumentCommandFacade * document)61         bool MoveBrushEdgesCommand::doVertexOperation(MapDocumentCommandFacade* document) {
62             m_newEdgePositions = document->performMoveEdges(m_edges, m_delta);
63             return true;
64         }
65 
doSelectNewHandlePositions(VertexHandleManager & manager,const Model::BrushList & brushes)66         void MoveBrushEdgesCommand::doSelectNewHandlePositions(VertexHandleManager& manager, const Model::BrushList& brushes) {
67             manager.selectEdgeHandles(m_newEdgePositions);
68         }
69 
doSelectOldHandlePositions(VertexHandleManager & manager,const Model::BrushList & brushes)70         void MoveBrushEdgesCommand::doSelectOldHandlePositions(VertexHandleManager& manager, const Model::BrushList& brushes) {
71             manager.selectEdgeHandles(m_oldEdgePositions);
72         }
73 
doCollateWith(UndoableCommand::Ptr command)74         bool MoveBrushEdgesCommand::doCollateWith(UndoableCommand::Ptr command) {
75             MoveBrushEdgesCommand* other = static_cast<MoveBrushEdgesCommand*>(command.get());
76 
77             if (!VectorUtils::equals(m_newEdgePositions, other->m_oldEdgePositions))
78                 return false;
79 
80             m_newEdgePositions = other->m_newEdgePositions;
81             m_delta += other->m_delta;
82 
83             return true;
84         }
85     }
86 }
87