1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + This file is part of enGrid. +
5 // + Copyright 2008-2014 enGits GmbH +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 #include "geometrytools.h"
24 #include "utilities.h"
25 #include "egvtkobject.h"
27 Triangle::Triangle() : EgVtkObject()
33 Triangle::Triangle(vec3_t a
, vec3_t b
, vec3_t c
) : EgVtkObject()
42 Triangle::Triangle(vtkUnstructuredGrid
* grid
, vtkIdType id_a
, vtkIdType id_b
, vtkIdType id_c
) : EgVtkObject()
48 grid
->GetPoints()->GetPoint(id_a
, m_Xa
.data());
49 grid
->GetPoints()->GetPoint(id_b
, m_Xb
.data());
50 grid
->GetPoints()->GetPoint(id_c
, m_Xc
.data());
54 Triangle::Triangle(vtkUnstructuredGrid
* grid
, vtkIdType id_cell
) : EgVtkObject()
57 EG_GET_CELL(id_cell
, grid
);
62 grid
->GetPoints()->GetPoint(m_IdA
, m_Xa
.data());
63 grid
->GetPoints()->GetPoint(m_IdB
, m_Xb
.data());
64 grid
->GetPoints()->GetPoint(m_IdC
, m_Xc
.data());
67 EG_ERR_RETURN("only triangles allowed at the moment");
71 void Triangle::setDefaults()
76 m_Xa
= vec3_t(0, 0, 0);
77 m_Xb
= vec3_t(0, 1, 0);
78 m_Xc
= vec3_t(0, 0, 1);
79 m_NormalA
= vec3_t(0, 0, 0);
80 m_NormalB
= vec3_t(0, 0, 0);
81 m_NormalC
= vec3_t(0, 0, 0);
84 void Triangle::setupTriangle()
86 m_HasNeighbour
.fill(false, 6);
90 m_G3
= m_G1
.cross(m_G2
);
92 if(m_G3
.abs2() <= 0) {
98 if(!checkVector(m_G3
)) {
99 qWarning() << "m_G1=" << m_G1
;
100 qWarning() << "m_G2=" << m_G2
;
101 qWarning() << "m_G3=" << m_G3
;
105 m_A
= 0.5 * m_G3
.abs();
110 if(!checkVector(m_G3
)) {
111 qWarning() << "m_G1="<<m_G1
;
112 qWarning() << "m_G2="<<m_G2
;
113 qWarning() << "m_G3="<<m_G3
;
114 qWarning() << "m_Xa="<<m_Xa
;
115 qWarning() << "m_Xb="<<m_Xb
;
116 qWarning() << "m_Xc="<<m_Xc
;
117 this->saveTriangle("crash");
124 m_GI
= m_G
.inverse();
126 m_SmallestLength
= (m_Xb
- m_Xa
).abs();
127 m_SmallestLength
= min(m_SmallestLength
, (m_Xc
- m_Xb
).abs());
128 m_SmallestLength
= min(m_SmallestLength
, (m_Xa
- m_Xc
).abs());
130 m_LongestLength
= (m_Xb
- m_Xa
).abs();
131 m_LongestLength
= max(m_LongestLength
, (m_Xc
- m_Xb
).abs());
132 m_LongestLength
= max(m_LongestLength
, (m_Xa
- m_Xc
).abs());
134 // compute minimal height
135 double ha
= (GeometryTools::projectPointOnEdge(m_Xa
, m_Xb
, (m_Xc
- m_Xb
)) - m_Xa
).abs();
136 double hb
= (GeometryTools::projectPointOnEdge(m_Xb
, m_Xa
, (m_Xc
- m_Xa
)) - m_Xb
).abs();
137 double hc
= (GeometryTools::projectPointOnEdge(m_Xc
, m_Xa
, (m_Xb
- m_Xa
)) - m_Xc
).abs();
138 m_SmallestHeight
= min(ha
, min(hb
, hc
));
142 vec3_t
Triangle::local3DToGlobal3D(vec3_t r
)
147 vec3_t
Triangle::global3DToLocal3D(vec3_t x
)
149 vec3_t tmp
= x
- m_Xa
;
153 vec3_t
Triangle::local2DToGlobal3D(vec2_t r
)
155 return local3DToGlobal3D(vec3_t(r
[0], r
[1], 0));
158 vec2_t
Triangle::global3DToLocal2D(vec3_t x
)
160 vec3_t r
= global3DToLocal3D(x
);
161 return vec2_t(r
[0], r
[1]);
164 bool Triangle::snapOntoTriangle(vec3_t xp
, vec3_t
&xi
, vec3_t
&ri
, double &d
, int& side
, bool restrict_to_triangle
)
167 double scal
= (xp
- this->m_Xa
) * this->m_G3
;
170 x1
= xp
+ this->m_G3
;
171 x2
= xp
- scal
* this->m_G3
- this->m_G3
;
173 x1
= xp
- this->m_G3
;
174 x2
= xp
- scal
* this->m_G3
+ this->m_G3
;
176 // (xi,ri) gets set to the intersection of the line with the plane here!
177 bool intersects_face
= GeometryTools::intersectEdgeAndTriangle(this->m_Xa
, this->m_Xb
, this->m_Xc
, x1
, x2
, xi
, ri
);
179 if (intersects_face
) {
180 vec3_t dx
= xp
- this->m_Xa
;
181 d
= fabs(dx
* this->m_G3
);
183 double kab
= GeometryTools::intersection(this->m_Xa
, this->m_Xb
- this->m_Xa
, xp
, this->m_Xb
- this->m_Xa
);
184 double kac
= GeometryTools::intersection(this->m_Xa
, this->m_Xc
- this->m_Xa
, xp
, this->m_Xc
- this->m_Xa
);
185 double kbc
= GeometryTools::intersection(this->m_Xb
, this->m_Xc
- this->m_Xb
, xp
, this->m_Xc
- this->m_Xb
);
187 double dab
= (this->m_Xa
+ kab
* (this->m_Xb
- this->m_Xa
) - xp
).abs2();
188 double dac
= (this->m_Xa
+ kac
* (this->m_Xc
- this->m_Xa
) - xp
).abs2();
189 double dbc
= (this->m_Xb
+ kbc
* (this->m_Xc
- this->m_Xb
) - xp
).abs2();
190 double da
= (this->m_Xa
- xp
).abs2();
191 double db
= (this->m_Xb
- xp
).abs2();
192 double dc
= (this->m_Xc
- xp
).abs2();
195 d
= 1e99
;//max(max(max(max(max(dab,dac),dbc),da),db),dc);
198 if ((kab
>= 0) && (kab
<= 1)) {
199 xi
= this->m_Xa
+ kab
* (this->m_Xb
- this->m_Xa
);
200 ri
= vec3_t(kab
, 0, 0);
207 if ((kbc
>= 0) && (kbc
<= 1)) {
208 xi
= this->m_Xb
+ kbc
* (this->m_Xc
- this->m_Xb
);
209 ri
= vec3_t(1 - kbc
, kbc
, 0);
216 if ((kac
>= 0) && (kac
<= 1)) {
217 xi
= this->m_Xa
+ kac
* (this->m_Xc
- this->m_Xa
);
218 ri
= vec3_t(0, kac
, 0);
250 if (!intersects_face
&& !restrict_to_triangle
) {
253 if (xi
[0] > 1e98
) { // should never happen
256 return intersects_face
;
259 void Triangle::saveTriangle(QString filename
)
264 EG_VTKSP(vtkUnstructuredGrid
, triangle_grid
);
265 allocateGrid(triangle_grid
, N_cells
, N_points
);
267 vtkIdType node_count
= 0;
271 triangle_grid
->GetPoints()->SetPoint(node_count
, m_Xa
.data()); pts
[0]=node_count
; node_count
++;
272 triangle_grid
->GetPoints()->SetPoint(node_count
, m_Xb
.data()); pts
[1]=node_count
; node_count
++;
273 triangle_grid
->GetPoints()->SetPoint(node_count
, m_Xc
.data()); pts
[2]=node_count
; node_count
++;
275 triangle_grid
->InsertNextCell(VTK_TRIANGLE
,3,pts
);cell_count
++;
277 saveGrid(triangle_grid
, filename
+"_triangle_grid");
280 void Triangle::setNormals(vec3_t na
, vec3_t nb
, vec3_t nc
)
285 // compute normal vectors in local coordinate system
286 m_RNormalA
= global3DToLocal3D(a() + nA());
287 m_RNormalB
= global3DToLocal3D(a() + nB());
288 m_RNormalC
= global3DToLocal3D(a() + nC());