fixed edge display for volume cells
[engrid-github.git] / src / libengrid / cadinterface.cpp
blob0e494118b7f2bd62101923a4a3bd1b697cb0101e
1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // + +
3 // + This file is part of enGrid. +
4 // + +
5 // + Copyright 2008-2014 enGits GmbH +
6 // + +
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. +
11 // + +
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. +
16 // + +
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/>. +
19 // + +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #include "cadinterface.h"
23 #include <QTextStream>
24 #include <QFile>
26 CadInterface::CadInterface()
28 QFile file(":/resources/misc/raysphere_fine.dat");
29 //QFile file(":/resources/misc/raysphere.dat");
30 //QFile file(":/resources/misc/raysphere_coarse.dat");
31 file.open(QIODevice::ReadOnly);
32 QTextStream s(&file);
33 int N;
34 s >> N;
35 m_RayPoints.resize(N);
36 for (int i = 0; i < N; ++i) {
37 for (int j = 0; j < 3; ++j) {
38 s >> m_RayPoints[i][j];
40 m_RayPoints[i].normalise();
42 m_LastRadius = 1e99;
43 m_LastNormal = vec3_t(0,0,0);
44 setName("generic CAD interface");
45 m_ShootRayImplemented = false;
46 getSet("surface meshing", "critical length for node snapping", 0.1, m_CriticalSnapLength);
49 void CadInterface::setForegroundGrid(vtkUnstructuredGrid *grid)
51 m_FGrid = grid;
52 m_FPart.trackGrid(m_FGrid);
57 vec3_t CadInterface::snap(vec3_t x, bool correct_curvature)
60 double L_best = 1e99;
61 double r_best;
62 vec3_t x_best;
63 vec3_t n_best;
64 bool no_hit = true;
65 foreach (vec3_t x_ray, m_RayPoints) {
66 double r_hit;
67 vec3_t x_hit;
68 vec3_t n_hit;
69 vec3_t v = x_ray;
71 // standard ray
72 if (shootRay(x, v, x_hit, n_hit, r_hit) != Miss) {
73 double L = (x_hit - x).abs();
74 if (L < L_best) {
75 x_best = x_hit;
76 n_best = n_hit;
77 r_best = r_hit;
78 L_best = L;
79 no_hit = false;
81 v = n_hit;
83 // shoot a "far-side return ray" ...
84 if (shootRay(x_hit, -1*x_ray, x_hit, n_hit, r_hit)) {
85 double L = (x_hit - x).abs();
86 if (L < L_best) {
87 x_best = x_hit;
88 n_best = n_hit;
89 r_best = r_hit;
90 L_best = L;
91 no_hit = false;
95 // re-shoot standard ray with surface normal
96 if (shootRay(x, v, x_hit, n_hit, r_hit) != Miss) {
97 double L = (x_hit - x).abs();
98 if (L < L_best) {
99 x_best = x_hit;
100 n_best = n_hit;
101 r_best = r_hit;
102 L_best = L;
103 no_hit = false;
107 // re-shoot standard ray with surface normal in opposite direction
108 v *= -1;
109 if (shootRay(x, v, x_hit, n_hit, r_hit) != Miss) {
110 double L = (x_hit - x).abs();
111 if (L < L_best) {
112 x_best = x_hit;
113 n_best = n_hit;
114 r_best = r_hit;
115 L_best = L;
116 no_hit = false;
122 if (no_hit) {
123 EG_BUG;
126 if (correct_curvature) {
127 x_best = correctCurvature(x_best);
130 m_LastNormal = n_best;
131 m_LastRadius = r_best;
132 return x_best;
135 vec3_t CadInterface::snapNode(vtkIdType id_node, bool correct_curvature)
137 vec3_t x;
138 m_FGrid->GetPoint(id_node, x.data());
139 return snapNode(id_node, x, correct_curvature);
142 vec3_t CadInterface::snapNode(vtkIdType id_node, vec3_t x, bool correct_curvature)
144 vec3_t n = m_FPart.globalNormal(id_node);
145 vec3_t x_proj;
146 if (shootRayAvailable()) {
147 projectNode(id_node, x, n, false, correct_curvature);
148 } else {
149 snap(x, correct_curvature);
151 double L_crit = m_CriticalSnapLength*m_FPart.getMinSurfaceStencilEdgeLength(id_node);
152 if ((x - x_proj).abs() < L_crit) {
153 return x_proj;
155 return snap(x, correct_curvature);
158 void CadInterface::notImplemented()
160 QString msg;
161 msg += "The functionality you are trying cannot be provided by the current CAD interface.\n";
162 msg += "You are using a \"" + name() + "\"";
163 EG_ERR_RETURN(msg);
167 vec3_t CadInterface::project(vec3_t x, vec3_t v, bool strict_direction, bool correct_curvature)
169 if (!checkVector(v)) {
170 return x;
172 vec3_t x_proj = x;
173 m_LastNormal = v;
174 m_LastRadius = 1e10;
176 vec3_t x_hit1, n_hit1, x_hit2, n_hit2;
177 double r_hit1, r_hit2;
178 CadInterface::HitType hit_type1, hit_type2;
180 hit_type1 = shootRay(x, v, x_hit1, n_hit1, r_hit1);
181 if (hit_type1 == CadInterface::Miss && !strict_direction) {
182 v *= -1;
183 hit_type1 = shootRay(x, v, x_hit1, n_hit1, r_hit1);
185 if (hit_type1 == CadInterface::Miss) {
186 m_Failed = true;
187 return x;
189 m_Failed = false;
190 v *= -1;
191 x_proj = x_hit1;
192 m_LastNormal = n_hit1;
193 m_LastRadius = r_hit1;
194 if (!strict_direction) {
195 hit_type2 = shootRay(x_hit1, v, x_hit2, n_hit2, r_hit2);
196 if (hit_type2 != CadInterface::Miss) {
197 if ((x - x_hit2).abs() < (x - x_hit1).abs()) {
198 x_proj = x_hit2;
199 m_LastNormal = n_hit2;
200 m_LastRadius = r_hit2;
205 if (correct_curvature) {
206 x_proj = correctCurvature(x_proj);
209 return x_proj;
212 vec3_t CadInterface::projectNode(vtkIdType, vec3_t x, vec3_t v, bool strict_direction, bool correct_curvature)
214 return project(x, v, strict_direction, correct_curvature);
217 vec3_t CadInterface::projectNode(vtkIdType id_node, vec3_t x, bool strict_direction, bool correct_curvature)
219 vec3_t v = m_FPart.globalNormal(id_node);
220 if (!checkVector(v)) {
221 cout << "vector defect (id_node=" << id_node << ")" << endl;
222 return x;
224 return projectNode(id_node, x, v, strict_direction, correct_curvature);
227 vec3_t CadInterface::projectNode(vtkIdType id_node, bool strict_direction, bool correct_curvature)
229 vec3_t x;
230 m_FGrid->GetPoint(id_node, x.data());
231 return projectNode(id_node, x, strict_direction, correct_curvature);
234 double CadInterface::getRadius(vtkIdType id_node)
236 vec3_t x;
237 m_FGrid->GetPoint(id_node, x.data());
238 snapNode(id_node, x, false);
239 return m_LastRadius;
242 CadInterface::HitType CadInterface::shootRay(vec3_t, vec3_t, vec3_t&, vec3_t&, double&)
244 notImplemented();
245 return Miss;