triangular geometries and BRL-CAD seem to work now
[engrid.git] / src / libengrid / brlcadinterface.cpp
blobf898d7a89bc2ce664f659e478b90eaa6aca86f27
1 //
2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 // + +
4 // + This file is part of enGrid. +
5 // + +
6 // + Copyright 2008-2013 enGits GmbH +
7 // + +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
12 // + +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
17 // + +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
20 // + +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 //
24 #include "brlcadinterface.h"
26 vec3_t BrlCadInterface::m_XIn;
27 vec3_t BrlCadInterface::m_XOut;
28 vec3_t BrlCadInterface::m_InNormal;
29 vec3_t BrlCadInterface::m_OutNormal;
30 bool BrlCadInterface::m_Hit;
31 double BrlCadInterface::m_InRadius;
32 double BrlCadInterface::m_OutRadius;
34 BrlCadInterface::BrlCadInterface(QString file_name, QString object_name)
36 m_Rtip = rt_dirbuild(qPrintable(file_name), m_IdBuf, sizeof(m_IdBuf));
37 if (m_Rtip == RTI_NULL) {
38 EG_ERR_RETURN("Unable to open BRL-CAD database!");
40 if (rt_gettree(m_Rtip, qPrintable(object_name)) < 0) {
41 EG_ERR_RETURN("unable to access selected object");
43 rt_prep_parallel(m_Rtip, 1);
44 application ap = {0};
45 m_Ap = ap;
46 m_Ap.a_rt_i = m_Rtip;
48 setName("BRL-CAD interface");
50 //m_Ap.a_onehit = 1;
53 int BrlCadInterface::hit(application *ap, struct partition *PartHeadp, seg *segs)
55 register struct partition *pp;
56 register struct hit *hitp;
57 register struct soltab *stp;
58 struct curvature cur;
59 point_t pt;
60 vect_t inormal;
61 vect_t onormal;
62 double curv;
63 int N = 0;
64 //for (pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) {
65 pp = PartHeadp->pt_forw;
67 ++N;
69 hitp = pp->pt_inhit;
70 stp = pp->pt_inseg->seg_stp;
72 VJOIN1(pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir);
74 RT_HIT_NORMAL(inormal, hitp, stp, &(ap->a_ray), pp->pt_inflip);
75 RT_CURVATURE(&cur, hitp, pp->pt_inflip, stp);
76 curv = max(fabs(cur.crv_c1), fabs(cur.crv_c2));
77 m_InRadius = 1.0/max(1e-10, curv);
79 m_XIn[0] = pt[0];
80 m_XIn[1] = pt[1];
81 m_XIn[2] = pt[2];
82 m_InNormal[0] = inormal[0];
83 m_InNormal[1] = inormal[1];
84 m_InNormal[2] = inormal[2];
86 hitp = pp->pt_outhit;
87 stp = pp->pt_outseg->seg_stp;
88 VJOIN1(pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir);
89 RT_HIT_NORMAL( onormal, hitp, stp, &(ap->a_ray), pp->pt_outflip );
90 RT_CURVATURE(&cur, hitp, pp->pt_inflip, stp);
91 curv = max(fabs(cur.crv_c1), fabs(cur.crv_c2));
92 m_OutRadius = 1.0/max(1e-10, curv);
94 m_XOut[0] = pt[0];
95 m_XOut[1] = pt[1];
96 m_XOut[2] = pt[2];
97 m_OutNormal[0] = onormal[0];
98 m_OutNormal[1] = onormal[1];
99 m_OutNormal[2] = onormal[2];
102 m_Hit = true;
105 int BrlCadInterface::miss(application *ap)
107 m_Hit = false;
110 bool BrlCadInterface::brlCadShootRay(vec3_t x, vec3_t v, vec3_t &x_in, vec3_t &x_out, vec3_t &n_in, vec3_t &n_out, double &r_in, double &r_out)
112 if (!checkVector(x)) {
113 EG_BUG;
115 if (!checkVector(v)) {
116 EG_BUG;
119 VSET(m_Ap.a_ray.r_pt, x[0], x[1], x[2]);
120 VSET(m_Ap.a_ray.r_dir, v[0], v[1], v[2]);
121 m_Hit = false;
122 m_Ap.a_hit = BrlCadInterface::hit;
123 m_Ap.a_miss = BrlCadInterface::miss;
124 rt_shootray(&m_Ap);
125 x_in = m_XIn;
126 n_in = m_InNormal;
127 r_in = m_InRadius;
128 x_out = m_XOut;
129 n_out = m_OutNormal;
130 r_out = m_OutRadius;
131 x = x_out;
132 if (!checkVector(x_in)) {
133 EG_BUG;
135 if (!checkVector(x_out)) {
136 EG_BUG;
138 if (!checkVector(n_in)) {
139 EG_BUG;
141 if (!checkVector(n_out)) {
142 EG_BUG;
144 return m_Hit;
147 BrlCadInterface::HitType BrlCadInterface::shootRay(vec3_t x, vec3_t v, vec3_t &x_hit, vec3_t &n_hit, double &r)
149 HitType hit_type = Miss;
150 v.normalise();
151 vec3_t x_in, x_out, n_in, n_out;
152 double r_in, r_out;
153 if (brlCadShootRay(x, v, x_in, x_out, n_in, n_out, r_in, r_out)) {
154 double d_in = (x_in - x)*v;
155 if (d_in > 0) {
156 x_hit = x_in;
157 n_hit = n_in;
158 r = r_in;
159 hit_type = HitIn;
161 double d_out = (x_out - x)*v;
162 if (d_out > 0) {
163 if (hit_type == Miss || d_out < d_in) {
164 x_hit = x_out;
165 n_hit = n_out;
166 hit_type = HitOut;
167 r = r_out;
171 return hit_type;
175 BrlCadInterface::PositionType BrlCadInterface::position(vec3_t x, vec3_t n)
177 vec3_t x_hit, n_hit;
178 double r_hit;
179 HitType hit_type = shootRay(x, n, x_hit, n_hit, r_hit);
180 if (hit_type == HitOut) {
181 return Inside;
183 if (hit_type == HitIn) {
184 return Outside;
187 // try to shoot in the opposite direction
188 n *= -1;
189 hit_type = shootRay(x, n, x_hit, n_hit, r_hit);
190 if (hit_type == HitOut) {
191 return Inside;
193 if (hit_type == HitIn) {
194 return Outside;
197 return Surface;