OpenWalnut  1.5.0dev
WDataCreatorTorus.h
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 #ifndef WDATACREATORTORUS_H
26 #define WDATACREATORTORUS_H
27 
28 #include <random>
29 
30 #include "core/common/math/WMath.h"
31 #include "core/common/WLimits.h"
32 #include "core/common/WObjectNDIP.h"
33 
34 #include "WDataSetFibersCreatorInterface.h"
35 #include "WDataSetPointsCreatorInterface.h"
36 
37 /**
38  * Create a torus
39  */
40 template< class T >
41 class WDataCreatorTorus: public WObjectNDIP< T >
42 {
43 public:
44  /**
45  * Abbreviate shared_ptr
46  */
47  typedef std::shared_ptr< WDataCreatorTorus< T > > SPtr;
48 
49  /**
50  * Abbreviate const shared_ptr
51  */
52  typedef std::shared_ptr< const WDataCreatorTorus< T > > ConstSPtr;
53 
54  /**
55  * Default constructor.
56  */
58 
59  /**
60  * Destructor.
61  */
62  virtual ~WDataCreatorTorus();
63 
64  /**
65  * Create the fiber dataset. This needs to be implemented by all the creators you write.
66  *
67  * \param seed the seed for the random values.
68  * \param progress progress indicator
69  * \param color color of all fibers
70  * \param numFibers number of fibers
71  * \param numVertsPerFiber number of vertices per fiber
72  * \param origin origin of the bbox
73  * \param size size of the bounding box
74  * \param vertices the vertex array. Fill this.
75  * \param fibIdx the fiber index array. Fill this.
76  * \param lengths the lengths array. Fill this.
77  * \param fibIdxVertexMap inverse map. Fill this.
78  * \param colors the color array. Fill this.
79  */
80  virtual void operator()( int seed,
81  WProgress::SPtr progress,
82  const WColor& color,
83  size_t numFibers,
84  size_t numVertsPerFiber,
85  const WPosition& origin,
86  const WPosition& size,
90  WDataSetFibers::IndexArray fibIdxVertexMap,
92 
93  /**
94  * Create the point dataset. This needs to be implemented by all the creators you write.
95  *
96  * \param seed the seed for the random values.
97  * \param progress progress indicator
98  * \param color color of all points
99  * \param numPoints number of points
100  * \param origin origin of the bbox
101  * \param size size of the bounding box
102  * \param vertices the vertex array. Fill this.
103  * \param colors the color array. Fill this.
104  */
105  virtual void operator()( int seed,
106  WProgress::SPtr progress,
107  const WColor& color,
108  size_t numPoints,
109  const WPosition& origin,
110  const WPosition& size,
113 protected:
114 private:
115  /**
116  * Calculates the transformation matrix
117  *
118  * \param origin origin of the bbox
119  * \param size size of the bounding box
120  * \return WMatrix4d The transformation matrix
121  */
122  WMatrix4d calculateTransform( const WPosition& origin, const WPosition& size );
123 
124  /**
125  * Calculates a vertex on a torus.
126  *
127  * \param torusRadius The radius of the torus ( to the midpoint of the ring)
128  * \param ringRadius The radius of the ring
129  * \param torusAngle The radius around the torus
130  * \param ringAngle The radius around the ring
131  * \return WVector4d The vector for the vertex
132  */
133  WVector4d calculateTorusVertex( double torusRadius, double ringRadius, double torusAngle, double ringAngle );
134 
135  /**
136  * The inner radius of the torus.
137  */
138  WPropDouble m_innerRadius;
139 
140  /**
141  * Property whether inner fibers should be created.
142  */
143  WPropBool m_generateInner;
144 
145  /**
146  * The rotation angle for the x axis.
147  */
148  WPropDouble m_rotateX;
149 
150  /**
151  * The rotation angle for the x axis.
152  */
153  WPropDouble m_rotateY;
154 
155  /**
156  * The rotation angle for the x axis.
157  */
158  WPropDouble m_rotateZ;
159 };
160 
161 
164 
165 
166 template< class T >
168  WObjectNDIP< T >( "Torus", "Create data in a torus shape." )
169 {
170  m_innerRadius = WObjectNDIP< T >::m_properties->addProperty( "Inner radius", "The inner radius of the torus.", 0.1 );
171  m_innerRadius->setMin( 0.01 );
172  m_innerRadius->setMax( 0.99 );
173 
174  m_generateInner = WObjectNDIP< T >::m_properties->addProperty( "Generate inner data", "Whether inner data should be generated.", true );
175 
176 
177  m_rotateX = WObjectNDIP< T >::m_properties->addProperty( "X rotation", "The rotation of the torus around the x axis.", 0.0 );
178  m_rotateX->setMin( 0 );
179  m_rotateX->setMax( pi() * 2 );
180 
181  m_rotateY = WObjectNDIP< T >::m_properties->addProperty( "Y rotation", "The rotation of the torus around the y axis.", 0.0 );
182  m_rotateY->setMin( 0 );
183  m_rotateY->setMax( pi() * 2 );
184 
185  m_rotateZ = WObjectNDIP< T >::m_properties->addProperty( "Z rotation", "The rotation of the torus around the z axis.", 0.0 );
186  m_rotateZ->setMin( 0 );
187  m_rotateZ->setMax( pi() * 2 );
188 }
189 
190 template< class T >
192 {
193  // cleanup
194 }
195 
196 template< class T >
198 {
199  return WMatrix4d(
200  osg::Matrixd::scale( size.x() / 2.0, size.y() / 2.0, size.z() / 2.0 ) *
201  osg::Matrixd::rotate(
202  m_rotateX->get(), osg::Vec3d( 1, 0, 0 ), m_rotateY->get(), osg::Vec3d( 0, 1, 0 ), m_rotateZ->get(), osg::Vec3d( 0, 0, 1 ) )
203  );
204 }
205 
206 template< class T >
207 WVector4d WDataCreatorTorus< T >::calculateTorusVertex( double torusRadius, double ringRadius, double torusAngle, double ringAngle )
208 {
209  double radCache = ( torusRadius + ringRadius * cos( ringAngle ) );
210  double x = radCache * cos( torusAngle );
211  double y = radCache * sin( torusAngle );
212  double z = ( ringRadius * sin( ringAngle ) );
213 
214  return WVector4d( x, y, z, 1.0 );
215 }
216 
217 
218 template< class T >
220  WProgress::SPtr progress,
221  const WColor& color,
222  size_t numFibers,
223  size_t numVertsPerFiber,
224  const WPosition& origin,
225  const WPosition& size,
229  WDataSetFibers::IndexArray fibIdxVertexMap,
231 {
232  double innerRadius = m_innerRadius->get() / 2.0;
233 
234  std::uniform_real_distribution< double > unifRadius( 0.01, innerRadius );
235  std::uniform_real_distribution< double > unifAngle( 0.0, pi() * 2.0 );
236  std::default_random_engine re;
237  re.seed( seed );
238 
239  WMatrix4d transform = calculateTransform( origin, size );
240 
241  float lowX, lowY, lowZ;
242  lowX = lowY = lowZ = wlimits::MAX_FLOAT;
243 
244  for( size_t fidx = 0; fidx < numFibers; ++fidx )
245  {
246  double irad = m_generateInner->get() ? unifRadius( re ) : innerRadius;
247  double iangle = unifAngle( re );
248 
249  double angleParam = pi() * 2.0 / numVertsPerFiber;
250 
251  fibIdx->push_back( fidx * numVertsPerFiber );
252  lengths->push_back( numVertsPerFiber );
253 
254  for( size_t vidx = 0; vidx < numVertsPerFiber; ++vidx )
255  {
256  WVector4d vec = calculateTorusVertex( 1.0 - innerRadius, irad, angleParam * vidx, iangle );
257  vec = transform * vec; // for whatever reason the translation inside the matrix does not work, so we do it manually
258  vec = WVector4d( vec.x() + origin.x() + size.x() / 2.0,
259  vec.y() + origin.y() + size.y() / 2.0,
260  vec.z() + origin.z() + size.z() / 2.0, 1.0 );
261 
262  lowX = fmin( lowX, vec.x() );
263  lowY = fmin( lowY, vec.y() );
264  lowZ = fmin( lowZ, vec.z() );
265 
266  vertices->push_back( vec.x() );
267  vertices->push_back( vec.y() );
268  vertices->push_back( vec.z() );
269 
270  colors->push_back( color.x() );
271  colors->push_back( color.y() );
272  colors->push_back( color.z() );
273  fibIdxVertexMap->push_back( fidx );
274  }
275 
276  ++( *progress );
277  }
278 
279  for( size_t vidx = 0; vidx < vertices->size(); vidx += 3 )
280  {
281  vertices->at( vidx + 0 ) -= lowX;
282  vertices->at( vidx + 1 ) -= lowY;
283  vertices->at( vidx + 2 ) -= lowZ;
284  }
285 }
286 
287 template< class T >
289  WProgress::SPtr progress,
290  const WColor& color,
291  size_t numPoints,
292  const WPosition& origin,
293  const WPosition& size,
296 {
297  double innerRadius = m_innerRadius->get() / 2.0;
298 
299  std::uniform_real_distribution< double > unifRadius( 0.01, innerRadius );
300  std::uniform_real_distribution< double > unifAngle( 0.0, pi() * 2.0 );
301  std::default_random_engine re;
302  re.seed( seed );
303 
304  WMatrix4d transform = calculateTransform( origin, size );
305 
306  float lowX, lowY, lowZ;
307  lowX = lowY = lowZ = wlimits::MAX_FLOAT;
308 
309  for( size_t pidx = 0; pidx < numPoints; ++pidx )
310  {
311  double irad = m_generateInner->get() ? unifRadius( re ) : innerRadius;
312  double iangle = unifAngle( re );
313  double iangle2 = unifAngle( re );
314 
315  WVector4d vec = calculateTorusVertex( 1.0 - innerRadius, irad, iangle2, iangle );
316  vec = transform * vec;
317  vec = WVector4d( vec.x() + origin.x() + size.x() / 2.0,
318  vec.y() + origin.y() + size.y() / 2.0,
319  vec.z() + origin.z() + size.z() / 2.0, 1.0 );
320 
321  lowX = fmin( lowX, vec.x() );
322  lowY = fmin( lowY, vec.y() );
323  lowZ = fmin( lowZ, vec.z() );
324 
325  vertices->push_back( vec.x() );
326  vertices->push_back( vec.y() );
327  vertices->push_back( vec.z() );
328 
329  colors->push_back( color.x() );
330  colors->push_back( color.y() );
331  colors->push_back( color.z() );
332 
333  ++( *progress );
334  }
335 
336  for( size_t vidx = 0; vidx < vertices->size(); vidx += 3 )
337  {
338  vertices->at( vidx + 0 ) -= lowX;
339  vertices->at( vidx + 1 ) -= lowY;
340  vertices->at( vidx + 2 ) -= lowZ;
341  }
342 }
343 
344 #endif // WDATACREATORTORUS_H
Create a torus.
virtual ~WDataCreatorTorus()
Destructor.
virtual void operator()(int seed, WProgress::SPtr progress, const WColor &color, size_t numFibers, size_t numVertsPerFiber, const WPosition &origin, const WPosition &size, WDataSetFibers::VertexArray vertices, WDataSetFibers::IndexArray fibIdx, WDataSetFibers::LengthArray lengths, WDataSetFibers::IndexArray fibIdxVertexMap, WDataSetFibers::ColorArray colors)
Create the fiber dataset.
WPropDouble m_rotateY
The rotation angle for the x axis.
std::shared_ptr< const WDataCreatorTorus< T > > ConstSPtr
Abbreviate const shared_ptr.
std::shared_ptr< WDataCreatorTorus< T > > SPtr
Abbreviate shared_ptr.
WPropDouble m_rotateZ
The rotation angle for the x axis.
WVector4d calculateTorusVertex(double torusRadius, double ringRadius, double torusAngle, double ringAngle)
Calculates a vertex on a torus.
WDataCreatorTorus()
Default constructor.
WPropBool m_generateInner
Property whether inner fibers should be created.
WPropDouble m_innerRadius
The inner radius of the torus.
WMatrix4d calculateTransform(const WPosition &origin, const WPosition &size)
Calculates the transformation matrix.
WPropDouble m_rotateX
The rotation angle for the x axis.
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< float > > VertexArray
List of vertex coordinates in term of components of vertices.
std::shared_ptr< std::vector< float > > ColorArray
Colors for each vertex in VertexArray.
std::shared_ptr< std::vector< float > > VertexArray
List of vertex coordinates in term of components of vertices.
ValueT & z()
Access z element of vector.
ValueT & y()
Access y element of vector.
ValueT & x()
Access x element of vector.
This is a base class for everything which has a Name,Description,Icon and Properties (=NDIP).
Definition: WObjectNDIP.h:42
This only is a 3d double vector.
std::shared_ptr< WProgress > SPtr
Shared pointer on a WProgress.
Definition: WProgress.h:48
const float MAX_FLOAT
Maximum float value.
Definition: WLimits.cpp:32