14 #include <boost/assign/std/vector.hpp>
16 #ifdef NUKLEI_USE_CGAL
18 #ifndef CGAL_EIGEN3_ENABLED
19 # define CGAL_EIGEN3_ENABLED 1
22 #include <CGAL/Simple_cartesian.h>
23 #include <CGAL/AABB_tree.h>
24 #include <CGAL/AABB_traits.h>
25 #include <CGAL/AABB_triangle_primitive.h>
26 #include <CGAL/property_map.h>
27 #include <CGAL/IO/read_off_points.h>
28 #include <CGAL/IO/read_xyz_points.h>
29 #include <CGAL/IO/write_xyz_points.h>
30 #include <CGAL/IO/Polyhedron_iostream.h>
32 #include <CGAL/squared_distance_3.h>
33 #include <CGAL/Point_with_normal_3.h>
39 #ifdef NUKLEI_USE_CGAL
40 typedef CGAL::Simple_cartesian<double> K;
43 typedef K::Line_3 Line;
44 typedef K::Point_3 Point;
45 typedef K::Plane_3 Plane;
46 typedef K::Vector_3 Vector;
47 typedef K::Segment_3 Segment;
48 typedef K::Triangle_3 Triangle;
49 typedef std::list<Triangle>::iterator Iterator;
50 typedef CGAL::AABB_triangle_primitive<K, Iterator> Primitive;
51 typedef CGAL::AABB_traits<K, Primitive> AABB_triangle_traits;
52 typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
53 #if CGAL_VERSION_NR >= 1040300000
54 typedef boost::optional< Tree::Intersection_and_primitive_id<Plane>::Type > Plane_intersection;
56 typedef boost::optional< Tree::Object_and_primitive_id > Plane_intersection;
60 SphereROI::SphereROI(
const std::string ¢erAndRadius)
62 std::istringstream is(centerAndRadius);
63 for (
unsigned int i = 0; i < 3; ++i)
69 BoxROI::BoxROI(
const std::string &s)
74 void BoxROI::setCenterAxesSize(
const std::string ¢erSize)
76 std::istringstream is(centerSize);
77 Vector3 center, axis1, axis2;
78 for (
unsigned int i = 0; i < 3; ++i)
80 for (
unsigned int i = 0; i < 3; ++i)
82 for (
unsigned int i = 0; i < 3; ++i)
86 axis1 -= center; axis2 -= center;
87 edgeLengths_[0] = axis1.Length()*2*1.2;
88 edgeLengths_[1] = axis2.Length()*2*1.2;
89 edgeLengths_[2] *= 2*1.0;
90 axis1.Normalize(); axis2.Normalize();
93 ori.SetColumn(0, axis1);
94 ori.SetColumn(1, axis2);
95 ori.SetColumn(2, la::normalized(axis1.Cross(axis2)));
99 la::copyRotation(centerOri_, ori);
102 void BoxROI::setCenterOriSize(
const std::string ¢erSize)
104 std::istringstream is(centerSize);
106 for (
unsigned int i = 0; i < 3; ++i)
108 for (
unsigned int i = 0; i < 4; ++i)
110 for (
unsigned int i = 0; i < 3; ++i)
112 la::copyRotation(centerOri_, ori);
115 bool SphereROI::contains_(
const Vector3 &v)
const
117 return dist<groupS::r3>::d(v, center_) <= radius_;
120 bool BoxROI::contains_(
const Vector3 &v)
const
122 Vector3 projection =
la::project(centerLoc_, centerOri_, v);
124 return std::fabs(projection[0]) <= edgeLengths_[0]/2. &&
125 std::fabs(projection[1]) <= edgeLengths_[1]/2. &&
126 std::fabs(projection[2]) <= edgeLengths_[2]/2.;
136 a(a), b(b), c(c), d(d)
144 BoxFace make_boxface(
const int a,
149 return BoxFace(a, b, c, d);
152 void BoxROI::pushTriangles_(std::list<boost::any>& triangles)
const
154 #ifdef NUKLEI_USE_CGAL
155 KernelCollection corners;
158 k.loc_ = Vector3(edgeLengths_.X()/2 , + edgeLengths_.Y()/2 , + edgeLengths_.Z()/2);
163 k.loc_ = Vector3(edgeLengths_.X()/2 , + edgeLengths_.Y()/2 , - edgeLengths_.Z()/2);
168 k.loc_ = Vector3(edgeLengths_.X()/2 , - edgeLengths_.Y()/2 , + edgeLengths_.Z()/2);
173 k.loc_ = Vector3(edgeLengths_.X()/2 , - edgeLengths_.Y()/2 , - edgeLengths_.Z()/2);
178 k.loc_ = Vector3(- edgeLengths_.X()/2 , + edgeLengths_.Y()/2 , + edgeLengths_.Z()/2);
183 k.loc_ = Vector3(- edgeLengths_.X()/2 , + edgeLengths_.Y()/2 , - edgeLengths_.Z()/2);
188 k.loc_ = Vector3(- edgeLengths_.X()/2 , - edgeLengths_.Y()/2 , + edgeLengths_.Z()/2);
193 k.loc_ = Vector3(- edgeLengths_.X()/2 , - edgeLengths_.Y()/2 , - edgeLengths_.Z()/2);
197 corners.transformWith(centerLoc_, centerOri_);
199 std::vector<BoxFace> faces;
201 using namespace boost::assign;
202 faces += make_boxface(0, 1, 3, 2),
203 make_boxface(2, 3, 7, 6),
204 make_boxface(6, 7, 5, 4),
205 make_boxface(4, 5, 1, 0),
206 make_boxface(0, 1, 3, 2),
207 make_boxface(0, 2, 6, 4),
208 make_boxface(1, 3, 7, 5);
211 for (std::vector<BoxFace>::const_iterator i = faces.begin();
212 i != faces.end(); ++i)
214 const Vector3& aa = corners.at(i->a).getLoc();
215 const Vector3& bb = corners.at(i->b).getLoc();
216 const Vector3& cc = corners.at(i->c).getLoc();
217 const Vector3& dd = corners.at(i->d).getLoc();
219 Point a(aa.X(), aa.Y(), aa.Z());
220 Point b(bb.X(), bb.Y(), bb.Z());
221 Point c(cc.X(), cc.Y(), cc.Z());
222 Point d(dd.X(), dd.Y(), dd.Z());
224 triangles.push_back(Triangle(a,b,c));
225 triangles.push_back(Triangle(a,d,c));
228 NUKLEI_THROW(
"This function requires CGAL. See http://renaud-detry.net/nuklei/group__install.html");
233 void BoxROI::buildAABBTree_()
235 #ifdef NUKLEI_USE_CGAL
236 std::list<Triangle> triangles;
237 std::list<boost::any> t;
239 for (std::list<boost::any>::const_iterator i = t.begin(); i != t.end(); ++i)
241 triangles.push_back(boost::any_cast<Triangle>(*i));
245 boost::shared_ptr<Tree> tree(
new Tree(triangles.begin(),triangles.end()));
248 NUKLEI_THROW(
"This function requires CGAL. See http://renaud-detry.net/nuklei/group__install.html");
252 #ifdef NUKLEI_USE_CGAL
253 bool intersects(Plane p,
const boost::any& t)
257 boost::shared_ptr<Tree> tree = boost::any_cast< boost::shared_ptr<Tree> >(t);
258 Plane_intersection plane_intersection = tree->any_intersection(p);
259 return static_cast<bool>(plane_intersection);
263 bool BoxROI::intersectsPlane(
const Vector3& p,
const Vector3& q,
const Vector3& r)
const
265 #ifdef NUKLEI_USE_CGAL
266 Point pp(p.X(), p.Y(), p.Z());
267 Point qq(q.X(), q.Y(), q.Z());
268 Point rr(r.X(), r.Y(), r.Z());
269 Plane plane_query(pp, qq, rr);
270 return intersects(plane_query, tree_);
272 NUKLEI_THROW(
"This function requires CGAL. See http://renaud-detry.net/nuklei/group__install.html");
276 bool BoxROI::intersectsPlane(
const Vector3& p,
const Vector3& v)
const
278 #ifdef NUKLEI_USE_CGAL
279 Vector vec(v.X(), v.Y(), v.Z());
280 Point a(p.X(), p.Y(), p.Z());
281 Plane plane_query(a,vec);
282 return intersects(plane_query, tree_);
284 NUKLEI_THROW(
"This function requires CGAL. See http://renaud-detry.net/nuklei/group__install.html");