WFiberHandler.cpp 10.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

#include <string>
Robin Eschbach's avatar
Robin Eschbach committed
26
#include <vector>
27

Robin Eschbach's avatar
Robin Eschbach committed
28
#include "action/WFiberActionAddFiber.h"
29
#include "action/WFiberActionAddVertex.h"
30
#include "action/WFiberActionRemoveVertex.h"
Robin Eschbach's avatar
Robin Eschbach committed
31
#include "action/WFiberActionRemoveFiber.h"
Robin Eschbach's avatar
Robin Eschbach committed
32
#include "action/WFiberActionToggle.h"
33 34
#include "core/common/WPathHelper.h"

35
#include "WConnectorData.h"
36 37
#include "WFiberHandler.h"

38

39 40 41
WFiberHandler::WFiberHandler( WMPointConnector* pointConnector )
{
    m_pointConnector = pointConnector;
42
    m_actionHandler = WActionHandler::SPtr( new WActionHandler() );
43
    m_fibers = PCFiberListSPtr( new PCFiberList() );
44
    m_hidden = boost::shared_ptr< std::vector< char > >( new std::vector< char >() );
45 46 47 48 49

    m_selectedFiber = 0;
    m_fiberCount = 1;
}

Robin Eschbach's avatar
Robin Eschbach committed
50
void WFiberHandler::addVertexToFiber( osg::Vec3 vertex, size_t fiberIdx, bool silent )
51
{
Robin Eschbach's avatar
Robin Eschbach committed
52
    m_fibers->at( fiberIdx ).push_back( vertex );
53 54 55

    if( !silent )
    {
Robin Eschbach's avatar
Robin Eschbach committed
56
        m_actionHandler->pushAction( WFiberActionAddVertex::SPtr( new WFiberActionAddVertex( vertex, fiberIdx, this ) ) );
57
    }
58 59
}

Robin Eschbach's avatar
Robin Eschbach committed
60
void WFiberHandler::addVertexToFiberAt( osg::Vec3 vertex, size_t fiberIdx, size_t position, bool silent )
61
{
Robin Eschbach's avatar
Robin Eschbach committed
62
    auto fiber = m_fibers->begin() + fiberIdx;
63
    fiber->emplace( fiber->begin() + position, vertex );
64

65 66
    if( !silent )
    {
Robin Eschbach's avatar
Robin Eschbach committed
67
        m_actionHandler->pushAction( WFiberActionAddVertex::SPtr( new WFiberActionAddVertex( vertex, fiberIdx, this ) ) );
68 69 70
    }
}

Robin Eschbach's avatar
Robin Eschbach committed
71
void WFiberHandler::removeVertexFromFiber( osg::Vec3 vertex, size_t fiberIdx, bool silent )
72
{
Robin Eschbach's avatar
Robin Eschbach committed
73
    auto fiber = m_fibers->begin() + fiberIdx;
74 75 76
    size_t position = 0;

    for( auto it = fiber->begin(); it != fiber->end(); it++)
77 78 79 80
    {
        if( *it == vertex )
        {
            fiber->erase( it );
81
            break;
82
        }
83 84 85 86 87
        position++;
    }

    if( !silent )
    {
Robin Eschbach's avatar
Robin Eschbach committed
88
        m_actionHandler->pushAction( WFiberActionRemoveVertex::SPtr( new WFiberActionRemoveVertex( vertex, fiberIdx, position, this ) ) );
89 90 91
    }
}

92 93 94 95 96 97 98 99
void WFiberHandler::clear()
{
    m_fibers->clear();
    m_hidden->clear();
    m_possibleFiberSelections->clear();

    m_fiberCount = 1;
    m_selectedFiber = 0;
100
    addFiber( "Track 0", true );
101 102
}

103 104 105 106 107 108 109 110 111 112 113 114 115
void WFiberHandler::selectLastPoint()
{
    PCFiber fiber = m_fibers->at( m_selectedFiber );
    if( !fiber.empty() )
    {
        m_pointConnector->getConnectorData()->selectPoint( fiber.back() );
    }
}

void WFiberHandler::createProperties( WPropertyGroup::SPtr properties )
{
    WPropertyBase::PropertyChangeNotifierType notifier = boost::bind( &WFiberHandler::updateProperty, this, boost::placeholders::_1 );

116 117 118
    WPropertyGroup::SPtr fiberGroup = properties->addPropertyGroup( "Fibers", "Property group for fiber selection, adding and deleting." );
    WPropertyGroup::SPtr undoGroup = properties->addPropertyGroup( "Undo | Redo", "Property group for undo and redo." );

Robin Eschbach's avatar
Robin Eschbach committed
119
    m_possibleFiberSelections = WItemSelection::SPtr( new WItemSelection() );
120
    m_fiberSelection = fiberGroup->addProperty(
121 122 123
        "Selected track", "The track to which the points are added", m_possibleFiberSelections->getSelectorNone(), notifier );

    addFiber( "Track 0", true );
124 125 126 127

    WPropertyHelper::PC_SELECTONLYONE::addTo( m_fiberSelection );
    WPropertyHelper::PC_NOTEMPTY::addTo( m_fiberSelection );

128 129
    m_addFiber = fiberGroup->addProperty( "Add track", "Add Track", WPVBaseTypes::PV_TRIGGER_READY, notifier );
    m_removeFiber = fiberGroup->addProperty( "Remove track", "Remove Track", WPVBaseTypes::PV_TRIGGER_READY, notifier );
130
    m_toggleFiber = fiberGroup->addProperty( "Toggle track", "Toggle Track", WPVBaseTypes::PV_TRIGGER_READY, notifier );
131

132 133
    m_undoTrigger = undoGroup->addProperty( "Undo", "Undo Changes", WPVBaseTypes::PV_TRIGGER_READY, notifier );
    m_redoTrigger = undoGroup->addProperty( "Redo", "Redo Changes", WPVBaseTypes::PV_TRIGGER_READY, notifier );
134 135
}

