WROIBox.cpp 11.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>
26
#include <utility>
27 28 29 30 31

#include <osg/LineWidth>
#include <osg/LightModel>

#include "WROIBox.h"
32
#include "WGraphicsEngine.h"
33
#include "WGEUtils.h"
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

size_t WROIBox::maxBoxId = 0;

void buildFacesFromPoints( osg::DrawElementsUInt* surfaceElements )
{
    surfaceElements->push_back( 0 );
    surfaceElements->push_back( 2 );
    surfaceElements->push_back( 3 );
    surfaceElements->push_back( 1 );

    surfaceElements->push_back( 2 );
    surfaceElements->push_back( 6 );
    surfaceElements->push_back( 7 );
    surfaceElements->push_back( 3 );

    surfaceElements->push_back( 6 );
    surfaceElements->push_back( 4 );
    surfaceElements->push_back( 5 );
    surfaceElements->push_back( 7 );

    surfaceElements->push_back( 4 );
    surfaceElements->push_back( 0 );
    surfaceElements->push_back( 1 );
    surfaceElements->push_back( 5 );

    surfaceElements->push_back( 1 );
    surfaceElements->push_back( 3 );
    surfaceElements->push_back( 7 );
    surfaceElements->push_back( 5 );

    surfaceElements->push_back( 0 );
    surfaceElements->push_back( 4 );
    surfaceElements->push_back( 6 );
    surfaceElements->push_back( 2 );
}

void buildLinesFromPoints( osg::DrawElementsUInt* surfaceElements )
{
    surfaceElements->push_back( 0 );
    surfaceElements->push_back( 2 );
    surfaceElements->push_back( 2 );
    surfaceElements->push_back( 3 );
    surfaceElements->push_back( 3 );
    surfaceElements->push_back( 1 );
    surfaceElements->push_back( 1 );
    surfaceElements->push_back( 0 );

    surfaceElements->push_back( 6 );
    surfaceElements->push_back( 4 );
    surfaceElements->push_back( 4 );
    surfaceElements->push_back( 5 );
    surfaceElements->push_back( 5 );
    surfaceElements->push_back( 7 );
    surfaceElements->push_back( 7 );
    surfaceElements->push_back( 6 );

    surfaceElements->push_back( 2 );
    surfaceElements->push_back( 6 );
    surfaceElements->push_back( 7 );
    surfaceElements->push_back( 3 );

    surfaceElements->push_back( 4 );
    surfaceElements->push_back( 0 );
    surfaceElements->push_back( 1 );
    surfaceElements->push_back( 5 );
}

101
void setVertices( osg::Vec3Array* vertices, WPosition_2 minPos, WPosition_2 maxPos )
102 103 104 105 106 107 108 109 110 111 112
{
    vertices->push_back( osg::Vec3( minPos[0], minPos[1], minPos[2] ) );
    vertices->push_back( osg::Vec3( minPos[0], minPos[1], maxPos[2] ) );
    vertices->push_back( osg::Vec3( minPos[0], maxPos[1], minPos[2] ) );
    vertices->push_back( osg::Vec3( minPos[0], maxPos[1], maxPos[2] ) );
    vertices->push_back( osg::Vec3( maxPos[0], minPos[1], minPos[2] ) );
    vertices->push_back( osg::Vec3( maxPos[0], minPos[1], maxPos[2] ) );
    vertices->push_back( osg::Vec3( maxPos[0], maxPos[1], minPos[2] ) );
    vertices->push_back( osg::Vec3( maxPos[0], maxPos[1], maxPos[2] ) );
}

113
WROIBox::WROIBox( WPosition_2 minPos, WPosition_2 maxPos ) :
114 115
    WROI(),
    boxId( maxBoxId++ ),
116
    m_pickNormal( WVector3d_2() ),
117
    m_oldPixelPosition( WVector2d_2::zero() ),
118 119
    m_color( osg::Vec4( 0.f, 1.f, 1.f, 0.4f ) ),
    m_notColor( osg::Vec4( 1.0f, 0.0f, 0.0f, 0.4f ) )
