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 "VertexHandleManager.h"
21 
22 #include "AttrString.h"
23 #include "PreferenceManager.h"
24 #include "Preferences.h"
25 #include "Model/Brush.h"
26 #include "Model/BrushFace.h"
27 #include "Model/PickResult.h"
28 #include "Renderer/Camera.h"
29 #include "Renderer/RenderBatch.h"
30 #include "Renderer/RenderService.h"
31 #include "Renderer/RenderUtils.h"
32 #include "Renderer/Shaders.h"
33 #include "Renderer/VertexArray.h"
34 #include "Renderer/VertexSpec.h"
35 
36 #include <cassert>
37 
38 namespace TrenchBroom {
39     namespace View {
40         const Model::Hit::HitType VertexHandleManager::VertexHandleHit = Model::Hit::freeHitType();
41         const Model::Hit::HitType VertexHandleManager::EdgeHandleHit   = Model::Hit::freeHitType();
42         const Model::Hit::HitType VertexHandleManager::FaceHandleHit   = Model::Hit::freeHitType();
43 
VertexHandleManager(View::MapDocumentWPtr document)44         VertexHandleManager::VertexHandleManager(View::MapDocumentWPtr document) :
45         m_totalVertexCount(0),
46         m_selectedVertexCount(0),
47         m_totalEdgeCount(0),
48         m_selectedEdgeCount(0),
49         m_totalFaceCount(0),
50         m_selectedFaceCount(0),
51         m_guideRenderer(document),
52         m_renderStateValid(false) {}
53 
unselectedVertexHandles() const54         const Model::VertexToBrushesMap& VertexHandleManager::unselectedVertexHandles() const {
55             return m_unselectedVertexHandles;
56         }
57 
selectedVertexHandles() const58         const Model::VertexToBrushesMap& VertexHandleManager::selectedVertexHandles() const {
59             return m_selectedVertexHandles;
60         }
61 
unselectedEdgeHandles() const62         const Model::VertexToEdgesMap& VertexHandleManager::unselectedEdgeHandles() const {
63             return m_unselectedEdgeHandles;
64         }
65 
selectedEdgeHandles() const66         const Model::VertexToEdgesMap& VertexHandleManager::selectedEdgeHandles() const {
67             return m_selectedEdgeHandles;
68         }
69 
unselectedFaceHandles() const70         const Model::VertexToFacesMap& VertexHandleManager::unselectedFaceHandles() const {
71             return m_unselectedFaceHandles;
72         }
73 
selectedFaceHandles() const74         const Model::VertexToFacesMap& VertexHandleManager::selectedFaceHandles() const {
75             return m_selectedFaceHandles;
76         }
77 
vertexHandlePositions() const78         Vec3::List VertexHandleManager::vertexHandlePositions() const {
79             Vec3::List result;
80             result.reserve(m_selectedVertexHandles.size() + m_unselectedVertexHandlePositions.size());
81             handlePositions(m_unselectedVertexHandles, result);
82             handlePositions(m_selectedVertexHandles, result);
83             return result;
84         }
85 
edgeHandlePositions() const86         Vec3::List VertexHandleManager::edgeHandlePositions() const {
87             Vec3::List result;
88             result.reserve(m_selectedEdgeHandles.size() + m_unselectedEdgeHandlePositions.size());
89             handlePositions(m_unselectedEdgeHandles, result);
90             handlePositions(m_selectedEdgeHandles, result);
91             return result;
92         }
93 
faceHandlePositions() const94         Vec3::List VertexHandleManager::faceHandlePositions() const {
95             Vec3::List result;
96             result.reserve(m_selectedFaceHandles.size() + m_unselectedFaceHandlePositions.size());
97             handlePositions(m_unselectedFaceHandles, result);
98             handlePositions(m_selectedFaceHandles, result);
99             return result;
100         }
101 
unselectedVertexHandlePositions() const102         Vec3::List VertexHandleManager::unselectedVertexHandlePositions() const {
103             Vec3::List result;
104             handlePositions(m_unselectedVertexHandles, result);
105             return result;
106         }
107 
unselectedEdgeHandlePositions() const108         Vec3::List VertexHandleManager::unselectedEdgeHandlePositions() const {
109             Vec3::List result;
110             handlePositions(m_unselectedEdgeHandles, result);
111             return result;
112         }
113 
unselectedFaceHandlePositions() const114         Vec3::List VertexHandleManager::unselectedFaceHandlePositions() const {
115             Vec3::List result;
116             handlePositions(m_unselectedFaceHandles, result);
117             return result;
118         }
119 
selectedVertexHandlePositions() const120         Vec3::List VertexHandleManager::selectedVertexHandlePositions() const {
121             Vec3::List result;
122             handlePositions(m_selectedVertexHandles, result);
123             return result;
124         }
125 
selectedEdgeHandlePositions() const126         Vec3::List VertexHandleManager::selectedEdgeHandlePositions() const {
127             Vec3::List result;
128             handlePositions(m_selectedEdgeHandles, result);
129             return result;
130         }
131 
selectedFaceHandlePositions() const132         Vec3::List VertexHandleManager::selectedFaceHandlePositions() const {
133             Vec3::List result;
134             handlePositions(m_selectedFaceHandles, result);
135             return result;
136         }
137 
isHandleSelected(const Vec3 & position) const138         bool VertexHandleManager::isHandleSelected(const Vec3& position) const {
139             return (isVertexHandleSelected(position) ||
140                     isEdgeHandleSelected(position) ||
141                     isFaceHandleSelected(position));
142         }
143 
isVertexHandleSelected(const Vec3 & position) const144         bool VertexHandleManager::isVertexHandleSelected(const Vec3& position) const {
145             return m_selectedVertexHandles.find(position) != m_selectedVertexHandles.end();
146         }
147 
isEdgeHandleSelected(const Vec3 & position) const148         bool VertexHandleManager::isEdgeHandleSelected(const Vec3& position) const {
149             return m_selectedEdgeHandles.find(position) != m_selectedEdgeHandles.end();
150         }
151 
isFaceHandleSelected(const Vec3 & position) const152         bool VertexHandleManager::isFaceHandleSelected(const Vec3& position) const {
153             return m_selectedFaceHandles.find(position) != m_selectedFaceHandles.end();
154         }
155 
selectedVertexCount() const156         size_t VertexHandleManager::selectedVertexCount() const {
157             return m_selectedVertexCount;
158         }
159 
totalVertexCount() const160         size_t VertexHandleManager::totalVertexCount() const {
161             return m_totalVertexCount;
162         }
163 
selectedEdgeCount() const164         size_t VertexHandleManager::selectedEdgeCount() const {
165             return m_selectedEdgeCount;
166         }
167 
totalEdgeCount() const168         size_t VertexHandleManager::totalEdgeCount() const {
169             return m_totalEdgeCount;
170         }
171 
selectedFaceCount() const172         size_t VertexHandleManager::selectedFaceCount() const {
173             return m_selectedFaceCount;
174         }
175 
totalSelectedFaceCount() const176         size_t VertexHandleManager::totalSelectedFaceCount() const {
177             return m_totalFaceCount;
178         }
179 
selectedBrushes() const180         Model::BrushSet VertexHandleManager::selectedBrushes() const {
181             Model::BrushSet brushSet;
182 
183             Model::VertexToBrushesMap::const_iterator vMapIt, vMapEnd;
184             for (vMapIt = m_selectedVertexHandles.begin(), vMapEnd = m_selectedVertexHandles.end(); vMapIt != vMapEnd; ++vMapIt) {
185                 const Model::BrushSet& brushes = vMapIt->second;
186                 brushSet.insert(brushes.begin(), brushes.end());
187             }
188 
189             Model::VertexToEdgesMap::const_iterator eMapIt, eMapEnd;
190             Model::BrushEdgeSet::const_iterator eIt, eEnd;
191             for (eMapIt = m_selectedEdgeHandles.begin(), eMapEnd = m_selectedEdgeHandles.end(); eMapIt != eMapEnd; ++eMapIt) {
192                 const Model::BrushEdgeSet& edges = eMapIt->second;
193 
194                 for (eIt = edges.begin(), eEnd = edges.end(); eIt != eEnd; ++eIt) {
195                     Model::BrushEdge* edge = *eIt;
196                     Model::Brush* brush = edge->firstFace()->payload()->brush();
197                     brushSet.insert(brush);
198                 }
199             }
200 
201             Model::VertexToFacesMap::const_iterator fMapIt, fMapEnd;
202             Model::BrushFaceSet::const_iterator fIt, fEnd;
203             for (fMapIt = m_selectedFaceHandles.begin(), fMapEnd = m_selectedFaceHandles.end(); fMapIt != fMapEnd; ++fMapIt) {
204                 const Model::BrushFaceSet& faces = fMapIt->second;
205 
206                 for (fIt = faces.begin(), fEnd = faces.end(); fIt != fEnd; ++fIt) {
207                     Model::BrushFace* face = *fIt;
208                     brushSet.insert(face->brush());
209                 }
210             }
211 
212             return brushSet;
213         }
214 
brushes(const Vec3 & handlePosition) const215         const Model::BrushSet& VertexHandleManager::brushes(const Vec3& handlePosition) const {
216             Model::VertexToBrushesMap::const_iterator mapIt = m_selectedVertexHandles.find(handlePosition);
217             if (mapIt != m_selectedVertexHandles.end())
218                 return mapIt->second;
219             mapIt = m_unselectedVertexHandles.find(handlePosition);
220             if (mapIt != m_unselectedVertexHandles.end())
221                 return mapIt->second;
222             return Model::EmptyBrushSet;
223         }
224 
edges(const Vec3 & handlePosition) const225         const Model::BrushEdgeSet& VertexHandleManager::edges(const Vec3& handlePosition) const {
226             Model::VertexToEdgesMap::const_iterator mapIt = m_selectedEdgeHandles.find(handlePosition);
227             if (mapIt != m_selectedEdgeHandles.end())
228                 return mapIt->second;
229             mapIt = m_unselectedEdgeHandles.find(handlePosition);
230             if (mapIt != m_unselectedEdgeHandles.end())
231                 return mapIt->second;
232             return Model::EmptyBrushEdgeSet;
233         }
234 
faces(const Vec3 & handlePosition) const235         const Model::BrushFaceSet& VertexHandleManager::faces(const Vec3& handlePosition) const {
236             Model::VertexToFacesMap::const_iterator mapIt = m_selectedFaceHandles.find(handlePosition);
237             if (mapIt != m_selectedFaceHandles.end())
238                 return mapIt->second;
239             mapIt = m_unselectedFaceHandles.find(handlePosition);
240             if (mapIt != m_unselectedFaceHandles.end())
241                 return mapIt->second;
242             return Model::EmptyBrushFaceSet;
243         }
244 
addBrush(Model::Brush * brush)245         void VertexHandleManager::addBrush(Model::Brush* brush) {
246             assert(brush != NULL);
247 
248             const Model::Brush::VertexList brushVertices = brush->vertices();
249             Model::Brush::VertexList::const_iterator vIt, vEnd;
250             for (vIt = brushVertices.begin(), vEnd = brushVertices.end(); vIt != vEnd; ++vIt) {
251                 const Model::BrushVertex* vertex = *vIt;
252                 Model::VertexToBrushesMap::iterator mapIt = m_selectedVertexHandles.find(vertex->position());
253                 if (mapIt != m_selectedVertexHandles.end()) {
254                     mapIt->second.insert(brush);
255                     m_selectedVertexCount++;
256                 } else {
257                     m_unselectedVertexHandles[vertex->position()].insert(brush);
258                 }
259             }
260             m_totalVertexCount += brushVertices.size();
261 
262             const Model::Brush::EdgeList brushEdges = brush->edges();
263             Model::Brush::EdgeList::const_iterator eIt, eEnd;
264             for (eIt = brushEdges.begin(), eEnd = brushEdges.end(); eIt != eEnd; ++eIt) {
265                 Model::BrushEdge* edge = *eIt;
266                 const Vec3 position = edge->center();
267                 Model::VertexToEdgesMap::iterator mapIt = m_selectedEdgeHandles.find(position);
268                 if (mapIt != m_selectedEdgeHandles.end()) {
269                     mapIt->second.insert(edge);
270                     m_selectedEdgeCount++;
271                 } else {
272                     m_unselectedEdgeHandles[position].insert(edge);
273                 }
274             }
275             m_totalEdgeCount+= brushEdges.size();
276 
277             const Model::BrushFaceList& brushFaces = brush->faces();
278             Model::BrushFaceList::const_iterator fIt, fEnd;
279             for (fIt = brushFaces.begin(), fEnd = brushFaces.end(); fIt != fEnd; ++fIt) {
280                 Model::BrushFace* face = *fIt;
281                 const Vec3 position = face->center();
282                 Model::VertexToFacesMap::iterator mapIt = m_selectedFaceHandles.find(position);
283                 if (mapIt != m_selectedFaceHandles.end()) {
284                     mapIt->second.insert(face);
285                     m_selectedFaceCount++;
286                 } else {
287                     m_unselectedFaceHandles[position].insert(face);
288                 }
289             }
290             m_totalFaceCount += brushFaces.size();
291             m_renderStateValid = false;
292         }
293 
removeBrush(Model::Brush * brush)294         void VertexHandleManager::removeBrush(Model::Brush* brush) {
295             const Model::Brush::VertexList brushVertices = brush->vertices();
296             Model::Brush::VertexList::const_iterator vIt, vEnd;
297             for (vIt = brushVertices.begin(), vEnd = brushVertices.end(); vIt != vEnd; ++vIt) {
298                 const Model::BrushVertex* vertex = *vIt;
299                 if (removeHandle(vertex->position(), brush, m_selectedVertexHandles)) {
300                     assert(m_selectedVertexCount > 0);
301                     m_selectedVertexCount--;
302                 } else {
303                     removeHandle(vertex->position(), brush, m_unselectedVertexHandles);
304                 }
305             }
306             assert(m_totalVertexCount >= brushVertices.size());
307             m_totalVertexCount -= brushVertices.size();
308 
309             const Model::Brush::EdgeList brushEdges = brush->edges();
310             Model::Brush::EdgeList::const_iterator eIt, eEnd;
311             for (eIt = brushEdges.begin(), eEnd = brushEdges.end(); eIt != eEnd; ++eIt) {
312                 Model::BrushEdge* edge = *eIt;
313                 const Vec3 position = edge->center();
314                 if (removeHandle(position, edge, m_selectedEdgeHandles)) {
315                     assert(m_selectedEdgeCount > 0);
316                     m_selectedEdgeCount--;
317                 } else {
318                     removeHandle(position, edge, m_unselectedEdgeHandles);
319                 }
320             }
321             assert(m_totalEdgeCount >= brushEdges.size());
322             m_totalEdgeCount -= brushEdges.size();
323 
324             const Model::BrushFaceList& brushFaces = brush->faces();
325             Model::BrushFaceList::const_iterator fIt, fEnd;
326             for (fIt = brushFaces.begin(), fEnd = brushFaces.end(); fIt != fEnd; ++fIt) {
327                 Model::BrushFace* face = *fIt;
328                 const Vec3 position = face->center();
329                 if (removeHandle(position, face, m_selectedFaceHandles)) {
330                     assert(m_selectedFaceCount > 0);
331                     m_selectedFaceCount--;
332                 } else {
333                     removeHandle(position, face, m_unselectedFaceHandles);
334                 }
335             }
336             assert(m_totalFaceCount >= brushFaces.size());
337             m_totalFaceCount -= brushFaces.size();
338             m_renderStateValid = false;
339         }
340 
clear()341         void VertexHandleManager::clear() {
342             m_unselectedVertexHandles.clear();
343             m_selectedVertexHandles.clear();
344             m_totalVertexCount = 0;
345             m_selectedVertexCount = 0;
346             m_unselectedEdgeHandles.clear();
347             m_selectedEdgeHandles.clear();
348             m_totalEdgeCount = 0;
349             m_selectedEdgeCount = 0;
350             m_unselectedFaceHandles.clear();
351             m_selectedFaceHandles.clear();
352             m_totalFaceCount = 0;
353             m_selectedFaceCount = 0;
354             m_renderStateValid = false;
355         }
356 
selectVertexHandle(const Vec3 & position)357         void VertexHandleManager::selectVertexHandle(const Vec3& position) {
358             size_t count = 0;
359             if ((count = moveHandle(position, m_unselectedVertexHandles, m_selectedVertexHandles)) > 0) {
360                 m_selectedVertexCount += count;
361                 m_renderStateValid = false;
362             }
363         }
364 
deselectVertexHandle(const Vec3 & position)365         void VertexHandleManager::deselectVertexHandle(const Vec3& position) {
366             size_t count = 0;
367             if ((count = moveHandle(position, m_selectedVertexHandles, m_unselectedVertexHandles)) > 0) {
368                 assert(m_selectedVertexCount >= count);
369                 m_selectedVertexCount -= count;
370                 m_renderStateValid = false;
371             }
372         }
373 
toggleVertexHandle(const Vec3 & position)374         void VertexHandleManager::toggleVertexHandle(const Vec3& position) {
375             size_t count = 0;
376             if ((count = moveHandle(position, m_unselectedVertexHandles, m_selectedVertexHandles)) > 0) {
377                 m_selectedVertexCount += count;
378                 m_renderStateValid = false;
379             } else if ((count = moveHandle(position, m_selectedVertexHandles, m_unselectedVertexHandles)) > 0) {
380                 assert(m_selectedVertexCount >= count);
381                 m_selectedVertexCount -= count;
382                 m_renderStateValid = false;
383             }
384         }
385 
selectVertexHandles(const Vec3::List & positions)386         void VertexHandleManager::selectVertexHandles(const Vec3::List& positions) {
387             Vec3::List::const_iterator it, end;
388             for (it = positions.begin(), end = positions.end(); it != end; ++it)
389                 selectVertexHandle(*it);
390         }
391 
deselectAllVertexHandles()392         void VertexHandleManager::deselectAllVertexHandles() {
393             Model::VertexToBrushesMap::const_iterator vIt, vEnd;
394             for (vIt = m_selectedVertexHandles.begin(), vEnd = m_selectedVertexHandles.end(); vIt != vEnd; ++vIt) {
395                 const Vec3& position = vIt->first;
396                 const Model::BrushSet& selectedBrushes = vIt->second;
397                 Model::BrushSet& unselectedBrushes = m_unselectedVertexHandles[position];
398                 unselectedBrushes.insert(selectedBrushes.begin(), selectedBrushes.end());
399             }
400             m_selectedVertexHandles.clear();
401             m_selectedVertexCount = 0;
402             m_renderStateValid = false;
403         }
404 
toggleVertexHandles(const Vec3::List & positions)405         void VertexHandleManager::toggleVertexHandles(const Vec3::List& positions) {
406             Vec3::List::const_iterator it, end;
407             for (it = positions.begin(), end = positions.end(); it != end; ++it)
408                 toggleVertexHandle(*it);
409         }
410 
selectEdgeHandle(const Vec3 & position)411         void VertexHandleManager::selectEdgeHandle(const Vec3& position) {
412             size_t count = 0;
413             if ((count = moveHandle(position, m_unselectedEdgeHandles, m_selectedEdgeHandles)) > 0) {
414                 m_selectedEdgeCount += count;
415                 m_renderStateValid = false;
416             }
417         }
418 
deselectEdgeHandle(const Vec3 & position)419         void VertexHandleManager::deselectEdgeHandle(const Vec3& position) {
420             size_t count = 0;
421             if ((count = moveHandle(position, m_selectedEdgeHandles, m_unselectedEdgeHandles)) > 0) {
422                 assert(m_selectedEdgeCount >= count);
423                 m_selectedEdgeCount -= count;
424                 m_renderStateValid = false;
425             }
426         }
427 
toggleEdgeHandle(const Vec3 & position)428         void VertexHandleManager::toggleEdgeHandle(const Vec3& position) {
429             size_t count = 0;
430             if ((count = moveHandle(position, m_unselectedEdgeHandles, m_selectedEdgeHandles)) > 0) {
431                 m_selectedEdgeCount += count;
432                 m_renderStateValid = false;
433             } else if ((count = moveHandle(position, m_selectedEdgeHandles, m_unselectedEdgeHandles)) > 0) {
434                 assert(m_selectedEdgeCount >= count);
435                 m_selectedEdgeCount -= count;
436                 m_renderStateValid = false;
437             }
438         }
439 
selectEdgeHandles(const Edge3::List & edges)440         void VertexHandleManager::selectEdgeHandles(const Edge3::List& edges) {
441             Edge3::List::const_iterator it, end;
442             for (it = edges.begin(), end = edges.end(); it != end; ++it) {
443                 const Edge3& edge = *it;
444                 selectEdgeHandle(edge.center());
445             }
446         }
447 
deselectAllEdgeHandles()448         void VertexHandleManager::deselectAllEdgeHandles() {
449             Model::VertexToEdgesMap::const_iterator eIt, eEnd;
450             for (eIt = m_selectedEdgeHandles.begin(), eEnd = m_selectedEdgeHandles.end(); eIt != eEnd; ++eIt) {
451                 const Vec3& position = eIt->first;
452                 const Model::BrushEdgeSet& selectedEdges = eIt->second;
453                 Model::BrushEdgeSet& unselectedEdges = m_unselectedEdgeHandles[position];
454                 unselectedEdges.insert(selectedEdges.begin(), selectedEdges.end());
455             }
456             m_selectedEdgeHandles.clear();
457             m_selectedEdgeCount = 0;
458             m_renderStateValid = false;
459         }
460 
toggleEdgeHandles(const Vec3::List & positions)461         void VertexHandleManager::toggleEdgeHandles(const Vec3::List& positions) {
462             Vec3::List::const_iterator it, end;
463             for (it = positions.begin(), end = positions.end(); it != end; ++it)
464                 toggleEdgeHandle(*it);
465         }
466 
selectFaceHandle(const Vec3 & position)467         void VertexHandleManager::selectFaceHandle(const Vec3& position) {
468             size_t count = 0;
469             if ((count = moveHandle(position, m_unselectedFaceHandles, m_selectedFaceHandles)) > 0) {
470                 m_selectedFaceCount += count;
471                 m_renderStateValid = false;
472             }
473         }
474 
deselectFaceHandle(const Vec3 & position)475         void VertexHandleManager::deselectFaceHandle(const Vec3& position) {
476             size_t count = 0;
477             if ((count = moveHandle(position, m_selectedFaceHandles, m_unselectedFaceHandles)) > 0) {
478                 assert(m_selectedFaceCount >= count);
479                 m_selectedFaceCount -= count;
480                 m_renderStateValid = false;
481             }
482         }
483 
toggleFaceHandle(const Vec3 & position)484         void VertexHandleManager::toggleFaceHandle(const Vec3& position) {
485             size_t count = 0;
486             if ((count = moveHandle(position, m_unselectedFaceHandles, m_selectedFaceHandles)) > 0) {
487                 m_selectedFaceCount += count;
488                 m_renderStateValid = false;
489             } else if ((count = moveHandle(position, m_selectedFaceHandles, m_unselectedFaceHandles)) > 0) {
490                 assert(m_selectedFaceCount >= count);
491                 m_selectedFaceCount -= count;
492                 m_renderStateValid = false;
493             }
494         }
495 
selectFaceHandles(const Polygon3::List & faces)496         void VertexHandleManager::selectFaceHandles(const Polygon3::List& faces) {
497             Polygon3::List::const_iterator it, end;
498             for (it = faces.begin(), end = faces.end(); it != end; ++it) {
499                 const Polygon3& face = *it;
500                 selectFaceHandle(face.center());
501             }
502         }
503 
deselectAllFaceHandles()504         void VertexHandleManager::deselectAllFaceHandles() {
505             Model::VertexToFacesMap::const_iterator fIt, fEnd;
506             for (fIt = m_selectedFaceHandles.begin(), fEnd = m_selectedFaceHandles.end(); fIt != fEnd; ++fIt) {
507                 const Vec3& position = fIt->first;
508                 const Model::BrushFaceSet& selectedFaces = fIt->second;
509                 Model::BrushFaceSet& unselectedFaces = m_unselectedFaceHandles[position];
510                 unselectedFaces.insert(selectedFaces.begin(), selectedFaces.end());
511             }
512             m_selectedFaceHandles.clear();
513             m_selectedFaceCount = 0;
514             m_renderStateValid = false;
515         }
516 
toggleFaceHandles(const Vec3::List & positions)517         void VertexHandleManager::toggleFaceHandles(const Vec3::List& positions) {
518             Vec3::List::const_iterator it, end;
519             for (it = positions.begin(), end = positions.end(); it != end; ++it)
520                 toggleFaceHandle(*it);
521         }
522 
hasSelectedHandles() const523         bool VertexHandleManager::hasSelectedHandles() const {
524             return !m_selectedVertexHandles.empty() || !m_selectedEdgeHandles.empty() || !m_selectedFaceHandles.empty();
525         }
526 
deselectAllHandles()527         void VertexHandleManager::deselectAllHandles() {
528             deselectAllVertexHandles();
529             deselectAllEdgeHandles();
530             deselectAllFaceHandles();
531         }
532 
reselectVertexHandles(const Model::BrushSet & brushes,const Vec3::List & positions,const FloatType maxDistance)533         void VertexHandleManager::reselectVertexHandles(const Model::BrushSet& brushes, const Vec3::List& positions, const FloatType maxDistance) {
534             Vec3::List::const_iterator oIt, oEnd, nIt, nEnd;
535             for (oIt = positions.begin(), oEnd = positions.end(); oIt != oEnd; ++oIt) {
536                 const Vec3& oldPosition = *oIt;
537                 const Vec3::List newPositions = findVertexHandlePositions(brushes, oldPosition, maxDistance);
538                 for (nIt = newPositions.begin(), nEnd = newPositions.end(); nIt != nEnd; ++nIt) {
539                     const Vec3& newPosition = *nIt;
540                     selectVertexHandle(newPosition);
541                 }
542             }
543         }
544 
reselectEdgeHandles(const Model::BrushSet & brushes,const Vec3::List & positions,const FloatType maxDistance)545         void VertexHandleManager::reselectEdgeHandles(const Model::BrushSet& brushes, const Vec3::List& positions, const FloatType maxDistance) {
546             Vec3::List::const_iterator oIt, oEnd, nIt, nEnd;
547             for (oIt = positions.begin(), oEnd = positions.end(); oIt != oEnd; ++oIt) {
548                 const Vec3& oldPosition = *oIt;
549                 const Vec3::List newPositions = findEdgeHandlePositions(brushes, oldPosition, maxDistance);
550                 for (nIt = newPositions.begin(), nEnd = newPositions.end(); nIt != nEnd; ++nIt) {
551                     const Vec3& newPosition = *nIt;
552                     selectEdgeHandle(newPosition);
553                 }
554             }
555         }
556 
reselectFaceHandles(const Model::BrushSet & brushes,const Vec3::List & positions,const FloatType maxDistance)557         void VertexHandleManager::reselectFaceHandles(const Model::BrushSet& brushes, const Vec3::List& positions, const FloatType maxDistance) {
558             Vec3::List::const_iterator oIt, oEnd, nIt, nEnd;
559             for (oIt = positions.begin(), oEnd = positions.end(); oIt != oEnd; ++oIt) {
560                 const Vec3& oldPosition = *oIt;
561                 const Vec3::List newPositions = findFaceHandlePositions(brushes, oldPosition, maxDistance);
562                 for (nIt = newPositions.begin(), nEnd = newPositions.end(); nIt != nEnd; ++nIt) {
563                     const Vec3& newPosition = *nIt;
564                     selectFaceHandle(newPosition);
565                 }
566             }
567         }
568 
pick(const Ray3 & ray,const Renderer::Camera & camera,Model::PickResult & pickResult,bool splitMode) const569         void VertexHandleManager::pick(const Ray3& ray, const Renderer::Camera& camera, Model::PickResult& pickResult, bool splitMode) const {
570             Model::VertexToBrushesMap::const_iterator vIt, vEnd;
571             Model::VertexToEdgesMap::const_iterator eIt, eEnd;
572             Model::VertexToFacesMap::const_iterator fIt, fEnd;
573 
574             if ((m_selectedEdgeHandles.empty() && m_selectedFaceHandles.empty()) || splitMode) {
575                 for (vIt = m_unselectedVertexHandles.begin(), vEnd = m_unselectedVertexHandles.end(); vIt != vEnd; ++vIt) {
576                     const Vec3& position = vIt->first;
577                     const Model::Hit hit = pickHandle(ray, camera, position, VertexHandleHit);
578                     if (hit.isMatch())
579                         pickResult.addHit(hit);
580                 }
581             }
582 
583             for (vIt = m_selectedVertexHandles.begin(), vEnd = m_selectedVertexHandles.end(); vIt != vEnd; ++vIt) {
584                 const Vec3& position = vIt->first;
585                 const Model::Hit hit = pickHandle(ray, camera, position, VertexHandleHit);
586                 if (hit.isMatch())
587                     pickResult.addHit(hit);
588             }
589 
590             if (m_selectedVertexHandles.empty() && m_selectedFaceHandles.empty() && !splitMode) {
591                 for (eIt = m_unselectedEdgeHandles.begin(), eEnd = m_unselectedEdgeHandles.end(); eIt != eEnd; ++eIt) {
592                     const Vec3& position = eIt->first;
593                     const Model::Hit hit = pickHandle(ray, camera, position, EdgeHandleHit);
594                     if (hit.isMatch())
595                         pickResult.addHit(hit);
596                 }
597             }
598 
599             for (eIt = m_selectedEdgeHandles.begin(), eEnd = m_selectedEdgeHandles.end(); eIt != eEnd; ++eIt) {
600                 const Vec3& position = eIt->first;
601                 const Model::Hit hit = pickHandle(ray, camera, position, EdgeHandleHit);
602                 if (hit.isMatch())
603                     pickResult.addHit(hit);
604             }
605 
606             if (m_selectedVertexHandles.empty() && m_selectedEdgeHandles.empty() && !splitMode) {
607                 for (fIt = m_unselectedFaceHandles.begin(), fEnd = m_unselectedFaceHandles.end(); fIt != fEnd; ++fIt) {
608                     const Vec3& position = fIt->first;
609                     const Model::Hit hit = pickHandle(ray, camera, position, FaceHandleHit);
610                     if (hit.isMatch())
611                         pickResult.addHit(hit);
612                 }
613             }
614 
615             for (fIt = m_selectedFaceHandles.begin(), fEnd = m_selectedFaceHandles.end(); fIt != fEnd; ++fIt) {
616                 const Vec3& position = fIt->first;
617                 const Model::Hit hit = pickHandle(ray, camera, position, FaceHandleHit);
618                 if (hit.isMatch())
619                     pickResult.addHit(hit);
620             }
621         }
622 
render(Renderer::RenderContext & renderContext,Renderer::RenderBatch & renderBatch,const bool splitMode)623         void VertexHandleManager::render(Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch, const bool splitMode) {
624             if (!m_renderStateValid)
625                 validateRenderState(splitMode);
626 
627             Renderer::RenderService renderService(renderContext, renderBatch);
628             renderService.setForegroundColor(pref(Preferences::HandleColor));
629             if (m_selectedEdgeHandles.empty() && m_selectedFaceHandles.empty() && !splitMode)
630                 renderService.renderPointHandles(VectorUtils::cast<Vec3f>(m_unselectedVertexHandlePositions));
631 
632             if (m_selectedVertexHandles.empty() && m_selectedFaceHandles.empty() && !splitMode)
633                 renderService.renderPointHandles(VectorUtils::cast<Vec3f>(m_unselectedEdgeHandlePositions));
634 
635             if (m_selectedVertexHandles.empty() && m_selectedEdgeHandles.empty() && !splitMode)
636                 renderService.renderPointHandles(VectorUtils::cast<Vec3f>(m_unselectedFaceHandlePositions));
637 
638             if ((!m_selectedEdgeHandles.empty() || !m_selectedFaceHandles.empty()) && !splitMode)
639                 renderService.renderLines(m_edgeVertices);
640 
641             renderService.setForegroundColor(pref(Preferences::SelectedHandleColor));
642             renderService.renderPointHandles(VectorUtils::cast<Vec3f>(m_selectedHandlePositions));
643         }
644 
renderHighlight(Renderer::RenderContext & renderContext,Renderer::RenderBatch & renderBatch,const Vec3 & position)645         void VertexHandleManager::renderHighlight(Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch, const Vec3& position) {
646             Renderer::RenderService renderService(renderContext, renderBatch);
647             renderService.setForegroundColor(pref(Preferences::SelectedHandleColor));
648             renderService.renderPointHandleHighlight(position);
649 
650             renderService.setForegroundColor(pref(Preferences::SelectedInfoOverlayTextColor));
651             renderService.setBackgroundColor(pref(Preferences::SelectedInfoOverlayBackgroundColor));
652             renderService.renderString(position.asString(), position);
653         }
654 
renderEdgeHighlight(Renderer::RenderContext & renderContext,Renderer::RenderBatch & renderBatch,const Vec3 & handlePosition)655         void VertexHandleManager::renderEdgeHighlight(Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch, const Vec3& handlePosition) {
656             Renderer::RenderService renderService(renderContext, renderBatch);
657             renderService.setForegroundColor(pref(Preferences::HandleColor));
658 
659             Model::VertexToEdgesMap::const_iterator it = m_unselectedEdgeHandles.find(handlePosition);
660             if (it != m_unselectedEdgeHandles.end()) {
661                 const Model::BrushEdgeSet& edges = it->second;
662                 assert(!edges.empty());
663 
664                 const Model::BrushEdge* edge = *edges.begin();
665                 renderService.renderLine(edge->firstVertex()->position(), edge->secondVertex()->position());
666             }
667         }
668 
renderFaceHighlight(Renderer::RenderContext & renderContext,Renderer::RenderBatch & renderBatch,const Vec3 & handlePosition)669         void VertexHandleManager::renderFaceHighlight(Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch, const Vec3& handlePosition) {
670             Renderer::RenderService renderService(renderContext, renderBatch);
671             renderService.setForegroundColor(pref(Preferences::HandleColor));
672 
673             Model::VertexToFacesMap::const_iterator it = m_unselectedFaceHandles.find(handlePosition);
674             if (it != m_unselectedFaceHandles.end()) {
675                 const Model::BrushFaceSet& faces = it->second;
676                 assert(!faces.empty());
677 
678                 const Model::BrushFace* face = *faces.begin();
679                 const Model::BrushFace::VertexList& vertices = face->vertices();
680 
681                 Vec3f::List vertexPositions;
682                 vertexPositions.reserve(vertices.size());
683                 Vec3f::toList(vertices.begin(), vertices.end(), Model::BrushGeometry::GetVertexPosition(), vertexPositions);
684 
685                 renderService.renderPolygonOutline(vertexPositions);
686             }
687         }
688 
renderGuide(Renderer::RenderContext & renderContext,Renderer::RenderBatch & renderBatch,const Vec3 & position)689         void VertexHandleManager::renderGuide(Renderer::RenderContext& renderContext, Renderer::RenderBatch& renderBatch, const Vec3& position) {
690             Renderer::RenderService renderService(renderContext, renderBatch);
691             m_guideRenderer.setPosition(position);
692             m_guideRenderer.setColor(Color(pref(Preferences::HandleColor), 0.5f));
693             renderBatch.add(&m_guideRenderer);
694         }
695 
findVertexHandlePositions(const Model::BrushSet & brushes,const Vec3 & query,const FloatType maxDistance)696         Vec3::List VertexHandleManager::findVertexHandlePositions(const Model::BrushSet& brushes, const Vec3& query, const FloatType maxDistance) {
697             Vec3::List result;
698             Model::BrushSet::const_iterator bIt, bEnd;
699             Model::Brush::VertexList::const_iterator vIt, vEnd;
700 
701             for (bIt = brushes.begin(), bEnd = brushes.end(); bIt != bEnd; ++bIt) {
702                 const Model::Brush* brush = *bIt;
703                 const Model::Brush::VertexList vertices = brush->vertices();
704                 for (vIt = vertices.begin(), vEnd = vertices.end(); vIt != vEnd; ++vIt) {
705                     const Model::BrushVertex* vertex = *vIt;
706                     if (query.squaredDistanceTo(vertex->position()) <= maxDistance * maxDistance)
707                         result.push_back(vertex->position());
708                 }
709             }
710 
711             return result;
712         }
713 
findEdgeHandlePositions(const Model::BrushSet & brushes,const Vec3 & query,const FloatType maxDistance)714         Vec3::List VertexHandleManager::findEdgeHandlePositions(const Model::BrushSet& brushes, const Vec3& query, const FloatType maxDistance) {
715             Vec3::List result;
716             Model::BrushSet::const_iterator bIt, bEnd;
717             Model::Brush::EdgeList::const_iterator eIt, eEnd;
718 
719             for (bIt = brushes.begin(), bEnd = brushes.end(); bIt != bEnd; ++bIt) {
720                 const Model::Brush* brush = *bIt;
721                 const Model::Brush::EdgeList edges = brush->edges();
722                 for (eIt = edges.begin(), eEnd = edges.end(); eIt != eEnd; ++eIt) {
723                     const Model::BrushEdge* edge = *eIt;
724                     const Vec3 center = edge->center();
725                     if (query.squaredDistanceTo(center) <= maxDistance * maxDistance)
726                         result.push_back(center);
727                 }
728             }
729 
730             return result;
731         }
732 
findFaceHandlePositions(const Model::BrushSet & brushes,const Vec3 & query,const FloatType maxDistance)733         Vec3::List VertexHandleManager::findFaceHandlePositions(const Model::BrushSet& brushes, const Vec3& query, const FloatType maxDistance) {
734             Vec3::List result;
735             Model::BrushSet::const_iterator bIt, bEnd;
736             Model::BrushFaceList::const_iterator fIt, fEnd;
737 
738             for (bIt = brushes.begin(), bEnd = brushes.end(); bIt != bEnd; ++bIt) {
739                 const Model::Brush* brush = *bIt;
740                 const Model::BrushFaceList& faces = brush->faces();
741                 for (fIt = faces.begin(), fEnd = faces.end(); fIt != fEnd; ++fIt) {
742                     const Model::BrushFace* face = *fIt;
743                     const Vec3 center = face->center();
744                     if (query.squaredDistanceTo(center) <= maxDistance * maxDistance)
745                         result.push_back(center);
746                 }
747             }
748 
749             return result;
750         }
751 
pickHandle(const Ray3 & ray,const Renderer::Camera & camera,const Vec3 & position,Model::Hit::HitType type) const752         Model::Hit VertexHandleManager::pickHandle(const Ray3& ray, const Renderer::Camera& camera, const Vec3& position, Model::Hit::HitType type) const {
753             const FloatType distance = camera.pickPointHandle(ray, position, pref(Preferences::HandleRadius));
754             if (!Math::isnan(distance)) {
755                 const Vec3 hitPoint = ray.pointAtDistance(distance);
756                 return Model::Hit::hit<Vec3>(type, distance, hitPoint, position);
757             }
758 
759             return Model::Hit::NoHit;
760         }
761 
validateRenderState(const bool splitMode)762         void VertexHandleManager::validateRenderState(const bool splitMode) {
763             assert(!m_renderStateValid);
764 
765             Model::VertexToBrushesMap::const_iterator vIt, vEnd;
766             Model::VertexToEdgesMap::const_iterator eIt, eEnd;
767             Model::VertexToFacesMap::const_iterator fIt, fEnd;
768 
769             m_unselectedVertexHandlePositions.clear();
770             m_unselectedEdgeHandlePositions.clear();
771             m_unselectedFaceHandlePositions.clear();
772             m_selectedHandlePositions.clear();
773             m_edgeVertices.clear();
774 
775             m_unselectedVertexHandlePositions.reserve(m_unselectedVertexHandles.size());
776             m_unselectedEdgeHandlePositions.reserve(m_unselectedEdgeHandles.size());
777             m_unselectedFaceHandlePositions.reserve(m_unselectedFaceHandles.size());
778             m_selectedHandlePositions.reserve(m_selectedVertexHandles.size() + m_selectedEdgeHandles.size() + m_selectedFaceHandles.size());
779 
780             for (vIt = m_unselectedVertexHandles.begin(), vEnd = m_unselectedVertexHandles.end(); vIt != vEnd; ++vIt) {
781                 const Vec3& position = vIt->first;
782                 m_unselectedVertexHandlePositions.push_back(position);
783             }
784 
785             for (eIt = m_unselectedEdgeHandles.begin(), eEnd = m_unselectedEdgeHandles.end(); eIt != eEnd; ++eIt) {
786                 const Vec3& position = eIt->first;
787                 m_unselectedEdgeHandlePositions.push_back(position);
788             }
789 
790             for (fIt = m_unselectedFaceHandles.begin(), fEnd = m_unselectedFaceHandles.end(); fIt != fEnd; ++fIt) {
791                 const Vec3& position = fIt->first;
792                 m_unselectedFaceHandlePositions.push_back(position);
793             }
794 
795             for (vIt = m_selectedVertexHandles.begin(), vEnd = m_selectedVertexHandles.end(); vIt != vEnd; ++vIt) {
796                 const Vec3& position = vIt->first;
797                 m_selectedHandlePositions.push_back(position);
798             }
799 
800 
801             for (eIt = m_selectedEdgeHandles.begin(), eEnd = m_selectedEdgeHandles.end(); eIt != eEnd; ++eIt) {
802                 const Vec3& position = eIt->first;
803                 m_selectedHandlePositions.push_back(position);
804 
805                 const Model::BrushEdgeSet& edges = eIt->second;
806                 Model::BrushEdgeSet::const_iterator edgeIt, edgeEnd;
807                 for (edgeIt = edges.begin(), edgeEnd = edges.end(); edgeIt != edgeEnd; ++edgeIt) {
808                     const Model::BrushEdge* edge = *edgeIt;
809                     m_edgeVertices.push_back(Vec3f(edge->firstVertex()->position()));
810                     m_edgeVertices.push_back(Vec3f(edge->secondVertex()->position()));
811                 }
812             }
813 
814             for (fIt = m_selectedFaceHandles.begin(), fEnd = m_selectedFaceHandles.end(); fIt != fEnd; ++fIt) {
815                 const Vec3f& position = fIt->first;
816                 m_selectedHandlePositions.push_back(Vec3f(position));
817 
818                 const Model::BrushFaceSet& faces = fIt->second;
819                 Model::BrushFaceSet::const_iterator faceIt, faceEnd;
820                 for (faceIt = faces.begin(), faceEnd = faces.end(); faceIt != faceEnd; ++faceIt) {
821                     const Model::BrushFace* face = *faceIt;
822                     const Model::BrushFace::EdgeList edges = face->edges();
823 
824                     Model::BrushFace::EdgeList::const_iterator edgeIt, edgeEnd;
825                     for (edgeIt = edges.begin(), edgeEnd = edges.end(); edgeIt != edgeEnd; ++edgeIt) {
826                         const Model::BrushEdge* edge = *edgeIt;
827                         m_edgeVertices.push_back(Vec3f(edge->firstVertex()->position()));
828                         m_edgeVertices.push_back(Vec3f(edge->secondVertex()->position()));
829                     }
830                 }
831             }
832 
833             m_renderStateValid = true;
834         }
835     }
836 }
837