OpenWalnut  1.5.0dev
WMSampleOnFibers.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 
29 #include "WMSampleOnFibers.h"
30 #include "core/common/WPropertyHelper.h"
31 #include "core/common/math/WMath.h"
32 #include "core/dataHandler/WDataHandler.h"
33 #include "core/kernel/WKernel.h"
34 
35 // This line is needed by the module loader to actually find your module. You need to add this to your module too. Do NOT add a ";" here.
36 W_LOADABLE_MODULE( WMSampleOnFibers )
37 
39  WModule()
40 {
41 }
42 
44 {
45  // Cleanup!
46 }
47 
48 std::shared_ptr< WModule > WMSampleOnFibers::factory() const
49 {
50  return std::shared_ptr< WModule >( new WMSampleOnFibers() );
51 }
52 
53 const char** WMSampleOnFibers::getXPMIcon() const
54 {
55  return NULL;
56 }
57 
58 const std::string WMSampleOnFibers::getName() const
59 {
60  return "Sample On Fibers";
61 }
62 
63 const std::string WMSampleOnFibers::getDescription() const
64 {
65  return "This module allows you to sample points on fibers using the parameters on a fiber.";
66 }
67 
69 {
70  // The input fiber dataset
71  m_fiberInput = std::shared_ptr< WModuleInputData < WDataSetFibers > >(
72  new WModuleInputData< WDataSetFibers >( shared_from_this(), "fibers", "The fiber dataset" )
73  );
74 
75  // As properties, every connector needs to be added to the list of connectors.
77 
78  // the points
79  m_pointsOutput = std::shared_ptr< WModuleOutputData < WDataSetPoints > >(
80  new WModuleOutputData< WDataSetPoints >( shared_from_this(), "out", "The point data." )
81  );
82 
83  // As above: make it known.
85 
86  // call WModule's initialization
88 }
89 
91 {
92  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
93 
94  m_paramHint = m_properties->addProperty( "Hint", "If you see this, your data does not contain fiber parameters.",
95  std::string( "Your data cannot be filtered due to missing parameters." ) );
96  m_paramHint->setPurpose( PV_PURPOSE_INFORMATION );
97 
98  m_color = m_properties->addProperty( "Color", "The color of the resulting points", defaultColor::WHITE, m_propCondition );
99  m_parameter = m_properties->addProperty( "Parameter", "Value where to sample", 0.0, m_propCondition );
100 
101  // call WModule's initialization
103 }
104 
106 {
107  // get notified about data changes
108  m_moduleState.setResetable( true, true );
109  m_moduleState.add( m_fiberInput->getDataChangedCondition() );
110  // Remember the condition provided to some properties in properties()? The condition can now be used with this condition set.
112 
113  ready();
114 
115  // main loop
116  while( !m_shutdownFlag() )
117  {
118  debugLog() << "Waiting ...";
120 
121  // woke up since the module is requested to finish?
122  if( m_shutdownFlag() )
123  {
124  break;
125  }
126 
127  // To query whether an input was updated, simply ask the input:
128  bool dataUpdated = m_fiberInput->handledUpdate();
129  std::shared_ptr< WDataSetFibers > dataSet = m_fiberInput->getData();
130  bool dataValid = ( dataSet != NULL );
131  bool propsChanged = m_parameter ||
132  m_color->changed();
133 
134  // reset everything if input was disconnected/invalid
135  if( !dataValid )
136  {
137  debugLog() << "Resetting output.";
138  m_pointsOutput->reset();
139  continue;
140  }
141 
142  if( dataValid && dataUpdated )
143  {
144  if( dataSet->getVertexParameters() )
145  {
146  m_parameterMin = dataSet->getVertexParameters()->operator[]( 0 );
147  m_parameterMax = dataSet->getVertexParameters()->operator[]( 0 );
148  for( WDataSetFibers::VertexParemeterArray::element_type::const_iterator it = dataSet->getVertexParameters()->begin();
149  it != dataSet->getVertexParameters()->end(); ++it )
150  {
151  m_parameterMax = std::max( *it, m_parameterMax );
152  m_parameterMin = std::min( *it, m_parameterMin );
153  }
154  }
155  else
156  {
157  m_parameterMin = 0.0;
158  m_parameterMax = 1.0;
159  }
160 
161  m_parameter->setRecommendedValue( m_parameterMin );
162  m_parameter->setMin( m_parameterMin );
163  m_parameter->setMax( m_parameterMax );
164  }
165 
166  if( dataValid && !dataUpdated && !propsChanged )
167  {
168  continue;
169  }
170 
171  WDataSetFibers::VertexArray fibVerts = dataSet->getVertices();
172  WDataSetFibers::ColorArray fibColors = dataSet->getColorScheme()->getColor();
173  WDataSetFibers::IndexArray fibStart = dataSet->getLineStartIndexes();
174  WDataSetFibers::LengthArray fibLen = dataSet->getLineLengths();
175  WDataSetFibers::VertexParemeterArray fibParams = dataSet->getVertexParameters();
176 
177  debugLog() << "Creating point data.";
178  WDataSetFibers::VertexArray filteredVerts( new WDataSetFibers::VertexArray::element_type() );
179  WDataSetFibers::ColorArray filteredColors( new WDataSetFibers::ColorArray::element_type() );
180  WBoundingBox filteredBB;
181 
182  if( fibParams )
183  {
184  m_paramHint->setHidden( true );
185 
186  double v = m_parameter->get( true );
187 
188  // progress indication
189  WProgress::SPtr progress = WProgress::SPtr( new WProgress( "Creating Points from Fibers.", fibStart->size() ) );
190  m_progress->addSubProgress( progress );
191 
192  // for each fiber:
193  for( size_t fidx = 0; fidx < fibStart->size() ; ++fidx )
194  {
195  ++*progress;
196 
197  // the start vertex index
198  size_t sidx = fibStart->at( fidx ) * 3;
199 
200  // the length of the fiber
201  size_t len = fibLen->at( fidx );
202 
203  // a line needs 2 verts at least, but also check first and only vertex
204  if( len < 2 )
205  {
206  if( fibParams->at( fibStart->at( fidx ) ) == v )
207  {
208  filteredVerts->push_back( fibVerts->at( sidx + 0 ) );
209  filteredVerts->push_back( fibVerts->at( sidx + 1 ) );
210  filteredVerts->push_back( fibVerts->at( sidx + 2 ) );
211 
212  filteredBB.expandBy(
213  osg::Vec3(
214  fibVerts->at( sidx + 0 ),
215  fibVerts->at( sidx + 1 ),
216  fibVerts->at( sidx + 2 ) )
217  );
218  }
219  continue;
220  }
221 
222  // keep track of the previous vertex
223  osg::Vec3 lastVert = osg::Vec3( fibVerts->at( sidx ),
224  fibVerts->at( sidx + 1 ),
225  fibVerts->at( sidx + 2 ) );
226  // keep track of the previous value
227  double lastParam = fibParams->at( fibStart->at( fidx ) );
228 
229  // walk along the fiber
230  for( size_t k = 0; k < len; ++k )
231  {
232  // get current vertex and value
233  osg::Vec3 vert = osg::Vec3( fibVerts->at( ( 3 * k ) + sidx ),
234  fibVerts->at( ( 3 * k ) + sidx + 1 ),
235  fibVerts->at( ( 3 * k ) + sidx + 2 ) );
236  double param = fibParams->at( k + fibStart->at( fidx ) );
237 
238  // is there a sample in between the values?
239  WIntervalDouble interval( param, lastParam );
240  if( isInClosed( interval, v ) )
241  {
242  // linearly interpolate
243  double n = ( v - lastParam ) / ( param - lastParam );
244  osg::Vec3 interpolatedVert( lastVert + ( vert - lastVert ) * n );
245 
246  filteredVerts->push_back( interpolatedVert.x() );
247  filteredVerts->push_back( interpolatedVert.y() );
248  filteredVerts->push_back( interpolatedVert.z() );
249 
250  filteredBB.expandBy( interpolatedVert );
251  }
252 
253  // keep track of the last value/vertex
254  lastParam = param;
255  lastVert = vert;
256  }
257  }
258 
259  // add colors
260  for( size_t i = 0; i < filteredVerts->size() / 3; ++i )
261  {
262  filteredColors->push_back( m_color->get( true ).r() );
263  filteredColors->push_back( m_color->get( true ).g() );
264  filteredColors->push_back( m_color->get( true ).b() );
265  filteredColors->push_back( m_color->get( true ).a() );
266  }
267 
268  WDataSetPoints::SPtr result( new WDataSetPoints( filteredVerts, filteredColors, filteredBB ) );
269  m_pointsOutput->updateData( result );
270  progress->finish();
271  m_progress->removeSubProgress( progress );
272  debugLog() << "Done filtering. Result are " << filteredVerts->size() / 3 << " points.";
273  }
274  else
275  {
276  warnLog() << "Data does not contain the values to use for sampling.";
277  m_paramHint->setHidden( false );
278  }
279  }
280 }
281 
void expandBy(const WBoundingBoxImpl< VT > &bb)
Expands this bounding box to include the given bounding box.
Definition: WBoundingBox.h:240
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
std::shared_ptr< std::vector< size_t > > IndexArray
Index list indexing fibers in VertexArray in terms of vertex numbers.
std::shared_ptr< std::vector< float > > ColorArray
Colors for each vertex in VertexArray.
std::shared_ptr< std::vector< size_t > > LengthArray
Lengths of fibers in terms of vertices.
std::shared_ptr< std::vector< double > > VertexParemeterArray
Parameter storage for each vertex.
std::shared_ptr< std::vector< float > > VertexArray
List of vertex coordinates in term of components of vertices.
Dataset to store a bunch of points without order or topology.
std::shared_ptr< WDataSetPoints > SPtr
Pointer to dataset.
This modules takes a fiber dataset and samples it at a given parameter value.
std::shared_ptr< WModuleInputData< WDataSetFibers > > m_fiberInput
The fiber dataset which is going to be used.
WPropDouble m_parameter
Filter fib point according to its parameter value and this value.
WPropString m_paramHint
A string which informs the user whether filtering is possible.
WMSampleOnFibers()
Default constructor.
virtual const std::string getName() const
Gives back the name of this module.
std::shared_ptr< WModuleOutputData< WDataSetPoints > > m_pointsOutput
The output connector used to provide the calculated point data to other modules.
WPropColor m_color
The color to use for the resulting points.
virtual void connectors()
Initialize the connectors this module is using.
virtual ~WMSampleOnFibers()
Destructor.
double m_parameterMax
fiber parameter max
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
virtual void properties()
Initialize the properties for this module.
virtual void moduleMain()
Entry point after loading the module.
virtual const std::string getDescription() const
Gives back a description of this module.
double m_parameterMin
fiber parameter min
std::shared_ptr< WCondition > m_propCondition
A condition used to notify about changes in several properties.
Class offering an instantiate-able data connection between modules.
Class offering an instantiate-able data connection between modules.
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
Definition: WModule.cpp:575
void addConnector(std::shared_ptr< WModuleInputConnector > con)
Adds the specified connector to the list of inputs.
Definition: WModule.cpp:108
wlog::WStreamedLogger warnLog() const
Logger instance for comfortable warning- logs.
Definition: WModule.cpp:580
std::shared_ptr< WProperties > m_properties
The property object for the module.
Definition: WModule.h:640
void ready()
Call this whenever your module is ready and can react on property changes.
Definition: WModule.cpp:505
WConditionSet m_moduleState
The internal state of the module.
Definition: WModule.h:703
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
Definition: WModule.h:652
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
Class managing progress inside of modules.
Definition: WProgress.h:42
std::shared_ptr< WProgress > SPtr
Shared pointer on a WProgress.
Definition: WProgress.h:48
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.