ViennaLS
Loading...
Searching...
No Matches
lsTransformMesh.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4
5#include <vcVectorType.hpp>
6
7#include <lsMesh.hpp>
8
9namespace viennals {
10
11using namespace viennacore;
12
15enum struct TransformEnum : unsigned {
19};
20
21template <class T> class TransformMesh {
22 SmartPointer<Mesh<T>> mesh = nullptr;
24 VectorType<T, 3> transformVector{};
25 T angle = 0.0;
26 double numericEps = 1e-6;
27
28 // check vector for all zeros
29 bool isValidVector() const {
30 if (DotProduct(transformVector, transformVector) < numericEps)
31 return false;
32 return true;
33 }
34
35 void translateMesh() {
36 // if vector is 0, just don't do anything
37 if (!isValidVector()) {
38 return;
39 }
40 for (auto &node : mesh->nodes) {
41 for (unsigned i = 0; i < 3; ++i) {
42 node[i] += transformVector[i];
43 }
44 }
45 }
46
47 // rotation of mesh around the vector transform vector by the angle
48 void rotateMesh() {
49 // if invalid input, dont do anything
50 if (!isValidVector()) {
51 return;
52 }
53 if (std::abs(angle) < numericEps) {
54 return;
55 }
56 const double norm = std::sqrt(transformVector[0] * transformVector[0] +
57 transformVector[1] * transformVector[1] +
58 transformVector[2] * transformVector[2]);
59 for (unsigned i = 0; i < 3; ++i) {
60 transformVector[i] /= norm;
61 }
62 const auto axis = transformVector;
63 double sinAngle = std::sin(angle);
64 double cosAngle = std::cos(angle);
65 double uniMinusCosAngle = 1 - cosAngle;
66 for (auto &node : mesh->nodes) {
67 auto oldNode = node;
68 double term1 = axis[0] * node[0] + axis[1] * node[1] + axis[2] * node[2];
69 for (unsigned i = 0; i < 3; ++i) {
70 unsigned ip1 = (i + 1) % 3;
71 unsigned ip2 = (i + 2) % 3;
72 node[i] =
73 axis[i] * term1 * uniMinusCosAngle + oldNode[i] * cosAngle +
74 (axis[ip1] * oldNode[ip2] - axis[ip2] * oldNode[ip1]) * sinAngle;
75 }
76 }
77 }
78
79 void scaleMesh() {
80 if (!isValidVector()) {
81 Logger::getInstance()
82 .addWarning("TransformMesh: TransformVector is not valid!")
83 .print();
84 return;
85 }
86 for (auto &node : mesh->nodes) {
87 for (unsigned i = 0; i < 3; ++i) {
88 node[i] *= transformVector[i];
89 }
90 }
91 }
92
93public:
94 TransformMesh(SmartPointer<Mesh<T>> passedMesh,
96 Vec3D<T> passedTransformVector = {}, double passedAngle = 0.0)
97 : mesh(passedMesh), transform(passedTransform),
98 transformVector(passedTransformVector), angle(passedAngle) {}
99
100 void apply() {
101 if (mesh == nullptr) {
102 Logger::getInstance()
103 .addWarning("No mesh passed to TransformMesh. Not transforming!")
104 .print();
105 }
106
107 switch (transform) {
109 translateMesh();
110 break;
112 rotateMesh();
113 break;
115 scaleMesh();
116 break;
117 default:
118 Logger::getInstance()
119 .addWarning(
120 "Invalid transform passed to TransformMesh. Not transforming!")
121 .print();
122 }
123 }
124};
125
126} // namespace viennals
This class holds an explicit mesh, which is always given in 3 dimensions. If it describes a 2D mesh,...
Definition lsMesh.hpp:21
void apply()
Definition lsTransformMesh.hpp:100
TransformMesh(SmartPointer< Mesh< T > > passedMesh, TransformEnum passedTransform=TransformEnum::TRANSLATION, Vec3D< T > passedTransformVector={}, double passedAngle=0.0)
Definition lsTransformMesh.hpp:94
Definition lsAdvect.hpp:36
TransformEnum
Enumeration for the different types of transformation operations.
Definition lsTransformMesh.hpp:15
@ TRANSLATION
Definition lsTransformMesh.hpp:16
@ SCALE
Definition lsTransformMesh.hpp:18
@ ROTATION
Definition lsTransformMesh.hpp:17
double T
Definition pyWrap.cpp:68