120 121 122 123
{
    m_minPos = minPos;
    m_maxPos = maxPos;

124 125 126
    boost::shared_ptr< WGraphicsEngine > ge = WGraphicsEngine::getGraphicsEngine();
    assert( ge );
    boost::shared_ptr< WGEViewer > viewer = ge->getViewerByName( "main" );
127
    assert( viewer );
128 129
    m_viewer = viewer;
    m_pickHandler = m_viewer->getPickHandler();
130
    m_pickHandler->getPickSignal()->connect( boost::bind( &WROIBox::registerRedrawRequest, this, _1 ) );
131

132 133
    m_surfaceGeometry = osg::ref_ptr<osg::Geometry>( new osg::Geometry() );
    m_surfaceGeometry->setDataVariance( osg::Object::DYNAMIC );
134

schurade's avatar
schurade committed
135
    //m_geode = osg::ref_ptr<osg::Geode>( new osg::Geode );
136
    std::stringstream ss;
schurade's avatar
[STYLE]  
schurade committed
137
    ss << "ROIBox" << boxId;
138

schurade's avatar
schurade committed
139
    setName( ss.str() );
140
    m_surfaceGeometry->setName( ss.str() );
141

142
    osg::ref_ptr<osg::Vec3Array> vertices = osg::ref_ptr<osg::Vec3Array>( new osg::Vec3Array );
143
    setVertices( vertices, minPos, maxPos );
144
    m_surfaceGeometry->setVertexArray( vertices );
145 146 147 148 149 150 151 152 153

    osg::DrawElementsUInt* surfaceElements;
    surfaceElements = new osg::DrawElementsUInt( osg::PrimitiveSet::QUADS, 0 );
    buildFacesFromPoints( surfaceElements );

    osg::DrawElementsUInt* lineElements;
    lineElements = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
    buildLinesFromPoints( lineElements );

154 155
    m_surfaceGeometry->addPrimitiveSet( surfaceElements );
    m_surfaceGeometry->addPrimitiveSet( lineElements );
schurade's avatar
schurade committed
156 157
    addDrawable( m_surfaceGeometry );
    osg::StateSet* state = getOrCreateStateSet();
158 159 160 161 162 163 164 165
    state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );

    osg::LineWidth* linewidth = new osg::LineWidth();
    linewidth->setWidth( 2.f );
    state->setAttributeAndModes( linewidth, osg::StateAttribute::ON );

    // ------------------------------------------------
    // colors
166
    osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
167

168
    colors->push_back( osg::Vec4( 0.0f, 0.0f, 1.0f, 0.5f ) );
169 170
    m_surfaceGeometry->setColorArray( colors );
    m_surfaceGeometry->setColorBinding( osg::Geometry::BIND_OVERALL );
171

schurade's avatar
[STYLE]  
schurade committed
172
    osg::ref_ptr< osg::LightModel > lightModel = new osg::LightModel();
173 174
    lightModel->setTwoSided( true );
    state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON );
schurade's avatar
[STYLE]  
schurade committed
175
    state->setMode( GL_BLEND, osg::StateAttribute::ON );
176

177
    m_not->set( false );
schurade's avatar
schurade committed
178

179
    assert( WGraphicsEngine::getGraphicsEngine() );
schurade's avatar
schurade committed
180
    WGraphicsEngine::getGraphicsEngine()->getScene()->addChild( this );
181

schurade's avatar
schurade committed
182 183
    setUserData( this );
    setUpdateCallback( osg::ref_ptr<ROIBoxNodeCallback>( new ROIBoxNodeCallback ) );
schurade's avatar
[STYLE]  
schurade committed
184 185

    setDirty();
schurade's avatar
schurade committed
186 187 188 189 190 191 192 193
}

WROIBox::~WROIBox()
{
//    std::cout << "destructor called" << std::endl;
//    std::cout << "ref count geode: " << m_geode->referenceCount() << std::endl;
//
//    WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_geode );
194 195
}

196
WPosition_2 WROIBox::getMinPos() const
197 198 199 200
{
    return m_minPos;
}

201
WPosition_2 WROIBox::getMaxPos() const
202 203 204 205
{
    return m_maxPos;
}

206
void WROIBox::registerRedrawRequest( WPickInfo pickInfo )
207 208 209 210
{
    boost::unique_lock< boost::shared_mutex > lock;
    lock = boost::unique_lock< boost::shared_mutex >( m_updateLock );

211
    m_pickInfo = pickInfo;
212 213 214 215 216

    lock.unlock();
}

