OpenWalnut  1.5.0dev
WSurface.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 <cmath>
26 #include <fstream>
27 #include <map>
28 #include <memory>
29 #include <vector>
30 
31 #include "WSurface.h"
32 #include "core/common/math/WLinearAlgebraFunctions.h"
33 #include "core/common/math/WMatrix.h"
34 #include "core/common/math/WTensorFunctions.h"
35 
37  : m_tMesh( new WTriangleMesh( 0, 0 ) ),
38  m_radius( 30.0 ),
39  m_mu( 8.0 ),
40  m_numDeBoorRows( 12 ),
41  m_numDeBoorCols( 12 ),
42  m_order( 4 ),
43  m_sampleRateT( 0.5 ),
44  m_sampleRateU( 0.5 ),
45  m_xAverage( 0.0 ),
46  m_yAverage( 0.0 ),
47  m_zAverage( 0.0 )
48 {
49 }
50 
52 {
53 }
54 
56 {
59 
60  std::vector< WVector3d >::iterator pointsIt;
61  for( pointsIt = points.begin(); pointsIt != points.end(); ++pointsIt )
62  {
63  WVector3d dmy = *pointsIt;
64  m_xAverage += dmy[0];
65  m_yAverage += dmy[1];
66  m_zAverage += dmy[2];
67  }
68 
69  m_xAverage /= points.size();
70  m_yAverage /= points.size();
71  m_zAverage /= points.size();
72 
73  for( pointsIt = points.begin(); pointsIt != points.end(); ++pointsIt )
74  {
75  WVector3d dmy = *pointsIt;
76 
77  result( 0, 0 ) += ( dmy[0] - m_xAverage ) * ( dmy[0] - m_xAverage ); //XX
78  result( 0, 1 ) += ( dmy[0] - m_xAverage ) * ( dmy[1] - m_yAverage ); //XY
79  result( 0, 2 ) += ( dmy[0] - m_xAverage ) * ( dmy[2] - m_zAverage ); //XZ
80 
81  result( 1, 1 ) += ( dmy[1] - m_yAverage ) * ( dmy[1] - m_yAverage ); //YY
82  result( 1, 2 ) += ( dmy[1] - m_yAverage ) * ( dmy[2] - m_zAverage ); //YZ
83 
84  result( 2, 2 ) += ( dmy[2] - m_zAverage ) * ( dmy[2] - m_zAverage ); //ZZ
85  }
86 
87  result( 1, 0 ) = result( 0, 1 );
88  result( 2, 0 ) = result( 0, 2 );
89  result( 2, 1 ) = result( 1, 2 );
90 
91  return result;
92 }
93 
94 void WSurface::getSplineSurfaceDeBoorPoints( std::vector< WVector3d > &givenPoints, std::vector< WVector3d > &deBoorPoints, int numRows, int numCols ) // NOLINT
95 {
96  double xMin = givenPoints[0][0];
97  double xMax = givenPoints[0][0];
98  double zMin = givenPoints[0][2];
99  double zMax = givenPoints[0][2];
100 
101  std::vector< WVector3d >::iterator givenPointsIt;
102 
103  for( givenPointsIt = givenPoints.begin(); givenPointsIt != givenPoints.end(); ++givenPointsIt )
104  {
105  WVector3d dmy = *givenPointsIt;
106  if( dmy[0] < xMin )
107  {
108  xMin = dmy[0];
109  }
110  if( dmy[0] > xMax )
111  {
112  xMax = dmy[0];
113  }
114  if( dmy[2] < zMin )
115  {
116  zMin = dmy[2];
117  }
118  if( dmy[2] > zMax )
119  {
120  zMax = dmy[2];
121  }
122  }
123 
124  double dX = ( xMax - xMin ) / ( numCols - 1 );
125  double dZ = ( zMax - zMin ) / ( numRows - 1 );
126 
127  deBoorPoints.reserve( numRows * numCols );
128 
129  for( int row = 0; row < numRows; ++row )
130  for( int col = 0; col < numCols; ++col )
131  {
132  double x = xMin + dX * col;
133  double z = zMin + dZ * row;
134 
135  double y = 0;
136  double numerator = 0, denominator = 0;
137 
138  //<local shepard with franke-little-weights>
139  for( givenPointsIt = givenPoints.begin(); givenPointsIt != givenPoints.end(); ++givenPointsIt )
140  {
141  WVector3d dmy1 = *givenPointsIt;
142  WVector3d dmyArray( dmy1[0], dmy1[1], dmy1[2] );
143  dmyArray[1] = 0;
144  WVector3d thisPoint( x, 0, z );
145 
146  double xi; //greek alphabet
147 
148  if( length( thisPoint - dmyArray ) < m_radius )
149  {
150  xi = 1 - length( thisPoint - dmyArray ) / m_radius;
151  }
152  else
153  {
154  xi = 0;
155  }
156 
157  numerator += ( pow( xi, m_mu ) * dmy1[1] );
158  denominator += ( pow( xi, m_mu ) );
159  }
160  if( denominator == 0 )
161  {
162  y = 0;
163  }
164  else
165  {
166  y = numerator / denominator;
167  }
168  //</local shepard with franke-little-weights>
169  deBoorPoints.push_back( WVector3d( x, y, z ) );
170  }
171  return;
172 }
173 
175 {
176  std::vector< WVector3d > deBoorPoints;
177  m_splinePoints.clear();
178 
180 
181  RealEigenSystem eigenSys;
182 
183  jacobiEigenvector3D( myTensor, &eigenSys );
184 
185  eigenSys[0].second = normalize( eigenSys[0].second );
186  eigenSys[1].second = normalize( eigenSys[1].second );
187  eigenSys[2].second = normalize( eigenSys[2].second );
188 
189  // This sorts the entries automatically :-)
190  std::map< double, WVector3d > sortedEigenSystem;
191  for( size_t i = 0; i < 3 ; ++i )
192  {
193  sortedEigenSystem[eigenSys[i].first] = eigenSys[i].second;
194  }
195 
196  WMatrix< double > transMatrix = WMatrix< double >( 3, 3 );
197 
198  std::map< double, WVector3d >::iterator sortedSystemIter = sortedEigenSystem.begin();
199  transMatrix( 1, 0 ) =( *sortedSystemIter ).second[0];
200  transMatrix( 1, 1 ) =( *sortedSystemIter ).second[1];
201  transMatrix( 1, 2 ) =( *sortedSystemIter ).second[2];
202 
203  ++sortedSystemIter;
204  transMatrix( 0, 0 ) =( *sortedSystemIter ).second[0];
205  transMatrix( 0, 1 ) =( *sortedSystemIter ).second[1];
206  transMatrix( 0, 2 ) =( *sortedSystemIter ).second[2];
207 
208  ++sortedSystemIter;
209  transMatrix( 2, 0 ) =( *sortedSystemIter ).second[0];
210  transMatrix( 2, 1 ) =( *sortedSystemIter ).second[1];
211  transMatrix( 2, 2 ) =( *sortedSystemIter ).second[2];
212 
213  std::vector< WVector3d >::iterator pointsIt;
214 
215  //translate and orientate given points to origin
216  for( pointsIt = m_supportPoints.begin(); pointsIt != m_supportPoints.end(); ++pointsIt )
217  {
218  ( *pointsIt )[0] -= m_xAverage;
219  ( *pointsIt )[1] -= m_yAverage;
220  ( *pointsIt )[2] -= m_zAverage;
221 
222  WVector3d dmy( ( *pointsIt )[0], ( *pointsIt )[1], ( *pointsIt )[2] );
223 
224  WVector3d result = transMatrix * dmy;
225  ( *pointsIt )[0] = result[0];
226  ( *pointsIt )[1] = result[1];
227  ( *pointsIt )[2] = result[2];
228  }
229 
230  //get de Boor points using shepard's method
232 
233  //translate and orientate de Boor points back
234  transMatrix = invertMatrix3x3( transMatrix );
235  for( pointsIt = deBoorPoints.begin(); pointsIt != deBoorPoints.end(); ++pointsIt )
236  {
237  WVector3d dmy( ( *pointsIt )[0], ( *pointsIt )[1], ( *pointsIt )[2] );
238 
239  WVector3d result = transMatrix * dmy;
240  ( *pointsIt )[0] = result[0];
241  ( *pointsIt )[1] = result[1];
242  ( *pointsIt )[2] = result[2];
243 
244  ( *pointsIt )[0] += m_xAverage;
245  ( *pointsIt )[1] += m_yAverage;
246  ( *pointsIt )[2] += m_zAverage;
247  }
248 
249  WBSplineSurface splineSurface( m_order, m_order, deBoorPoints, m_numDeBoorCols, m_numDeBoorRows );
250 
252 
253  m_renderpointsPerCol = splineSurface.getNumSamplePointsU();
254  m_renderpointsPerRow = splineSurface.getNumSamplePointsT();
255 
256  std::shared_ptr< WTriangleMesh > newMesh( new WTriangleMesh( m_splinePoints.size(), 2 * m_renderpointsPerCol * m_renderpointsPerRow ) );
257 
258  for( std::vector< WVector3d >::iterator posIt = m_splinePoints.begin(); posIt != m_splinePoints.end(); ++posIt )
259  {
260  newMesh->addVertex( ( *posIt )[0], ( *posIt )[1], ( *posIt )[2] );
261  }
262 
263  for( int z = 0; z < m_renderpointsPerCol - 1; ++z )
264  {
265  for( int x = 0; x < m_renderpointsPerRow - 1; ++x )
266  {
267  int p0 = z * m_renderpointsPerCol + x;
268  int p1 = z * m_renderpointsPerCol + x + 1;
269  int p2 = ( z + 1 ) * m_renderpointsPerCol + x;
270  int p3 = ( z + 1 ) * m_renderpointsPerCol + x + 1;
271 
272  newMesh->addTriangle( p0, p1, p2 );
273  newMesh->addTriangle( p2, p1, p3 );
274  }
275  }
276 
277  m_tMesh = newMesh;
278 }
279 
280 std::vector< WVector3d > WSurface::getSplinePoints()
281 {
282  return m_splinePoints;
283 }
284 
286 {
288  execute();
289 }
290 
291 void WSurface::setSupportPoints( std::vector< WVector3d> supportPoints, bool forceUpdate )
292 {
293  m_supportPoints = supportPoints;
294  if( forceUpdate )
295  {
296  execute();
297  }
298 }
299 
300 std::shared_ptr< WTriangleMesh > WSurface::getTriangleMesh()
301 {
302  return m_tMesh;
303 }
A B-spline surface.
int getNumSamplePointsT()
Returns the number of sample points in the first direction that were used for the last call to sample...
void samplePoints(std::vector< WVector3d > *points, double tResolution, double uResolution)
Compute sample points on the spline surface for a given resolution in the two directions.
int getNumSamplePointsU()
Returns the number of sample points in the second direction that were used for the last call to sampl...
std::vector< WVector3d > m_splinePoints
stores the input points ????
Definition: WSurface.h:118
std::vector< WVector3d > m_supportPoints
stores the support points
Definition: WSurface.h:116
int m_renderpointsPerRow
resolution of the output mesh
Definition: WSurface.h:121
int m_numDeBoorCols
number of of columns for deBoor grid
Definition: WSurface.h:108
void setSupportPoints(std::vector< WVector3d > supportPoints, bool forceUpdate=false)
sets the vector of support points the surface is calculated from
Definition: WSurface.cpp:291
int m_order
order the splines
Definition: WSurface.h:109
~WSurface()
Destructs this WSurface.
Definition: WSurface.cpp:51
double m_sampleRateT
sampling rate of spline in first direction
Definition: WSurface.h:110
double m_mu
parameter of local shepard with franke-little-weights
Definition: WSurface.h:106
double m_zAverage
global mean of z values for covariance matrix
Definition: WSurface.h:114
void setSetSampleRate(float r)
SEts the sample rate for the splines.
Definition: WSurface.cpp:285
WTensorSym< 2, 3, double > getCovarianceMatrix(std::vector< WVector3d > points)
Calculates the covariance matrix for a given number of points inspace.
Definition: WSurface.cpp:55
std::vector< WVector3d > getSplinePoints()
Returns a copy of the spline point vector.
Definition: WSurface.cpp:280
double m_radius
param for the algo
Definition: WSurface.h:105
std::shared_ptr< WTriangleMesh > m_tMesh
Triangle mesh of the surface.
Definition: WSurface.h:103
double m_xAverage
global mean of x values for covariance matrix
Definition: WSurface.h:112
void getSplineSurfaceDeBoorPoints(std::vector< WVector3d > &givenPoints, std::vector< WVector3d > &deBoorPoints, int numRows, int numCols)
Calculates numRows*numCols deBoor points from given input points.
Definition: WSurface.cpp:94
void execute()
Runs the algo and constructs a spine surface from the given input points.
Definition: WSurface.cpp:174
int m_numDeBoorRows
number of of rows for deBoor grid
Definition: WSurface.h:107
double m_sampleRateU
sampling rate of spline in second direction
Definition: WSurface.h:111
WSurface()
Constructs new WSurface.
Definition: WSurface.cpp:36
int m_renderpointsPerCol
resolution of the output mesh
Definition: WSurface.h:120
std::shared_ptr< WTriangleMesh > getTriangleMesh()
getter
Definition: WSurface.cpp:300
double m_yAverage
global mean of y values for covariance matrix
Definition: WSurface.h:113
Implements a symmetric tensor that has the same number of components in every direction.
Definition: WTensorSym.h:73
Triangle mesh data structure allowing for convenient access of the elements.
Definition: WTriangleMesh.h:46