Developer Documentation
TriangleBSPT.hh
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 
44 //=============================================================================
45 //
46 // CLASS TriangleBSPT
47 //
48 //=============================================================================
49 
50 #pragma once
51 
52 
53 //== INCLUDES =================================================================
54 
55 #include "BSPTreeNode.hh"
56 #include "TriangleBSPCoreT.hh"
57 #include "BSPImplT.hh"
58 
59 #include <list>
60 //== CLASS DEFINITION =========================================================
61 
62 template <class BSPTraits>
63 class TriangleBSPT : public BSPImplT< TriangleBSPCoreT<BSPTraits> >
64 {
65 public:
67  typedef typename Base::Scalar Scalar;
68  TriangleBSPT(const BSPTraits& _traits,
69  const Scalar& _infinity = std::numeric_limits<Scalar>::infinity()) : Base(_traits, _infinity) {}
70 };
71 
72 //== CLASS DEFINITION =========================================================
73 
74 template <class Mesh, class SpecificTraits>
75 class OVMOMCommonTriangleBSPTraits : public SpecificTraits
76 {
77 public:
78 
79  typedef typename SpecificTraits::Point Point;
80  typedef typename SpecificTraits::Handle Handle;
81  typedef typename Point::value_type Scalar;
82  typedef std::vector<Handle> Handles;
83  typedef typename Handles::iterator HandleIter;
85 
86  explicit OVMOMCommonTriangleBSPTraits(const Mesh& _mesh) : SpecificTraits(_mesh) {}
87 
88  Scalar sqrdist(const Handle _h, const Point& _p) const
89  {
90  Point p0, p1, p2, q;
91  this->points(_h, p0, p1, p2);
92  return ACG::Geometry::distPointTriangleSquaredStable(_p, p0, p1, p2, q);
93  }
94 
95  void calculateBoundingBox(Node* _node, Point& median, int& axis)
96  {
97  //determine splitting axis
98  HandleIter it_h;
99  Point p0, p1, p2, bb_min, bb_max;
100  bb_min.vectorize(std::numeric_limits<typename Point::value_type>::infinity());
101  bb_max.vectorize(-std::numeric_limits<typename Point::value_type>::infinity());
102  std::list<Point> vertices;
103 
104  for (it_h = _node->begin(); it_h != _node->end(); ++it_h) {
105  this->points(*it_h, p0, p1, p2);
106  /*
107  bb_min.minimize(p0);
108  bb_min.minimize(p1);
109  bb_min.minimize(p2);
110  bb_max.maximize(p0);
111  bb_max.maximize(p1);
112  bb_max.maximize(p2);*/
113 
114  vertices.push_back(p0);
115  vertices.push_back(p1);
116  vertices.push_back(p2);
117  }
118  bb_min = _node->bb_min;
119  bb_max = _node->bb_max;
120 
121  // split longest side of bounding box
122  Point bb = bb_max - bb_min;
123  Scalar length = bb[0];
124  axis = 0;
125  if (bb[1] > length)
126  length = bb[(axis = 1)];
127  if (bb[2] > length)
128  length = bb[(axis = 2)];
129 
130  //calculate the median value in axis-direction
131  switch (axis) {
132  case 0:
133  vertices.sort(x_sort());
134  break;
135  case 1:
136  vertices.sort(y_sort());
137  break;
138  case 2:
139  vertices.sort(z_sort());
140  break;
141  }
142  vertices.unique();
143 
144  size_t size = vertices.size();
145  typename std::list<Point>::iterator it_v;
146  it_v = vertices.begin();
147  std::advance(it_v, size / 2);
148  median = *it_v;
149 
150  }
151 
152  void calculateBoundingBoxRoot(Node* _node)
153  {
154  HandleIter it;
155  Point p0, p1, p2, bb_min, bb_max;
156  bb_min.vectorize(FLT_MAX);
157  bb_max.vectorize(-FLT_MAX);
158  for (it = _node->begin(); it != _node->end(); ++it) {
159  this->points(*it, p0, p1, p2);
160  bb_min.minimize(p0);
161  bb_min.minimize(p1);
162  bb_min.minimize(p2);
163  bb_max.maximize(p0);
164  bb_max.maximize(p1);
165  bb_max.maximize(p2);
166  }
167  _node->bb_min = bb_min;
168  _node->bb_max = bb_max;
169  }
170 
171 private:
172  //functors for sorting in different directions
173  struct x_sort { bool operator()(const Point& first, const Point& second) { return (first[0] < second[0]); } };
174  struct y_sort { bool operator()(const Point& first, const Point& second) { return (first[1] < second[1]); } };
175  struct z_sort { bool operator()(const Point& first, const Point& second) { return (first[2] < second[2]); } };
176 };
177 
178 
179 //== CLASS DEFINITION =========================================================
180 
181 template <class Mesh>
183 {
184 public:
185  typedef typename Mesh::Point Point;
186  typedef typename Mesh::FaceHandle Handle;
187  typedef typename Mesh::VertexHandle VertexHandle;
188  explicit OMSpecificTriangleBSPTraits(const Mesh& _mesh) : mesh_(_mesh) {}
189 
191  inline void points(const Handle &_h, Point& _p0, Point& _p1, Point& _p2) const
192  {
193  const auto &mesh = this->mesh_;
194  typename Mesh::CFVIter fv_it(mesh.cfv_iter(_h));
195  _p0 = mesh.point(*fv_it);
196  ++fv_it;
197  _p1 = mesh.point(*fv_it);
198  ++fv_it;
199  _p2 = mesh.point(*fv_it);
200  }
201 protected:
202  const Mesh& mesh_;
203 };
204 
205 template<class Mesh>
207 
208 
209 //== CLASS DEFINITION =========================================================
210 template <class Mesh>
212  : public TriangleBSPT<OpenMeshTriangleBSPTraits<Mesh> >
213 {
214 public:
216  typedef TriangleBSPT<Traits> Base;
217  typedef typename Traits::Scalar Scalar;
218  OpenMeshTriangleBSPT(const Mesh& _mesh,
219  const Scalar& _infinity = std::numeric_limits<Scalar>::infinity())
220  : Base(Traits(_mesh), _infinity) {}
221 };
222 
223 
224 #if (defined ENABLE_POLYHEDRALMESH_SUPPORT) \
225  || (defined ENABLE_HEXAHEDRALMESH_SUPPORT) \
226  || (defined ENABLE_TETRAHEDRALMESH_SUPPORT)
227 
228 #include <OpenVolumeMesh/Core/PropertyHandles.hh>
229 //== CLASS DEFINITION =========================================================
230 
231 // Make sure all faces of the mesh have valence 3.
232 template <class Mesh>
233 class OVMSpecificTriangleBSPTraits
234 {
235 public:
236  typedef typename Mesh::PointT Point;
237  typedef OpenVolumeMesh::FaceHandle Handle;
238  typedef OpenVolumeMesh::VertexHandle VertexHandle;
239  explicit OVMSpecificTriangleBSPTraits(const Mesh& _mesh) : mesh_(_mesh) {}
240 
242  inline void points(const Handle &_h, Point& _p0, Point& _p1, Point& _p2) const
243  {
244  const auto &mesh = this->mesh_;
245  assert(mesh.valence(_h) == 3);
246  auto hfv_it (mesh.hfv_iter(mesh.halfface_handle(_h, 0)));
247  _p0 = mesh.vertex(*hfv_it++);
248  _p1 = mesh.vertex(*hfv_it++);
249  _p2 = mesh.vertex(*hfv_it++);
250  }
251 protected:
252  const Mesh& mesh_;
253 };
254 
255 
256 template<class Mesh>
257 using OpenVolumeMeshTriangleBSPTraits = OVMOMCommonTriangleBSPTraits<Mesh, OVMSpecificTriangleBSPTraits<Mesh>>;
258 
259 //== CLASS DEFINITION =========================================================
260 template <class Mesh>
261 class OpenVolumeMeshTriangleBSPT
262  : public TriangleBSPT<OpenVolumeMeshTriangleBSPTraits<Mesh> >
263 {
264 public:
265  typedef OpenVolumeMeshTriangleBSPTraits<Mesh> Traits;
266  typedef TriangleBSPT<Traits> Base;
267  typedef typename Traits::Scalar Scalar;
268  OpenVolumeMeshTriangleBSPT(const Mesh& _mesh,
269  const Scalar& _infinity = std::numeric_limits<Scalar>::infinity())
270  : Base(Traits(_mesh), _infinity) {}
271 };
272 
273 #endif
274 
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
void calculateBoundingBox(Node *_node, Point &median, int &axis)
Definition: TriangleBSPT.hh:95
void points(const Handle &_h, Point &_p0, Point &_p1, Point &_p2) const
Returns the points belonging to the face handle _h.
Vec::value_type distPointTriangleSquaredStable(const Vec &_p, const Vec &_v0, const Vec &_v1, const Vec &_v2, Vec &_nearestPoint)
squared distance from point _p to triangle (_v0, _v1, _v2)
Definition: Algorithms.cc:466
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136