00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_TRIANGLE_MESH_3D_H
00051 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_TRIANGLE_MESH_3D_H
00052
00053 #include "prim_common.h"
00054 #include "aabb_3d.h"
00055 #include "point_2d.h"
00056 #include "ray_3d.h"
00057 #include "impl/intersect_triangle_3d.h"
00058 #include "../stde/iterator_range.h"
00059 #include "../num/impl/matrix_solve.h"
00060 #include "../spat/default_object_traits.h"
00061
00062 namespace lass
00063 {
00064 namespace prim
00065 {
00066
00067 struct IndexTriangle
00068 {
00069 std::size_t vertices[3];
00070 std::size_t normals[3];
00071 std::size_t uvs[3];
00072
00073 const size_t size() const { return 3; }
00074 static const std::size_t null() { return static_cast<std::size_t>(-1); }
00075 };
00076
00077 template
00078 <
00079 typename T,
00080 template <typename T, typename OT, typename SH> class BoundingVolumeHierarchy,
00081 typename SplitHeuristics
00082 >
00083 class TriangleMesh3D
00084 {
00085 public:
00086
00087 typedef TriangleMesh3D<T, BoundingVolumeHierarchy, SplitHeuristics> TSelf;
00088
00089 typedef Point3D<T> TPoint;
00090 typedef typename TPoint::TVector TVector;
00091 typedef Point2D<T> TUv;
00092 typedef Aabb3D<T> TAabb;
00093 typedef Ray3D<T> TRay;
00094
00095 typedef typename TPoint::TValue TValue;
00096 typedef typename TPoint::TParam TParam;
00097 typedef typename TPoint::TReference TReference;
00098 typedef typename TPoint::TConstReference TConstReference;
00099 typedef typename TPoint::TNumTraits TNumTraits;
00100
00101 enum { dimension = TPoint::dimension };
00102
00103 template <typename U> struct Rebind
00104 {
00105 typedef TriangleMesh3D<U, BoundingVolumeHierarchy, SplitHeuristics> Type;
00106 };
00107
00108 struct IntersectionContext
00109 {
00110 TVector normal;
00111 TVector dPoint_dU;
00112 TVector dPoint_dV;
00113 TVector dNormal_dU;
00114 TVector dNormal_dV;
00115 TVector geometricNormal;
00116 TUv uv;
00117 };
00118
00119 struct Triangle
00120 {
00121 const TPoint* vertices[3];
00122 const TVector* normals[3];
00123 const TUv* uvs[3];
00124 Triangle* others[3];
00125 unsigned creaseLevel[3];
00126
00127 const Result intersect(const TRay& ray, TReference t, TParam tMin = 0,
00128 IntersectionContext* context = 0) const;
00129 const size_t side(const TPoint* v) const;
00130 };
00131
00132 typedef IntersectionContext TIntersectionContext;
00133 typedef Triangle TTriangle;
00134 typedef IndexTriangle TIndexTriangle;
00135 typedef std::vector<Triangle> TTriangles;
00136 typedef std::vector<TPoint> TVertices;
00137 typedef std::vector<TVector> TNormals;
00138 typedef std::vector<TUv> TUvs;
00139
00140 typedef typename TTriangles::const_iterator TTriangleIterator;
00141 typedef typename TVertices::const_iterator TVertexIterator;
00142 typedef typename TNormals::const_iterator TNormalIterator;
00143 typedef typename TUvs::const_iterator TUvIterator;
00144
00145 TriangleMesh3D();
00146 template <typename VertexInputRange, typename IndexTriangleInputRange>
00147 TriangleMesh3D(
00148 const VertexInputRange& vertices, const IndexTriangleInputRange& triangles);
00149 template <typename VertexInputRange, typename NormalInputRange,
00150 typename UvInputRange, typename IndexTriangleInputRange>
00151 TriangleMesh3D(
00152 const VertexInputRange& vertices, const NormalInputRange& normals,
00153 const UvInputRange& uvs, const IndexTriangleInputRange& triangles);
00154
00155 const TTriangles& triangles() const;
00156 const TVertices& vertices() const;
00157 const TNormals& normals() const;
00158 const TUvs& uvs() const;
00159 template <typename OutputIterator>
00160 OutputIterator indexTriangles(OutputIterator triangles) const;
00161
00162 const TAabb aabb() const;
00163 const TValue area() const;
00164
00165 void smoothNormals(TParam maxAngleInRadians);
00166 void flatFaces();
00167 void loopSubdivision(unsigned level);
00168 void autoSew();
00169 void autoCrease(unsigned level);
00170
00171 const Result intersect(const TRay& ray, TTriangleIterator& triangle, TReference t,
00172 TParam tMin = 0, IntersectionContext* context = 0) const;
00173 const bool intersects(const TRay& ray, TParam tMin, TParam tMax) const;
00174
00175 void swap(TSelf& other);
00176
00177 private:
00178
00179 typedef spat::DefaultAabbRayTraits<TAabb, TRay> TAabbRayTraits;
00180
00181 struct TriangleTraits: public TAabbRayTraits
00182 {
00183 typedef typename TSelf::TTriangle TObject;
00184 typedef typename TSelf::TTriangleIterator TObjectIterator;
00185 typedef const TTriangle& TObjectReference;
00186 typedef void TInfo;
00187
00188 typedef typename TAabbRayTraits::TAabb TAabb;
00189 typedef typename TAabbRayTraits::TRay TRay;
00190 typedef typename TAabbRayTraits::TPoint TPoint;
00191 typedef typename TAabbRayTraits::TVector TVector;
00192 typedef typename TAabbRayTraits::TValue TValue;
00193 typedef typename TAabbRayTraits::TParam TParam;
00194 typedef typename TAabbRayTraits::TReference TReference;
00195 typedef typename TAabbRayTraits::TConstReference TConstReference;
00196
00197 static const TAabb objectAabb(TObjectIterator triangle)
00198 {
00199 TAabb result;
00200 result += *(triangle->vertices[0]);
00201 result += *(triangle->vertices[1]);
00202 result += *(triangle->vertices[2]);
00203 return result;
00204 }
00205 static const bool objectIntersect(TObjectIterator triangle, const TRay& ray,
00206 TReference t, TParam tMin, const TInfo* info)
00207 {
00208 return triangle->intersect(ray, t, tMin) == rOne;
00209 }
00210 static const bool objectIntersects(TObjectIterator triangle, const TRay& ray,
00211 TParam tMin, TParam tMax, const TInfo* info)
00212 {
00213 TValue t;
00214 Result hit = triangle->intersect(ray, t, tMin);
00215 return hit == rOne && t < tMax;
00216 }
00217 };
00218
00219 typedef BoundingVolumeHierarchy<TTriangle, TriangleTraits, SplitHeuristics> TTriangleTree;
00220
00221 struct LogicalEdge
00222 {
00223 Triangle* triangle;
00224 const TPoint* tail;
00225 const TPoint* head;
00226 LogicalEdge(Triangle* triangle, const TPoint* tail, const TPoint* head):
00227 triangle(triangle), tail(tail), head(head) {}
00228 bool operator<(const LogicalEdge& other) const
00229 {
00230 return tail < other.tail || (tail == other.tail && head < other.head);
00231 }
00232 };
00233
00234 struct PositionalEdge
00235 {
00236 Triangle* triangle;
00237 size_t k1;
00238 size_t k2;
00239 PositionalEdge(Triangle* triangle, size_t k1, size_t k2):
00240 triangle(triangle), k1(k1), k2(k2)
00241 {
00242 const TPoint& v1 = *triangle->vertices[k1];
00243 x_[ 0] = v1.x;
00244 x_[ 1] = v1.y;
00245 x_[ 2] = v1.z;
00246 const TPoint& v2 = *triangle->vertices[k2];
00247 x_[ 3] = v2.x;
00248 x_[ 4] = v2.y;
00249 x_[ 5] = v2.z;
00250 }
00251 const bool operator<(const PositionalEdge& other) const
00252 {
00253 for (size_t i = 0; i < size_; ++i)
00254 {
00255 if (x_[i] < other.x_[i]) return true;
00256 if (x_[i] > other.x_[i]) return false;
00257 }
00258 return false;
00259 }
00260 private:
00261 enum { size_ = 6 };
00262 TValue x_[size_];
00263 };
00264
00265 typedef std::vector<const Triangle*> TVertexTriangles;
00266 typedef std::vector<TPoint> TVertexRing;
00267 typedef std::vector<TVector> TNormalRing;
00268 typedef std::vector<TUv> TUvRing;
00269
00270 template <typename IndexTriangleInputRange>
00271 void buildMesh(const IndexTriangleInputRange& triangles);
00272 void connectTriangles();
00273 void findVertexTriangles(TVertexTriangles& vertexTriangles) const;
00274 void findVertexRing(const TPoint& vertex, const Triangle* vertexTriangle,
00275 TVertexRing& ring, TVertexRing& creases, TNormalRing& normals, TUvRing& uvs) const;
00276 void subdivide();
00277
00278 TTriangleTree tree_;
00279 TTriangles triangles_;
00280 TVertices vertices_;
00281 TNormals normals_;
00282 TUvs uvs_;
00283 unsigned numBoundaryEdges_;
00284 };
00285
00286 }
00287
00288 }
00289
00290 #include "triangle_mesh_3d.inl"
00291
00292 #define LASS_PRIM_HAVE_PY_EXPORT_TRAITS_TRIANGLE_MESH_3D
00293 #ifdef LASS_GUARDIAN_OF_INCLUSION_UTIL_PYOBJECT_PLUS_H
00294 # include "pyobject_util.h"
00295 #endif
00296
00297 #ifdef LASS_GUARDIAN_OF_INCLUSION_PRIM_HALF_EDGE_MESH_3D_H
00298 # include "half_edge_mesh_3d_triangle_mesh_3d.h"
00299 #endif
00300
00301 #endif
00302
00303