OpenWalnut  1.5.0dev
WFiberHandler.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <memory>
27 #include <string>
28 #include <vector>
29 
30 #include "WConnectorData.h"
31 #include "WFiberHandler.h"
32 #include "action/WFiberActionAddFiber.h"
33 #include "action/WFiberActionAddVertex.h"
34 #include "action/WFiberActionMultideselect.h"
35 #include "action/WFiberActionMultiselect.h"
36 #include "action/WFiberActionRemoveFiber.h"
37 #include "action/WFiberActionRemoveVertex.h"
38 #include "action/WFiberActionToggle.h"
39 #include "core/common/WPathHelper.h"
40 
41 
43 {
44  m_pointConnector = pointConnector;
47  m_hidden = std::shared_ptr< std::vector< char > >( new std::vector< char >() );
48 
49  m_selectedFiber = 0;
50  m_fiberCount = 1;
51 }
52 
54 {
55  if( m_fibers->empty() )
56  {
57  return;
58  }
59 
60  for( auto fiber = m_fibers->begin(); fiber != m_fibers->end(); fiber++ )
61  {
62  if( fiber->empty() )
63  {
64  continue;
65  }
66 
67  std::sort( fiber->begin(), fiber->end(), []( osg::Vec3 a, osg::Vec3 b )
68  {
69  if( a.z() != b.z() )
70  {
71  return a.z() < b.z();
72  }
73 
74  if( a.x() != b.x() )
75  {
76  return a.x() < b.x();
77  }
78 
79  return a.y() < b.y();
80  } );
81  }
82 }
83 
84 void WFiberHandler::addVertexToFiber( osg::Vec3 vertex, size_t fiberIdx, bool silent )
85 {
86  auto fiber = m_fibers->begin() + fiberIdx;
87  if( std::find( fiber->begin(), fiber->end(), vertex ) != fiber->end() )
88  {
89  return;
90  }
91 
92  fiber->push_back( vertex );
93  sortVertices();
94 
95  if( !silent )
96  {
97  m_actionHandler->pushAction( WFiberActionAddVertex::SPtr( new WFiberActionAddVertex( vertex, fiberIdx, this ) ) );
98  }
99 }
100 
101 void WFiberHandler::addVerticesToFiber( std::vector< osg::Vec3 > vertices, size_t fiberIdx, bool silent )
102 {
103  auto fiber = m_fibers->begin() + fiberIdx;
104  for( auto vertex = fiber->begin(); vertex != fiber->end(); vertex++ )
105  {
106  auto it = std::find( vertices.begin(), vertices.end(), *vertex );
107  if( it != vertices.end() )
108  {
109  vertices.erase( it );
110  }
111  }
112 
113  if( vertices.empty() )
114  {
115  return;
116  }
117 
118  for( auto vertex = vertices.begin(); vertex != vertices.end(); vertex++ )
119  {
120  fiber->push_back( *vertex );
121  }
122  sortVertices();
123 
124  if( !silent )
125  {
126  m_actionHandler->pushAction( WFiberActionMultiselect::SPtr( new WFiberActionMultiselect( vertices, fiberIdx, this ) ) );
127  }
128 }
129 
130 void WFiberHandler::removeVerticesFromFiber( std::vector< osg::Vec3 > vertices, size_t fiberIdx, bool silent )
131 {
132  auto fiber = m_fibers->begin() + fiberIdx;
133 
134  for( auto vertex = vertices.begin(); vertex != vertices.end(); vertex++ )
135  {
136  auto it = std::find( fiber->begin(), fiber->end(), *vertex );
137  if( it != fiber->end() )
138  {
139  fiber->erase( it );
140  }
141  }
142 
143  if( !silent )
144  {
145  m_actionHandler->pushAction( WFiberActionMultideselect::SPtr( new WFiberActionMultideselect( vertices, fiberIdx, this ) ) );
146  }
147 }
148 
149 void WFiberHandler::addVertexToFiberAt( osg::Vec3 vertex, size_t fiberIdx, size_t position, bool silent )
150 {
151  auto fiber = m_fibers->begin() + fiberIdx;
152  fiber->emplace( fiber->begin() + position, vertex );
153 
154  if( !silent )
155  {
156  m_actionHandler->pushAction( WFiberActionAddVertex::SPtr( new WFiberActionAddVertex( vertex, fiberIdx, this ) ) );
157  }
158 }
159 
160 void WFiberHandler::removeVertexFromFiber( osg::Vec3 vertex, size_t fiberIdx, bool silent )
161 {
162  auto fiber = m_fibers->begin() + fiberIdx;
163  size_t position = 0;
164 
165  for( auto it = fiber->begin(); it != fiber->end(); it++ )
166  {
167  if( *it == vertex )
168  {
169  fiber->erase( it );
170  break;
171  }
172  position++;
173  }
174 
175  if( !silent )
176  {
177  m_actionHandler->pushAction( WFiberActionRemoveVertex::SPtr( new WFiberActionRemoveVertex( vertex, fiberIdx, position, this ) ) );
178  }
179 }
180 
182 {
183  m_fibers->clear();
184  m_hidden->clear();
185  m_possibleFiberSelections->clear();
186 
187  m_fiberCount = 1;
188  m_selectedFiber = 0;
189  addFiber( "Track 0", true );
190 }
191 
193 {
194  PCFiber fiber = m_fibers->at( m_selectedFiber );
195  if( !fiber.empty() )
196  {
197  m_pointConnector->getConnectorData()->selectPoint( fiber.back() );
198  }
199 }
200 
202 {
203  WPropertyBase::PropertyChangeNotifierType notifier = boost::bind( &WFiberHandler::updateProperty, this, boost::placeholders::_1 );
204 
205  WPropertyGroup::SPtr fiberGroup = properties->addPropertyGroup( "Fibers", "Property group for fiber selection, adding and deleting." );
206  WPropertyGroup::SPtr undoGroup = properties->addPropertyGroup( "Undo | Redo", "Property group for undo and redo." );
207 
209  m_fiberSelection = fiberGroup->addProperty(
210  "Selected track", "The track to which the points are added", m_possibleFiberSelections->getSelectorNone(), notifier );
211 
212  addFiber( "Track 0", true );
213 
216 
217  m_addFiber = fiberGroup->addProperty( "Add track", "Add Track", WPVBaseTypes::PV_TRIGGER_READY, notifier );
218  m_removeFiber = fiberGroup->addProperty( "Remove track", "Remove Track", WPVBaseTypes::PV_TRIGGER_READY, notifier );
219  m_toggleFiber = fiberGroup->addProperty( "Toggle track", "Toggle Track", WPVBaseTypes::PV_TRIGGER_READY, notifier );
220 
222  selections->addItem( ItemType::create( "Brush", "Brush", "", NULL ) );
223  selections->addItem( ItemType::create( "Line Loop", "Line Loop", "", NULL ) );
224  selections->addItem( ItemType::create( "Box", "Box", "", NULL ) );
225  m_selectionType = fiberGroup->addProperty( "Selection Type", "The type of the selection", selections->getSelectorFirst(), notifier );
228 
229  m_undoTrigger = undoGroup->addProperty( "Undo", "Undo Changes", WPVBaseTypes::PV_TRIGGER_READY, notifier );
230  m_redoTrigger = undoGroup->addProperty( "Redo", "Redo Changes", WPVBaseTypes::PV_TRIGGER_READY, notifier );
231 }
232 
233 static bool sortComparator( std::shared_ptr< WItemSelectionItem > a, std::shared_ptr< WItemSelectionItem > b )
234 {
235  return a->getName().compare( b->getName() ) < 0;
236 }
237 
238 void WFiberHandler::addFiber( std::string name, bool silent, bool updateSelector )
239 {
240  m_fibers->push_back( PCFiber() );
241  m_hidden->push_back( false );
242 
243  m_possibleFiberSelections->addItem( ItemType::create( name, name, "", NULL ) );
244 
245  if( updateSelector )
246  {
247  selectorUpdate( m_fibers->size() - 1 );
248  }
249 
250  if( !silent )
251  {
252  m_actionHandler->pushAction( WFiberActionAddFiber::SPtr( new WFiberActionAddFiber( name, m_fibers->size() - 1, this ) ) );
253  }
254 }
255 
257 {
258  m_fiberSelection->set( m_possibleFiberSelections->getSelector( idx ) );
259 }
260 
261 void WFiberHandler::addFiberAt( std::string name, size_t position, bool hidden, bool silent, PCFiber fiber )
262 {
263  m_fibers->emplace( m_fibers->begin() + position, fiber );
264  m_hidden->emplace( m_hidden->begin() + position, hidden );
265 
266  m_possibleFiberSelections->addItem( ItemType::create( name, name, "", NULL ) );
267  m_possibleFiberSelections->stableSort( &sortComparator );
268 
269  m_fiberSelection->set( m_possibleFiberSelections->getSelectorLast() );
270 
271  if( !fiber.empty() )
272  {
274  }
275 
276  if( !silent )
277  {
278  m_actionHandler->pushAction( WFiberActionAddFiber::SPtr( new WFiberActionAddFiber( name, position, this ) ) );
279  }
280 }
281 
282 void WFiberHandler::removeFiber( size_t idx, bool silent, bool updateSelector )
283 {
284  if( idx == 0 )
285  {
286  return;
287  }
288 
289  std::string name = m_possibleFiberSelections->at( idx )->getName();
290  PCFiber fiber = m_fibers->at( idx );
291 
292  bool hidden = m_hidden->at( idx );
293 
294  m_fibers->erase( m_fibers->begin() + idx );
295  m_hidden->erase( m_hidden->begin() + idx );
296 
298 
299  if( updateSelector )
300  {
301  selectorUpdate( m_fibers->size() - 1 );
302  }
303 
305 
306  if( !silent )
307  {
308  m_actionHandler->pushAction( WFiberActionRemoveFiber::SPtr( new WFiberActionRemoveFiber( name, idx, fiber, hidden, this ) ) );
309  }
310 }
311 
312 void WFiberHandler::toggleFiber( size_t idx, bool silent )
313 {
315  std::string name = selection->getName();
316  if( isHidden( idx ) )
317  {
318  name = name.substr( 0, name.size() - 2 );
319  }
320  else
321  {
322  name = name + " *";
323  }
324  m_hidden->at( idx ) = !( m_hidden->at( idx ) );
325 
326  m_possibleFiberSelections->replace( selection, ItemType::create( name, name, "", NULL ) );
327  m_fiberSelection->set( m_possibleFiberSelections->getSelector( idx ) );
328 
330 
331  if( !silent )
332  {
333  m_actionHandler->pushAction( WFiberActionToggle::SPtr( new WFiberActionToggle( idx , this ) ) );
334  }
335 }
336 
337 bool WFiberHandler::isHidden( size_t idx )
338 {
339  return m_hidden->at( idx );
340 }
341 
342 void WFiberHandler::selectFiber( size_t idx )
343 {
344  m_selectedFiber = idx;
345  m_pointConnector->getConnectorData()->deselectPoint();
346 
347  selectLastPoint();
348 
350 }
351 
352 bool WFiberHandler::getFiberOfPoint( osg::Vec3 vertex, size_t* idx )
353 {
354  for( size_t fiberIdx = 0; fiberIdx < m_fibers->size(); fiberIdx++ )
355  {
356  PCFiber fiber = m_fibers->at( fiberIdx );
357  if( std::find( fiber.begin(), fiber.end(), vertex ) != fiber.end() )
358  {
359  if( idx != NULL )
360  {
361  *idx = fiberIdx;
362  }
363  return true;
364  }
365  }
366  return false;
367 }
368 
369 bool WFiberHandler::isPointHidden( osg::Vec3 vertex )
370 {
371  size_t idx = 0;
372  return getFiberOfPoint( vertex, &idx ) && isHidden( idx );
373 }
374 
376 {
377  if( property == m_addFiber && m_addFiber->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
378  {
380  createNewFiber();
381  }
382  else if( property == m_removeFiber && m_removeFiber->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
383  {
385  removeFiber( m_fiberSelection->get().getItemIndexOfSelected( 0 ) );
386  }
387  else if( property == m_toggleFiber && m_toggleFiber->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
388  {
390  toggleFiber( m_fiberSelection->get().getItemIndexOfSelected( 0 ) );
391  }
392  else if( property == m_undoTrigger && m_undoTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
393  {
395  m_actionHandler->undo();
396  }
397  else if( property == m_redoTrigger && m_redoTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
398  {
400  m_actionHandler->redo();
401  }
402  else if( property == m_fiberSelection )
403  {
404  selectFiber( m_fiberSelection->get().getItemIndexOfSelected( 0 ) );
405  }
406  else if( property == m_selectionType )
407  {
408  m_pointConnector->getOnscreenSelection()->setSelectionType(
409  static_cast< WOnscreenSelection::WSelectionType >( m_selectionType->get().getItemIndexOfSelected( 0 ) ) );
410  }
411 }
412 
414 {
415  return m_fibers;
416 }
417 
418 
420 {
421  return m_pointConnector;
422 }
423 
425 {
426  return m_selectedFiber;
427 }
428 
430 {
431  return m_actionHandler;
432 }
433 
434 void WFiberHandler::setFiberCount( size_t fiberCount )
435 {
436  this->m_fiberCount = fiberCount;
437 }
438 
440 {
441  std::string name = "Track " + boost::lexical_cast< std::string >( m_fiberCount );
442  m_fiberCount++;
443  addFiber( name );
444 }
Handles undo and redo action.
std::shared_ptr< WActionHandler > SPtr
A shared_ptr to this class.
The action when adding a fiber.
std::shared_ptr< WFiberActionAddFiber > SPtr
A shared_ptr to this class.
The action when adding a Vertex.
std::shared_ptr< WFiberActionAddVertex > SPtr
A shared_ptr to this class.
The action when adding multiple Vertices.
std::shared_ptr< WFiberActionMultideselect > SPtr
A shared_ptr to this class.
The action when adding multiple Vertices.
std::shared_ptr< WFiberActionMultiselect > SPtr
A shared_ptr to this class.
The action when removing a fiber.
std::shared_ptr< WFiberActionRemoveFiber > SPtr
A shared_ptr to this class.
The action when removing a Vertex.
std::shared_ptr< WFiberActionRemoveVertex > SPtr
A shared_ptr to this class.
The action when toggling a fiber.
std::shared_ptr< WFiberActionToggle > SPtr
A shared_ptr to this class.
void addVertexToFiber(osg::Vec3 vertex, size_t fiberIdx, bool silent=false)
Adds a vertex to the currently selected fiber.
void removeVerticesFromFiber(std::vector< osg::Vec3 > vertices, size_t fiberIdx, bool silent=false)
Removes multiple vertices from the currently selected fiber.
void selectLastPoint()
Selects the last point of the currently selected fiber.
WPropTrigger m_undoTrigger
Property (button) to undo the last action.
WActionHandler::SPtr getActionHandler()
void setFiberCount(size_t fiberCount)
Sets the fiber count.
void updateProperty(WPropertyBase::SPtr property)
Update handler for the properties.
WPropTrigger m_addFiber
Property (button) to add a new fiber.
void toggleFiber(size_t idx, bool silent=false)
Toggles the visibility of a fiber.
std::vector< osg::Vec3 > PCFiber
Vector of 3D vectors, representing points.
Definition: WFiberHandler.h:63
void addVertexToFiberAt(osg::Vec3 vertex, size_t fiberIdx, size_t position, bool silent=false)
Adds a vertex to the currently selected fiber.
PCFiberListSPtr getFibers()
void addFiber(std::string name, bool silent=false, bool updateSelector=true)
Adds a new fiber.
WActionHandler::SPtr m_actionHandler
Handles the undo and redo action.
void selectorUpdate(size_t idx)
Updates the UI selector.
bool isHidden(size_t idx)
Checks if a fiber is hidden.
WPropTrigger m_removeFiber
Property (button) to remove a fiber.
bool getFiberOfPoint(osg::Vec3 vertex, size_t *idx=NULL)
Gets the index of the fiber of a point.
void removeVertexFromFiber(osg::Vec3 vertex, size_t fiberIdx, bool silent=false)
Removes a vertex from the currently selected fiber.
size_t getSelectedFiber()
WPropTrigger m_redoTrigger
Property (button) to redo the last action.
void createNewFiber()
Creates a new fiber.
WMPointConnector * m_pointConnector
A reference to the WMPointConnector this belongs to.
std::vector< PCFiber > PCFiberList
Vector, that could contain multiple fibers.
Definition: WFiberHandler.h:68
void addVerticesToFiber(std::vector< osg::Vec3 > vertices, size_t fiberIdx, bool silent=false)
Adds multiple vertices to the currently selected fiber.
std::shared_ptr< PCFiberList > PCFiberListSPtr
Shared pointer to fibers-vector.
Definition: WFiberHandler.h:73
WPropSelection m_selectionType
The type of the selection.
std::shared_ptr< std::vector< char > > m_hidden
Vector for the visibility of the fibers.
void sortVertices()
Sorts the vertices by their z value.
bool isPointHidden(osg::Vec3 vertex)
Checks whether a point is in a hidden fiber.
int m_fiberCount
Stores the amount of new created fibers.
void selectFiber(size_t idx)
Selects a fiber by its index in the fibers vector.
void removeFiber(size_t idx, bool silent=false, bool updateSelector=true)
Removes a fiber at an index in the fibers vector.
WFiberHandler(WMPointConnector *pointConnector)
Creates the list of fibers.
size_t m_selectedFiber
Represents the index of the current active fiber.
PCFiberListSPtr m_fibers
A pointer to the list of fibers.
std::shared_ptr< WItemSelection > m_possibleFiberSelections
The list of possible fibers, which can be selected.
WPropSelection m_fiberSelection
Represents the current active fiber selection property.
WPropTrigger m_toggleFiber
Property (button) to toggle the visibility of a fiber.
void createProperties(WPropertyGroup::SPtr properties)
Creates the properties for this handler.
void addFiberAt(std::string name, size_t position, bool hidden, bool silent=false, PCFiber fiber=PCFiber())
Adds a new or an old fiber at a specific position.
void clear()
Clears the data in this handler.
WMPointConnector * getPointConnector()
static SPtr create(T value, std::string name, std::string description="", const char **icon=NULL)
Create a instance of the item.
std::shared_ptr< WItemSelectionItem > SPtr
Abbreviation for a shared pointer.
A class containing a list of named items.
std::shared_ptr< WItemSelection > SPtr
Convenience typedef for a std::shared_ptr< WItemSelection >
This module connects the points in a point dataset.
void updateAll()
Updates all.
std::shared_ptr< WOnscreenSelection > getOnscreenSelection()
std::shared_ptr< WConnectorData > getConnectorData()
void updateOutput()
Updates the fiber output.
WSelectionType
The different types of selection.
boost::function< void(std::shared_ptr< WPropertyBase >)> PropertyChangeNotifierType
Signal signature emitted during set operations.
std::shared_ptr< WPropertyBase > SPtr
Convenience typedef for a std::shared_ptr< WPropertyBase >
Definition: WPropertyBase.h:53
std::shared_ptr< WPropertyGroup > SPtr
shared pointer to object of this type
@ PV_TRIGGER_TRIGGERED
Trigger property: got triggered.
@ PV_TRIGGER_READY
Trigger property: is ready to be triggered (again)
void addTo(WPropSelection prop)
Add the PC_NOTEMPTY constraint to the property.
void addTo(WPropSelection prop)
Add the PC_SELECTONLYONE constraint to the property.