OMToolkit  1.0
The polygonal mesh processing tool.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
OMTransformationSolver.hxx
Go to the documentation of this file.
1 //==============================================================================
14 #ifndef _OM_TRANSFORMATION_SOLVER_HXX_
15 #define _OM_TRANSFORMATION_SOLVER_HXX_
16 
18 // Constructor - computes desired transformation
19 // Produces transformation matrix, which projects mesh coordinates intu tangent raster coordinates
20 // Center vertex will be projected to a center of a matrix
21 // @param matrixLength Raster length - square raster edge length (real in mesh space)
22 // @param resolution Number of raster pixels (matrix dimensions) - matrix is squared
23 // @param normal Normal on spacified vertex (futire Z direction)
24 // @param direction Direction of future X direction (for example maximum curvature direction)
25 // @param origin Coordinates of a vertex
27 template <class Vector>
29 {
30  // init helper variables
31  m_matrixLength = matrixLength;
32  m_resolution = resolution;
33  m_pixelSize = m_resolution/m_matrixLength;
34  ScalarT halfSize = m_resolution/2-0.5;
35 
36  // shift to center
37  m_modelTo2D = Eigen::Translation<ScalarT, 3>(-origin[0], -origin[1], -origin[2]);
38 
39  // set aux to normal orthogonaly projected to XY plane
40  VectorT aux = normal;
41  aux[2] = 0.0;
42 
43  // Align with ZX plane
44  ScalarT angle = vectorSignedAngle(VectorT(1.0, 0.0, 0.0), aux, VectorT(0.0, 0.0, 1.0));
45  m_modelTo2D = AngleAxis<ScalarT>(-angle, VectorEigen::UnitZ()) * m_modelTo2D;
46 
47  // update aux
48  aux = transformTo2DLinear(normal);
49 
50  // Align with ZY plane
51  angle = vectorSignedAngle(VectorT(0.0, 0.0, 1.0), aux, VectorT(0.0, 1.0, 0.0));
52  m_modelTo2D = AngleAxis<ScalarT>(-angle, VectorEigen::UnitY()) * m_modelTo2D;
53 
54  // Rotate ZX plane to satisfy direction
55  aux = transformTo2DLinear(direction);
56  aux[2] = 0.0;
57  angle = vectorSignedAngle(VectorT(1.0, 0.0, 0.0), aux, VectorT(0.0, 0.0, 1.0));
58  m_modelTo2D = AngleAxis<ScalarT>(-angle, VectorEigen::UnitZ()) * m_modelTo2D;
59 
60  // scale
61  m_modelTo2D = Scaling<ScalarT, 3>(m_pixelSize, m_pixelSize, m_pixelSize)* m_modelTo2D;
62 
63  // shift center to center of a matrix
64  m_modelTo2D = Translation<ScalarT, 3>(halfSize, halfSize, 0.0) *m_modelTo2D;
65 
66  // save inverse matrix
67  m_2DToModel = m_modelTo2D.inverse();
68 }
69 
71 // Transforms a mesh point (OpenMesh VecXX) to a raster
72 // @param point Point to be transformed
73 // @return Transformed point
75 template <class Vector>
77 {
78  VectorT aux;
79  ScalarT *data = point.data();
80  ScalarT *matrixData = m_modelTo2D.data();
81  aux[0] = data[0] * matrixData[0] + data[1] * matrixData[4] + data[2] * matrixData[8] + matrixData[12];
82  aux[1] = data[0] * matrixData[1] + data[1] * matrixData[5] + data[2] * matrixData[9] + matrixData[13];
83  aux[2] = data[0] * matrixData[2] + data[1] * matrixData[6] + data[2] * matrixData[10] + matrixData[14];
84  return aux;
85 }
86 
88 // Transforms a raster point (OpenMesh VecXX) to a mesh space
89 // @param point Point to be transformed
90 // @return Transformed point
92 template <class Vector>
94 {
95  VectorT aux;
96  ScalarT *data = point.data();
97  ScalarT *matrixData = m_2DToModel.data();
98  aux[0] = data[0] * matrixData[0] + data[1] * matrixData[4] + data[2] * matrixData[8] + matrixData[12];
99  aux[1] = data[0] * matrixData[1] + data[1] * matrixData[5] + data[2] * matrixData[9] + matrixData[13];
100  aux[2] = data[0] * matrixData[2] + data[1] * matrixData[6] + data[2] * matrixData[10] + matrixData[14];
101  return aux;
102 }
103 
105 // Transforms a mesh vector (OpenMesh VecXX) to a raster
106 // @param point Vector to be transformed
107 // @return Transformed vector
109 template <class Vector>
111 {
112  VectorT aux;
113  ScalarT *data = vector.data();
114  ScalarT *matrixData = m_modelTo2D.data();
115  aux[0] = data[0] * matrixData[0] + data[1] * matrixData[4] + data[2] * matrixData[8];
116  aux[1] = data[0] * matrixData[1] + data[1] * matrixData[5] + data[2] * matrixData[9];
117  aux[2] = data[0] * matrixData[2] + data[1] * matrixData[6] + data[2] * matrixData[10];
118  return aux;
119 }
120 
122 // Transforms a raster vector (OpenMesh VecXX) to a mesh space
123 // @param point Vector to be transformed
124 // @return Transformed vector
126 template <class Vector>
128 {
129  VectorT aux;
130  ScalarT *data = vector.data();
131  ScalarT *matrixData = m_2DToModel.data();
132  aux[0] = data[0] * matrixData[0] + data[1] * matrixData[4] + data[2] * matrixData[8];
133  aux[1] = data[0] * matrixData[1] + data[1] * matrixData[5] + data[2] * matrixData[9];
134  aux[2] = data[0] * matrixData[2] + data[1] * matrixData[6] + data[2] * matrixData[10];
135  return aux;
136 }
137 
139 // Function returns a signed angle (0..Pi) with use of a reference vector
140 // @param vec1 First vector
141 // @param vec2 Second vector
142 // @reference Reference vector (i.e. normal vector etc..)
143 // @return Signed angle of two vectors in interval 0..Pi
145 template <class Vector>
147 {
148  // calculate vectors length
149  ScalarT vec1Length = vec1.norm();
150  ScalarT vec2Length = vec2.norm();
151 
152  // calculatce vectors angle, test existence
153  if ( (vec1Length != 0.0) && (vec2Length != 0.0) )
154  {
155  VectorT normal; // given vectors normal
156 
157  // calculate vectors normal
158  normal = vec1%vec2;
159  // determine angle sign
160  ScalarT sign = ((normal|reference) < 0) ? -1 : 1;
161  // return result angle
162  return acos( (vec1|vec2) / (vec1Length * vec2Length) ) * sign;
163  }
164  else
165  return 0.0;
166 }
167 
169 // Function returns an unsigned angle (0..Pi)
170 // @param vec1 First vector
171 // @param vec2 Second vector
172 // @return Unsigned angle of two vectors in interval 0..Pi
174 template <class Vector>
176 {
177  // calculate vectors length
178  ScalarT vec1Length = vec1.norm();
179  ScalarT vec2Length = vec2.norm();
180 
181  // calculatce vectors angle, test existence
182  if ( (vec1Length != 0.0) && (vec2Length != 0.0) )
183  return acos( (vec1|vec2) / (vec1Length * vec2Length) );
184  else
185  return 0.0;
186 }
187 
189 // Function returns maximum coordinate of a associed matrix
190 // @returns Desired dimensions
192 template <class Vector>
194 {
195  return VectorT(m_resolution-1, m_resolution-1, 0.0);
196 }
197 
199 // Function returns pixel width (in a mesh space)
201 template <class Vector>
203 {
204  return m_pixelSize;
205 }
206 
207 #endif