Evaluate function gradient at position x-y-z and pass back vector. Point x[3] is transformed through transform (if provided).
| 174 | // Evaluate function gradient at position x-y-z and pass back vector. Point |
| 175 | // x[3] is transformed through transform (if provided). |
| 176 | void vtkImplicitFunction::FunctionGradient(const double x[3], double g[3]) |
| 177 | { |
| 178 | if (!this->Transform) |
| 179 | { |
| 180 | this->EvaluateGradient(const_cast<double*>(x), g); |
| 181 | } |
| 182 | else // pass point through transform |
| 183 | { |
| 184 | double pt[3]; |
| 185 | double A[3][3]; |
| 186 | this->Transform->Update(); |
| 187 | this->Transform->InternalTransformDerivative(x, pt, A); |
| 188 | this->EvaluateGradient(static_cast<double*>(pt), g); |
| 189 | |
| 190 | // The gradient must be transformed using the same math as is |
| 191 | // use for a normal to a surface: it must be multiplied by the |
| 192 | // inverse of the transposed inverse of the Jacobian matrix of |
| 193 | // the transform, which is just the transpose of the Jacobian. |
| 194 | vtkMath::Transpose3x3(A, A); |
| 195 | vtkMath::Multiply3x3(A, g, g); |
| 196 | |
| 197 | /* If the determinant of the Jacobian matrix is negative, |
| 198 | then the gradient points in the opposite direction. This |
| 199 | behaviour is actually incorrect, but is necessary to |
| 200 | balance the incorrect behaviour of FunctionValue. Otherwise, |
| 201 | if you feed certain VTK filters a transform with a flip |
| 202 | the gradient will point in the wrong direction and they |
| 203 | will never converge to a result */ |
| 204 | |
| 205 | if (vtkMath::Determinant3x3(A) < 0) |
| 206 | { |
| 207 | g[0] = -g[0]; |
| 208 | g[1] = -g[1]; |
| 209 | g[2] = -g[2]; |
| 210 | } |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | // Overload standard modified time function. If Transform is modified, |
| 215 | // then this object is modified as well. |
no test coverage detected