91 typedef TriangleMesh3D<T, BoundingVolumeHierarchy, SplitHeuristics> TSelf;
94 typedef typename TPoint::TVector TVector;
95 typedef Point2D<T> TUv;
99 typedef typename TPoint::TValue TValue;
100 typedef typename TPoint::TParam TParam;
101 typedef typename TPoint::TReference TReference;
102 typedef typename TPoint::TConstReference TConstReference;
103 typedef typename TPoint::TNumTraits TNumTraits;
105 typedef impl::IntersectTriangle3DWoop<TPoint> TIntersectTriangleWoop;
110 dimension = TPoint::dimension,
113 template <
typename U>
struct Rebind
115 typedef TriangleMesh3D<U, BoundingVolumeHierarchy, SplitHeuristics> Type;
118 struct IntersectionContext
126 TVector geometricNormal;
132 typedef typename TPoint::TVector TVector;
134 const TPoint* vertices[3];
135 const TVector* normals[3];
138 unsigned creaseLevel[3];
141 Result intersect(
const TRay& ray, TReference t, TParam tMin = 0, IntersectionContext* context = 0)
const;
142 Result intersect(
const TIntersectTriangleWoop& intersectWoop, TReference t, TParam tMin = 0, IntersectionContext* context = 0)
const;
143 size_t side(
const TPoint* v)
const;
145 TVector geometricNormal()
const;
148 typedef IntersectionContext TIntersectionContext;
149 typedef Triangle TTriangle;
150 typedef IndexTriangle TIndexTriangle;
153 typedef std::vector<Triangle> TTriangles;
154 typedef std::vector<TPoint> TVertices;
155 typedef std::vector<TVector> TNormals;
156 typedef std::vector<TUv> TUvs;
158 typedef typename TTriangles::const_iterator TTriangleIterator;
159 typedef typename TVertices::const_iterator TVertexIterator;
160 typedef typename TNormals::const_iterator TNormalIterator;
161 typedef typename TUvs::const_iterator TUvIterator;
163 typedef std::vector<TTriangleIterator> TTriangleIterators;
165 TriangleMesh3D(
const SplitHeuristics& heuristics = SplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
167 template <
typename VertexInputRange,
typename IndexTriangleInputRange>
169 const VertexInputRange& vertices,
const IndexTriangleInputRange& triangles,
170 const SplitHeuristics& heuristics = SplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
172 template <
typename VertexInputRange,
typename NormalInputRange,
typename UvInputRange,
typename IndexTriangleInputRange>
174 const VertexInputRange& vertices,
const NormalInputRange& normals,
const UvInputRange& uvs,
const IndexTriangleInputRange& triangles,
175 const SplitHeuristics& heuristics = SplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
177 template <
typename IndexTriangleInputRange>
179 TVertices&& vertices,
const IndexTriangleInputRange& triangles,
180 const SplitHeuristics& heuristics = SplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth)
183 template <
typename IndexTriangleInputRange>
185 TVertices&& vertices, TNormals&& normals, TUvs&& uvs,
const IndexTriangleInputRange& triangles,
186 const SplitHeuristics& heuristics = SplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth)
189 TriangleMesh3D(
const TriangleMesh3D& other);
190 TriangleMesh3D(TriangleMesh3D&& other);
192 TriangleMesh3D& operator=(
const TriangleMesh3D& other);
193 TriangleMesh3D& operator=(TriangleMesh3D&& other);
195 const TTriangles& triangles()
const;
196 const TVertices& vertices()
const;
197 const TNormals& normals()
const;
198 const TUvs& uvs()
const;
199 template <
typename OutputIterator>
200 OutputIterator indexTriangles(OutputIterator triangles)
const;
202 const TAabb aabb()
const;
203 const TValue area()
const;
205 void smoothNormals();
208 void loopSubdivision(
unsigned level);
213 void autoCrease(
unsigned level);
216 using TFilter = std::function<bool(TTriangleIterator, TValue t)>;
218 Result intersect(
const TRay& ray, TTriangleIterator& triangle, TReference t, TParam tMin = 0, IntersectionContext* context = 0)
const;
219 bool intersects(
const TRay& ray, TParam tMin, TParam tMax)
const;
221 Result intersectFilter(
const TRay& ray, TTriangleIterator& triangle, TReference t, TParam tMin, TFilter filter, IntersectionContext* context = 0)
const;
224 void swap(TSelf& other);
228 typedef spat::DefaultAabbRayTraits<TAabb, TRay> TAabbRayTraits;
232 const TIntersectTriangleWoop woop;
233 const TFilter filter;
235 IntersectInfo(
const TRay& ray, TFilter filter):
236 woop(ray.support(), ray.direction()),
240 struct TriangleTraits:
public TAabbRayTraits
242 typedef typename TSelf::TTriangle TObject;
243 typedef typename TSelf::TTriangleIterator TObjectIterator;
244 typedef const TTriangle& TObjectReference;
247 typedef typename TAabbRayTraits::TAabb TAabb;
248 typedef typename TAabbRayTraits::TRay TRay;
249 typedef typename TAabbRayTraits::TPoint TPoint;
250 typedef typename TAabbRayTraits::TVector TVector;
251 typedef typename TAabbRayTraits::TValue TValue;
252 typedef typename TAabbRayTraits::TParam TParam;
253 typedef typename TAabbRayTraits::TReference TReference;
254 typedef typename TAabbRayTraits::TConstReference TConstReference;
256 static const TAabb objectAabb(TObjectIterator triangle)
259 result += *(triangle->vertices[0]);
260 result += *(triangle->vertices[1]);
261 result += *(triangle->vertices[2]);
264 static bool objectIntersect(TObjectIterator triangle,
const TRay& , TReference t, TParam tMin,
const TInfo* info)
267 const IntersectInfo* myInfo =
static_cast<const IntersectInfo*
>(info);
268 const bool hit = triangle->intersect(myInfo->woop, t, tMin) ==
rOne;
273 if (myInfo->filter && !myInfo->filter(triangle, t))
279 static bool objectIntersects(TObjectIterator triangle,
const TRay& , TParam tMin, TParam tMax,
const TInfo* info)
282 const IntersectInfo* myInfo =
static_cast<const IntersectInfo*
>(info);
284 const bool hit = triangle->intersect(myInfo->woop, t, tMin) ==
rOne;
285 if (!hit || t >= tMax)
289 if (myInfo->filter && !myInfo->filter(triangle, t))
295 static bool objectIntersects(TObjectIterator triangle,
const TAabb& aabb,
const TInfo*)
297 const prim::Triangle3D<T> temp(
298 *(triangle->vertices[0]),
299 *(triangle->vertices[1]),
300 *(triangle->vertices[2]));
301 return prim::intersects(temp, aabb);
305 typedef BoundingVolumeHierarchy<TTriangle, TriangleTraits, SplitHeuristics> TTriangleTree;
308 defaultMaxObjectsPerLeaf = TTriangleTree::defaultMaxObjectsPerLeaf,
309 defaultMaxDepth = TTriangleTree::defaultMaxDepth,
317 LogicalEdge(Triangle* triangle,
const TPoint* tail,
const TPoint* head):
318 triangle(triangle), tail(tail), head(head) {}
319 bool operator==(
const LogicalEdge& other)
const
321 return tail == other.tail && head == other.head;
323 bool operator<(
const LogicalEdge& other)
const
325 return tail < other.tail || (tail == other.tail && head < other.head);
329 struct PositionalEdge
334 PositionalEdge(Triangle* triangle,
size_t k1,
size_t k2):
335 triangle(triangle), k1(k1), k2(k2)
337 const TPoint& v1 = *triangle->vertices[k1];
341 const TPoint& v2 = *triangle->vertices[k2];
346 bool operator<(
const PositionalEdge& other)
const
348 for (
size_t i = 0; i < size_; ++i)
350 if (x_[i] < other.x_[i])
return true;
351 if (x_[i] > other.x_[i])
return false;
363 typedef typename TPoint::TVector TVector;
365 HalfEdge(
const Triangle* triangle,
size_t edge): triangle_(triangle), edge_(edge) { LASS_ASSERT(edge_ < 3); }
366 HalfEdge(
const Triangle* triangle,
const TPoint* tail): triangle_(triangle), edge_(triangle->side(tail)) { LASS_ASSERT(edge_ < 3); }
367 const Triangle* triangle()
const {
return triangle_; }
368 size_t edge()
const {
return edge_; }
370 const TPoint* vertex()
const {
return triangle_->vertices[edge_]; }
371 const TVector* normal()
const {
return triangle_->normals[edge_]; }
372 const TUv* uv()
const {
return triangle_->uvs[edge_]; }
373 unsigned creaseLevel()
const {
return triangle_->creaseLevel[edge_]; }
374 void setNormal(
const TVector* normal) {
const_cast<Triangle*
>(triangle_)->normals[edge_] = normal; }
375 const TVector vector()
const {
return *oNext().vertex() - *vertex(); }
377 HalfEdge oPrev()
const {
return HalfEdge(triangle_, (edge_ + 2) % 3); }
378 HalfEdge oNext()
const {
return HalfEdge(triangle_, (edge_ + 1) % 3); }
379 HalfEdge rPrev()
const {
return sym().oNext(); }
380 HalfEdge rNext()
const {
return oPrev().sym(); }
383 const Triangle* other = triangle_->others[edge_];
384 if (!other || other->others[0] == triangle_)
386 return HalfEdge(other,
size_t(0));
388 if (other->others[1] == triangle_)
390 return HalfEdge(other, 1);
392 LASS_ASSERT(other->others[2] == triangle_);
393 return HalfEdge(other, 2);
396 bool isCrease()
const
398 return creaseLevel() > 0 || sym().sym() != *
this;
401 bool operator!()
const {
return !triangle_; }
402 explicit operator bool()
const {
return triangle_ != 0; }
404 const Triangle* triangle_;
408 typedef std::vector<const Triangle*> TVertexTriangles;
409 typedef std::vector<const TPoint*> TVertexRing;
410 typedef std::vector<const TUv*> TUvRing;
412 typedef std::pair<Triangle*, Triangle*> TWing;
413 typedef std::map<const TPoint*, TWing> TOddVertexWings;
415 template <
typename IndexTriangleInputIterator>
void buildMesh(IndexTriangleInputIterator first, IndexTriangleInputIterator last);
416 void connectTriangles();
417 void findVertexTriangles(TVertexTriangles& vertexTriangles)
const;
418 void findVertexRing(
const TPoint& vertex,
const Triangle* vertexTriangle, TVertexRing& ring, TVertexRing& creases, TUvRing& uvs)
const;
420 void subdivide(TTriangleIterators& selected, TOddVertexWings& oddVertexWings);
423 TTriangles triangles_;
427 size_t numBoundaryEdges_;