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