OMToolkit 1.0 The polygonal mesh processing tool.

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

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>
28 OMTransformationSolver<Vector>::OMTransformationSolver(ScalarT matrixLength, ScalarT resolution, VectorT normal, VectorT direction, VectorT origin)
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>
76 typename OMTransformationSolver<Vector>::VectorT OMTransformationSolver<Vector>::transformTo2D(VectorT point)
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>
93 typename OMTransformationSolver<Vector>::VectorT OMTransformationSolver<Vector>::transformToMesh(VectorT point)
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>
110 typename OMTransformationSolver<Vector>::VectorT OMTransformationSolver<Vector>::transformTo2DLinear(VectorT 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>
127 typename OMTransformationSolver<Vector>::VectorT OMTransformationSolver<Vector>::transformToMeshLinear(VectorT 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>
146 typename OMTransformationSolver<Vector>::ScalarT OMTransformationSolver<Vector>::vectorSignedAngle(VectorT& vec1, VectorT& vec2, VectorT reference)
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>
175 typename OMTransformationSolver<Vector>::ScalarT OMTransformationSolver<Vector>::vectorAngle(VectorT& vec1, VectorT& vec2)
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>
193 typename OMTransformationSolver<Vector>::VectorT OMTransformationSolver<Vector>::getMaxBounds()
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>
202 typename OMTransformationSolver<Vector>::ScalarT OMTransformationSolver<Vector>::getPixelSize()
203 {
204 return m_pixelSize;
205 }
206
207 #endif