Code_TYMPAN  4.4.0
Industrial site acoustic simulation
cgal_tools.cpp
Go to the documentation of this file.
1 
10 #include <cassert>
11 #include <algorithm>
12 #include <functional>
13 
14 #include "cgal_tools.h"
15 
16 namespace tympan
17 {
18 
19 CGAL_Plane to_cgal(const OPlan& oplan)
20 {
22  CGAL_Vector3 n(to_cgal(oplan.rframe._vecK));
23  return CGAL_Plane(o, n);
24 }
25 
27 {
28  return v / sqrt(v.squared_length());
29 }
30 
31 std::deque<CGAL_Point3> build_box(float w, float h, CGAL_Point3 pta, CGAL_Point3 ptb)
32 {
33  // AB vector
34  CGAL_Vector3 pta_ptb(pta, ptb);
35  // We need to build a plane containing pt A and pt B. A third point is needed.
36  CGAL_Point3 some_point(0, 1, 0); // have a try (Y axis)
37  // If AB vector and Asome_point vectors are colinear, use X axis instead of Y axis
38  if (CGAL::cross_product(pta_ptb, CGAL_Vector3(pta, some_point)) == CGAL::NULL_VECTOR)
39  some_point = CGAL_Point3(1, 0, 0);
40  // Build a plane with pt A, pt B and the arbitrary point and compute the orthogonal vector
41  CGAL_Vector3 ortho = normalize(CGAL::orthogonal_vector(pta, ptb, some_point));
42  // Compute another orthogonal vector
43  CGAL_Vector3 ortho2 = CGAL::cross_product(normalize(pta_ptb), ortho);
44  // Build the face containing pt A (add 2 perpendicular unit vectors respectively multiplied by
45  // w/2 and h/2 since the face dimension is l x h)
46  std::deque<CGAL_Point3> vertices;
47  vertices.push_back(pta - ortho * h / 2 + ortho2 * w / 2); // orig
48  vertices.push_back(pta - ortho * h / 2 + ortho2 * w / 2 + pta_ptb); // x
49  vertices.push_back(pta - ortho * h / 2 - ortho2 * w / 2); // y
50  vertices.push_back(pta + ortho * h / 2 + ortho2 * w / 2); // z
51  return vertices;
52 }
53 
54 void intersection_report(std::deque<size_t>* intersected, CGAL_Triangles::iterator start_index,
55  const CGAL_TBox& a, const CGAL_TBox& b)
56 {
57  // here we know the 2 boxes intersect, but we don't know for sure that the triangle of
58  // box a intersects with box b. Make sure it is the case before inserting the triangle
59  if (CGAL::do_intersect(*a.handle(), b.bbox()))
60  {
61  intersected->push_back(a.handle() - start_index);
62  }
63 }
64 
65 // This implementation is inspired from http://doc.cgal.org/4.4/Box_intersection_d/index.html
66 // (see parts "4 Minimal Example for Intersecting Boxes" and
67 // "5 Example for Finding Intersecting 3D Triangles")
68 std::deque<size_t> intersected_triangles(CGAL_Triangles& triangle_soup, std::deque<CGAL_Point3> query_box,
69  float length, float width, float height)
70 {
71  std::deque<CGAL_TBox> boxes;
72  // Put the triangles of the scene (triangle soup) in iso-oriented bounded boxes
73  for (CGAL_Triangles::iterator it = triangle_soup.begin(); it != triangle_soup.end(); it++)
74  {
75  boxes.push_back(CGAL_TBox(it->bbox(), it));
76  }
77  // Create a triangle whose bounding box will have the dimensions of the "query" box,
78  // choosing 3 nodes of the box as the triangle nodes (works because CGAL bounding box is
79  // iso-oriented)
80  CGAL_Triangles query_triangle;
81  query_triangle.push_back(CGAL_Triangle(query_box[0], query_box[1], query_box[2]));
82  std::deque<CGAL_TBox> query_tboxes;
83  CGAL::Bbox_3 box = query_triangle.begin()->bbox();
84  // Make sure the new query box has the same dimensions as "query" OBox2
85 #ifndef NDEBUG
86  double epsilon = 0.0001;
87  double x_dim = abs(box.xmax() - box.xmin());
88  double y_dim = abs(box.ymax() - box.ymin());
89  double z_dim = abs(box.zmax() - box.zmin());
90 #endif
91  assert(abs(x_dim - length) < epsilon &&
92  "The dimension X of CGAL query box doesn't match query parameter.");
93  assert(abs(y_dim - width) < epsilon && "The dimension Y CGAL query box doesn't match query parameter.");
94  assert(abs(z_dim - height) < epsilon &&
95  "The dimension Z of CGAL query box doesn't match query parameter.");
96  query_tboxes.push_back(CGAL_TBox(box, query_triangle.begin()));
97  // Compute intersection between the triangles from the triangle soup and the box
98  // from the query.
99  // "intersected" will contain the indices of the triangles of the triangle soup
100  // that intersect with the triangle of the query deque.
101  std::deque<size_t> intersected;
102  // use currying to specify container and triangle start index from here and therefore
103  // avoid using global variables (these variables must be accessible from the callback function,
104  // but CGAL::box_intersection_d requires a callback function that only deals with 2 boxes).
105  auto cgal_callback = std::bind(intersection_report, &intersected, triangle_soup.begin(),
106  std::placeholders::_1, std::placeholders::_2);
107  CGAL::box_intersection_d(boxes.begin(), boxes.end(), query_tboxes.begin(), query_tboxes.end(),
108  cgal_callback);
109  // remove duplicates (first order the triangle ids since std::unique only works on
110  // an ordered container)
111  std::sort(intersected.begin(), intersected.end());
112  auto last = std::unique(intersected.begin(), intersected.end());
113  intersected.erase(last, intersected.end());
114  return intersected;
115 }
116 
117 /* **** class PolygonTriangulator **** */
118 
120 {
121  assert(poly.size() > 2);
122  assert(poly.is_simple() && "The polygon need to be simple - no 8 shape");
123  unsigned i = 0; // index of the current ve
124  BOOST_FOREACH (const CGAL_Point2& current, poly.container())
125  {
126  Vertex_handle current_vh = cdt.insert(current);
127  current_vh->info() = VertexInfo(i);
128  poly_vh.push_back(current_vh);
129  if (i > 0)
130  {
131  cdt.insert_constraint(poly_vh[i - 1], poly_vh[i]);
132  }
133  ++i;
134  }
135  // Closes the polygon
136  cdt.insert_constraint(poly_vh[--i], poly_vh[0]);
137 } // PolygonTriangulator::PolygonTriangulator()
138 
139 PolygonTriangulator::~PolygonTriangulator() {} // PolygonTriangulator::~PolygonTriangulator()
140 
142 {
143  assert(poly_vh.size() == poly.size() && "Inconsistency btw points and vertices vectors.");
144  // Let the checked access std exception trigger for out-of-bound indices
145  return poly_vh.at(i);
146 }
147 
148 void PolygonTriangulator::exportTriangles(std::deque<PolygonTriangulator::Triangle>& triangles) const
149 {
150  assert(triangles.size() == 0 && "triangles output arguments expected to be empty");
151  for (CDT::Finite_faces_iterator it = cdt.finite_faces_begin(); it != cdt.finite_faces_end(); ++it)
152  {
153  // Extract a representative inner point
154  CGAL_Point2 center = CGAL::centroid(cdt.triangle(it));
155  // Test whether it is inside the polygon
156  switch (poly.bounded_side(center))
157  {
158  case CGAL::ON_UNBOUNDED_SIDE:
159  case CGAL::ON_BOUNDARY: // this is the degenerate case of a flat triangle
160  continue;
161  case CGAL::ON_BOUNDED_SIDE:
162  triangles.push_back(cdt.triangle(it)); // `it` is a Face_handle
163  break;
164  }
165  }
166 }
167 
168 void PolygonTriangulator::exportTrianglesIndices(std::deque<Tri_indices>& triangles) const
169 {
170 
171  assert(triangles.size() == 0 && "triangles output arguments expected to be empty");
172  for (CDT::Finite_faces_iterator it = cdt.finite_faces_begin(); it != cdt.finite_faces_end(); ++it)
173  {
174  // Extract a representative inner point
175  CGAL_Point2 center = CGAL::centroid(cdt.triangle(it));
176  // Test whether it is inside the polygon
177  switch (poly.bounded_side(center))
178  {
179  case CGAL::ON_UNBOUNDED_SIDE:
180  case CGAL::ON_BOUNDARY: // this is the degenerate case of a flat triangle
181  continue;
182  case CGAL::ON_BOUNDED_SIDE:
183  Tri_indices tri;
184  for (unsigned i = 0; i < 3; ++i)
185  {
186  tri[i] = it->vertex(i)->info().i;
187  }
188  triangles.push_back(tri);
189  break;
190  }
191  }
192 }
193 
194 } // namespace tympan
Utilities to ease (and wrap) use of CGAL.
Plan defined by its equation : ax+by+cz+d=0.
Definition: plan.h:31
ORepere3D rframe
Definition: plan.h:333
OVector3D _vecK
Vector K for the Z axis.
Definition: 3d.h:1285
OPoint3D _origin
The origin point.
Definition: 3d.h:1279
PolygonTriangulator(const CGAL_Polygon &poly_)
Constructor from a CGAL_Polygon.
Definition: cgal_tools.cpp:119
const Vertex_handle & vertex_handle(unsigned i) const
Return the ith vertex handle.
Definition: cgal_tools.cpp:141
virtual ~PolygonTriangulator()
Destructor.
Definition: cgal_tools.cpp:139
const CGAL_Polygon & poly
Reference to the CGAL_Polygon to triangulate.
Definition: cgal_tools.h:188
CDT::Vertex_handle Vertex_handle
Definition: cgal_tools.h:143
boost::array< unsigned, 3 > Tri_indices
Definition: cgal_tools.h:149
void exportTrianglesIndices(std::deque< Tri_indices > &triangles) const
Exports the triangles inside the polygon.
Definition: cgal_tools.cpp:168
void exportTriangles(std::deque< CDT::Triangle > &triangles) const
Exports the triangles inside the polygon.
Definition: cgal_tools.cpp:148
Vertex_handles_container poly_vh
Polygon vertex handles.
Definition: cgal_tools.h:187
CGAL_Vector3 normalize(CGAL_Vector3 v)
normalize vector v
Definition: cgal_tools.cpp:26
CGAL::Triangle_3< CGAL_Gt > CGAL_Triangle
Definition: cgal_tools.h:50
CGAL_Plane to_cgal(const OPlan &oplan)
Convert a OPlan to CGAL_Plane.
Definition: cgal_tools.cpp:19
CGAL::Point_3< CGAL_Gt > CGAL_Point3
Definition: cgal_tools.h:45
CGAL::Vector_3< CGAL_Gt > CGAL_Vector3
Definition: cgal_tools.h:47
CGAL::Point_2< CGAL_Gt > CGAL_Point2
Definition: cgal_tools.h:44
CGAL::Box_intersection_d::Box_with_handle_d< double, 3, CGAL_Triangles::iterator > CGAL_TBox
Definition: cgal_tools.h:52
std::deque< CGAL_Triangle > CGAL_Triangles
Definition: cgal_tools.h:51
std::deque< CGAL_Point3 > build_box(float w, float h, CGAL_Point3 pta, CGAL_Point3 ptb)
return 4 points defining a 3D parallelepiped
Definition: cgal_tools.cpp:31
CGAL::Plane_3< CGAL_Gt > CGAL_Plane
Definition: cgal_tools.h:49
CGAL::Polygon_2< CGAL_Gt > CGAL_Polygon
Definition: cgal_tools.h:48
void intersection_report(std::deque< size_t > *intersected, CGAL_Triangles::iterator start_index, const CGAL_TBox &a, const CGAL_TBox &b)
Definition: cgal_tools.cpp:54
std::deque< size_t > intersected_triangles(CGAL_Triangles &triangle_soup, std::deque< CGAL_Point3 > query_box, float length, float width, float height)
Find the triangles from triangle_soup that are intersected by the 3D box including the points of quer...
Definition: cgal_tools.cpp:68