Blender  V2.93
BLI_mesh_intersect.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
26 #ifdef WITH_GMP
27 
28 # include <iostream>
29 
30 # include "BLI_array.hh"
31 # include "BLI_double3.hh"
32 # include "BLI_index_range.hh"
33 # include "BLI_map.hh"
34 # include "BLI_math_mpq.hh"
35 # include "BLI_mpq3.hh"
36 # include "BLI_span.hh"
37 # include "BLI_utility_mixins.hh"
38 # include "BLI_vector.hh"
39 
40 namespace blender::meshintersect {
41 
42 constexpr int NO_INDEX = -1;
43 
59 struct Vert {
60  mpq3 co_exact;
61  double3 co;
62  int id = NO_INDEX;
63  int orig = NO_INDEX;
64 
65  Vert() = default;
66  Vert(const mpq3 &mco, const double3 &dco, int id, int orig);
67  ~Vert() = default;
68 
70  bool operator==(const Vert &other) const;
71 
73  uint64_t hash() const;
74 };
75 
76 std::ostream &operator<<(std::ostream &os, const Vert *v);
77 
85 struct Plane {
86  mpq3 norm_exact;
87  mpq_class d_exact;
88  double3 norm;
89  double d;
90 
91  Plane() = default;
92  Plane(const mpq3 &norm_exact, const mpq_class &d_exact);
93  Plane(const double3 &norm, const double d);
94 
95  /* Test equality on the exact fields. */
96  bool operator==(const Plane &other) const;
97 
98  /* Hash on the exact fields. */
99  uint64_t hash() const;
100 
101  void make_canonical();
102  bool exact_populated() const;
103  void populate_exact();
104 };
105 
106 std::ostream &operator<<(std::ostream &os, const Plane *plane);
107 
124 struct Face : NonCopyable {
125  Array<const Vert *> vert;
126  Array<int> edge_orig;
127  Array<bool> is_intersect;
128  Plane *plane = nullptr;
129  int id = NO_INDEX;
130  int orig = NO_INDEX;
131 
132  using FacePos = int;
133 
134  Face() = default;
135  Face(Span<const Vert *> verts, int id, int orig, Span<int> edge_origs, Span<bool> is_intersect);
136  Face(Span<const Vert *> verts, int id, int orig);
137  ~Face();
138 
139  bool is_tri() const
140  {
141  return vert.size() == 3;
142  }
143 
144  /* Test equality of verts, in same positions. */
145  bool operator==(const Face &other) const;
146 
147  /* Test equality faces allowing cyclic shifts. */
148  bool cyclic_equal(const Face &other) const;
149 
150  FacePos next_pos(FacePos p) const
151  {
152  return (p + 1) % vert.size();
153  }
154 
155  FacePos prev_pos(FacePos p) const
156  {
157  return (p + vert.size() - 1) % vert.size();
158  }
159 
160  const Vert *const &operator[](int index) const
161  {
162  return vert[index];
163  }
164 
165  int size() const
166  {
167  return vert.size();
168  }
169 
170  const Vert *const *begin() const
171  {
172  return vert.begin();
173  }
174 
175  const Vert *const *end() const
176  {
177  return vert.end();
178  }
179 
180  IndexRange index_range() const
181  {
182  return IndexRange(vert.size());
183  }
184 
185  void populate_plane(bool need_exact);
186 
187  bool plane_populated() const
188  {
189  return plane != nullptr;
190  }
191 };
192 
193 std::ostream &operator<<(std::ostream &os, const Face *f);
194 
202 class IMeshArena : NonCopyable, NonMovable {
203  class IMeshArenaImpl;
204  std::unique_ptr<IMeshArenaImpl> pimpl_;
205 
206  public:
207  IMeshArena();
208  ~IMeshArena();
209 
214  void reserve(int vert_num_hint, int face_num_hint);
215 
216  int tot_allocated_verts() const;
217  int tot_allocated_faces() const;
218 
225  const Vert *add_or_find_vert(const mpq3 &co, int orig);
226  const Vert *add_or_find_vert(const double3 &co, int orig);
227 
228  Face *add_face(Span<const Vert *> verts,
229  int orig,
230  Span<int> edge_origs,
231  Span<bool> is_intersect);
232  Face *add_face(Span<const Vert *> verts, int orig, Span<int> edge_origs);
233  Face *add_face(Span<const Vert *> verts, int orig);
234 
236  const Vert *find_vert(const mpq3 &co) const;
237  const Face *find_face(Span<const Vert *> verts) const;
238 };
239 
251 class IMesh {
252  Array<Face *> face_; /* Not `const` so can lazily populate planes. */
253  Array<const Vert *> vert_; /* Only valid if vert_populated_. */
254  Map<const Vert *, int> vert_to_index_; /* Only valid if vert_populated_. */
255  bool vert_populated_ = false;
256 
257  public:
258  IMesh() = default;
259  IMesh(Span<Face *> faces) : face_(faces)
260  {
261  }
262 
263  void set_faces(Span<Face *> faces);
264  Face *face(int index) const
265  {
266  return face_[index];
267  }
268 
269  int face_size() const
270  {
271  return face_.size();
272  }
273 
274  int vert_size() const
275  {
276  return vert_.size();
277  }
278 
279  bool has_verts() const
280  {
281  return vert_populated_;
282  }
283 
284  void set_dirty_verts()
285  {
286  vert_populated_ = false;
287  vert_to_index_.clear();
288  vert_ = Array<const Vert *>();
289  }
290 
291  /* Pass `max_verts` if there is a good bound estimate on the maximum number of verts. */
292  void populate_vert();
293  void populate_vert(int max_verts);
294 
295  const Vert *vert(int index) const
296  {
297  BLI_assert(vert_populated_);
298  return vert_[index];
299  }
300 
302  int lookup_vert(const Vert *v) const;
303 
304  IndexRange vert_index_range() const
305  {
306  BLI_assert(vert_populated_);
307  return IndexRange(vert_.size());
308  }
309 
310  IndexRange face_index_range() const
311  {
312  return IndexRange(face_.size());
313  }
314 
315  Span<const Vert *> vertices() const
316  {
317  BLI_assert(vert_populated_);
318  return Span<const Vert *>(vert_);
319  }
320 
321  Span<Face *> faces() const
322  {
323  return Span<Face *>(face_);
324  }
325 
335  bool erase_face_positions(int f_index, Span<bool> face_pos_erase, IMeshArena *arena);
336 
337  void remove_null_faces();
338 };
339 
340 std::ostream &operator<<(std::ostream &os, const IMesh &mesh);
341 
352 IMesh trimesh_self_intersect(const IMesh &tm_in, IMeshArena *arena);
353 
354 IMesh trimesh_nary_intersect(const IMesh &tm_in,
355  int nshapes,
356  std::function<int(int)> shape_fn,
357  bool use_self,
358  IMeshArena *arena);
359 
361 IMesh triangulate_polymesh(IMesh &imesh, IMeshArena *arena);
362 
364 void write_obj_mesh(IMesh &m, const std::string &objname);
365 
366 } /* namespace blender::meshintersect */
367 
368 #endif /* WITH_GMP */
#define BLI_assert(a)
Definition: BLI_assert.h:58
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE btVector3 & operator[](int i)
Get a mutable reference to a row of the matrix as a vector.
Definition: btMatrix3x3.h:157
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition: btVector3.h:263
struct Vert Vert
static float verts[][3]
static char faces[256]
struct Face Face
std::ostream & operator<<(std::ostream &os, const CDT_result< T > &r)
constexpr bool operator==(StringRef a, StringRef b)
#define hash
Definition: noise.c:169
unsigned __int64 uint64_t
Definition: stdint.h:93