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 
21 #include "MoveBrushFacesCommand.h"
22 
23 #include "Model/Brush.h"
24 #include "Model/Snapshot.h"
25 #include "View/MapDocument.h"
26 #include "View/MapDocumentCommandFacade.h"
27 #include "View/VertexHandleManager.h"
28 
29 namespace TrenchBroom {
30     namespace View {
31         const Command::CommandType MoveBrushFacesCommand::Type = Command::freeType();
32 
move(const Model::VertexToFacesMap & faces,const Vec3 & delta)33         MoveBrushFacesCommand::Ptr MoveBrushFacesCommand::move(const Model::VertexToFacesMap& faces, const Vec3& delta) {
34             Model::BrushList brushes;
35             Model::BrushFacesMap brushFaces;
36             Polygon3::List facePositions;
37             extractFaceMap(faces, brushes, brushFaces, facePositions);
38 
39             return Ptr(new MoveBrushFacesCommand(brushes, brushFaces, facePositions, delta));
40         }
41 
MoveBrushFacesCommand(const Model::BrushList & brushes,const Model::BrushFacesMap & faces,const Polygon3::List & facePositions,const Vec3 & delta)42         MoveBrushFacesCommand::MoveBrushFacesCommand(const Model::BrushList& brushes, const Model::BrushFacesMap& faces, const Polygon3::List& facePositions, const Vec3& delta) :
43         VertexCommand(Type, "Move Brush Faces", brushes),
44         m_faces(faces),
45         m_oldFacePositions(facePositions),
46         m_delta(delta) {
47             assert(!m_delta.null());
48         }
49 
doCanDoVertexOperation(const MapDocument * document) const50         bool MoveBrushFacesCommand::doCanDoVertexOperation(const MapDocument* document) const {
51             const BBox3& worldBounds = document->worldBounds();
52             Model::BrushFacesMap::const_iterator it, end;
53             for (it = m_faces.begin(), end = m_faces.end(); it != end; ++it) {
54                 Model::Brush* brush = it->first;
55                 const Polygon3::List& faces = it->second;
56                 if (!brush->canMoveFaces(worldBounds, faces, m_delta))
57                     return false;
58             }
59             return true;
60         }
61 
doVertexOperation(MapDocumentCommandFacade * document)62         bool MoveBrushFacesCommand::doVertexOperation(MapDocumentCommandFacade* document) {
63             m_newFacePositions = document->performMoveFaces(m_faces, m_delta);
64             return true;
65         }
66 
doSelectNewHandlePositions(VertexHandleManager & manager,const Model::BrushList & brushes)67         void MoveBrushFacesCommand::doSelectNewHandlePositions(VertexHandleManager& manager, const Model::BrushList& brushes) {
68             manager.selectFaceHandles(m_newFacePositions);
69         }
70 
doSelectOldHandlePositions(VertexHandleManager & manager,const Model::BrushList & brushes)71         void MoveBrushFacesCommand::doSelectOldHandlePositions(VertexHandleManager& manager, const Model::BrushList& brushes) {
72             manager.selectFaceHandles(m_oldFacePositions);
73         }
74 
doCollateWith(UndoableCommand::Ptr command)75         bool MoveBrushFacesCommand::doCollateWith(UndoableCommand::Ptr command) {
76             MoveBrushFacesCommand* other = static_cast<MoveBrushFacesCommand*>(command.get());
77 
78             if (!VectorUtils::equals(m_newFacePositions, other->m_oldFacePositions))
79                 return false;
80 
81             m_newFacePositions = other->m_newFacePositions;
82             m_delta += other->m_delta;
83 
84             return true;
85         }
86     }
87 }
88