Robin Eschbach's avatar
Robin Eschbach committed
136
static bool sortComparator( boost::shared_ptr< WItemSelectionItem > a, boost::shared_ptr< WItemSelectionItem > b )
137
{
Robin Eschbach's avatar
Robin Eschbach committed
138 139 140
    return a->getName().compare( b->getName() ) < 0;
}

141
void WFiberHandler::addFiber( std::string name, bool silent, bool updateSelector )
Robin Eschbach's avatar
Robin Eschbach committed
142 143
{
    m_fibers->push_back( PCFiber() );
Robin Eschbach's avatar
Robin Eschbach committed
144 145
    m_hidden->push_back( false );

Robin Eschbach's avatar
Robin Eschbach committed
146
    m_possibleFiberSelections->addItem( ItemType::create( name, name, "", NULL ) );
147 148 149

    if( updateSelector )
    {
150
        selectorUpdate( m_fibers->size() - 1 );
151
    }
Robin Eschbach's avatar
Robin Eschbach committed
152 153

    if( !silent )
154
    {
Robin Eschbach's avatar
Robin Eschbach committed
155 156 157
        m_actionHandler->pushAction( WFiberActionAddFiber::SPtr( new WFiberActionAddFiber( name, m_fibers->size() - 1, this ) ) );
    }
}
158

159
void WFiberHandler::selectorUpdate( size_t idx )
160
{
161
    m_fiberSelection->set( m_possibleFiberSelections->getSelector( idx ) );
162 163
}

Robin Eschbach's avatar
Robin Eschbach committed
164
void WFiberHandler::addFiberAt( std::string name, size_t position, bool hidden, bool silent, PCFiber fiber )
Robin Eschbach's avatar
Robin Eschbach committed
165 166
{
    m_fibers->emplace( m_fibers->begin() + position, fiber );
Robin Eschbach's avatar
Robin Eschbach committed
167
    m_hidden->emplace( m_hidden->begin() + position, hidden );
Robin Eschbach's avatar
Robin Eschbach committed
168 169 170

    m_possibleFiberSelections->addItem( ItemType::create( name, name, "", NULL ) );
    m_possibleFiberSelections->stableSort( &sortComparator );
171

Robin Eschbach's avatar
Robin Eschbach committed
172 173 174 175 176
    m_fiberSelection->set( m_possibleFiberSelections->getSelectorLast() );

    if( !fiber.empty() )
    {
        m_pointConnector->updateOutput();
177
    }
Robin Eschbach's avatar
Robin Eschbach committed
178 179

    if( !silent )
180
    {
Robin Eschbach's avatar
Robin Eschbach committed
181 182 183 184 185 186 187 188 189 190 191 192 193
        m_actionHandler->pushAction( WFiberActionAddFiber::SPtr( new WFiberActionAddFiber( name, position, this ) ) );
    }
}

void WFiberHandler::removeFiber( size_t idx, bool silent )
{
    if( idx == 0 )
    {
        return;
    }

    std::string name = m_possibleFiberSelections->at( idx )->getName();
    PCFiber fiber = m_fibers->at( idx );
194

Robin Eschbach's avatar
Robin Eschbach committed
195 196
    bool hidden = m_hidden->at( idx );

Robin Eschbach's avatar
Robin Eschbach committed
197
    m_fibers->erase( m_fibers->begin() + idx );
Robin Eschbach's avatar
Robin Eschbach committed
198
    m_hidden->erase( m_hidden->begin() + idx );
199

Robin Eschbach's avatar
Robin Eschbach committed
200 201 202 203 204 205 206
    m_possibleFiberSelections->remove( m_possibleFiberSelections->at( idx ) );
    m_fiberSelection->set( m_possibleFiberSelections->getSelectorLast() );

    m_pointConnector->updateOutput();

    if( !silent )
    {
Robin Eschbach's avatar
Robin Eschbach committed
207
        m_actionHandler->pushAction( WFiberActionRemoveFiber::SPtr( new WFiberActionRemoveFiber( name, idx, fiber, hidden, this ) ) );
Robin Eschbach's avatar
Robin Eschbach committed
208 209 210
    }
}