void WROIBox::updateGFX()
217
{
218 219
    boost::unique_lock< boost::shared_mutex > lock;
    lock = boost::unique_lock< boost::shared_mutex >( m_updateLock );
220 221

    std::stringstream ss;
222 223
    ss << "ROIBox" << boxId << "";
    if ( m_pickInfo.getName() == ss.str() )
224
    {
225
        WVector2d_2 newPixelPos( m_pickInfo.getPickPixel() );
schurade's avatar
[STYLE]  
schurade committed
226
        if ( m_isPicked )
227
        {
228
            osg::Vec3 in( newPixelPos.x(), newPixelPos.y(), 0.0 );
229
            osg::Vec3 world = wge::unprojectFromScreen( in, m_viewer->getCamera() );
230

231 232
            WPosition_2 newPixelWorldPos( world[0], world[1], world[2] );
            WPosition_2 oldPixelWorldPos;
233
            if(  m_oldPixelPosition.x() == 0 && m_oldPixelPosition.y() == 0 )
234 235 236 237 238
            {
                oldPixelWorldPos = newPixelWorldPos;
            }
            else
            {
239
                osg::Vec3 in( m_oldPixelPosition.x(), m_oldPixelPosition.y(), 0.0 );
240
                osg::Vec3 world = wge::unprojectFromScreen( in, m_viewer->getCamera() );
241
                oldPixelWorldPos = WPosition_2( world[0], world[1], world[2] );
242 243
            }

244
            WVector3d_2 moveVec = newPixelWorldPos - oldPixelWorldPos;
245

246
            osg::ref_ptr<osg::Vec3Array> vertices = osg::ref_ptr<osg::Vec3Array>( new osg::Vec3Array );
247 248

            // resize Box
249
            if( m_pickInfo.getModifierKey() == WPickInfo::SHIFT )
250
            {
251
                if( m_pickNormal[0] <= 0 && m_pickNormal[1] <= 0 && m_pickNormal[2] <= 0 )
252
                {
253
                    m_maxPos += m_pickNormal * dot( moveVec, m_pickNormal );
254
                }
255
                if( m_pickNormal[0] >= 0 && m_pickNormal[1] >= 0 && m_pickNormal[2] >= 0 )
256
                {
257
                    m_minPos += m_pickNormal * dot( moveVec, m_pickNormal );
258 259 260
                }

                setVertices( vertices, m_minPos, m_maxPos );
261
                m_surfaceGeometry->setVertexArray( vertices );
262 263 264 265 266 267 268 269
            }

            // move Box
            if( m_pickInfo.getModifierKey() == WPickInfo::NONE )
            {
                m_minPos += moveVec;
                m_maxPos += moveVec;
                setVertices( vertices, m_minPos, m_maxPos );
270
                m_surfaceGeometry->setVertexArray( vertices );
271
            }
272 273 274
        }
        else
        {
275
            m_pickNormal = m_pickInfo.getPickNormal();
276 277 278 279
            // color for moving box
            if( m_pickInfo.getModifierKey() == WPickInfo::NONE )
            {
                osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
280
                if ( m_not->get() )
281
                {
282
                    colors->push_back( m_notColor );
283 284 285
                }
                else
                {
286
                    colors->push_back( m_color );
287
                }
288 289
                m_surfaceGeometry->setColorArray( colors );
            }
290
            if( m_pickInfo.getModifierKey() == WPickInfo::SHIFT )
291 292
            {
                osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
293
                colors->push_back( osg::Vec4( 0.0f, 1.0f, 0.0f, 0.4f ) );
294 295
                m_surfaceGeometry->setColorArray( colors );
            }
296
        }
297
        m_oldPixelPosition = newPixelPos;
298
        setDirty();
299
        m_isPicked = true;
300

301
        signalRoiChange();
302
    }
303
    if ( m_isPicked && m_pickInfo.getName() == "unpick" )
304
    {
305 306
        // Perform all actions necessary for finishing a pick

307
        osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
308
        if ( m_not->get() )
309
        {
310
            colors->push_back( m_notColor );
311 312 313
        }
        else
        {
314
            colors->push_back( m_color );
315
        }
316
        m_surfaceGeometry->setColorArray( colors );
317
        m_pickNormal = WVector3d_2();
318 319
        m_isPicked = false;
    }
320

321
    if ( m_dirty->get() )
322 323
    {
        osg::ref_ptr<osg::Vec4Array> colors = osg::ref_ptr<osg::Vec4Array>( new osg::Vec4Array );
324
        if ( m_not->get() )
325
        {
326
            colors->push_back( m_notColor );
327 328 329
        }
        else
        {
330
            colors->push_back( m_color );
331 332 333 334
        }
        m_surfaceGeometry->setColorArray( colors );
    }

335
    lock.unlock();
336
}
337 338 339 340 341 342 343 344 345 346

void WROIBox::setColor( osg::Vec4 color )
{
    m_color = color;
}

void WROIBox::setNotColor( osg::Vec4 color )
{
    m_notColor = color;
}