Hermes2D  2.0
transformable.cpp
1 // This file is part of Hermes2D.
2 //
3 // Hermes2D is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // Hermes2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
15 
16 #include "transformable.h"
17 #include "mesh.h"
18 namespace Hermes
19 {
20  namespace Hermes2D
21  {
22 #define H2D_IDENTIFY_TRF { 1.0, 1.0 }, { 0.0, 0.0 }
23 
24  Trf tri_trf[H2D_TRF_NUM] =
25  {
26  { { 0.5, 0.5 }, { -0.5, -0.5 } }, // son 0
27  { { 0.5, 0.5 }, { 0.5, -0.5 } }, // son 1
28  { { 0.5, 0.5 }, { -0.5, 0.5 } }, // son 2
29  { {-0.5, -0.5 }, { -0.5, -0.5 } }, // son 3
30  { H2D_IDENTIFY_TRF }, // identity
31  { H2D_IDENTIFY_TRF }, // identity
32  { H2D_IDENTIFY_TRF }, // identity
33  { H2D_IDENTIFY_TRF }, // identity
34  { H2D_IDENTIFY_TRF } // identity
35  };
36 
37  Trf quad_trf[H2D_TRF_NUM] =
38  {
39  { { 0.5, 0.5 }, { -0.5, -0.5 } }, // son 0
40  { { 0.5, 0.5 }, { 0.5, -0.5 } }, // son 1
41  { { 0.5, 0.5 }, { 0.5, 0.5 } }, // son 2
42  { { 0.5, 0.5 }, { -0.5, 0.5 } }, // son 3
43  { { 1.0, 0.5 }, { 0.0, -0.5 } }, // horz son 0
44  { { 1.0, 0.5 }, { 0.0, 0.5 } }, // horz son 1
45  { { 0.5, 1.0 }, { -0.5, 0.0 } }, // vert son 0
46  { { 0.5, 1.0 }, { 0.5, 0.0 } }, // vert son 1
47  { H2D_IDENTIFY_TRF } // identity
48  };
49 
50  Transformable::Transformable()
51  {
52  memset(stack, 0, sizeof(stack));
54  element = NULL;
55  }
56 
57  Transformable::~Transformable() {}
58 
60 
62  {
63  assert(top > 0);
64  ctm = stack + (--top);
65  sub_idx = (sub_idx - 1) >> 3;
66  }
67 
68  uint64_t Transformable::get_transform() const { return sub_idx; }
69 
71  {
72  stack[0].m[0] = stack[0].m[1] = 1.0;
73  stack[0].t[0] = stack[0].t[1] = 0.0;
74  ctm = stack;
75  sub_idx = top = 0;
76  }
77 
79  {
80  if(e==NULL) throw Exceptions::NullException(1);
81  element = e;
82  this->reset_transform();
83  }
84 
85  void Transformable::set_transform(uint64_t idx)
86  {
87  int son[25];
88  int i = 0;
89  while (idx > 0)
90  {
91  son[i++] = (idx - 1) & 7;
92  idx = (idx - 1) >> 3;
93  }
95  for (int k = i-1; k >= 0; k--)
96  push_transform(son[k]);
97  }
98 
100  {
101  assert(element != NULL);
102  if(top >= H2D_MAX_TRN_LEVEL)
103  throw Hermes::Exceptions::Exception("Too deep transform.");
104 
105  Trf* mat = stack + (++top);
106  Trf* tr = (element->is_triangle() ? tri_trf + son : quad_trf + son);
107 
108  mat->m[0] = ctm->m[0] * tr->m[0];
109  mat->m[1] = ctm->m[1] * tr->m[1];
110  mat->t[0] = ctm->m[0] * tr->t[0] + ctm->t[0];
111  mat->t[1] = ctm->m[1] * tr->t[1] + ctm->t[1];
112 
113  ctm = mat;
114  sub_idx = (sub_idx << 3) + son + 1; // see traverse.cpp if this changes
115  }
116 
117  void Transformable::push_transforms(std::set<Transformable *>& transformables, int son)
118  {
119  for(std::set<Transformable *>::iterator it = transformables.begin(); it != transformables.end(); ++it)
120  if(*it != NULL)
121  (*it)->push_transform(son);
122  }
123  void Transformable::pop_transforms(std::set<Transformable *>& transformables)
124  {
125  for(std::set<Transformable *>::iterator it = transformables.begin(); it != transformables.end(); ++it)
126  if(*it != NULL)
127  (*it)->pop_transform();
128  }
129  }
130 }