211 212 213 214 215 216 217 218 219 220 221 222
void WFiberHandler::toggleFiber( size_t idx, bool silent )
{
    WItemSelectionItem::SPtr selection = m_possibleFiberSelections->at( idx );
    std::string name = selection->getName();
    if( isHidden( idx ) )
    {
        name = name.substr( 0, name.size() - 2 );
    }
    else
    {
        name = name + " *";
    }
Robin Eschbach's avatar
Robin Eschbach committed
223
    m_hidden->at( idx ) = !( m_hidden->at( idx ) );
224 225 226 227 228 229

    m_possibleFiberSelections->replace( selection, ItemType::create( name, name, "", NULL ) );
    m_fiberSelection->set( m_possibleFiberSelections->getSelector( idx ) );

    m_pointConnector->updatePoints();
    m_pointConnector->updateOutput();
Robin Eschbach's avatar
Robin Eschbach committed
230 231 232 233

    if( !silent )
    {
        m_actionHandler->pushAction( WFiberActionToggle::SPtr( new WFiberActionToggle( idx , this ) ) );
Robin Eschbach's avatar
Robin Eschbach committed
234 235 236
    }
}

237 238
bool WFiberHandler::isHidden( size_t idx )
{
Robin Eschbach's avatar
Robin Eschbach committed
239
    return m_hidden->at( idx );
240 241
}

Robin Eschbach's avatar
Robin Eschbach committed
242 243 244 245 246 247 248 249
void WFiberHandler::selectFiber( size_t idx )
{
    m_selectedFiber = idx;
    m_pointConnector->getConnectorData()->deselectPoint();

    selectLastPoint();

    m_pointConnector->updatePoints();
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
    m_pointConnector->updateOutput();
}

bool WFiberHandler::getFiberOfPoint( osg::Vec3 vertex, size_t* idx )
{
    for( size_t fiberIdx = 0; fiberIdx < m_fibers->size(); fiberIdx++ )
    {
        PCFiber fiber = m_fibers->at( fiberIdx );
        if( std::find( fiber.begin(), fiber.end(), vertex ) != fiber.end() )
        {
            if(idx != NULL)
            {
                *idx = fiberIdx;
            }
            return true;
        }
    }
    return false;
}

bool WFiberHandler::isPointHidden( osg::Vec3 vertex )
{
    size_t idx = 0;
    return getFiberOfPoint( vertex, &idx ) && isHidden( idx );
Robin Eschbach's avatar
Robin Eschbach committed
274 275 276 277 278 279 280 281
}

void WFiberHandler::updateProperty( WPropertyBase::SPtr property )
{
    if( property == m_addFiber && m_addFiber->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
    {
        m_addFiber->set( WPVBaseTypes::PV_TRIGGER_READY, false );

282
        std::string name = "Track " + boost::lexical_cast< std::string >( m_fiberCount );
Robin Eschbach's avatar
Robin Eschbach committed
283 284 285 286 287 288 289
        m_fiberCount++;
        addFiber( name );
    }
    else if( property == m_removeFiber && m_removeFiber->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
    {
        m_removeFiber->set( WPVBaseTypes::PV_TRIGGER_READY, false );
        removeFiber( m_fiberSelection->get().getItemIndexOfSelected( 0 ) );
290
    }
291 292 293 294 295
    else if( property == m_toggleFiber && m_toggleFiber->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
    {
        m_toggleFiber->set( WPVBaseTypes::PV_TRIGGER_READY, false );
        toggleFiber( m_fiberSelection->get().getItemIndexOfSelected( 0 ) );
    }
Robin Eschbach's avatar
Robin Eschbach committed
296
    else if( property == m_undoTrigger && m_undoTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
297 298 299 300
    {
        m_undoTrigger->set( WPVBaseTypes::PV_TRIGGER_READY, false );
        m_actionHandler->undo();
    }
Robin Eschbach's avatar
Robin Eschbach committed
301
    else if( property == m_redoTrigger && m_redoTrigger->get( true ) == WPVBaseTypes::PV_TRIGGER_TRIGGERED )
302 303 304 305
    {
        m_redoTrigger->set( WPVBaseTypes::PV_TRIGGER_READY, false );
        m_actionHandler->redo();
    }
Robin Eschbach's avatar
Robin Eschbach committed
306 307 308 309
    else if( property == m_fiberSelection )
    {
        selectFiber( m_fiberSelection->get().getItemIndexOfSelected( 0 ) );
    }
310 311 312 313 314 315
}

WFiberHandler::PCFiberListSPtr WFiberHandler::getFibers()
{
    return m_fibers;
}
316 317 318 319 320 321


WMPointConnector* WFiberHandler::getPointConnector()
{
    return m_pointConnector;
}
Robin Eschbach's avatar
Robin Eschbach committed
322 323 324 325 326

size_t WFiberHandler::getSelectedFiber()
{
    return m_selectedFiber;
}
Robin Eschbach's avatar
Robin Eschbach committed
327 328 329 330 331

WActionHandler::SPtr WFiberHandler::getActionHandler()
{
    return m_actionHandler;
}
332 333 334 335

void WFiberHandler::setFiberCount( size_t fiberCount )
{
    this->m_fiberCount = fiberCount;
Robin Eschbach's avatar
Robin Eschbach committed
336
}