OpenWalnut  1.5.0dev
WMDatasetManipulator.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 <memory>
26 #include <string>
27 #include <utility>
28 #include <vector>
29 
30 #include "WMDatasetManipulator.h"
31 #include "WMDatasetManipulator.xpm"
32 #include "WManipulatorNormalize.h"
33 #include "WManipulatorRotation.h"
34 #include "WManipulatorScaling.h"
35 #include "WManipulatorTranslation.h"
36 #include "core/dataHandler/WDataSetFibers.h"
37 #include "core/dataHandler/WDataSetPoints.h"
38 #include "core/dataHandler/WDataSetSingle.h"
39 #include "core/dataHandler/WGridRegular3D.h"
40 #include "core/dataHandler/WGridTransformOrtho.h"
41 #include "core/graphicsEngine/WTriangleMesh.h"
42 #include "core/kernel/WKernel.h"
43 
44 W_LOADABLE_MODULE( WMDatasetManipulator )
45 
47  WModule(),
48  m_strategy( "Manipulators", "Select one of the manipulators.", NULL, "Manipulator", "A list of all available manipulators" )
49 {
50  m_strategy.addStrategy( std::shared_ptr< WObjectNDIP< WManipulatorInterface > >( new WManipulatorTranslation() ) );
51  m_strategy.addStrategy( std::shared_ptr< WObjectNDIP< WManipulatorInterface > >( new WManipulatorRotation() ) );
52  m_strategy.addStrategy( std::shared_ptr< WObjectNDIP< WManipulatorInterface > >( new WManipulatorScaling() ) );
53  m_strategy.addStrategy( std::shared_ptr< WObjectNDIP< WManipulatorInterface > >( new WManipulatorNormalize( &m_data ) ) );
54 }
55 
57 {
58 }
59 
60 std::shared_ptr< WModule > WMDatasetManipulator::factory() const
61 {
62  return std::shared_ptr< WModule >( new WMDatasetManipulator() );
63 }
64 
66 {
67  return WMDatasetManipulator_xpm;
68 }
69 
70 std::string const WMDatasetManipulator::getName() const
71 {
72  return "Dataset Manipulator";
73 }
74 
75 std::string const WMDatasetManipulator::getDescription() const
76 {
77  return "This module allows manipulation of the dataset properties via manipulators in the 3D scene.";
78 }
79 
81 {
82  m_input = std::shared_ptr< WModuleInputData< WDataSet > >(
83  new WModuleInputData< WDataSet >( shared_from_this(), "in", "The input dataset." ) );
85 
86  m_output = std::shared_ptr< WModuleOutputData < WDataSet > >(
87  new WModuleOutputData< WDataSet >( shared_from_this(), "out", "The transformed dataset." ) );
89 
91 }
92 
94 {
95  m_propCondition = std::shared_ptr< WCondition >( new WCondition );
96 
97  m_resetTrigger = m_properties->addProperty( "Reset", "Reset transformation.", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
98  m_applyTrigger = m_properties->addProperty( "Apply", "Apply transformation.", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
99 
100  m_properties->addProperty( m_strategy.getProperties() );
101 
103 }
104 
106 {
107  m_moduleState.setResetable( true, true );
109  m_moduleState.add( m_input->getDataChangedCondition() );
110  m_moduleState.add( m_strategy.getProperties()->getUpdateCondition() );
111 
112  ready();
113 
114  while( !m_shutdownFlag() )
115  {
117 
118  if( m_shutdownFlag() )
119  {
120  break;
121  }
122 
123  if( m_input->getData() && m_data != m_input->getData() )
124  {
125  m_data = m_input->getData();
126  initMatrix();
127  m_output->updateData( m_data );
128  }
129 
130  if( m_data && m_strategy()->transformationChanged() )
131  {
132  WMatrixFixed< double, 4, 4 > mat = m_strategy()->getTransformationMatrix();
133 
134  std::shared_ptr< WDataSet > data = transformData( mat * m_currentMat );
135 
136  m_output->updateData( data );
137  }
138 
140  {
142 
143  if( m_data )
144  {
145  initMatrix();
146  m_output->updateData( m_data );
147  }
148  }
149 
151  {
153 
154  if( m_data )
155  {
156  WMatrixFixed< double, 4, 4 > mat = m_strategy()->getTransformationMatrix();
157  m_currentMat = mat * m_currentMat;
158  std::shared_ptr< WDataSet > data = transformData( m_currentMat );
159 
160  m_output->updateData( data );
161  m_strategy()->reset();
162  }
163  }
164  }
165 }
166 
167 std::shared_ptr< WDataSet > WMDatasetManipulator::transformData( WMatrixFixed< double, 4, 4 > const& mat )
168 {
169  std::shared_ptr< WDataSetSingle > asSingle = std::dynamic_pointer_cast< WDataSetSingle >( m_data );
170  if( asSingle )
171  {
172  std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >( asSingle->getGrid() );
173  if( !grid )
174  {
175  return std::shared_ptr< WDataSet >();
176  }
177 
178  WMatrixFixed< double, 4, 4 > m = grid->getTransformationMatrix();
179  m *= mat;
180 
181  WMatrix< double > z( m );
182  WGridTransformOrtho tr( z );
183  std::shared_ptr< WGrid > newGrid( new WGridRegular3D( grid->getNbCoordsX(), grid->getNbCoordsY(), grid->getNbCoordsZ(), tr ) );
184 
185  return asSingle->clone( newGrid );
186  }
187 
188  std::shared_ptr< WDataSetFibers > asFibers = std::dynamic_pointer_cast< WDataSetFibers >( m_data );
189  if( asFibers )
190  {
191  debugLog() << "Got fibers!";
192 
193  std::shared_ptr< std::vector< float > > vertices = asFibers->getVertices();
194  std::shared_ptr< std::vector< float > > newVertices( new std::vector< float >( vertices->size() ) );
195 
196  for( std::size_t k = 0; k < vertices->size() / 3; ++k )
197  {
198  WVector4d v( ( *vertices )[ 3 * k + 0 ], ( *vertices )[ 3 * k + 1 ], ( *vertices )[ 3 * k + 2 ], 1.0 );
199  WVector4d w = mat * v;
200  ( *newVertices )[ 3 * k + 0 ] = w[ 0 ] / w[ 3 ];
201  ( *newVertices )[ 3 * k + 1 ] = w[ 1 ] / w[ 3 ];
202  ( *newVertices )[ 3 * k + 2 ] = w[ 2 ] / w[ 3 ];
203  }
204 
205  std::shared_ptr< WDataSetFibers > data( new WDataSetFibers( newVertices, asFibers->getLineStartIndexes(),
206  asFibers->getLineLengths(), asFibers->getVerticesReverse() ) );
207  return data;
208  }
209 
210  std::shared_ptr< WDataSetPoints > asPoints = std::dynamic_pointer_cast< WDataSetPoints >( m_data );
211  if( asPoints )
212  {
213  std::shared_ptr< std::vector< float > > p( new std::vector< float >( asPoints->getVertices()->size() ) );
214 
215  for( std::size_t k = 0; k < asPoints->getVertices()->size(); k += 3 )
216  {
217  WVector4d vec( asPoints->getVertices()->operator[]( k + 0 ),
218  asPoints->getVertices()->operator[]( k + 1 ),
219  asPoints->getVertices()->operator[]( k + 2 ),
220  1.0 );
221 
222  vec = mat * vec;
223  p->operator[] ( k + 0 ) = vec[ 0 ];
224  p->operator[] ( k + 1 ) = vec[ 1 ];
225  p->operator[] ( k + 2 ) = vec[ 2 ];
226  }
227 
228  return std::shared_ptr< WDataSetPoints >( new WDataSetPoints( p, asPoints->getColors() ) );
229  }
230 
231  return std::shared_ptr< WDataSet >();
232 }
233 
235 {
236  std::shared_ptr< WDataSetSingle > asSingle = std::dynamic_pointer_cast< WDataSetSingle >( m_data );
237  if( asSingle )
238  {
239  std::shared_ptr< WGridRegular3D > grid = std::dynamic_pointer_cast< WGridRegular3D >( asSingle->getGrid() );
240  if( !grid )
241  {
243  }
244 
245  m_currentMat = grid->getTransformationMatrix();
246  }
247  else if( std::dynamic_pointer_cast< WDataSetFibers >( m_data ) )
248  {
250  }
251  else if( std::dynamic_pointer_cast< WDataSetPoints >( m_data ) )
252  {
254  }
255 }
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
Represents a simple set of WFibers.
Dataset to store a bunch of points without order or topology.
A grid that has parallelepiped cells which all have the same proportion.
Implements an orthogonal grid transformation.
Module allowing manipulation of the dataset scaling, orientation and position.
std::shared_ptr< WModuleOutputData< WDataSet > > m_output
An output connector for the transformed dataset.
std::shared_ptr< WCondition > m_propCondition
A condition for property updates.
std::shared_ptr< WDataSet > m_data
The current data.
WMatrixFixed< double, 4, 4 > m_currentMat
The current transformation.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
virtual void connectors()
Initialize the connectors this module is using.
WPropTrigger m_applyTrigger
A trigger to add the transformation from the currently active strategy to the current transformation.
virtual void properties()
Initialize the properties for this module.
WPropTrigger m_resetTrigger
A trigger to reset the current transformation to the initial one.
virtual void moduleMain()
Entry point after loading the module.
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...
std::shared_ptr< WModuleInputData< WDataSet > > m_input
An input connector that accepts any dataset.
WStrategyHelper< WObjectNDIP< WManipulatorInterface > > m_strategy
The strategy to use for dataset transformation manipulation.
virtual const std::string getName() const
Gives back the name of this module.
std::shared_ptr< WDataSet > transformData(WMatrixFixed< double, 4, 4 > const &mat)
Transform the data using the provided transformation matrix.
void initMatrix()
Init the matrix to be applied from the transformations stored in the current dataset.
virtual const std::string getDescription() const
Gives back a description of this module.
WMDatasetManipulator()
Constructor.
virtual ~WMDatasetManipulator()
Destructor.
A manipulator to scale datasets to form a unit cube.
A manipulator for rotating a dataset around an axis in the world coordinate system.
A manipulator to scale datasets in world coords.
A manipulator for translation of datasets in world coordinates.
static MatrixType identity()
Returns an identity matrix.
Definition: WMatrixFixed.h:310
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
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
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
WProperties::SPtr getProperties() const
Get this strategy selectors properties.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
@ PV_TRIGGER_TRIGGERED
Trigger property: got triggered.
@ PV_TRIGGER_READY
Trigger property: is ready to be triggered (again)