WMVectorAlign.cpp 4.77 KB
Newer Older
1 2 3 4
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
5
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
// 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>
#include <vector>

#include "core/dataHandler/WDataSetVector.h"
#include "core/kernel/WKernel.h"
30
#include "WMVectorAlign.h"
31
#include "WMVectorAlign.xpm"
32 33

// This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
34
W_LOADABLE_MODULE( WMVectorAlign )
35

36
WMVectorAlign::WMVectorAlign():
37 38 39 40
    WModule()
{
}

41
WMVectorAlign::~WMVectorAlign()
42 43 44
{
}

45
boost::shared_ptr< WModule > WMVectorAlign::factory() const
46
{
47
    return boost::shared_ptr< WModule >( new WMVectorAlign() );
48 49
}

50
const char** WMVectorAlign::getXPMIcon() const
51
{
52
    return WMVectorAlign_xpm; // Please put a real icon here.
53 54
}

55
const std::string WMVectorAlign::getName() const
56
{
57
    return "Vector Align";
58 59
}

60
const std::string WMVectorAlign::getDescription() const
61
{
62
    return "Aligns vectors of each grid cell, so they are aligned in same halfspace.";
63 64
}

65
void WMVectorAlign::connectors()
66 67 68 69 70 71 72 73
{
    m_vectorIC = WModuleInputData< WDataSetVector >::createAndAdd( shared_from_this(), "vectors", "Some vector dataset." );
    m_vectorOC = WModuleOutputData< WDataSetVector >::createAndAdd( shared_from_this(), "alignedVectors",
            "Dataset where vectors are aligned inside the halfspace" );

    WModule::connectors();
}

74
void WMVectorAlign::properties()
75 76 77 78
{
    WModule::properties();
}

79
void WMVectorAlign::requirements()
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
{
}

namespace
{
    boost::shared_ptr< WDataSetVector > alignVectors( boost::shared_ptr< WDataSetVector > vectors )
    {
        size_t numVecs = vectors->getValueSet()->size();
        std::vector< WVector3d > newData;
        newData.reserve( numVecs );
        for( size_t i = 0; i < numVecs; ++i  )
        {
            newData.push_back( vectors->getVectorAt( i ) );
        }

95
        boost::shared_ptr< WGridRegular3D > grid = boost::dynamic_pointer_cast< WGridRegular3D >( vectors->getGrid() );
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
        if( !grid )
        {
            return vectors;
        }

        boost::shared_ptr< std::vector< double > > data( new std::vector< double > );

        for( size_t i = 0; i < numVecs; ++i  )
        {
            std::vector< size_t > neighbours = grid->getNeighbours( i );
            for( size_t j = 0; j < neighbours.size(); ++j )
            {
                double sign = 1.0;
                if( neighbours[j] > i ) // just to speed up and ensure that once vectors written to data will never be changed afterwards
                {
                    if( dot( newData[i], newData[ neighbours[j] ] ) < 0.0 )
                    {
                        sign = -1.0;
                    }
                    newData[ neighbours[ j ] ] *= sign;
                }
            }
            // newData[i] will never change from now on anymore
            data->push_back( newData[i][0] );
            data->push_back( newData[i][1] );
            data->push_back( newData[i][2] );
        }
        boost::shared_ptr< WValueSet< double > > values( new WValueSet< double >( 1, 3, data, W_DT_DOUBLE ) );
        return boost::shared_ptr< WDataSetVector >( new WDataSetVector( values, grid ) );
    }
}

128
void WMVectorAlign::moduleMain()
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
{
    // get notified about data changes
    m_moduleState.setResetable( true, true );
    m_moduleState.add( m_vectorIC->getDataChangedCondition() );

    ready();

    // main loop
    while( !m_shutdownFlag() )
    {
        infoLog() << "Waiting ...";
        m_moduleState.wait();

        // woke up since the module is requested to finish?
        if( m_shutdownFlag() )
        {
            break;
        }

        // save data behind connectors since it might change during processing
        boost::shared_ptr< WDataSetVector > vectors = m_vectorIC->getData();

        if( !vectors ) // if data valid
        {
            continue;
        }

        m_vectorOC->updateData( alignVectors( vectors ) );
    }
}