OpenWalnut  1.5.0dev
WLineStripCallback.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 <cmath>
27 #include <cstddef>
28 #include <memory>
29 
30 #include <osg/Array>
31 #include <osg/Drawable>
32 #include <osg/Geometry>
33 #include <osg/NodeVisitor>
34 #include <osg/PrimitiveSet>
35 #include <osg/Vec3>
36 
37 #include "WLineStripCallback.h"
38 #include "core/common/WPropertyTypes.h"
39 #include "core/common/WPropertyVariable.h"
40 #include "core/dataHandler/WEEG2Segment.h"
41 #include "core/dataHandler/WEEGValueMatrix.h"
42 
44  WPropDouble timePos,
45  WPropDouble timeRange,
46  std::shared_ptr< WEEG2Segment > segment,
47  double samplingRate )
48  : m_channelID( channelID ),
49  m_currentTimePos( 0.0 ),
50  m_currentTimeRange( -1.0 ),
51  m_timePos( timePos ),
52  m_timeRange( timeRange ),
53  m_segment( segment ),
54  m_samplingRate( samplingRate )
55 {
56 }
57 
58 void WLineStripCallback::update( osg::NodeVisitor* /*nv*/, osg::Drawable* drawable )
59 {
60  const double timePos = m_timePos->get();
61  const double timeRange = m_timeRange->get();
62 
63  if( timePos != m_currentTimePos || timeRange != m_currentTimeRange )
64  {
65  osg::Geometry* geometry = static_cast< osg::Geometry* >( drawable );
66  if( geometry )
67  {
68  const std::size_t nbSamples = m_segment->getNumberOfSamples();
69  const std::size_t startSample = clampToRange( timePos * m_samplingRate, 0u, nbSamples - 1u );
70  const std::size_t endSample = clampToRange( std::ceil( ( timePos + timeRange ) * m_samplingRate ) + 1.0,
71  startSample,
72  nbSamples );
73  const std::size_t currentStartSample = clampToRange( m_currentTimePos * m_samplingRate, 0u, nbSamples - 1u );
74  const std::size_t currentEndSample = ( 0.0 <= m_currentTimeRange ) ?
76  currentStartSample,
77  nbSamples ) :
78  currentStartSample;
79 
80  osg::Vec3Array* vertices = new osg::Vec3Array();
81  vertices->reserve( endSample - startSample );
82 
83  // load the values before the current vertices from WEEG
84  std::size_t start = startSample;
85  std::size_t end = std::min( endSample, currentStartSample );
86  if( start < end )
87  {
88  const std::size_t length = end - start;
89  std::shared_ptr< const WEEGValueMatrix > values = m_segment->getValues( start, length );
90  for( std::size_t i = 0; i < length; ++i )
91  {
92  vertices->push_back( osg::Vec3( ( start + i ) / m_samplingRate, (*values)[m_channelID][i], -0.001 ) );
93  }
94  }
95 
96  // copy the values from the current vertices
97  start = std::max( startSample, currentStartSample );
98  end = std::min( endSample, currentEndSample );
99  if( start < end )
100  {
101  const osg::Vec3Array* currentVertices = static_cast< osg::Vec3Array* >( geometry->getVertexArray() );
102  vertices->insert( vertices->end(),
103  currentVertices->begin() + ( start - currentStartSample ),
104  currentVertices->begin() + ( end - currentStartSample ) );
105  }
106 
107  // load the values after the current vertices from WEEG
108  start = std::max( startSample, currentEndSample );
109  end = endSample;
110  if( start < end )
111  {
112  const std::size_t length = end - start;
113  std::shared_ptr< const WEEGValueMatrix > values = m_segment->getValues( start, length );
114  for( std::size_t i = 0; i < length; ++i )
115  {
116  vertices->push_back( osg::Vec3( ( start + i ) / m_samplingRate, (*values)[m_channelID][i], -0.001 ) );
117  }
118  }
119 
120  geometry->setVertexArray( vertices );
121 
122  osg::DrawArrays* primitiveSet = static_cast< osg::DrawArrays* >( geometry->getPrimitiveSet( 0 ) );
123  primitiveSet->setCount( endSample - startSample );
124  }
125 
126  m_currentTimePos = timePos;
127  m_currentTimeRange = timeRange;
128  }
129 }
130 
131 std::size_t WLineStripCallback::clampToRange( double value, std::size_t min, std::size_t max ) const
132 {
133  std::size_t out = ( value > 0.0 ) ? value : 0u;
134  if( out < min )
135  {
136  out = min;
137  }
138  else if( max < out )
139  {
140  out = max;
141  }
142 
143  return out;
144 }
std::size_t clampToRange(double value, std::size_t min, std::size_t max) const
Convert the given double value to std::size_t and clamp it into the given range.
WLineStripCallback(std::size_t channelID, WPropDouble timePos, WPropDouble timeRange, std::shared_ptr< WEEG2Segment > segment, double samplingRate)
Constructor.
double m_currentTimeRange
the width of the graph in seconds which is currently used
double m_currentTimePos
the time position in seconds where to start the graph at the left edge which is currently used
WPropDouble m_timePos
the time position in seconds where to start the graph at the left edge as property
double m_samplingRate
sampling rate used by the recording
virtual void update(osg::NodeVisitor *, osg::Drawable *drawable)
Callback method called by the NodeVisitor.
std::shared_ptr< WEEG2Segment > m_segment
pointer to the EEG segment
const std::size_t m_channelID
the number of the channel
WPropDouble m_timeRange
the width of the graph in seconds as property